# CNB Exchange Rates

Tento projekt je určen pro stahování a správu kurzů cizích měn vůči české koruně (CZK) z webu České národní banky (ČNB). Data jsou ukládána do interní SQLite databáze a lze je vyhledávat podle data a kódu měny.

## Funkce

- **Stahování dat**:
  - Roční data pro celý rok.
  - Měsíční data pro konkrétní měnu a časové období.
  - Denní data pro konkrétní datum.
- **Interní databáze**: Všechna stažená data jsou ukládána do SQLite databáze pro rychlé vyhledávání.
- **Vyhledávání kurzů**: Lze vyhledat kurz pro zadané datum a měnu. Pokud kurz pro dané datum neexistuje, program aplikuje pravidla pro víkendy a státní svátky.
- **Správa státních svátků**: Program obsahuje seznam státních svátků v ČR a umí je rozpoznat.
- **Kontrola data a času**: Program kontroluje, zda jsou požadovaná data již k dispozici. Pro dnešní datum před 14:30 a pro budoucí data vrací chybu.
- **Automatické stahování**: Lze aktivovat automatické stahování denních dat pro dnešní datum po 14:30.
- **Kontrola konzistence ročních dat**: Při startu programu automaticky kontroluje, zda roční data pro aktuální rok obsahují záznamy za poslední 3 pracovní dny. Pokud ne, data jsou automaticky aktualizována.
- **Automatické stahování ročních dat**: Pokud jsou požadována data pro rok, který v databázi není, program automaticky stáhne roční data pro daný rok, aktualizuje databázi a teprve poté vrátí výsledek.
- **Generování reportů**: Lze vygenerovat report kurzů pro zadaný rok, měsíc nebo časové období včetně dopočítaných kurzů pro dny, kdy ve vstupních datech neexistovali.
- **Správné dopočítání kurzů**: Program správně aplikuje pravidla ČNB pro dopočítání kurzů pro víkendy a svátky jak při vyhledávání (`--get-rate`), tak při generování reportů.

## Požadavky

- Python 3.6 nebo vyšší
- Knihovny: `requests`

## Instalace

1. Naklonujte repozitář:
   ```bash
   git clone <url-repozitare>
   cd cnb_exchange_rates
   ```

2. Nainstalujte požadované knihovny:
   ```bash
   pip install requests
   ```

## Použití

### Spuštění CLI

Všechny operace se provádějí pomocí skriptu `src/cli.py`.

```bash
python src/cli.py [argumenty]
```

Při každém spuštění programu:

1. Automaticky inicializuje databázi.
2. Zkontroluje konzistenci ročních dat pro aktuální rok. Pokud data neobsahují záznamy za poslední 3 pracovní dny, jsou automaticky aktualizována.

### Argumenty

- `--year ROK`: Stáhne roční data pro zadaný rok.
- `-c`, `--currency MENA`: Kód měny (např. USD) pro měsíční stahování, vyhledání kurzu nebo generování reportu.
- `--start-date ZACATEK`: Počáteční datum pro měsíční stahování nebo generování reportu. Formát: `DD.MM.YYYY`.
- `--end-date KONEC`: Koncové datum pro měsíční stahování nebo generování reportu. Formát: `DD.MM.YYYY`.
- `--date DATUM`: Stáhne denní data pro zadané datum. Formát: `DD.MM.YYYY`.
- `--get-rate DATUM`: Vyhledá kurz pro zadané datum. Formát: `DD.MM.YYYY`. Vyžaduje `-c` nebo `--currency`.
- `--auto-download`: Povolí automatické stahování denních dat pro dnešní datum, pokud je po 14:30 a kurz není k dispozici.
- `--report-year ROK [--report-month MESIC]`: Vygeneruje report kurzů pro zadaný rok (a případně měsíc). Vyžaduje `-c` nebo `--currency`.
- `--report-period ZACATEK KONEC`: Vygeneruje report kurzů pro zadané časové období. Vyžaduje `-c` nebo `--currency`.

### Příklady

1. **Stažení ročních dat pro rok 2020**:
   ```bash
   python src/cli.py --year 2020
   ```

2. **Stažení měsíčních dat pro měnu USD v lednu 2025**:
   ```bash
   python src/cli.py -c USD --start-date 01.01.2025 --end-date 31.01.2025
   ```

3. **Stažení denních dat pro datum 08.08.2025**:
   ```bash
   python src/cli.py --date 08.08.2025
   ```

4. **Vyhledání kurzu USD pro datum 08.08.2025**:
   ```bash
   python src/cli.py --get-rate 08.08.2025 -c USD
   ```

5. **Vyhledání kurzu USD pro víkendové datum 10.08.2025 (použije kurz z předchozího pracovního dne)**:
   ```bash
   python src/cli.py --get-rate 10.08.2025 -c USD
   ```

6. **Vyhledání kurzu USD pro dnešní datum po 14:30 s automatickým stažením dat (pokud nejsou k dispozici)**:
   ```bash
   python src/cli.py --get-rate DD.MM.YYYY -c USD --auto-download
   ```
   *(Nahraďte `DD.MM.YYYY` aktuálním datem)*

7. **Vygenerování ročního reportu kurzů pro USD za rok 2020**:
   ```bash
   python src/cli.py --report-year 2020 -c USD
   ```

8. **Vygenerování měsíčního reportu kurzů pro USD za červenec 2020**:
   ```bash
   python src/cli.py --report-year 2020 --report-month 7 -c USD
   ```

9. **Vygenerování reportu kurzů pro USD za období 01.07.2020 - 31.07.2020**:
   ```bash
   python src/cli.py --report-period 01.07.2020 31.07.2020 -c USD
   ```

## Chování při různých časech a datumech

- **Budoucí datum**: Program vrátí chybu, protože kurzy pro budoucí data ještě nebyly vydány.
- **Dnešní datum před 14:30**: Program vrátí chybu, protože kurzy jsou vyhlašovány po 14:30.
- **Dnešní datum po 14:30**: Program vyhledá kurz. Pokud není k dispozici a je aktivní `--auto-download`, automaticky stáhne denní data.
- **Minulé datum**: Program vyhledá kurz. Pokud není k dispozici, aplikuje pravidla pro víkendy a státní svátky.

## Automatická kontrola konzistence ročních dat

Při každém spuštění programu:

1. Zkontroluje, zda roční data pro aktuální rok obsahují záznamy za poslední 3 pracovní dny.
2. Pokud záznamy chybí, automaticky stáhne aktualizovaná roční data.
3. Tímto způsobem je zajištěna konzistence dat pro aktuální rok, protože každý den přibývají nové záznamy.

## Automatické stahování ročních dat při vyhledávání

Pokud při vyhledávání kurzu zjistí program, že databáze neobsahuje data pro požadovaný rok:

1. Automaticky stáhne roční data pro daný rok.
2. Aktualizuje databázi.
3. Teprve poté vyhledá a vrátí kurz.

## Generování reportů o kurzech

Program umí vygenerovat reporty kurzů pro zadaný rok, měsíc nebo časové období. Reporty obsahují:

- Kurzy pro všechny dny v zadaném období.
- Dopočítané kurzy pro dny, kdy ve vstupních datech neexistovali (např. víkendy, svátky).
- Poznámky o tom, zda byl kurz nalezen v databázi nebo dopočítán.

Výstupní soubory jsou ve formátu CSV a jsou uloženy v adresáři `data/`.

## Správné dopočítání kurzů pro víkendy a svátky

Program správně aplikuje pravidla ČNB pro dopočítání kurzů:

- **Pro víkendy a svátky**: Použije se kurz z posledního dne před nimi, který měl kurz vyhlášený pro tento víkend/svátek.
- **Pro běžné dny bez kurzu**: Použije se kurz z posledního pracovního dne před ním.

Příklad:
- 1.1.2021 (pátek) - svátek, kurz 21.387
- 2.1.2021 (sobota) - víkend, žádný kurz → použije se kurz 21.387 z 1.1.2021
- 3.1.2021 (neděle) - víkend, žádný kurz → použije se kurz 21.387 z 1.1.2021

Tato logika je aplikována jak při vyhledávání kurzu pomocí `--get-rate`, tak při generování reportů.

## Struktura projektu

- `src/`: Zdrojové kódy.
  - `cli.py`: Hlavní skript s CLI rozhraním.
  - `data_fetcher.py`: Funkce pro stahování dat z ČNB.
  - `database.py`: Funkce pro práci s SQLite databází.
  - `holidays.py`: Funkce pro práci se státními svátky.
  - `rate_finder.py`: Funkce pro vyhledávání kurzů.
  - `rate_reporter.py`: Funkce pro generování reportů o kurzech.
- `data/`: Adresář pro ukládání stažených dat a databáze.
  - `exchange_rates.db`: SQLite databáze s kurzy.
  - `holidays.json`: Seznam státních svátků v ČR.
  - `*.csv`: Stažená data a reporty v CSV formátu.
- `tests/`: Testy jednotlivých modulů.

## Testování

Pro spuštění testů přejděte do adresáře projektu a spusťte:

```bash
python tests/test_holidays.py
python tests/test_data_fetcher.py
python tests/test_rate_finder.py
python tests/test_data_consistency.py
python tests/test_auto_yearly_download.py
python tests/test_rate_reporter.py
python tests/test_rate_calculation.py
```

## Licence

Tento projekt je licencován pod MIT licencí.