Metadata-Version: 2.5
Name: qtx-nav-m2m
Version: 0.1.5
Summary: Python client library for the NAV M2M REST API
Author: Pongracz Istvan
License: MIT
Requires-Python: >=3.11
Requires-Dist: httpx<1.0,>=0.28
Requires-Dist: pydantic<3.0,>=2.11
Provides-Extra: dev
Requires-Dist: pytest-asyncio<2.0,>=1.1; extra == 'dev'
Requires-Dist: pytest<9.0,>=8.4; extra == 'dev'
Requires-Dist: ruff<1.0,>=0.12; extra == 'dev'
Description-Content-Type: text/markdown

# qtx-nav-m2m

Python klienskönyvtár a NAV M2M REST API szolgáltatásaihoz.

## Aktuális verzió

- `0.1.5` (2026-08-28): az `adozo` service pénzösszeg-mezői mostantól `Decimal`
  típusúak a korábbi `float` helyett. A tételes adószámla kötelező
  időpontmezői (`tranzakcio_idopontja`, `lekerdezes_idopontja`) hiányos vagy
  érvénytelen NAV-válasz esetén `M2mInvalidResponseError` kivételt dobnak
  csendes `datetime.min` helyettesítés helyett.
- `0.1.4`: a `result_code`-os response modellek közös kényelmi felületet kaptak
  (`is_success`, `is_no_data`, `result_category`, `require_success()`), valamint
  bekerültek a `wait_for_*()` polling metódusok a fájlstátusz-, jogviszony- és
  bizonylat-státusz műveletekhez.
- `0.1.3`: a `bizonylat` service `*_from_path()` metódusai már kiolvassák a
  `bizonylat_tipus` és `bizonylat_verzio` értéket az XML namespace-ből, ha a
  hívó ezeket nem adja meg. Emellett bekerült a központi, maszkolt HTTP-logolás
  a `qtx_nav_m2m.http` loggeren.
- `0.1.2`: típusellenőrzési javítások kerültek be, különösen a `bizonylat`
  modellek Pylance-kompatibilis típusaiban.
- `0.1.1`: ebben a verzióban csak optimalizálás történt, funkcionális bővítés
  nem.

## Cél

Az API-végpontok technikai részleteinek elfedése Python függvényekkel, valamint
a JSON válaszok típusos Python modellekké alakítása.

## Támogatott területek

- `common`: tokenkezelés, nonce beváltása, regisztráció aktiválása, NAV közös
  fájltár
- `bizonylat`: új formátumú bizonylatok kalkulációja, validációja és beküldése
- `adozo`: adózói adatok lekérdezése
- `document`: régi ÁNYK-formátumú bizonylatok kezelése, későbbre hagyva

## Megvalósítási állapot

A `common` végpontok elkészültek és unit tesztekkel ellenőrzöttek:

- token létrehozása
- nonce beváltása és regisztráció aktiválása
- fájl feltöltése a NAV közös fájltárába, majd a vírusellenőrzési állapot
  lekérdezése

## Egylépéses regisztráció

A teljes NAV-regisztrációt a kliens `register()` metódusa vezényli le. A
`nonce` továbbra is bemenő adat, mert ezt a NAV ideiglenes jelszóként kéri a
nonce végponton; a második kulcsrész már a NAV válaszából érkezik.

```python
result = client.register(
    key_first_part="...",
    nonce="...",
    activation_message_id="...",
)

signature_key = result.signature_key
```

Az aktiválás után a kliens automatikusan új access tokent kér, így a
`register()` visszatérésekor a kliens már közvetlenül használható.

## Egységes response-kezelés

Minden olyan response, amely tartalmaz `result_code` mezőt, egységes kényelmi
felületet ad a hívóoldalnak.

Elérhető property-k és metódusok:

- `result_code`
- `result_code_value`
- `result_category`
- `is_success`, `is_no_data`, `is_in_progress`, `is_retryable`
- `is_permission_error`, `is_invalid_input`, `is_invalid_signature`
- `is_business_error`, `is_temporary_error`, `is_other_error`
- `require_success()`

```python
from qtx_nav_m2m import M2mClient, M2mResultError

with M2mClient(config) as client:
    response = client.adozo.get_hianyzo_bevallas("12345678")

    if response.is_no_data:
        print("Nincs hiányzó bevallás.")

    try:
        response.require_success()
    except M2mResultError as exc:
        print(exc.result_code.value)
        print(exc.result_category.value)
        print(exc.result_message)
```

## Adozo service

Az adózói adatlekérdezések a `client.adozo` szolgáltatáson keresztül érhetők
el. A kliens automatikusan generálja a `messageId` értéket, valamint a NAV
specifikáció szerinti signature-t.

Támogatott végpontok:

- összesített és tételes adószámla
- köztartozás-egyenleg
- hiányzó bevallások
- biztosítotti jogviszony és a lekérdezés státusza
- egyszerűsített foglalkoztatás egy foglalkoztatottra vagy foglalkoztatói
  listára
- köztartozás-mentesség (KOMA)

Példa köztartozás-egyenleg lekérdezésére:

```python
from qtx_nav_m2m import M2mClient

with M2mClient(config) as client:
    response = client.adozo.get_koztartozas_egyenleg(
        adoalany_azonosito="12345678",
    )

    response.require_success()

    if response.koztartozas_egyenleg is not None:
        print(response.koztartozas_egyenleg.osszes_eloiras)
```

Az `adozo` service pénzösszeg-mezői a `0.1.5` verziótól `Decimal` típusúak.
Ez kompatibilitási változás a korábbi `float` alapú viselkedéshez képest.

## Bizonylat service

Az új formátumú bizonylatok végpontjai a `client.bizonylat` szolgáltatáson
keresztül érhetők el:

- `create_kalkulacio` és `get_kalkulacio`
- `create_validacio` és `get_validacio`
- `create_bizonylat` és `get_bizonylat`

A létrehozó műveletek `bytes` típusú XML-t fogadnak. A kliens elvégzi az
opcionális GZIP tömörítést, a SHA-256 hash képzését, a NAV signature
előállítását és a Base64 kódolást.

```python
with M2mClient(config) as client:
    response = client.bizonylat.create_validacio(
        bizonylat_tipus="T1042E",
        bizonylat_verzio="1.0",
        bizonylat_xml=b"<Bizonylat />",
    )

    if response.ugy_azonosito is not None:
        status = client.bizonylat.wait_for_validacio(response.ugy_azonosito)
        status.require_success()
```

A `*_from_path()` kényelmi metódusok beolvassák a fájlt, majd a gyökérelem
namespace-éből kiolvassák a `bizonylat_tipus` és `bizonylat_verzio` értéket.
Ha ezek explicit meg vannak adva, akkor a kliens ellenőrzi, hogy egyeznek-e az
XML-lel, és eltérés esetén `ValueError` kivételt dob.

## Polling helper példák

Az aszinkron végpontpároknál a kliens külön `wait_for_*()` kényelmi metódusokat
ad. Ezek addig kérdezik le újra a státuszvégpontot, amíg a feldolgozás
`FOLYAMATBAN` vagy `WAITING` állapotban van, illetve timeout esetén
`TimeoutError` kivételt dobnak.

```python
with M2mClient(config) as client:
    upload = client.common.filestore.add_file(b"payload")
    upload.require_success()

    status = client.common.wait_for_file_status(
        upload.file_id,
        poll_interval_seconds=1.0,
        timeout_seconds=60.0,
    )
    status.require_success()
```

## HTTP logolás

A kliens a központi HTTP-rétegben a `qtx_nav_m2m.http` loggerre ír szűrt,
maszkolt logeseményeket.

Megjelenő események:

- `nav_m2m_request_started`
- `nav_m2m_request_finished`
- `nav_m2m_request_failed`

Az érzékeny mezők, mint az `Authorization`, `signature`, `accessToken`,
`clientSecret` és `password`, maszkoltan kerülnek logolásra. A nagy payloadok,
például a `bizonylatXml`, teljes tartalom helyett csak összefoglaló
metaadatként szerepelnek.

## Dokumentált specifikációs eltérés: bizonylat

A bizonylat specifikációk között két fontos eltérés található:

- az OpenAPI leírás 30 másodperces, a DOCX specifikáció 60 másodperces
  szinkron válaszidőt említ
- a signature műveletfüggő adata a bizonylat XML SHA-256 hash-e, és az
  implementáció ehhez hexadecimális reprezentációt használ

Ezeket az eltéréseket nem fedjük el találgatással; az implementáció és a
tesztek ezt a döntést követik.

## HTTP-kliens és API-verziók

A `M2mClient` egy közös `M2mHttpClient` példányt használ, amelyet az összes
service megoszt.

- a `common` végpontok a `/rest-api/1.1` útvonalat használják
- az `adozo` és `bizonylat` végpontok a saját specifikációjuk szerinti
  `/rest-api/1.0` útvonalon működnek

## Projekt-előkészítés

```powershell
python -m venv .venv
.venv\Scripts\Activate.ps1
.\.venv\Scripts\python.exe -m pip install -U pip
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
```

## Dokumentációk elhelyezése

- A NAV DOCX specifikációk helye: `docs/specifications/`
- A Swagger/OpenAPI YAML fájlok helye: `openapi/`

## Smoke test

A gyökérben található `main.py` placeholder hitelesítési adatokkal meghívja a
token végpontot. Ezzel ellenőrizhető, hogy a NAV szerver elérhető-e:

```powershell
.\.venv\Scripts\python.exe main.py
```
