6.1 KiB
plan_id, title, storage, legacy_phase, created, status, type, autonomous, delegation, files_modified, quality_radar
| plan_id | title | storage | legacy_phase | created | status | type | autonomous | delegation | files_modified | quality_radar | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 20260721-2324-import-json-grosze-ceny | Poprawka parsowania cen z paragonu JSON (grosze → złote) | plan-first | null | 2026-07-21T23:24:13+02:00 | planned | execute | true | auto |
|
degraded |
Purpose
Import z JSON zwraca zawyżone kwoty, więc zaksięgowane wydatki są błędne. To realny błąd danych finansowych — musi być deterministyczny, nie „mniej więcej".
Output
Zmodyfikowany app/Libraries/ReceiptParser.php — prompt informuje model, że w surowym JSON z kasy fiskalnej wartości kwotowe to liczby CAŁKOWITE w groszach i trzeba je podzielić przez 100.
Source Files
@app/Libraries/ReceiptParser.php
Dowód (analiza pliku d:\telefon-download\2607202229016050.json)
Format eParagon trzyma WSZYSTKIE kwoty jako liczby całkowite w groszach:
sellLine.price=369, total=369, quantity=1→ 3,69 zł (DrozdzKrem)sellLine.price=129, total=258, quantity=2→ 1,29 zł/szt, 2,58 zł razem (CukChupa)sumInCurrency.fiscalTotal=1315→ 13,15 zł;totalWithPacks=1365→ 13,65 zł- Kaucja
pack.price=50→ 0,50 zł
ReceiptParser::parse() (linia 59) wysyła surowy JSON jako input_text bez informacji o jednostce; prompt (prompt()) opisuje tylko kolumny paragonu obrazkowego/PDF. Model odczytuje 369 dosłownie jako 369 zł.
<impact_scan>
Quality Radar
Status: degraded (jscpd/ast-grep wyłączone polityką w config.md; brak pełnego indeksu codebase-memory-mcp — analiza ręczna kodu i pliku wejściowego).
Tools: analiza ręczna ReceiptParser.php + przykładowy JSON.
Affected Areas
- Import paragonów (Plan 3):
app/Libraries/ReceiptParser.php— jedyny plik zmieniany. Gałąźelse(JSON/tekst) wparse()i treśćprompt(). - Bez zmian:
Receipts.php, modele,receipt_category_map, migracje, trasy, widoki, ścieżka obrazów/PDF.
Duplicate / Hardcoded Risks
- Niedeterminizm OCR/LLM (znany,
quality_risks.md): dla JSON „podziel przez 100" to reguła deterministyczna dla modelu rozumującego — obsłużone w Task 1, weryfikowane realnym importem (AC-1). - Brak drugiego źródła prawdy: reguła w prompcie, żadnych nowych stałych ani powielonej logiki kwot.
Explicit Deferrals
- Pełny natywny parser eParagon w PHP (pominięcie AI dla JSON, zero tokenów, 100% determinizm) — odroczone (YAGNI): straciłby ładne nazwy
displayi podpowiedzi kategorii z AI, a to szerszy refaktor. Podnieść tylko jeśli reguła promptu okaże się zawodna dla JSON. - Kwoty ze ścieżki obrazka/PDF — bez zmian, nie dotyczy tego błędu. </impact_scan>
<acceptance_criteria>
AC-1: Ceny z JSON w złotych, nie w groszach
Given plik d:\telefon-download\2607202229016050.json importowany przez ekran paragonu
When ReceiptParser sparsuje pozycje
Then pozycja "DrozdzKremPorz110g" ma amount 3.69 (nie 369)
And "CukChupaZegarek14,7g" (qty 2) ma amount 2.58 (nie 258)
And total = 13.65 (nie 1365)
AC-2: Import obrazka/PDF bez regresji
Given paragon jako zdjęcie lub PDF (nie JSON)
When ReceiptParser sparsuje paragon
Then kwoty są odczytane jak dotychczas (bez dzielenia przez 100)
</acceptance_criteria>
Task 1: Dodać regułę „grosze → złote" do promptu dla wejścia JSON app/Libraries/ReceiptParser.php W metodzie `prompt()` dodać zasadę informującą model, że jeśli dane wejściowe to surowy JSON z kasy fiskalnej (eParagon / JPK_KASA_PARAGON), to wszystkie pola kwotowe (m.in. `price`, `total`, `brutto`, `cena`, `wart`, `fiscalTotal`, `totalWithPacks`, `amount`) są liczbami CAŁKOWITYMI w GROSZACH i należy podzielić je przez 100, aby uzyskać wartość w złotych. Reguła dotyczy TYLKO wejścia JSON — dla zdjęcia/PDF kwoty odczytywać jak dotąd. Doprecyzować, że w JSON `amount` pozycji = pole `total` danego wiersza sprzedaży podzielone przez 100 (łączna wartość pozycji, nie cena jednostkowa), a `total` paragonu = kwota do zapłaty (`totalWithPacks`) / 100. Nie zmieniać sygnatury metod, gałęzi `image/`/`application/pdf`, ani `normalize()`. php -l app/Libraries/ReceiptParser.php AC-1, AC-2 (reguła warunkowa tylko dla JSON) ## Do Not Change - Ścieżka obrazka (`input_image`) i PDF (`input_file`) w `parse()`. - `normalize()`, sygnatury metod, model OpenAI, klucz `.env`. - Kontroler `Receipts`, modele, `receipt_category_map`, migracje, trasy, widoki.Scope Limits
- Bez natywnego parsera JSON w PHP (odroczone).
- Bez zmian formatu wyświetlania kwot ani logiki księgowania w
confirm().
<success_criteria>
- AC-1 i AC-2 spełnione.
- Zmiana ograniczona do
app/Libraries/ReceiptParser.php. - Brak regresji ścieżki obrazek/PDF. </success_criteria>