Перейти до вмісту

Технічне завдання: передача документів для звітності в податкову через Медок для Python

Матеріал з K2 ERP Wiki Ukraine — База знань з автоматизації та санкцій в Україні

SEO title: Технічне завдання: Передача документів для звітності в податкову через M.E.Doc для Python SEO description: Технічне завдання на реалізацію Python-сервісу для передачі документів податкової звітності через інтеграцію з M.E.Doc. SEO keywords: Python, M.E.Doc, Медок, Medoc REST API, податкова звітність, ДПС, API, XML, КЕП, електронна звітність, технічне завдання Alternative to:



Головна ідея: розробити Python-сервіс, який формує, перевіряє, передає та контролює документи податкової звітності через інтеграцію з M.E.Doc / Medoc REST API.

Важливо: M.E.Doc REST API використовується як інтеграційний шар між обліковою системою та програмою M.E.Doc. Для повної реалізації потрібно мати ліцензію/модуль інтеграції, налаштований M.E.Doc, доступ до REST API та офіційну документацію методів.

Технічний стек: Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Docker.

1. Мета

Метою задачі є створення Python-сервісу для передачі документів податкової звітності через M.E.Doc.

Сервіс повинен забезпечити:

  • прийом даних звітності з ERP / облікової системи;
  • формування або прийом готового XML-документа;
  • перевірку документа перед передачею;
  • передачу документа в M.E.Doc;
  • запуск підписання та відправки через M.E.Doc, якщо підтримується API;
  • отримання зовнішнього ID документа;
  • синхронізацію статусів;
  • отримання квитанцій або результатів обробки;
  • збереження історії передачі;
  • обробку помилок;
  • повторну відправку;
  • журналювання всіх технічних і бізнес-подій.

2. Область застосування

Функціонал використовується для автоматизації передачі документів податкової звітності з ERP або облікової системи до M.E.Doc з подальшим поданням до ДПС.

До області задачі входить:

  • створення Python API для прийому документів;
  • створення клієнта інтеграції з M.E.Doc REST API;
  • формування XML або прийом готового XML;
  • збереження документа;
  • перевірка обов'язкових реквізитів;
  • передача документа в M.E.Doc;
  • запуск підписання / відправки через M.E.Doc;
  • отримання статусів;
  • отримання квитанцій;
  • журнал подій;
  • retry-механізм;
  • захист API-ключів і службових доступів;
  • інтеграція з ERP.

До першої версії не входить:

  • повна заміна інтерфейсу M.E.Doc;
  • власна реалізація подання напряму до API ДПС;
  • власна реалізація КЕП, якщо підписання виконується у M.E.Doc;
  • автоматичне оновлення всіх XSD-схем;
  • повноцінний UI для бухгалтера;
  • автоматична бухгалтерська перевірка сум;
  • підтримка всіх типів податкової, статистичної та фінансової звітності.

3. Джерела інтеграції

Компонент Призначення Коментар
M.E.Doc Формування, підписання, відправка та отримання квитанцій по звітності. Основна система для подання звітності.
M.E.Doc REST API Інтеграційний API для роботи з документами. Потрібна активна інтеграція та документація методів.
M.E.Doc Інтеграція Модуль обміну з обліковими системами. Дозволяє переносити первинні документи та регламентовану звітність.
Python-сервіс Інтеграційний шар між ERP та M.E.Doc. Реалізується в межах цього ТЗ.
ERP / облікова система Джерело даних для звітності. Наприклад K2 ERP або інша система.

4. Передумови

Для реалізації задачі необхідно отримати:

  • встановлений та налаштований M.E.Doc;
  • активний модуль M.E.Doc Інтеграція / REST API;
  • мережевий доступ до M.E.Doc API;
  • базовий URL M.E.Doc REST API;
  • спосіб авторизації в API;
  • технічну документацію endpoint-ів;
  • перелік доступних типів звітності;
  • формат передачі файлів;
  • формат метаданих документа;
  • правила створення документа в M.E.Doc;
  • правила підписання документа;
  • правила відправки документа;
  • правила отримання статусів;
  • правила отримання квитанцій;
  • тестовий контур або тестову організацію;
  • технічний контакт з боку постачальника M.E.Doc.

5. Терміни та скорочення

Термін Опис
Python-сервіс Окремий backend-сервіс або модуль, який виконує інтеграцію з M.E.Doc.
M.E.Doc / Медок Програмний комплекс для електронної звітності та документообігу.
Medoc REST API API для інтеграції облікових систем з M.E.Doc.
ДПС Державна податкова служба України.
XML Формат електронного документа звітності.
XSD Схема перевірки XML-документа.
КЕП Кваліфікований електронний підпис.
API Програмний інтерфейс інтеграції.
Webhook Механізм отримання подій від зовнішньої системи.
Polling Періодичне опитування зовнішнього API.
Квитанція Підтвердження прийняття, відхилення або обробки звіту.

6. Архітектура рішення

6.1. Загальна схема

ERP / Accounting System
        |
        | 1. Дані для звітності або готовий XML
        v
Python Tax Reporting Service
        |
        | 2. Валідація та збереження документа
        v
Medoc Integration Adapter
        |
        | 3. Передача документа через Medoc REST API
        v
M.E.Doc
        |
        | 4. Підписання / відправка / обробка
        v
ДПС
        |
        | 5. Квитанції / статуси
        v
M.E.Doc
        |
        | 6. Синхронізація статусів
        v
Python Tax Reporting Service
        |
        | 7. Оновлення статусу в ERP
        v
ERP / Accounting System

6.2. Основні компоненти Python-сервісу

Компонент Опис
API Layer REST API для прийому документів від ERP.
Document Builder Формує XML або приймає готовий файл.
Validation Layer Перевіряє реквізити, структуру та статус документа.
Medoc Client Python-клієнт для роботи з M.E.Doc REST API.
Status Sync Worker Фоновий процес для оновлення статусів.
Receipt Loader Завантажує квитанції та результати обробки.
Storage Layer Зберігає документи, квитанції, статуси та логи.
Audit Logger Фіксує всі дії користувачів і системи.

7. User Story

7.1. Передача документа в M.E.Doc

Як користувач ERP, я хочу передати документ звітності в M.E.Doc без ручного імпорту, щоб скоротити час підготовки та подання звітності.

7.2. Підписання та відправка

Як бухгалтер, я хочу ініціювати підписання та відправку документа через M.E.Doc, щоб не виконувати ці дії вручну в окремому вікні, якщо це підтримується API.

7.3. Отримання статусу

Як бухгалтер, я хочу бачити статус документа в ERP, щоб розуміти, чи документ створено, передано, підписано, відправлено до ДПС, прийнято або відхилено.

7.4. Отримання квитанцій

Як бухгалтер, я хочу отримати квитанції в ERP, щоб мати підтвердження результату подання звітності.

7.5. Повторна відправка

Як користувач, я хочу повторно відправити документ після технічної помилки, щоб не створювати документ заново.

7.6. Технічний аудит

Як адміністратор, я хочу бачити журнал API-запитів і відповідей, щоб швидко знаходити причину помилок інтеграції.

8. Функціональні вимоги

8.1. Створення документа

Python-сервіс повинен приймати документ від ERP.

Мінімальний набір вхідних даних:

Поле Тип Обов'язковість Опис
taxpayer_id string Так РНОКПП або ЄДРПОУ платника.
taxpayer_name string Так Назва компанії або ПІБ ФОП.
report_type string Так Тип звіту або документа.
period string Так Звітний період.
document_number string Так Номер документа.
document_date date Так Дата документа.
file_format string Так XML, PDF, ZIP або інший підтримуваний формат.
file_content_base64 string Так Вміст документа у Base64.
metadata object Ні Додаткові реквізити для M.E.Doc.

8.2. Валідація документа

Перед передачею система повинна перевірити:

  • наявність обов'язкових полів;
  • коректність РНОКПП або ЄДРПОУ;
  • коректність звітного періоду;
  • наявність файлу;
  • допустимий формат файлу;
  • розмір файлу;
  • коректність імені файлу;
  • відповідність XML-структурі;
  • відповідність XSD, якщо схема доступна;
  • відсутність дубля документа;
  • наявність налаштувань інтеграції з M.E.Doc.

8.3. Передача документа в M.E.Doc

Python-сервіс повинен мати метод для передачі документа в M.E.Doc.

Логічний endpoint Python-сервісу:

POST /api/v1/tax-reports/{report_id}/send-to-medoc

Очікувана дія:

  1. Отримати документ із локальної БД.
  2. Перевірити статус документа.
  3. Отримати файл зі сховища.
  4. Підготувати метадані.
  5. Викликати Medoc Integration Adapter.
  6. Отримати зовнішній ID документа в M.E.Doc.
  7. Зберегти зовнішній ID у БД.
  8. Оновити статус документа.
  9. Записати подію в журнал.

8.4. Підписання документа

Система повинна підтримувати один із режимів:

Режим Опис Пріоритет
Підписання в M.E.Doc Документ передається в M.E.Doc, а підписання виконується засобами M.E.Doc. Основний режим.
Підписання в Python-сервісі Python-сервіс підписує документ до передачі в M.E.Doc. Опційно.
Ручне підписання Користувач підписує документ у клієнті M.E.Doc. Резервний режим.

8.5. Відправка документа до ДПС

Якщо M.E.Doc REST API підтримує відповідний метод, Python-сервіс повинен ініціювати відправку документа до ДПС.

Логічний endpoint Python-сервісу:

POST /api/v1/tax-reports/{report_id}/send-to-tax

Очікувана дія:

  1. Перевірити, що документ створено в M.E.Doc.
  2. Перевірити, що документ підписано або готовий до підписання.
  3. Викликати метод M.E.Doc для відправки.
  4. Оновити статус на SentToTax.
  5. Записати подію в журнал.

8.6. Отримання статусів

Система повинна підтримувати два способи оновлення статусів:

Спосіб Опис Пріоритет
Polling Періодичне опитування M.E.Doc REST API. Обов'язково для MVP.
Webhook Отримання подій від M.E.Doc, якщо підтримується. Опційно.

8.7. Отримання квитанцій

Система повинна завантажувати та зберігати:

  • квитанцію №1;
  • квитанцію №2;
  • квитанцію про відхилення;
  • підписаний документ;
  • PDF-візуалізацію, якщо доступна;
  • технічний протокол обробки, якщо доступний;
  • raw-відповідь M.E.Doc.

8.8. Повторна відправка

Повторна відправка дозволена тільки для документів у статусах:

  • ValidationError;
  • Failed;
  • Rejected;
  • DeliveryError;
  • NeedResend.

Повторна відправка не дозволена для статусів:

  • Accepted;
  • SentToTax;
  • WaitingForTaxReceipt;
  • SentToMedoc;
  • WaitingForSignature.

9. Статуси документа

Внутрішній статус Опис
Draft Документ створено, але ще не готовий до передачі.
Generated Файл документа сформовано.
ValidationError Документ не пройшов перевірку.
ReadyToSend Документ готовий до передачі.
Sending Документ передається в M.E.Doc.
SentToMedoc Документ успішно передано в M.E.Doc.
CreatedInMedoc Документ створено в M.E.Doc.
WaitingForSignature Документ очікує підписання.
Signed Документ підписано.
SentToTax Документ передано до ДПС.
WaitingForTaxReceipt Очікується квитанція або результат обробки.
Receipt1Received Отримано квитанцію №1.
Accepted Документ прийнято.
Rejected Документ відхилено.
DeliveryError Помилка доставки.
Failed Технічна помилка.
Cancelled Документ скасовано.

10. Мапінг статусів M.E.Doc

Фінальний мапінг статусів потрібно побудувати після отримання офіційного довідника статусів M.E.Doc.

Попередній логічний мапінг:

Статус M.E.Doc Внутрішній статус Опис
created CreatedInMedoc Документ створено в M.E.Doc.
imported SentToMedoc Документ імпортовано / передано в M.E.Doc.
waiting_signature WaitingForSignature Очікується підпис.
signed Signed Документ підписано.
sent SentToTax Документ відправлено.
receipt_1 Receipt1Received Отримано квитанцію №1.
waiting_receipt WaitingForTaxReceipt Очікується квитанція.
accepted Accepted Документ прийнято.
rejected Rejected Документ відхилено.
error Failed Помилка обробки.

Уточнення: значення статусів є попередніми. Реальні коди статусів потрібно взяти з API-документації M.E.Doc.

11. API Python-сервісу

11.1. Створення документа

POST /api/v1/tax-reports

Приклад тіла запиту:

{
  "taxpayer_id": "1234567890",
  "taxpayer_name": "ФОП Іваненко Іван Іванович",
  "report_type": "single_tax_declaration",
  "period": "2026-Q1",
  "document_number": "DECL-2026-0001",
  "document_date": "2026-04-15",
  "file_format": "xml",
  "file_content_base64": "BASE64_XML_CONTENT",
  "metadata": {
    "source_system": "K2 ERP",
    "created_by": "user@example.com"
  }
}

Очікувана відповідь:

{
  "id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
  "status": "Generated",
  "message": "Document created"
}

11.2. Перевірка документа

POST /api/v1/tax-reports/{report_id}/validate

Очікувана відповідь:

{
  "id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
  "status": "ReadyToSend",
  "errors": []
}

11.3. Передача в M.E.Doc

POST /api/v1/tax-reports/{report_id}/send-to-medoc

Очікувана відповідь:

{
  "id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
  "status": "SentToMedoc",
  "medoc_document_id": "external-document-id",
  "message": "Document sent to M.E.Doc"
}

11.4. Підписання документа

POST /api/v1/tax-reports/{report_id}/sign

Очікувана відповідь:

{
  "id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
  "status": "Signed",
  "message": "Document signed via M.E.Doc"
}

11.5. Відправка до ДПС

POST /api/v1/tax-reports/{report_id}/send-to-tax

Очікувана відповідь:

{
  "id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
  "status": "SentToTax",
  "message": "Document sent to tax authority via M.E.Doc"
}

11.6. Оновлення статусу

POST /api/v1/tax-reports/{report_id}/sync-status

Очікувана відповідь:

{
  "id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
  "old_status": "SentToMedoc",
  "new_status": "WaitingForSignature",
  "medoc_status": "waiting_signature"
}

11.7. Отримання документа

GET /api/v1/tax-reports/{report_id}

11.8. Отримання журналу

GET /api/v1/tax-reports/{report_id}/events

11.9. Завантаження квитанцій

POST /api/v1/tax-reports/{report_id}/download-receipts

11.10. Повторна відправка

POST /api/v1/tax-reports/{report_id}/resend

12. Medoc Integration Client

12.1. Призначення

Medoc Integration Client — це Python-клас або пакет, який інкапсулює роботу з M.E.Doc REST API.

12.2. Основні методи

class MedocClient:
    def create_document(self, document: "DocumentPayload") -> "MedocDocumentResponse":
        pass

    def upload_tax_report(self, document: "DocumentPayload") -> "MedocDocumentResponse":
        pass

    def get_document(self, document_id: str) -> "MedocDocumentResponse":
        pass

    def get_document_status(self, document_id: str) -> "MedocStatusResponse":
        pass

    def sign_document(self, document_id: str) -> "MedocDocumentResponse":
        pass

    def send_document(self, document_id: str) -> "MedocDocumentResponse":
        pass

    def download_original(self, document_id: str) -> bytes:
        pass

    def download_signed_document(self, document_id: str) -> bytes:
        pass

    def download_receipts(self, document_id: str) -> list[bytes]:
        pass

    def cancel_document(self, document_id: str, reason: str) -> "MedocDocumentResponse":
        pass

12.3. Конфігурація клієнта

from pydantic_settings import BaseSettings


class MedocSettings(BaseSettings):
    base_url: str
    api_key: str | None = None
    username: str | None = None
    password: str | None = None
    company_code: str | None = None
    timeout_seconds: int = 30
    retry_count: int = 3
    retry_backoff_seconds: int = 5
    verify_ssl: bool = True

Приклад змінних середовища:

MEDOC_BASE_URL=http://medoc-server.local:8080
MEDOC_API_KEY=********
MEDOC_USERNAME=integration_user
MEDOC_PASSWORD=********
MEDOC_COMPANY_CODE=12345678
MEDOC_TIMEOUT_SECONDS=30
MEDOC_RETRY_COUNT=3
MEDOC_RETRY_BACKOFF_SECONDS=5

Заборонено: зберігати API key, паролі, токени або паролі КЕП у коді, Git-репозиторії чи відкритих логах.

13. Передача документа в M.E.Doc

13.1. Логічний процес

1. Отримати документ з БД.
2. Перевірити, що документ має статус ReadyToSend.
3. Отримати файл зі сховища.
4. Підготувати метадані.
5. Викликати MedocClient.upload_tax_report().
6. Отримати ID документа в M.E.Doc.
7. Зберегти ID у локальній БД.
8. Оновити статус на SentToMedoc.
9. Записати подію в журнал.

13.2. Приклад Python-логіки

from uuid import UUID
from datetime import datetime, timezone


def send_report_to_medoc(report_id: UUID, db: "Session") -> "TaxReport":
    report = tax_report_repository.get_by_id(db, report_id)

    if report.status != TaxReportStatus.READY_TO_SEND:
        raise InvalidStatusError(
            f"Report {report_id} cannot be sent from status {report.status}"
        )

    file_bytes = file_storage.read(report.file_path)

    payload = DocumentPayload(
        title=report.title,
        number=report.document_number,
        date=report.document_date,
        file_name=report.file_name,
        file_content=file_bytes,
        file_format=report.file_format,
        metadata={
            "taxpayer_id": report.taxpayer_id,
            "taxpayer_name": report.taxpayer_name,
            "report_type": report.report_type,
            "period": report.period,
            "source_system": report.source_system,
        },
    )

    response = medoc_client.upload_tax_report(payload)

    report.medoc_document_id = response.id
    report.status = TaxReportStatus.SENT_TO_MEDOC
    report.sent_at = datetime.now(timezone.utc)

    audit_logger.log(
        entity_id=report.id,
        event_type="SENT_TO_MEDOC",
        details={
            "medoc_document_id": response.id,
            "raw_status": response.status,
        },
    )

    db.commit()
    return report

14. Підписання та відправка через M.E.Doc

14.1. Логічний процес підписання

1. Перевірити, що документ створено в M.E.Doc.
2. Перевірити, що документ не був відправлений раніше.
3. Викликати метод підписання M.E.Doc.
4. Отримати результат підписання.
5. Оновити статус на Signed або Failed.
6. Записати подію в журнал.

14.2. Логічний процес відправки

1. Перевірити, що документ підписано.
2. Викликати метод відправки M.E.Doc.
3. Отримати результат відправки.
4. Оновити статус на SentToTax або Failed.
5. Запустити очікування квитанцій.
6. Записати подію в журнал.

14.3. Приклад Python-логіки

def sign_and_send_report(report_id: UUID, db: "Session") -> "TaxReport":
    report = tax_report_repository.get_by_id(db, report_id)

    if not report.medoc_document_id:
        raise InvalidStatusError("Report is not created in M.E.Doc")

    if report.status not in {
        TaxReportStatus.SENT_TO_MEDOC,
        TaxReportStatus.CREATED_IN_MEDOC,
        TaxReportStatus.WAITING_FOR_SIGNATURE,
    }:
        raise InvalidStatusError(
            f"Report {report_id} cannot be signed from status {report.status}"
        )

    sign_response = medoc_client.sign_document(report.medoc_document_id)

    report.status = TaxReportStatus.SIGNED
    audit_logger.log(
        entity_id=report.id,
        event_type="SIGNED_IN_MEDOC",
        details={"raw_status": sign_response.status},
    )

    send_response = medoc_client.send_document(report.medoc_document_id)

    report.status = TaxReportStatus.SENT_TO_TAX
    report.sent_to_tax_at = datetime.now(timezone.utc)

    audit_logger.log(
        entity_id=report.id,
        event_type="SENT_TO_TAX",
        details={"raw_status": send_response.status},
    )

    db.commit()
    return report

15. Робота зі статусами

15.1. Фонове оновлення

Система повинна мати background worker, який періодично оновлює статуси документів.

Рекомендована періодичність:

Статус документа Інтервал перевірки
SentToMedoc кожні 5 хвилин
CreatedInMedoc кожні 5 хвилин
WaitingForSignature кожні 15 хвилин
SentToTax кожні 10 хвилин
WaitingForTaxReceipt кожні 10 хвилин
Receipt1Received кожні 10 хвилин
Accepted / Rejected не перевіряти

15.2. Приклад worker-а

def sync_pending_reports() -> None:
    reports = tax_report_repository.get_reports_for_sync()

    for report in reports:
        try:
            medoc_status = medoc_client.get_document_status(
                report.medoc_document_id
            )

            new_status = status_mapper.map_medoc_status(medoc_status)

            if new_status != report.status:
                old_status = report.status

                tax_report_repository.update_status(
                    report_id=report.id,
                    new_status=new_status,
                    raw_status=medoc_status.raw_status,
                )

                audit_logger.log(
                    entity_id=report.id,
                    event_type="STATUS_CHANGED",
                    details={
                        "old_status": old_status,
                        "new_status": new_status,
                        "medoc_status": medoc_status.raw_status,
                    },
                )

        except Exception as exc:
            audit_logger.log(
                entity_id=report.id,
                event_type="STATUS_SYNC_FAILED",
                details={"error": str(exc)},
            )

16. Модель даних

16.1. tax_reports

Поле Тип Опис
id uuid Внутрішній ID документа.
taxpayer_id varchar РНОКПП або ЄДРПОУ.
taxpayer_name varchar Назва платника.
report_type varchar Тип звіту.
period varchar Звітний період.
document_number varchar Номер документа.
document_date date Дата документа.
title varchar Назва документа.
file_name varchar Назва файлу.
file_path varchar Шлях до файлу у сховищі.
file_format varchar XML, PDF, ZIP тощо.
status varchar Внутрішній статус.
medoc_document_id varchar ID документа у M.E.Doc.
medoc_raw_status varchar Останній raw-статус M.E.Doc.
last_sync_at timestamp Дата останньої синхронізації.
sent_at timestamp Дата передачі в M.E.Doc.
sent_to_tax_at timestamp Дата відправки до ДПС.
accepted_at timestamp Дата прийняття.
rejected_at timestamp Дата відхилення.
error_message text Остання помилка.
source_system varchar ERP або інша система-джерело.
created_at timestamp Дата створення.
updated_at timestamp Дата оновлення.

16.2. tax_report_events

Поле Тип Опис
id uuid ID події.
report_id uuid ID документа.
event_type varchar Тип події.
old_status varchar Попередній статус.
new_status varchar Новий статус.
payload jsonb Технічні дані події.
created_by varchar Користувач або system.
created_at timestamp Дата події.

16.3. tax_report_files

Поле Тип Опис
id uuid ID файлу.
report_id uuid ID документа.
file_type varchar original, signed, pdf, receipt_1, receipt_2, error_protocol.
file_name varchar Назва файлу.
file_path varchar Шлях до файлу.
content_type varchar MIME-тип.
size_bytes integer Розмір файлу.
created_at timestamp Дата створення.

17. Обробка помилок

17.1. Типи помилок

Тип помилки Опис Дія системи
ValidationError Некоректні дані документа. Не відправляти документ, показати список помилок.
MedocAuthError Помилка авторизації в M.E.Doc API. Зупинити відправку, повідомити адміністратора.
MedocApiError API повернув помилку. Записати відповідь API, дозволити повтор.
MedocTimeoutError Перевищено час очікування. Виконати retry.
MedocUnavailableError Сервер M.E.Doc недоступний. Повторити пізніше, повідомити адміністратора.
DuplicateDocumentError Документ вже був переданий. Заборонити повтор без підтвердження.
FileStorageError Неможливо прочитати або записати файл. Зафіксувати помилку, повідомити адміністратора.
StatusMappingError Невідомий статус від M.E.Doc. Зберегти raw-статус, створити подію UnknownStatus.
SignatureError Помилка підписання документа. Зберегти помилку, дозволити повторне підписання.

17.2. Retry-логіка

Retry застосовується для:

  • timeout;
  • тимчасової недоступності M.E.Doc API;
  • HTTP 429;
  • HTTP 500;
  • HTTP 502;
  • HTTP 503;
  • HTTP 504;
  • тимчасових мережевих помилок.

Retry не застосовується для:

  • помилок валідації;
  • неправильного API key;
  • відсутності прав доступу;
  • відхилення документа податковою;
  • дублювання документа;
  • некоректного формату файлу;
  • помилки КЕП через неправильний пароль.

18. Безпека

Система повинна забезпечити:

  • зберігання API key тільки у змінних середовища або secret storage;
  • заборону логування API key;
  • заборону зберігання паролів КЕП у відкритому вигляді;
  • маскування персональних даних у технічних логах;
  • контроль доступу до документів;
  • контроль доступу до квитанцій;
  • журналювання всіх операцій;
  • HTTPS для API-запитів, якщо M.E.Doc API розгорнутий з TLS;
  • перевірку SSL-сертифіката, якщо використовується HTTPS;
  • обмеження доступу до адміністративних endpoint-ів;
  • резервне копіювання документів і квитанцій.

19. Налаштування

19.1. Змінні середовища

APP_ENV=production
DATABASE_URL=postgresql+psycopg://user:password@db:5432/reports
FILE_STORAGE_PATH=/data/tax-reports

MEDOC_BASE_URL=http://medoc-server.local:8080
MEDOC_API_KEY=********
MEDOC_USERNAME=integration_user
MEDOC_PASSWORD=********
MEDOC_COMPANY_CODE=12345678
MEDOC_TIMEOUT_SECONDS=30
MEDOC_RETRY_COUNT=3
MEDOC_RETRY_BACKOFF_SECONDS=5

STATUS_SYNC_ENABLED=true
STATUS_SYNC_INTERVAL_SECONDS=300
RECEIPT_DOWNLOAD_ENABLED=true

19.2. Конфігурація типів документів

document_types:
  single_tax_declaration:
    title: "Декларація платника єдиного податку"
    allowed_formats:
      - xml
      - pdf
    requires_signature: true
    requires_receipt: true

  tax_request:
    title: "Запит до податкової"
    allowed_formats:
      - xml
      - pdf
    requires_signature: true
    requires_receipt: true

  unified_report:
    title: "Об'єднана звітність"
    allowed_formats:
      - xml
      - zip
    requires_signature: true
    requires_receipt: true

  vat_declaration:
    title: "Декларація з ПДВ"
    allowed_formats:
      - xml
      - zip
    requires_signature: true
    requires_receipt: true

20. Логування та аудит

Система повинна логувати:

Подія Що зберігати
Створення документа ID, користувач, дата, тип документа.
Валідація Результат, список помилок.
Передача в M.E.Doc Endpoint, час, статус відповіді, зовнішній ID.
Підписання Результат, дата, raw-відповідь M.E.Doc.
Відправка до ДПС Результат, дата, raw-відповідь M.E.Doc.
Помилка API HTTP-код, тіло відповіді, correlation ID.
Оновлення статусу Старий статус, новий статус, raw-статус M.E.Doc.
Завантаження квитанції Тип файлу, назва, дата.
Повторна відправка Причина, користувач, дата.
Скасування документа Причина, користувач, дата.

21. Acceptance Criteria

21.1. Створення документа

Критерій Очікуваний результат
AC-1 ERP передає дані документа у Python-сервіс. У системі створюється запис tax_reports.
AC-2 Передано файл документа. Файл зберігається у файловому сховищі.
AC-3 Передано некоректні дані. Система повертає список помилок валідації.

21.2. Передача в M.E.Doc

Критерій Очікуваний результат
AC-4 Документ має статус ReadyToSend. Система дозволяє передачу в M.E.Doc.
AC-5 M.E.Doc API повертає успішну відповідь. У документі зберігається medoc_document_id.
AC-6 M.E.Doc повертає помилку. Система зберігає помилку та не втрачає документ.
AC-7 Документ вже був переданий. Система не створює дубль без окремого підтвердження.

21.3. Підписання та відправка

Критерій Очікуваний результат
AC-8 Документ створено в M.E.Doc. Система дозволяє ініціювати підписання.
AC-9 Підписання виконано успішно. Статус документа змінюється на Signed.
AC-10 Документ підписано. Система дозволяє відправку до ДПС.
AC-11 Відправка виконана успішно. Статус документа змінюється на SentToTax.

21.4. Статуси

Критерій Очікуваний результат
AC-12 Worker запускає синхронізацію. Статуси документів оновлюються автоматично.
AC-13 M.E.Doc повертає новий статус. Внутрішній статус документа змінюється.
AC-14 M.E.Doc повертає невідомий статус. Raw-статус зберігається, створюється подія UnknownStatus.

21.5. Квитанції та файли

Критерій Очікуваний результат
AC-15 Документ прийнято. Система завантажує квитанцію №2 або результат обробки.
AC-16 Документ відхилено. Система зберігає причину відхилення.
AC-17 Користувач відкриває картку документа. Він бачить всі пов'язані файли та статуси.

22. MVP

До MVP входить:

  • REST API для створення документа;
  • збереження документа;
  • базова валідація;
  • Medoc Integration Client;
  • передача документа в M.E.Doc;
  • збереження зовнішнього ID;
  • ручний запуск синхронізації статусу;
  • журнал подій;
  • базова обробка помилок.

До MVP не входить:

  • webhook-інтеграція;
  • інтеграція напряму з ДПС;
  • власний модуль КЕП;
  • складний UI;
  • автоматичне оновлення XSD;
  • підтримка всіх типів звітності;
  • автоматичне створення декларацій з бухгалтерських даних.

23. Етапи реалізації

Етап 1. Базова структура Python-сервісу

  • створити FastAPI-проєкт;
  • налаштувати PostgreSQL;
  • створити моделі tax_reports, tax_report_events, tax_report_files;
  • реалізувати конфігурацію через environment variables;
  • реалізувати healthcheck endpoint.

Етап 2. Робота з документами

  • реалізувати створення документа;
  • реалізувати збереження файлу;
  • реалізувати валідацію;
  • реалізувати статуси;
  • реалізувати журнал подій.

Етап 3. Medoc Integration Client

  • реалізувати авторизацію;
  • реалізувати upload_tax_report;
  • реалізувати create_document;
  • реалізувати get_document_status;
  • реалізувати download_document;
  • реалізувати download_receipts;
  • реалізувати обробку помилок;
  • реалізувати retry.

Етап 4. Передача документів

  • реалізувати endpoint send-to-medoc;
  • зберігати medoc_document_id;
  • оновлювати статуси;
  • логувати API-взаємодію.

Етап 5. Підписання та відправка

  • реалізувати sign endpoint;
  • реалізувати send-to-tax endpoint;
  • обробити помилки КЕП;
  • обробити помилки відправки;
  • фіксувати всі етапи в журналі.

Етап 6. Синхронізація статусів

  • реалізувати background worker;
  • реалізувати періодичне оновлення статусів;
  • реалізувати мапінг статусів;
  • реалізувати обробку невідомих статусів.

Етап 7. Квитанції та результати обробки

  • реалізувати завантаження квитанцій;
  • реалізувати збереження PDF/XML/receipt-файлів;
  • реалізувати прив'язку файлів до документа;
  • реалізувати перегляд історії.

Етап 8. Production hardening

  • додати Dockerfile;
  • додати docker-compose;
  • додати structured logging;
  • додати metrics;
  • додати alerting;
  • додати rate limiting;
  • додати security review.

24. Ризики

Ризик Опис Як зменшити
Неповна або закрита API-документація Частина методів M.E.Doc може бути доступна лише в межах ліцензійного модуля. Отримати офіційну документацію та тестовий доступ.
Залежність від локального M.E.Doc API може працювати тільки за наявності встановленого та налаштованого M.E.Doc. Передбачити healthcheck M.E.Doc API.
Зміна API Endpoint-и або формати відповіді можуть змінюватися. Інкапсулювати API в окремому MedocClient.
Невідомі статуси M.E.Doc може повертати статуси, яких немає в системі. Зберігати raw-статус та мати UnknownStatus.
Дублювання документів Повторна відправка може створити дубль. Перевіряти medoc_document_id перед відправкою.
Помилки авторизації Доступ до API може бути неправильним або простроченим. Додати healthcheck інтеграції та повідомлення адміністратору.
Недоступність M.E.Doc Сервер M.E.Doc або мережа можуть бути тимчасово недоступні. Використовувати retry та чергу задач.
Помилки КЕП Можливі проблеми з ключами, паролями або сертифікатами. Відображати зрозумілу помилку та дозволяти повторне підписання.
Персональні дані Документи можуть містити РНОКПП, ЄДРПОУ, фінансові дані. Маскувати логи та обмежити доступ.

25. Відкриті питання

  1. Яка версія M.E.Doc використовується?
  2. Чи активований модуль M.E.Doc REST API / Інтеграція?
  3. Який базовий URL API?
  4. Який механізм авторизації використовується?
  5. Які endpoint-и використовуються для створення документа?
  6. Які endpoint-и використовуються для підписання?
  7. Які endpoint-и використовуються для відправки?
  8. Які endpoint-и використовуються для отримання статусів?
  9. Які endpoint-и використовуються для отримання квитанцій?
  10. Який формат документа підтримується: XML, PDF, ZIP, JSON?
  11. Чи Python-сервіс має сам формувати XML, чи отримує готовий XML з ERP?
  12. Де виконується КЕП: у Python-сервісі, у M.E.Doc або користувачем у клієнті M.E.Doc?
  13. Чи потрібна підтримка ФОП, юридичних осіб або обох варіантів?
  14. Які типи звітів підтримуються першими?
  15. Чи є тестове середовище?
  16. Чи підтримуються webhook-и?
  17. Який SLA по оновленню статусів?
  18. Де зберігати файли: локально, S3, MinIO, DMS?
  19. Хто має доступ до API key?
  20. Чи потрібно робити UI, чи тільки backend API?

26. Приклад структури Python-проєкту

tax_reporting_medoc_service/
  app/
    main.py
    config.py
    api/
      routes/
        tax_reports.py
        health.py
    core/
      security.py
      logging.py
      exceptions.py
    db/
      session.py
      models.py
      migrations/
    services/
      tax_report_service.py
      validation_service.py
      status_sync_service.py
      receipt_service.py
      signing_service.py
    integrations/
      medoc/
        client.py
        schemas.py
        status_mapper.py
        exceptions.py
    repositories/
      tax_report_repository.py
      event_repository.py
      file_repository.py
    workers/
      sync_statuses.py
      download_receipts.py
    storage/
      file_storage.py
  tests/
    unit/
    integration/
  Dockerfile
  docker-compose.yml
  pyproject.toml
  README.md

27. Технічні вимоги до Python

Компонент Рекомендація
Python 3.11 або вище.
Web framework FastAPI.
HTTP client httpx.
Validation Pydantic.
ORM SQLAlchemy.
DB PostgreSQL.
Migrations Alembic.
Background jobs Celery, RQ або APScheduler.
Tests pytest.
Containers Docker.
Logging structlog або стандартний logging у JSON-форматі.

28. Definition of Done

Задача вважається завершеною, якщо:

  • Python-сервіс розгортається через Docker;
  • API створення документа працює;
  • документ зберігається у БД та файловому сховищі;
  • документ проходить валідацію;
  • документ передається в M.E.Doc;
  • зовнішній ID документа зберігається;
  • статус документа оновлюється;
  • помилки API обробляються;
  • retry-механізм працює;
  • журнал подій заповнюється;
  • написані unit-тести для ключових сервісів;
  • написані інтеграційні тести для MedocClient з mock API;
  • документація для запуску додана в README;
  • фінальні endpoint-и M.E.Doc винесені в конфігурацію.

29. Джерела

30. Див. також