- Add --json CLI flag for structured JSON output across all commands - Implement JSON formatting functions for different data types: * Single rate lookups with fallback information * Unified tax rates (single year and multi-year) * Last available rates * Error responses with codes and details - Add auto-download functionality for missing monthly data in tax calculations - Modify calculate_tax_yearly_average to automatically fetch missing months - Add rate limiting (1s delay) between API calls to be respectful - Update CLI argument parsing and output logic for JSON/text modes - Maintain full backward compatibility - existing commands work unchanged - Enhance documentation with JSON usage examples and schema - Update help text to include new --json option Features: - JSON output for programmatic consumption - Automatic data fetching for incomplete years - Structured error handling - Comprehensive documentation updates Breaking changes: None (fully backward compatible)
277 lines
10 KiB
Markdown
277 lines
10 KiB
Markdown
# 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ů.
|
|
- **Výpočet Jednotného kurzu**: Lze vypočítat 'Jednotný kurz' pro daňové účely podle metodiky ČNB jako aritmetický průměr kurzů k posledním dnům každého měsíce v roce.
|
|
- **JSON výstup**: Všechny příkazy podporují JSON formát pro programové zpracování pomocí přepínače `--json`.
|
|
|
|
## 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`.
|
|
- `--stats [ROK]`: Vypočítá 'Jednotný kurz' pro daňové účely podle metodiky ČNB. Pokud je zadán rok, vytvoří kurz pro konkrétní rok. Pokud není rok zadán, vytvoří kurzy pro všechny roky s dostupnými daty. Vyžaduje `-c` nebo `--currency`.
|
|
- `--json`: Výstup ve formátu JSON místo prostého textu pro programové zpracování.
|
|
|
|
### 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
|
|
```
|
|
|
|
10. **Výpočet Jednotného kurzu pro daňové účely pro USD za rok 2025**:
|
|
```bash
|
|
python src/cli.py --stats 2025 -c USD
|
|
```
|
|
|
|
11. **Výpočet Jednotného kurzu pro daňové účely pro všechny roky s daty**:
|
|
```bash
|
|
python src/cli.py --stats -c USD
|
|
```
|
|
|
|
12. **Získání posledního dostupného kurzu USD**:
|
|
```bash
|
|
python src/cli.py -c USD
|
|
```
|
|
|
|
13. **JSON výstup pro vyhledání kurzu**:
|
|
```bash
|
|
python src/cli.py --get-rate 01.01.2025 -c USD --json
|
|
```
|
|
|
|
14. **JSON výstup pro výpočet Jednotného kurzu**:
|
|
```bash
|
|
python src/cli.py --stats 2025 -c USD --json
|
|
```
|
|
|
|
## JSON formát
|
|
|
|
Při použití přepínače `--json` program vrací strukturovaná data ve formátu JSON:
|
|
|
|
### Jednotlivý kurz
|
|
```json
|
|
{
|
|
"currency": "USD",
|
|
"rate": 24.214,
|
|
"date": "01.01.2025",
|
|
"timestamp": "2025-01-12T10:30:00Z"
|
|
}
|
|
```
|
|
|
|
### Jednotný kurz pro jeden rok
|
|
```json
|
|
{
|
|
"currency": "USD",
|
|
"year": 2025,
|
|
"unified_rate": 21.84,
|
|
"calculation_date": "2025-01-12T10:30:00Z"
|
|
}
|
|
```
|
|
|
|
### Jednotný kurz pro více let
|
|
```json
|
|
{
|
|
"currency": "USD",
|
|
"results": [
|
|
{"year": 2023, "unified_rate": 23.45},
|
|
{"year": 2024, "unified_rate": 23.28},
|
|
{"year": 2025, "unified_rate": 21.84}
|
|
],
|
|
"calculation_date": "2025-01-12T10:30:00Z"
|
|
}
|
|
```
|
|
|
|
### Poslední dostupný kurz
|
|
```json
|
|
{
|
|
"currency": "USD",
|
|
"rate": 20.632,
|
|
"date": "31.12.2025",
|
|
"timestamp": "2025-01-12T10:30:00Z"
|
|
}
|
|
```
|
|
|
|
### Chyba
|
|
```json
|
|
{
|
|
"error": "Kurz nebyl nalezen",
|
|
"code": "RATE_NOT_FOUND",
|
|
"timestamp": "2025-01-12T10:30:00Z"
|
|
}
|
|
```
|
|
|
|
## 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í. |