first
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# Číselníky, výdejní místa a pomocné metody
|
||||
|
||||
## Číselníky
|
||||
|
||||
`GET /codelists/{name}?limit=1000&offset=0` → `GET codelist/{name}` v PPL.
|
||||
Podporované názvy:
|
||||
|
||||
| Název | Obsah |
|
||||
|---|---|
|
||||
| `product` | produkty/služby (BUSS, PRIV, COPL, ...) |
|
||||
| `country` | země + povolení dobírky (COD) |
|
||||
| `currency` | povolené měny |
|
||||
| `service` | doplňkové služby k zásilkám |
|
||||
| `servicePriceLimit` | min/max hodnoty služeb (dobírka, připojištění) |
|
||||
| `ageCheck` | varianty kontroly věku příjemce (15/18+) |
|
||||
| `externalNumber` | typy externích čísel (např. CUST) |
|
||||
| `shipmentPhase` | fáze zásilky |
|
||||
| `status` | statusy zásilky (tracking) |
|
||||
| `validationMessage` | chybové kódy a hlášení |
|
||||
| `proofOfIdentityType` | typy osobních dokladů |
|
||||
| `documentFileType` | typy dokumentů (celní dokumenty) |
|
||||
|
||||
Stránkování se předává v hlavičkách `X-Paging-Total-Items-Count`,
|
||||
`X-Paging-Offset`, `X-Paging-Limit`.
|
||||
|
||||
## Výdejní místa
|
||||
|
||||
`GET /access-points?countryCode=CZ&limit=100&offset=0` → `GET accessPoint`.
|
||||
Filtry: `zipCode`, `city`, `accessPointCode`, `accessPointTypes`
|
||||
(ParcelShop/ParcelBox/AlzaBox), GPS `latitude`+`longitude`+`radius` (km),
|
||||
`pickupEnabled`, `activeCardPayment`, `activeCashPayment`, `sizes` (S/M/L/XL).
|
||||
Odpověď: adresa, otevírací doba, GPS, kapacity dle velikostí.
|
||||
|
||||
## Našeptávač adres
|
||||
|
||||
`GET /address-whisper?street=...&city=...&zipCode=...&calledFrom=Street`
|
||||
→ `GET addressWhisper`. Vrací kandidáty adres vč. pole `valid` —
|
||||
vhodné pro validaci adresy před vytvořením zásilky.
|
||||
|
||||
## Routing
|
||||
|
||||
`GET /routing?country=CZ&zipCode=60200&...` → `GET routing`.
|
||||
Vrací `routeCode`, `depotCode`, `depotPosition`, `region`, `secondWave`.
|
||||
|
||||
## Zákazník
|
||||
|
||||
- `GET /customer` → `GET customer` — bankovní účty (měny pro dobírku, SWIFT)
|
||||
- `GET /customer/addresses` → `GET customer/address` — registrované adresy
|
||||
- `POST /customer/number-range` → `POST customer/numberRange` — přidělení
|
||||
číselné řady zásilek `{productType, quantity}` → `packNumberFrom/To`
|
||||
|
||||
## Ostatní
|
||||
|
||||
- `GET /cpl-info` → `GET info` — stav/verze CPL API
|
||||
- `GET /version-information` → `GET versionInformation` — novinky API
|
||||
- `GET /data/{dataGuid}` → `GET data/{dataGuid}` — binární tisková data etikety
|
||||
|
||||
## Generická proxy
|
||||
|
||||
`/proxy/{cesta}` (GET/POST/PUT/PATCH/DELETE) předá request 1:1 na CPL API
|
||||
s doplněným Bearer tokenem — pokrývá vše, co nemá typovaný endpoint,
|
||||
i budoucí metody. Příklad:
|
||||
|
||||
```
|
||||
GET /proxy/codelist/product?Limit=10&Offset=0
|
||||
POST /proxy/shipment/batch (tělo 1:1 dle PPL dokumentace, bez transliterace)
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
# Objednávky přepravy a svozu
|
||||
|
||||
| Endpoint služby | Upstream CPL | Popis |
|
||||
|---|---|---|
|
||||
| `POST /orders/batch` | `POST order/batch` | vytvoření objednávek (max 100), vrací `batchId` |
|
||||
| `GET /orders/batch/{batchId}` | `GET order/batch/{batchId}` | stav zpracování |
|
||||
| `POST /orders/create-and-wait` | (kombinace) | synchronní obálka |
|
||||
| `GET /orders` | `GET order` | vyhledání objednávek |
|
||||
| `POST /orders/cancel` | `POST order/cancel` | zrušení objednávky |
|
||||
|
||||
## Typy objednávek (`orderType`)
|
||||
|
||||
- **CollectionOrder** — svoz z registrované adresy zákazníka (pravidelní
|
||||
odesílatelé). `recipient` se neuvádí.
|
||||
- **TransportOrder** — vyzvednutí z libovolné adresy; `sender` i `recipient`
|
||||
jsou povinné.
|
||||
|
||||
Povinná pole: `referenceId` (1–50 znaků), `shipmentCount` (1–50), `sendDate`.
|
||||
Volitelné: `productType` (BUSS domácí / IMPO mezinárodní), `customerReference`,
|
||||
`email`, `note`, `sendTimeFrom`, `sendTimeTo`.
|
||||
|
||||
## Stav zpracování
|
||||
|
||||
`GET /orders/batch/{batchId}` vrací `items[]` s `importState`
|
||||
(Accepted/InProcess/Complete/Error) a případným `errorMessage`/`errorCode`.
|
||||
|
||||
## Vyhledání
|
||||
|
||||
`GET /orders?limit=100&offset=0` — filtry: `orderNumbers`, `orderReferences`
|
||||
(= referenceId z batch requestu), `customerReferences`, `shipmentNumbers`,
|
||||
`orderIds`, `dateFrom/dateTo`, `sendDate`, `productType`,
|
||||
`orderStates` (Created, PickedUp, NotPickedUp, Canceled), `orderType`.
|
||||
Odpověď vrací i přidělená čísla zásilek (`shipmentNumbers`).
|
||||
|
||||
## Zrušení
|
||||
|
||||
`POST /orders/cancel?orderReference=ORD-0001` (nebo `customerReference=...`),
|
||||
volitelné tělo `{"note": "důvod"}`.
|
||||
@@ -0,0 +1,94 @@
|
||||
# PPL CPL API — přehled služby
|
||||
|
||||
Stateless multi-tenant proxy nad PPL CPL API (Create Package Label).
|
||||
Upstream: `https://api.dhl.com/ecs/ppl/myapi2` (production),
|
||||
`https://api-dev.dhl.com/ecs/ppl/myapi2` (test).
|
||||
Dokumentace PPL: https://ppl-cpl-api.apidog.io/
|
||||
|
||||
## Autentizace
|
||||
|
||||
Každý request nese hlavičky:
|
||||
|
||||
- `X-Client-Id` — PPL ClientId (secret)
|
||||
- `X-Client-Secret` — PPL ClientSecret (secret)
|
||||
- `X-Environment` — `production` (default) nebo `test`
|
||||
- `Accept-Language` — volitelně, předává se do PPL (např. `cs-CZ`)
|
||||
|
||||
Služba z údajů získá OAuth Bearer token (`POST {base}/login/getAccessToken`,
|
||||
grant `client_credentials`, scope `myapi2`) a **cachuje ho in-memory** pod
|
||||
SHA-256 hashem údajů. Důvod: PPL vydá max. 12 tokenů/min a token platí 30 minut.
|
||||
Token se obnovuje 60 s před expirací; na HTTP 401 z PPL se jednou obnoví
|
||||
a request se zopakuje.
|
||||
|
||||
## Limity PPL, které služba respektuje
|
||||
|
||||
- min. 40 ms rozestup mezi requesty (globální throttle v procesu),
|
||||
- max. 1000 zásilek / 100 objednávek v jednom batchi,
|
||||
- batchId platí 30 dní,
|
||||
- pouze Latin znaky bez diakritiky — viz transliterace níže.
|
||||
|
||||
## Transliterace diakritiky
|
||||
|
||||
CPL API odmítá texty s diakritikou. Těla `POST /shipments/batch`,
|
||||
`/shipments/create-and-wait`, `/orders/batch` a `/orders/create-and-wait`
|
||||
se defaultně rekurzivně transliterují přes unidecode (`Jiří Dvořák` →
|
||||
`Jiri Dvorak`). Chování:
|
||||
|
||||
- query parametr `transliterate=true|false` na requestu má přednost,
|
||||
- jinak platí env `CPL_TRANSLITERATE` (default `true`),
|
||||
- generická `/proxy/...` NEtransliteruje nikdy (předává 1:1).
|
||||
|
||||
## Chybové odpovědi
|
||||
|
||||
Jednotný JSON `{error, message, detail}`; `detail` obsahuje původní
|
||||
problem+json z PPL (typ, title, errors...).
|
||||
|
||||
| Status | Význam |
|
||||
|---|---|
|
||||
| 400 | validační chyba (vstup zde nebo v PPL) |
|
||||
| 401 | chybějící X- hlavičky nebo PPL odmítlo údaje/token |
|
||||
| 403 | chybí oprávnění (role) k metodě v PPL |
|
||||
| 404 | batch/zásilka/objednávka neexistuje |
|
||||
| 429 | rate limit PPL |
|
||||
| 502 | výpadek / neočekávaná chyba PPL |
|
||||
|
||||
Všechny chyby se logují (bez secrets) — žádná tichá selhání.
|
||||
|
||||
## Konfigurace (environment variables)
|
||||
|
||||
| Proměnná | Default | Význam |
|
||||
|---|---|---|
|
||||
| `ROOT_PATH` | `""` | prefix za reverse proxy (`/apps/pplcplapi`) |
|
||||
| `CPL_DEFAULT_ENVIRONMENT` | `production` | prostředí bez hlavičky X-Environment |
|
||||
| `CPL_PRODUCTION_BASE_URL` / `CPL_TEST_BASE_URL` | viz výše | base URL upstreamu |
|
||||
| `CPL_OAUTH_SCOPE` | `myapi2` | OAuth scope |
|
||||
| `CPL_TRANSLITERATE` | `true` | default transliterace diakritiky |
|
||||
| `UPSTREAM_TIMEOUT_SECONDS` | `60` | timeout volání PPL |
|
||||
| `TOKEN_REFRESH_MARGIN_SECONDS` | `60` | předstih obnovy tokenu |
|
||||
| `MIN_REQUEST_INTERVAL_SECONDS` | `0.04` | rozestup requestů na PPL |
|
||||
| `BATCH_POLL_INTERVAL_SECONDS` | `1.0` | interval pollingu create-and-wait |
|
||||
| `BATCH_WAIT_TIMEOUT_SECONDS` | `30` | default timeout create-and-wait |
|
||||
| `LOG_LEVEL` | `INFO` | úroveň logování |
|
||||
|
||||
Žádné secrets se nekonfigurují přes env — vše chodí per-request v hlavičkách.
|
||||
|
||||
## Struktura kódu
|
||||
|
||||
```
|
||||
app/
|
||||
main.py — FastAPI aplikace, root_path, popis pro Swagger
|
||||
config.py — env konfigurace
|
||||
credentials.py — X- hlavičky -> Credentials (dependency)
|
||||
token_cache.py — in-memory cache OAuth tokenů
|
||||
cpl_client.py — autentizovaný httpx klient, throttle, relay helpery
|
||||
transliterate.py — rekurzivní unidecode JSON těl
|
||||
errors.py — typované chyby + handlery
|
||||
routers/
|
||||
meta.py — /health, /version
|
||||
shipments.py — zásilky, etikety, tracking, storno, celní dokumenty
|
||||
orders.py — objednávky svozu/přepravy
|
||||
codelists.py — číselníky, /version-information, /cpl-info
|
||||
lookups.py — /access-points, /address-whisper, /routing, /data/{guid}
|
||||
customer.py — /customer, /customer/addresses, /customer/number-range
|
||||
proxy.py — generická proxy /proxy/{cesta}
|
||||
```
|
||||
@@ -0,0 +1,67 @@
|
||||
# Zásilky
|
||||
|
||||
Tok CPL API je asynchronní (dávkový). Mapování na upstream metody:
|
||||
|
||||
| Endpoint služby | Upstream CPL | Popis |
|
||||
|---|---|---|
|
||||
| `POST /shipments/batch` | `POST shipment/batch` | vytvoření zásilek (max 1000), vrací `batchId` |
|
||||
| `GET /shipments/batch/{batchId}` | `GET shipment/batch/{batchId}` | stav importu |
|
||||
| `GET /shipments/batch/{batchId}/labels` | `GET shipment/batch/{batchId}/label` | binární etikety |
|
||||
| `PUT /shipments/batch/{batchId}/label-settings` | `PUT shipment/batch/{batchId}` | změna formátu etiket |
|
||||
| `POST /shipments/batch/connect-set` | `POST shipment/batch/connectSet` | spojení zásilek do sady |
|
||||
| `POST /shipments/create-and-wait` | (kombinace výše) | synchronní obálka |
|
||||
| `GET /shipments` | `GET shipment` | tracking / vyhledání |
|
||||
| `POST /shipments/{n}/cancel` | `POST shipment/{n}/cancel` | storno (PPL vrací 202) |
|
||||
| `POST /shipments/{n}/redirect` | `POST shipment/{n}/redirect` | úprava kontaktu příjemce |
|
||||
| `POST /shipments/{n}/documents` | `POST shipment/{n}/documents` | celní dokumenty (multipart) |
|
||||
|
||||
## Vytvoření zásilky
|
||||
|
||||
`POST /shipments/batch` — tělo se předává 1:1 do PPL (viz příklad ve Swaggeru).
|
||||
Povinné: `shipments[].referenceId`, `shipments[].productType`,
|
||||
`shipments[].recipient.zipCode` + `country`. Odpověď:
|
||||
|
||||
```json
|
||||
{ "batchId": "1c37...", "location": "https://.../shipment/batch/1c37...", "correlationId": "..." }
|
||||
```
|
||||
|
||||
Query parametr `transliterate` řídí převod diakritiky (default dle služby).
|
||||
|
||||
### Stav importu
|
||||
|
||||
`GET /shipments/batch/{batchId}` vrací `items[]` s `importState`:
|
||||
`Accepted` → `InProcess` → `Complete` (etikety připraveny) / `Error`
|
||||
(`errorMessage`, `errorCode`). Po dokončení obsahuje `labelUrl` per zásilka,
|
||||
příp. `completeLabel.labelUrls` (souhrnné PDF).
|
||||
|
||||
### Etikety
|
||||
|
||||
`GET /shipments/batch/{batchId}/labels?limit=200&offset=0&pageSize=A4&position=1`
|
||||
vrací binární soubor ve formátu z `labelSettings.format`
|
||||
(Pdf / Zpl / Jpeg / Png / Svg; DPI 203–1200). Jednotlivé etikety lze stáhnout
|
||||
i přes `GET /data/{dataGuid}` (guid z `labelUrl`).
|
||||
|
||||
## create-and-wait (doporučeno pro e-shop scénář)
|
||||
|
||||
`POST /shipments/create-and-wait?timeout_seconds=30&include_labels=true`
|
||||
|
||||
1. vytvoří batch,
|
||||
2. polluje stav (interval 1 s) dokud vše není Complete/Error nebo nevyprší timeout,
|
||||
3. s `include_labels=true` stáhne etikety a vrátí je v base64.
|
||||
|
||||
Odpověď: `{batchId, completed, items[], completeLabel, label?: {contentType, base64}}`.
|
||||
`completed=false` = timeout; zpracování v PPL běží dál, stav lze dosledovat
|
||||
přes `GET /shipments/batch/{batchId}` (batchId platí 30 dní).
|
||||
|
||||
## Tracking
|
||||
|
||||
`GET /shipments?shipmentNumbers=...&limit=100&offset=0` — filtry:
|
||||
`shipmentNumbers`, `invoiceNumbers`, `customerReferences`, `variableSymbols`
|
||||
(vše max 50 hodnot, lze opakovat), `dateFrom`, `dateTo`, `shipmentStates`.
|
||||
Odpověď obsahuje tracking události; paging v hlavičkách `X-Paging-*`.
|
||||
|
||||
## Celní dokumenty
|
||||
|
||||
`POST /shipments/{n}/documents?documentFileType=...` — multipart pole `files`
|
||||
(max 5 souborů, 1 MB celkem; pdf, doc(x), xls(x), jpg, jpeg, png, odt, ods, txt).
|
||||
Typy viz `GET /codelists/documentFileType`.
|
||||
Reference in New Issue
Block a user