#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys as _sys _sys.stdout.reconfigure(encoding="utf-8", errors="replace") _sys.stderr.reconfigure(encoding="utf-8", errors="replace") """ zadej_davku.py ============== Odešle asynchronní požadavek na VZP B2B službu SeznamRegPojistencuB2B (seznam zakapitovaných/registrovaných pojištěnců za dané období). Použití: python zadej_davku.py [mesic] [rok] python zadej_davku.py 2 2025 # únor 2025 python zadej_davku.py # předchozí měsíc (výchozí) Výstup: - korelační ID zprávy (pro pozdější spárování asynchronní odpovědi) - stavVyrizeniPozadavku=2 znamená "přijato, VZP zpracovává" - finální odpověď přijde asynchronně na AS2 endpoint partnera """ import sys import uuid import argparse from pathlib import Path from datetime import date, timedelta from requests_pkcs12 import Pkcs12Adapter import requests import xml.etree.ElementTree as ET # ── KONFIGURACE ─────────────────────────────────────────────────────────────── PFX_PATH = Path(__file__).resolve().parent.parent / "Certificates" / "picka.pfx" PFX_PASSWORD = "Vlado7309208104+" ICZ = "09305000" ENV = "prod" NS_VZP = "http://xmlns.gemsystem.cz/SeznamRegPojistencuB2B" NS_COMMON = "http://xmlns.gemsystem.cz/CommonB2B" NS_SOAP = "http://schemas.xmlsoap.org/soap/envelope/" ENDPOINT_SIMU = "https://simu.b2b.vzp.cz/B2BProxy/HttpProxy/SIMUSeznamRegPojistencuB2B?sluzba=SIMUSeznamRegPojistencuB2B" ENDPOINT_PROD = "https://prod.b2b.vzp.cz/B2BProxy/HttpProxy/SeznamRegPojistencuB2B" # ── ARGUMENTY ──────────────────────────────────────────────────────────────── parser = argparse.ArgumentParser(description="Požadavek na seznam registrovaných pojištěnců VZP") parser.add_argument("mesic", nargs="?", type=int, help="Měsíc (1-12)") parser.add_argument("rok", nargs="?", type=int, help="Rok (např. 2025)") parser.add_argument("--simu", action="store_true", help="Použít simulační prostředí") parser.add_argument("--pdf", action="store_true", help="Výstup jako PDF (výchozí: text/plain)") args = parser.parse_args() # Výchozí: předchozí měsíc if args.mesic and args.rok: mesic, rok = args.mesic, args.rok else: prvni_tohoto = date.today().replace(day=1) predchozi = prvni_tohoto - timedelta(days=1) mesic, rok = predchozi.month, predchozi.year format_vystupu = "application/pdf" if args.pdf else "text/plain" endpoint = ENDPOINT_SIMU if args.simu else ENDPOINT_PROD # ── KONTROLY ───────────────────────────────────────────────────────────────── if not PFX_PATH.exists(): print(f"CHYBA: certifikát nenalezen: {PFX_PATH}") sys.exit(1) if not (1 <= mesic <= 12): print(f"CHYBA: neplatný měsíc: {mesic}") sys.exit(1) # ── SESTAVENÍ POŽADAVKU ─────────────────────────────────────────────────────── id_zpravy = uuid.uuid4().hex[:12].upper() soap = f""" {id_zpravy} {ICZ} {id_zpravy} {ICZ} zp {mesic} {rok} {format_vystupu} """ # ── ODESLÁNÍ ───────────────────────────────────────────────────────────────── print(f"Období: {mesic:02d}/{rok}") print(f"Formát: {format_vystupu}") print(f"Prostředí: {'SIMU' if args.simu else 'PROD'}") print(f"IČZ: {ICZ}") print(f"ID zprávy: {id_zpravy}") print(f"Endpoint: {endpoint}") print() session = requests.Session() session.mount("https://", Pkcs12Adapter( pkcs12_filename=str(PFX_PATH), pkcs12_password=PFX_PASSWORD )) try: resp = session.post( endpoint, data=soap.encode("utf-8"), headers={"Content-Type": "text/xml; charset=utf-8", "SOAPAction": "process"}, timeout=30 ) except requests.RequestException as e: print(f"CHYBA při spojení: {e}") sys.exit(1) print(f"HTTP status: {resp.status_code}") print() # ── PARSOVÁNÍ ODPOVĚDI ──────────────────────────────────────────────────────── if not resp.content: print("→ Požadavek přijat (prázdná odpověď = asynchronní služba).") print(f"→ VZP zpracuje a odešle výsledek na AS2 endpoint.") print(f"→ ID zprávy pro spárování: {id_zpravy}") else: try: root = ET.fromstring(resp.text) NS = {"soap": NS_SOAP, "vzp": NS_VZP} korelace = root.find(".//vzp:korelaceZpravy", NS) text_odp = root.find(".//vzp:textOdpovedi", NS) stav = root.find(".//vzp:stavVyrizeniPozadavku", NS) print(f"Korelace zprávy: {korelace.text if korelace is not None else '–'}") print(f"Text odpovědi: {text_odp.text if text_odp is not None else '–'}") print(f"Stav vyřízení: {stav.text if stav is not None else '–'}") if stav is not None and stav.text == "2": print() print("→ VZP zpracovává — finální odpověď přijde asynchronně na AS2 endpoint.") print(f"→ ID zprávy pro spárování: {id_zpravy}") except ET.ParseError: print("Nepodařilo se parsovat XML odpověď:") print(resp.text)