Metadata-Version: 2.5
Name: qtx-nav-m2m
Version: 0.1.0
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.

## 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ás, 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

A kliens futás közben is használható új tokennel és a regisztráció után összeálló
végleges aláírókulccsal. A `set_config()` új HTTP-klienst hoz létre, és eldobja a
régi tokeneket és a hozzájuk tartozó runtime állapotot.

## 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ó.

## Adózó 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ásmentessé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",
    )

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

## 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. A státuszlekérdezésekhez az indító művelet
által visszaadott `ugy_azonosito` szükséges.

```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.get_validacio(response.ugy_azonosito)
```

A `*_from_path()` kényelmi metódusok csak beolvassák a fájlt, majd továbbadják
a meglévő `bytes`-os API-nak. Ez hasznos a fájlválasztós felhasználói flow-nál,
de a core logikát nem duplikálja.

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

A bizonylat specifikációk között két 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. A hash
  reprezentációját az OpenAPI nem részletezi, ezért a NAV általános
  interfészpéldáját követve a hexadecimális SHA-256 értéket használjuk.

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 token és a közös HTTP-beállítások így minden service számára
elérhetők.

A `common.filestore` nem ugyanaz, mint a `bizonylat` service:

- a `common.filestore` a NAV közös fájltárába tölt fel egy nyers fájlt, majd a
  fájlazonosító alapján a feldolgozási állapotot lehet lekérdezni;
- a `bizonylat` service XML-alapú NAV dokumentumküldést kezel, saját signature-
  és payload-szabályokkal.

Az API-verzió nem a klienshez kötött, hanem az egyes kéréseknél adható meg. Ez
lehetővé teszi, hogy a common végpontok a `/rest-api/1.1`, míg például az adozo
végpontok a saját specifikációjuk szerinti `/rest-api/1.0` útvonalon működjenek
ugyanazzal a HTTP-klienssel és tokennel.

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

```bash
python -m venv .venv
```

Windows PowerShell:

```powershell
.venv\Scripts\Activate.ps1
python -m pip install -U pip
python -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/`

Ezek a forrásanyagok nincsenek a kezdőcsomagba bemásolva.

## Forráskód és aktuális mappastruktúra

```text
qtx_nav_m2m/
├── main.py
├── openapi/
├── docs/
├── README.md
├── src/
│   └── qtx_nav_m2m/
│       ├── __init__.py
│       ├── client.py
│       ├── config.py
│       ├── core/
│       │   ├── authentication.py
│       │   ├── exceptions.py
│       │   ├── http_client.py
│       │   ├── message.py
│       │   └── signature.py
│       └── services/
│           ├── adozo/
│           │   ├── _base.py
│           │   ├── employment.py
│           │   ├── legal_relationship.py
│           │   ├── models/
│           │   ├── public_debt.py
│           │   ├── returns.py
│           │   ├── service.py
│           │   └── tax_account.py
│           ├── bizonylat/
│           │   ├── models/
│           │   └── service.py
│           └── common/
│               ├── __init__.py
│               ├── filestore.py
│               ├── models/
│               ├── registration.py
│               └── token.py
└── tests/
    └── test_package.py
```

## 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
```
