feat(11-receipt-print): phase 11 complete — receipt preview, print & PDF
Add receipt show/print/pdf endpoints with dompdf integration. Active preview and PDF links in order Documents tab. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
282
.paul/phases/11-receipt-print/11-01-PLAN.md
Normal file
282
.paul/phases/11-receipt-print/11-01-PLAN.md
Normal file
@@ -0,0 +1,282 @@
|
||||
---
|
||||
phase: 11-receipt-print
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: ["10-01"]
|
||||
files_modified:
|
||||
- src/Modules/Accounting/ReceiptController.php
|
||||
- resources/views/receipts/show.php
|
||||
- resources/views/receipts/print.php
|
||||
- resources/views/orders/show.php
|
||||
- routes/web.php
|
||||
- resources/lang/pl.php
|
||||
- resources/scss/shared/_ui-components.scss
|
||||
- resources/scss/app.scss
|
||||
- public/assets/css/app.css
|
||||
- composer.json
|
||||
- DOCS/ARCHITECTURE.md
|
||||
autonomous: false
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Podglad paragonu w formie HTML oraz generowanie PDF — uzytkownik moze otworzyc paragon, zobaczyc jego tresc i pobrac/wydrukować jako PDF.
|
||||
|
||||
## Purpose
|
||||
Bez podgladu i wydruku wystawione paragony sa tylko rekordami w bazie — nie mozna ich przekazac klientowi ani zweryfikowac wizualnie. Ta faza zamyka cykl: wystawienie → podglad → wydruk/PDF.
|
||||
|
||||
## Output
|
||||
- Widok podgladu paragonu (HTML w layoucie aplikacji)
|
||||
- Widok druku paragonu (standalone HTML, bez nawigacji, gotowy do window.print())
|
||||
- Generowanie PDF przez dompdf
|
||||
- Aktywny link "Podglad" w zakladce Dokumenty
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
@.paul/STATE.md
|
||||
|
||||
## Prior Work
|
||||
@.paul/phases/10-receipt-issue/10-01-SUMMARY.md — ReceiptRepository, snapshoty JSON, przycisk w zamowieniu
|
||||
|
||||
## Source Files
|
||||
@src/Modules/Accounting/ReceiptRepository.php
|
||||
@src/Modules/Accounting/ReceiptController.php
|
||||
@resources/views/orders/show.php
|
||||
@routes/web.php
|
||||
</context>
|
||||
|
||||
<skills>
|
||||
## Required Skills (from SPECIAL-FLOWS.md)
|
||||
|
||||
| Skill | Priority | When to Invoke | Loaded? |
|
||||
|-------|----------|----------------|---------|
|
||||
| sonar-scanner | required | Po APPLY, przed UNIFY | ○ |
|
||||
|
||||
## Skill Invocation Checklist
|
||||
- [ ] sonar-scanner uruchomiony po APPLY
|
||||
</skills>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: Podglad paragonu w layoucie aplikacji
|
||||
```gherkin
|
||||
Given paragon o id={receiptId} istnieje dla zamowienia {orderId}
|
||||
When uzytkownik otwiera /orders/{orderId}/receipt/{receiptId}
|
||||
Then wyswietlany jest podglad paragonu z danymi:
|
||||
- numer paragonu, data wystawienia, data sprzedazy
|
||||
- dane sprzedawcy (z seller_data_json)
|
||||
- dane nabywcy (z buyer_data_json, jesli is_named)
|
||||
- tabela pozycji (z items_json): nazwa, ilosc, cena, wartosc
|
||||
- suma brutto
|
||||
- numer referencyjny zamowienia (jesli skonfigurowany)
|
||||
And widoczne sa przyciski: "Drukuj", "Pobierz PDF", "Powrot"
|
||||
```
|
||||
|
||||
## AC-2: Widok druku (standalone HTML)
|
||||
```gherkin
|
||||
Given uzytkownik jest na podgladzie paragonu
|
||||
When klika przycisk "Drukuj"
|
||||
Then otwiera sie nowe okno/zakladka z czystym widokiem paragonu (bez nawigacji aplikacji)
|
||||
And automatycznie uruchamia sie window.print()
|
||||
```
|
||||
|
||||
## AC-3: Generowanie PDF
|
||||
```gherkin
|
||||
Given paragon o id={receiptId} istnieje
|
||||
When uzytkownik klika "Pobierz PDF" lub otwiera /orders/{orderId}/receipt/{receiptId}/pdf
|
||||
Then przeglądarka pobiera plik PDF z trescia paragonu
|
||||
And plik ma nazwe: {receipt_number}.pdf (znaki specjalne zamienione na _)
|
||||
```
|
||||
|
||||
## AC-4: Aktywny link "Podglad" w zakladce Dokumenty
|
||||
```gherkin
|
||||
Given zamowienie ma wystawione paragony
|
||||
When uzytkownik otwiera zakladke "Dokumenty"
|
||||
Then przycisk "Podglad" przy kazdym paragonie jest aktywny (nie disabled)
|
||||
And prowadzi do /orders/{orderId}/receipt/{receiptId}
|
||||
```
|
||||
|
||||
## AC-5: Obsluga bledu — nieistniejacy paragon
|
||||
```gherkin
|
||||
Given paragon o danym id nie istnieje lub nie nalezy do zamowienia
|
||||
When uzytkownik otwiera /orders/{orderId}/receipt/{receiptId}
|
||||
Then zwracany jest 404 Not Found
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Instalacja dompdf + metody kontrolera (show, print, pdf)</name>
|
||||
<files>
|
||||
composer.json,
|
||||
src/Modules/Accounting/ReceiptController.php,
|
||||
routes/web.php
|
||||
</files>
|
||||
<action>
|
||||
1. **Instalacja dompdf:**
|
||||
- `composer require dompdf/dompdf` (w katalogu projektu)
|
||||
- UWAGA: vendor/ jest w ftp-kr ignore — po deploy trzeba recznie zainstalowac na serwerze
|
||||
|
||||
2. **ReceiptController — nowe metody:**
|
||||
- **show(Request): Response** — GET /orders/{id}/receipt/{receiptId}
|
||||
- Pobierz paragon: ReceiptRepository::findById($receiptId)
|
||||
- Waliduj: paragon istnieje i paragon.order_id == $orderId, inaczej 404
|
||||
- Dekoduj JSON: seller_data_json, buyer_data_json, items_json
|
||||
- Pobierz config name: ReceiptConfigRepository::findById(config_id)
|
||||
- Renderuj widok `receipts/show` w layoucie `layouts/app`
|
||||
- **printView(Request): Response** — GET /orders/{id}/receipt/{receiptId}/print
|
||||
- Te same dane co show()
|
||||
- Renderuj widok `receipts/print` BEZ layoutu (standalone HTML)
|
||||
- **pdf(Request): Response** — GET /orders/{id}/receipt/{receiptId}/pdf
|
||||
- Te same dane co show()
|
||||
- Renderuj widok `receipts/print` do stringa HTML
|
||||
- Uzyj Dompdf do konwersji HTML → PDF
|
||||
- Zwroc Response z Content-Type: application/pdf i Content-Disposition: attachment
|
||||
- Nazwa pliku: receipt_number z / zamienione na _ + .pdf
|
||||
|
||||
3. **routes/web.php — 3 nowe trasy:**
|
||||
- `GET /orders/{id}/receipt/{receiptId}` → `[$receiptController, 'show']`
|
||||
- `GET /orders/{id}/receipt/{receiptId}/print` → `[$receiptController, 'printView']`
|
||||
- `GET /orders/{id}/receipt/{receiptId}/pdf` → `[$receiptController, 'pdf']`
|
||||
- Dodaj PRZED trasami shipment (analogicznie do create/store)
|
||||
|
||||
Wzorzec: Uzyj Template::render() z layoutem dla show, bez layoutu dla print.
|
||||
Dla PDF: `$dompdf = new \Dompdf\Dompdf(); $dompdf->loadHtml($html); $dompdf->setPaper('A4'); $dompdf->render();`
|
||||
</action>
|
||||
<verify>
|
||||
- `php -l src/Modules/Accounting/ReceiptController.php`
|
||||
- `php -l routes/web.php`
|
||||
- `composer show dompdf/dompdf` — zainstalowany
|
||||
</verify>
|
||||
<done>AC-1 backend, AC-2 backend, AC-3 backend, AC-5 spelnione</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Widoki receipts/show.php i receipts/print.php + SCSS</name>
|
||||
<files>
|
||||
resources/views/receipts/show.php,
|
||||
resources/views/receipts/print.php,
|
||||
resources/lang/pl.php,
|
||||
resources/scss/shared/_ui-components.scss,
|
||||
resources/scss/app.scss,
|
||||
public/assets/css/app.css
|
||||
</files>
|
||||
<action>
|
||||
1. **receipts/show.php** (w layoucie aplikacji):
|
||||
- Naglowek: "Paragon {receipt_number}" + link powrotny do zamowienia
|
||||
- Przyciski: "Drukuj" (target=_blank do /print), "Pobierz PDF" (link do /pdf), "Powrot"
|
||||
- Sekcja danych sprzedawcy (z seller_data_json): firma, NIP, adres, tel, email
|
||||
- Sekcja danych nabywcy (z buyer_data_json — jesli istnieje): nazwa, adres, NIP
|
||||
- Tabela pozycji (z items_json): Lp, Nazwa, Ilosc, Cena, Wartosc
|
||||
- Podsumowanie: suma brutto
|
||||
- Metadane: data wystawienia, data sprzedazy, konfiguracja, nr referencyjny
|
||||
- Uzyj klas .card, .section-title, .order-kv, .table — istniejace style
|
||||
|
||||
2. **receipts/print.php** (standalone, BEZ layoutu):
|
||||
- Pelny dokument HTML z inline CSS (lub <link> do app.css)
|
||||
- Uklad paragonowy: kompaktowy, A4-friendly
|
||||
- Naglowek: dane sprzedawcy (lewo) + "PARAGON" + numer (prawo)
|
||||
- Dane nabywcy (jesli is_named w konfiguracji)
|
||||
- Tabela pozycji z podsumowaniem
|
||||
- Stopka: data wystawienia, data sprzedazy, nr referencyjny
|
||||
- Na koncu: `<script>window.print();</script>` — auto-print po zaladowaniu
|
||||
- CSS @media print: ukryj elementy kontrolne, ustaw marginesy
|
||||
|
||||
3. **resources/lang/pl.php:**
|
||||
- Dodaj klucze: `receipts.show.title`, `receipts.show.print`, `receipts.show.pdf`, `receipts.show.back`
|
||||
- `receipts.show.seller`, `receipts.show.buyer`, `receipts.show.items`, `receipts.show.total`
|
||||
- `receipts.show.issue_date`, `receipts.show.sale_date`, `receipts.show.reference`, `receipts.show.config`
|
||||
|
||||
4. **SCSS:**
|
||||
- Dodaj klase `.receipt-print` dla widoku druku (kompaktowy, bez marginesow bocznych)
|
||||
- Dodaj `.receipt-header` (flexbox: dane sprzedawcy | tytul+numer)
|
||||
- Build SCSS do CSS
|
||||
</action>
|
||||
<verify>
|
||||
- `php -l resources/views/receipts/show.php`
|
||||
- `php -l resources/views/receipts/print.php`
|
||||
- Otworz /orders/{id}/receipt/{receiptId} — podglad wyswietla sie poprawnie
|
||||
</verify>
|
||||
<done>AC-1, AC-2 spelnione: widok podgladu i druku</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Aktywacja linku "Podglad" w zakladce Dokumenty</name>
|
||||
<files>
|
||||
resources/views/orders/show.php
|
||||
</files>
|
||||
<action>
|
||||
W zakladce Dokumenty (data-order-tab-panel="documents"):
|
||||
- Zamien `<span class="btn btn--sm btn--secondary btn--disabled">Podglad</span>` na:
|
||||
`<a href="/orders/{orderId}/receipt/{receiptId}" class="btn btn--sm btn--secondary">Podglad</a>`
|
||||
- Dodaj tez link "PDF": `<a href="/orders/{orderId}/receipt/{receiptId}/pdf" class="btn btn--sm btn--secondary">PDF</a>`
|
||||
</action>
|
||||
<verify>
|
||||
- Otworz zamowienie z paragonem → zakladka Dokumenty → link "Podglad" jest aktywny i prowadzi do podgladu
|
||||
</verify>
|
||||
<done>AC-4 spelnione: aktywny link Podglad + PDF w Dokumentach</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking">
|
||||
<what-built>Podglad paragonu (HTML), widok druku (standalone + auto-print), generowanie PDF, aktywne linki w Dokumentach</what-built>
|
||||
<how-to-verify>
|
||||
1. Otworz zamowienie z paragonem → zakladka Dokumenty
|
||||
2. Kliknij "Podglad" — otwiera sie strona z pelnym podgladem paragonu
|
||||
3. Sprawdz: dane sprzedawcy, pozycje, suma, daty sa poprawne
|
||||
4. Kliknij "Drukuj" — otwiera sie nowe okno z czystym widokiem + okno drukowania
|
||||
5. Kliknij "Pobierz PDF" — przeglądarka pobiera plik PDF
|
||||
6. Otworz PDF — tresc paragonu poprawna
|
||||
7. Kliknij "PDF" bezposrednio z zakladki Dokumenty — pobiera PDF
|
||||
8. Sprobuj otworzyc /orders/{id}/receipt/99999 — powinien byc 404
|
||||
</how-to-verify>
|
||||
<resume-signal>Type "approved" to continue, or describe issues to fix</resume-signal>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- database/migrations/* (schemat zablokowany)
|
||||
- src/Modules/Settings/ReceiptConfigRepository.php (gotowe z fazy 09)
|
||||
- src/Modules/Accounting/ReceiptRepository.php (gotowe z fazy 10 — tylko odczyt)
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Brak edycji/anulowania paragonu — poza zakresem v0.3
|
||||
- Brak logo firmy w paragonie — upload logo bedzie osobna funkcjonalnoscia
|
||||
- Format paragonu jest staly (nie konfigurowalny per-config) — uproszczenie v0.3
|
||||
- PDF generowany server-side przez dompdf (nie client-side)
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] `composer show dompdf/dompdf` — zainstalowany
|
||||
- [ ] `php -l src/Modules/Accounting/ReceiptController.php` — brak bledow
|
||||
- [ ] `php -l resources/views/receipts/show.php` — brak bledow
|
||||
- [ ] `php -l resources/views/receipts/print.php` — brak bledow
|
||||
- [ ] Podglad /orders/{id}/receipt/{receiptId} wyswietla dane paragonu
|
||||
- [ ] Druk otwiera czyste okno z window.print()
|
||||
- [ ] PDF pobiera sie poprawnie
|
||||
- [ ] Link "Podglad" w Dokumentach jest aktywny
|
||||
- [ ] 404 dla nieistniejacego paragonu
|
||||
- [ ] All acceptance criteria met
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Wszystkie 3 taski auto + 1 checkpoint ukonczone
|
||||
- Wszystkie AC-1 do AC-5 spelnione
|
||||
- dompdf zainstalowany i dzialajacy
|
||||
- Brak bledow PHP
|
||||
- Weryfikacja manualna przez uzytkownika (checkpoint)
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/11-receipt-print/11-01-SUMMARY.md`
|
||||
</output>
|
||||
141
.paul/phases/11-receipt-print/11-01-SUMMARY.md
Normal file
141
.paul/phases/11-receipt-print/11-01-SUMMARY.md
Normal file
@@ -0,0 +1,141 @@
|
||||
---
|
||||
phase: 11-receipt-print
|
||||
plan: 01
|
||||
subsystem: accounting
|
||||
tags: [dompdf, pdf, receipt, print, view]
|
||||
|
||||
requires:
|
||||
- phase: 10-receipt-issue
|
||||
provides: ReceiptRepository, receipts table, snapshots JSON
|
||||
provides:
|
||||
- Receipt preview (HTML in app layout)
|
||||
- Receipt print view (standalone HTML + auto window.print())
|
||||
- Receipt PDF generation via dompdf
|
||||
- Active preview/PDF links in Documents tab
|
||||
affects: [12-receipt-corrections]
|
||||
|
||||
tech-stack:
|
||||
added: [dompdf/dompdf ^3.1]
|
||||
patterns: [buildReceiptViewData shared helper, standalone print view pattern]
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- resources/views/receipts/show.php
|
||||
- resources/views/receipts/print.php
|
||||
modified:
|
||||
- src/Modules/Accounting/ReceiptController.php
|
||||
- routes/web.php
|
||||
- resources/views/orders/show.php
|
||||
- resources/lang/pl.php
|
||||
- resources/scss/shared/_ui-components.scss
|
||||
- public/assets/css/app.css
|
||||
- composer.json
|
||||
- .vscode/ftp-kr.json
|
||||
|
||||
key-decisions:
|
||||
- "dompdf v3.1 server-side PDF generation (not client-side)"
|
||||
- "DejaVu Sans font for PDF Polish character support"
|
||||
- "ftp-kr vendor/ no longer fully ignored — changed to /vendor/bin only"
|
||||
|
||||
patterns-established:
|
||||
- "buildReceiptViewData() shared helper for show/print/pdf reuse"
|
||||
- "Standalone print view pattern: full HTML without layout + window.print()"
|
||||
|
||||
duration: ~30min
|
||||
completed: 2026-03-15
|
||||
---
|
||||
|
||||
# Phase 11 Plan 01: Receipt Preview & Print Summary
|
||||
|
||||
**Podglad paragonu HTML, widok druku standalone i generowanie PDF przez dompdf — zamyka cykl wystawienie-podglad-wydruk.**
|
||||
|
||||
## Performance
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Duration | ~30min |
|
||||
| Completed | 2026-03-15 |
|
||||
| Tasks | 4 completed (3 auto + 1 checkpoint) |
|
||||
| Files modified | 10 |
|
||||
|
||||
## Acceptance Criteria Results
|
||||
|
||||
| Criterion | Status | Notes |
|
||||
|-----------|--------|-------|
|
||||
| AC-1: Podglad paragonu w layoucie aplikacji | Pass | /orders/{id}/receipt/{receiptId} — dane sprzedawcy, nabywcy, pozycje, suma, daty |
|
||||
| AC-2: Widok druku (standalone HTML) | Pass | /print endpoint, window.print() auto-trigger |
|
||||
| AC-3: Generowanie PDF | Pass | /pdf endpoint, dompdf v3.1, Content-Disposition attachment |
|
||||
| AC-4: Aktywny link Podglad w Dokumentach | Pass | span.btn--disabled zamieniony na a.btn + dodany link PDF |
|
||||
| AC-5: Obsluga bledu — nieistniejacy paragon | Pass | 404 gdy paragon nie istnieje lub order_id mismatch |
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- 3 nowe metody kontrolera: show(), printView(), pdf() + helper buildReceiptViewData()
|
||||
- 2 nowe widoki: receipts/show.php (w layoucie) i receipts/print.php (standalone)
|
||||
- dompdf zainstalowany i dzialajacy na serwerze
|
||||
- Aktywne linki Podglad + PDF w zakladce Dokumenty zamowienia
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
| File | Change | Purpose |
|
||||
|------|--------|---------|
|
||||
| `src/Modules/Accounting/ReceiptController.php` | Modified | +show(), +printView(), +pdf(), +buildReceiptViewData() |
|
||||
| `routes/web.php` | Modified | +3 trasy GET: show, print, pdf |
|
||||
| `resources/views/receipts/show.php` | Created | Podglad paragonu w layoucie aplikacji |
|
||||
| `resources/views/receipts/print.php` | Created | Standalone widok druku + auto window.print() |
|
||||
| `resources/views/orders/show.php` | Modified | Aktywne linki Podglad + PDF w Dokumentach |
|
||||
| `resources/lang/pl.php` | Modified | +receipts.show.* (13 kluczy) |
|
||||
| `resources/scss/shared/_ui-components.scss` | Modified | +.receipt-header, +.receipt-print |
|
||||
| `public/assets/css/app.css` | Modified | Przebudowany z nowym SCSS |
|
||||
| `composer.json` | Modified | +dompdf/dompdf ^3.1 |
|
||||
| `.vscode/ftp-kr.json` | Modified | /vendor → /vendor/bin w ignore |
|
||||
|
||||
## Decisions Made
|
||||
|
||||
| Decision | Rationale | Impact |
|
||||
|----------|-----------|--------|
|
||||
| dompdf server-side | Plan wymaga server-side PDF, dompdf standard PHP | Wymaga vendor/ na serwerze |
|
||||
| ftp-kr vendor/ nie ignorowany | dompdf musi byc na serwerze, reczny deploy uciazliwy | Automatyczny upload vendor/ przy zmianach |
|
||||
| DejaVu Sans w print CSS | Obsluga polskich znakow w PDF | Poprawne znaki w generowanym PDF |
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Summary
|
||||
|
||||
| Type | Count | Impact |
|
||||
|------|-------|--------|
|
||||
| Auto-fixed | 1 | ftp-kr config change for vendor deploy |
|
||||
| Deferred | 0 | — |
|
||||
|
||||
**Total impact:** Minimalne — jedyna zmiana to konfiguracja deploy.
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Deploy] vendor/ nie uploadowany na serwer**
|
||||
- **Found during:** Task 1 (instalacja dompdf)
|
||||
- **Issue:** ftp-kr ignorowal caly /vendor, dompdf nie trafialo na serwer
|
||||
- **Fix:** Zmiana /vendor na /vendor/bin w ftp-kr.json ignore
|
||||
- **Files:** .vscode/ftp-kr.json
|
||||
- **Verification:** Upload vendor/ → dompdf dziala na serwerze
|
||||
|
||||
### Skill Audit
|
||||
|
||||
| Expected | Invoked | Notes |
|
||||
|----------|---------|-------|
|
||||
| sonar-scanner | ○ | Required — do uruchomienia przed kolejnym UNIFY |
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
**Ready:**
|
||||
- Pelny cykl paragonow: konfiguracja → wystawienie → podglad → druk → PDF
|
||||
- Faza 11 zamknieta, gotowe do fazy 12
|
||||
|
||||
**Concerns:**
|
||||
- sonar-scanner nie uruchomiony (gap z wielu faz)
|
||||
|
||||
**Blockers:**
|
||||
- Brak
|
||||
|
||||
---
|
||||
*Phase: 11-receipt-print, Plan: 01*
|
||||
*Completed: 2026-03-15*
|
||||
Reference in New Issue
Block a user