# run_all_v1.1.py — IWRS: kompletní pipeline Pacienti + Léky

**Verze:** 1.1 | **Datum:** 2026-06-10

- **v1.1:** všechny moduly pipeline přesunuty na úroveň `IWRS/` — adresáře
  `Patients/` a `Drugs/` už pipeline nepotřebuje. Worker přejmenován:
  `Patients/import_to_mongo.py` → `import_patients_mongo.py`; parsery notifikací
  vyčleněny do `notification_parsers.py` (bez závislosti na MySQL).
- **v1.0:** první verze sjednocené pipeline (nahradila `Drugs/run_all.py`
  a `Patients/download_all.py`+`import_all.py`).

Jeden vstupní skript na úrovni `IWRS/`, který stáhne z janssen.4gclinical.com
a naimportuje do MongoDB (db `studie`) data pacientů i léků pro obě studie
(77242113UCO3001, 42847922MDD3003).

## Tok souborů

```
IWRS/Incoming/            ← sem padá vše stažené (pacienti i léky, datumované názvy)
IWRS/Incoming/Processed/  ← sem se přesouvá po úspěšném importu
```

- Při chybě importu soubor **zůstává v Incoming/** a zpracuje se při příštím běhu.
- Import jde vždy **nejstarší soubor napřed** (mtime) — chronologická správnost snapshotů.
- Kolize jména v Processed/ → přepíše se (Mongo už data má, soubor je jen archiv).
- Adresář `IWRS/Incoming/` je v `.gitignore`.
- Původní adresáře `Drugs/xls_*` zůstávají zmrazené na místě jako archiv — nový kód je nepoužívá.

## Názvy souborů v Incoming/

| Typ | Vzor |
|---|---|
| Subject Summary | `YYYY-MM-DD {study} Subject Summary Report.xlsx` |
| Subject Detail | `YYYY-MM-DD {study} {subject} Subject Detail.xlsx` |
| Notifikace | `{datum}_{study}_{subject}_{label}.pdf` + `.json` |
| Onsite Inventory | `YYYY-MM-DD {study} Onsite Inventory {site}.xlsx` |
| IP Destruction | `YYYY-MM-DD {study} IP Destruction {basket}.xlsx` |
| Shipments Report | `YYYY-MM-DD {study} Shipments Report.xlsx` |
| Shipment Details | `YYYY-MM-DD {study} Shipment Details {shipment_id}.xlsx` |

Při kolizi (druhý běh ve stejný den) se před příponu přidá ` HHMM`.
Metadata (site, basket, study) se při importu čtou primárně z **obsahu** souboru;
z názvu se bere jen `shipment_id` u Shipment Details.

## Průběh

### Fáze 1 — stahování (2 přihlášení, per studie jedna browser session)

1. Login + výběr studie (`common/iwrs_portal.py`)
2. **Pacienti** (`download_patients.py`):
   - Subject Summary Report
   - per subjekt: Subject Detail XLSX + notifikace PDF+JSON (stahují se jen
     notifikace, jejichž `pk` ještě není v Mongo `iwrs_notifications`)
3. **Léky** (`download_drugs.py`):
   - Onsite Inventory — všechna centra, vždy znovu
   - IP Destruction — přeskočí košíky už importované v `iwrs_destruction`
     (destrukce je immutable)
   - Shipments Report — vždy znovu
   - Shipment Details — jen CZ zásilky; přeskočí zásilky, jejichž položky
     jsou v `iwrs_shipment_items` se statusem RECEIVED (finální stav).
     CANCELLED zásilky se stahují při každém běhu (záměrně zachováno).

### Fáze 2 — import (po stažení obou studií)

1. `ensure_indexes()` (jednou)
2. **Pacienti** (`import_patients.py`): summary → detaily → notifikace;
   per soubor, po úspěchu přesun do Processed/
3. **Léky** (`import_drugs.py`): jeden `import_id` per studie a běh;
   parsuje všechny čekající soubory (nejstarší napřed, poslední vyhrává per `_id`),
   pak hromadný zápis:
   - `iwrs_shipments`, `iwrs_shipment_items`, `iwrs_inventory` — upsert + snapshot
   - `iwrs_destruction` — upsert bez snapshotu
   Po úspěšném zápisu se zparsované soubory přesunou do Processed/;
   soubor s chybou parsování zůstává v Incoming/.
   Prázdný inventory report (centrum bez zásob — jen meta řádky `Site:` atd.,
   bez tabulky léků) se bere jako 0 položek a normálně se archivuje.

## Použití

```
python run_all_v1.1.py                    # vše (download + import, obě studie)
python run_all_v1.1.py --download-only    # jen stažení do Incoming/
python run_all_v1.1.py --import-only      # jen import čekajících souborů
python run_all_v1.1.py --only-patients    # jen pacientská část
python run_all_v1.1.py --only-drugs       # jen léková část
python run_all_v1.1.py --study 42847922MDD3003   # jen jedna studie
```

Prohlížeč běží s `headless=False` (viditelné okno) jako dosud.
Moduly `import_patients.py` a `import_drugs.py` lze spustit i samostatně.

## Mapa modulů (vše na úrovni IWRS/)

```
IWRS/
  run_all_v1.1.py                  ← vstupní skript (CLI, orchestrace)
  download_patients.py             ← summary + delegace na download_subject_details.run()
  download_subject_details.py      ← detaily subjektů + notifikace (worker)
  import_patients.py               ← orchestrace importu pacientů
  import_patients_mongo.py         ← worker: summary + visits → Mongo (ex Patients/import_to_mongo.py)
  import_notifications_to_mongo.py ← worker: notifikace PDF+JSON → Mongo
  notification_parsers.py          ← parsery textů notifikací (bez MySQL)
  download_drugs.py                ← 4 typy reportů → Incoming/, skip-logika přes Mongo
  import_drugs.py                  ← parsery + import léků z Incoming/
  common/
    iwrs_portal.py                 ← BASE_URL, credentials, login(page, study)
    paths.py                       ← INCOMING/PROCESSED, unique_path, move_done, sorted_by_mtime
    mongo_writer.py                ← konvertory, upserty, snapshoty, import log
  Trash/                           ← run_all_v1.0.py + .md
```

## Úklid IWRS (provedeno 2026-06-10)

Na úrovni `IWRS/` zůstává jen aktivní kód a data:
`run_all_v1.1.py`, `create_report_v1.0.py` (+ oba `.md`), 8 modulů pipeline,
`common/`, `Incoming/` (+ `Processed/`) a `Reports/`.

Vše ostatní je v `IWRS/Trash/`: celé adresáře `Patients/` a `Drugs/`
(vč. zmrazených archivů `xls_*`, starých výstupů `output/` a `CreatedReports/`
a jejich vlastních `Trash/`), `Testing/`, `backfill_mysql_to_mongo.py`
(jednorázový legacy nástroj; importoval `db_config` z Patients, v Trash zůstává
funkční vedle sebe), `reports.json` a `run_all_v1.0.*`.

Reportovací skripty byly sjednoceny do `IWRS/create_report_v1.0.py` — původní
`Drugs/create_report.py` a `Patients/create_subject_report.py` jsou v Trash.

## Jednorázová migrace (provedeno 2026-06-10)

- `Patients/Incoming/Zpracováno/` (1343 souborů) → `IWRS/Incoming/Processed/`
- `.gitignore`: `IWRS/Patients/Incoming/` → `IWRS/Incoming/`
- Staré vstupní skripty → `Patients/Trash/`, `Drugs/Trash/`
- v1.1: moduly pipeline → úroveň `IWRS/` (git mv, historie zachována)
