feat(08-10-receipt-module): phases 08-10 complete — receipt issuing from orders
Phase 08 — DB Foundation: - 3 new tables: receipt_configs, receipts, receipt_number_counters - company_settings extended with BDO, REGON, KRS, logo fields Phase 09 — Receipt Config: - CRUD for receipt configurations (Settings > Accounting) - ReceiptConfigController + ReceiptConfigRepository Phase 10 — Receipt Issuing: - ReceiptRepository with atomic numbering (INSERT ON DUPLICATE KEY UPDATE) - ReceiptController with snapshot pattern (seller/buyer/items as JSON) - "Wystaw paragon" button in order view - Documents tab showing both receipts and marketplace documents - Activity log entry on receipt creation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
320
.paul/phases/10-receipt-issue/10-01-PLAN.md
Normal file
320
.paul/phases/10-receipt-issue/10-01-PLAN.md
Normal file
@@ -0,0 +1,320 @@
|
||||
---
|
||||
phase: 10-receipt-issue
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: ["09-01"]
|
||||
files_modified:
|
||||
- src/Modules/Accounting/ReceiptRepository.php
|
||||
- src/Modules/Accounting/ReceiptController.php
|
||||
- src/Modules/Orders/OrdersController.php
|
||||
- resources/views/orders/show.php
|
||||
- resources/views/orders/receipt-create.php
|
||||
- routes/web.php
|
||||
- resources/lang/pl.php
|
||||
- resources/scss/shared/_ui-components.scss
|
||||
- public/assets/css/app.css
|
||||
- DOCS/ARCHITECTURE.md
|
||||
autonomous: false
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Umozliwienie wystawiania paragonow z poziomu widoku zamowienia — przycisk "Wystaw paragon", formularz wyboru konfiguracji z podgladem pozycji, zapis do bazy z atomowym numerowaniem i snapshotem danych.
|
||||
|
||||
## Purpose
|
||||
Kluczowa funkcjonalnosc modulu Ksiegowosci (v0.3) — sprzedawca moze wystawic paragon bezposrednio z zamowienia, bez opuszczania widoku zamowienia.
|
||||
|
||||
## Output
|
||||
- `ReceiptRepository` — CRUD na `receipts` + atomowe numerowanie przez `receipt_number_counters`
|
||||
- `ReceiptController` — formularz tworzenia paragonu + zapis
|
||||
- Przycisk "Wystaw paragon" w widoku zamowienia
|
||||
- Lista wystawionych paragonow w zakladce "Dokumenty"
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
@.paul/STATE.md
|
||||
|
||||
## Prior Work
|
||||
@.paul/phases/08-db-foundation/08-01-SUMMARY.md — schemat tabel receipts, receipt_configs, receipt_number_counters
|
||||
@.paul/phases/09-receipt-config/09-01-SUMMARY.md — CRUD konfiguracji, ReceiptConfigRepository, wzorce Request/Csrf
|
||||
|
||||
## Source Files
|
||||
@database/migrations/20260315_000051_create_receipts_table.sql
|
||||
@database/migrations/20260315_000052_create_receipt_number_counters_table.sql
|
||||
@src/Modules/Settings/ReceiptConfigRepository.php
|
||||
@src/Modules/Settings/CompanySettingsRepository.php
|
||||
@src/Modules/Orders/OrdersController.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: Przycisk "Wystaw paragon" w widoku zamowienia
|
||||
```gherkin
|
||||
Given uzytkownik jest na stronie szczegulow zamowienia /orders/{id}
|
||||
When sa aktywne konfiguracje paragonow
|
||||
Then widoczny jest przycisk "Wystaw paragon" w sekcji akcji
|
||||
And przycisk prowadzi do formularza /orders/{id}/receipt/create
|
||||
```
|
||||
|
||||
## AC-2: Formularz wystawiania paragonu
|
||||
```gherkin
|
||||
Given uzytkownik otwiera /orders/{id}/receipt/create
|
||||
When formularz sie laduje
|
||||
Then widoczny jest select z aktywnymi konfiguracjami paragonow
|
||||
And wyswietlona jest tabela pozycji zamowienia (nazwa, ilosc, cena, suma)
|
||||
And wyswietlone sa pola: data wystawienia (domyslnie dzis), data sprzedazy (wg konfiguracji)
|
||||
And widoczny jest podglad danych sprzedawcy z company_settings
|
||||
And przycisk "Wystaw paragon" submituje formularz
|
||||
```
|
||||
|
||||
## AC-3: Zapis paragonu z atomowym numerowaniem
|
||||
```gherkin
|
||||
Given uzytkownik wypelnia formularz i klika "Wystaw paragon"
|
||||
When POST /orders/{id}/receipt/store jest wysylany
|
||||
Then tworzony jest rekord w tabeli receipts z:
|
||||
- receipt_number wygenerowanym atomowo z receipt_number_counters (INSERT ON DUPLICATE KEY UPDATE)
|
||||
- seller_data_json jako snapshot company_settings
|
||||
- items_json jako snapshot pozycji zamowienia
|
||||
- total_net i total_gross obliczone z pozycji
|
||||
- sale_date okreslona wg sale_date_source z konfiguracji
|
||||
- order_reference_value wypelnione wg order_reference z konfiguracji
|
||||
And uzytkownik jest przekierowany na /orders/{id} z flash success
|
||||
```
|
||||
|
||||
## AC-4: Lista paragonow w zakladce Dokumenty
|
||||
```gherkin
|
||||
Given zamowienie ma wystawione paragony
|
||||
When uzytkownik klika zakladke "Dokumenty"
|
||||
Then wyswietlona jest tabela paragonow (numer, data wystawienia, kwota brutto, konfiguracja)
|
||||
And kazdy paragon ma link do podgladu (na razie placeholder — faza 11)
|
||||
```
|
||||
|
||||
## AC-5: Walidacja — brak duplikatow i brak pustych konfiguracji
|
||||
```gherkin
|
||||
Given uzytkownik probuje wystawic paragon
|
||||
When nie ma aktywnych konfiguracji
|
||||
Then przycisk "Wystaw paragon" nie jest widoczny w widoku zamowienia
|
||||
|
||||
Given uzytkownik submituje formularz bez wybranej konfiguracji
|
||||
When POST jest wysylany
|
||||
Then zwracany jest blad walidacji i paragon nie jest tworzony
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: ReceiptRepository — CRUD + atomowe numerowanie</name>
|
||||
<files>src/Modules/Accounting/ReceiptRepository.php</files>
|
||||
<action>
|
||||
Utworz nowy modul `src/Modules/Accounting/` z klasa `ReceiptRepository`:
|
||||
|
||||
1. **Konstruktor:** przyjmuje `PDO $pdo`
|
||||
2. **getNextNumber(int $configId, string $numberFormat, string $numberingType): string**
|
||||
- Atomowe numerowanie przez `INSERT INTO receipt_number_counters (config_id, year, month, last_number) VALUES (:config_id, :year, :month, 1) ON DUPLICATE KEY UPDATE last_number = last_number + 1`
|
||||
- Odczyt `last_number` przez `SELECT last_number FROM receipt_number_counters WHERE config_id = :config_id AND year = :year AND month = :month`
|
||||
- Dla `numbering_type = 'yearly'`: month = NULL (w unique key)
|
||||
- Dla `numbering_type = 'monthly'`: month = biezacy miesiac
|
||||
- Podmiana w formacie: `%N` → numer (z zerem wiodacym min 3 cyfry), `%M` → miesiac (2 cyfry), `%Y` → rok (4 cyfry)
|
||||
3. **create(array $data): int**
|
||||
- INSERT do `receipts` ze wszystkimi polami
|
||||
- Zwraca `lastInsertId()`
|
||||
4. **findByOrderId(int $orderId): array**
|
||||
- SELECT receipts + LEFT JOIN receipt_configs (na nazwe konfiguracji)
|
||||
- ORDER BY created_at DESC
|
||||
5. **findById(int $id): ?array**
|
||||
- SELECT * WHERE id = :id
|
||||
|
||||
Wzorzec: analogicznie do ReceiptConfigRepository (PDO, prepared statements, strict types).
|
||||
Namespace: `App\Modules\Accounting`
|
||||
</action>
|
||||
<verify>Klasa parsuje sie bez bledow: `php -l src/Modules/Accounting/ReceiptRepository.php`</verify>
|
||||
<done>AC-3 backend spelnione: atomowe numerowanie i zapis paragonu</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: ReceiptController + routing + widok formularza</name>
|
||||
<files>
|
||||
src/Modules/Accounting/ReceiptController.php,
|
||||
resources/views/orders/receipt-create.php,
|
||||
routes/web.php,
|
||||
resources/lang/pl.php
|
||||
</files>
|
||||
<action>
|
||||
1. **ReceiptController** (`App\Modules\Accounting`):
|
||||
- Konstruktor: `Template, Translator, AuthService, ReceiptRepository, ReceiptConfigRepository, CompanySettingsRepository, OrdersRepository`
|
||||
- **create(Request $request): Response** — GET /orders/{id}/receipt/create
|
||||
- Pobierz zamowienie przez OrdersRepository::findDetails($orderId)
|
||||
- Pobierz aktywne konfiguracje: ReceiptConfigRepository::listAll() + filtruj is_active = 1
|
||||
- Pobierz dane sprzedawcy: CompanySettingsRepository::getSettings()
|
||||
- Renderuj widok `orders/receipt-create`
|
||||
- **store(Request $request): Response** — POST /orders/{id}/receipt/store
|
||||
- Walidacja: config_id wymagane, zamowienie istnieje
|
||||
- CSRF: Csrf::validate()
|
||||
- Pobierz konfiguracje (findById), zamowienie (findDetails), company settings
|
||||
- Oblicz sale_date wg `sale_date_source`: order_date → ordered_at, payment_date → z payments, issue_date → dzis
|
||||
- Oblicz order_reference_value wg `order_reference`: none → NULL, orderpro → internal_order_number, integration → external_order_id
|
||||
- Zbuduj seller_data_json z company_settings (company_name, tax_number, street, city, postal_code, phone, email, bank_account, bdo_number, regon, court_register)
|
||||
- Zbuduj buyer_data_json z address (invoice lub customer)
|
||||
- Zbuduj items_json z pozycji zamowienia (original_name, quantity, original_price_with_tax, sku, ean)
|
||||
- Oblicz total_gross = suma(qty * price), total_net = total_gross (paragony nie rozdzielaja netto/brutto — wartosc taka sama)
|
||||
- Wygeneruj numer przez ReceiptRepository::getNextNumber()
|
||||
- ReceiptRepository::create() ze wszystkimi danymi
|
||||
- Flash::set('order.success', 'Paragon wystawiony: ' . $receiptNumber)
|
||||
- Redirect /orders/{id}
|
||||
|
||||
2. **Widok receipt-create.php:**
|
||||
- Layout z naglowkiem "Wystaw paragon" + link powrotny do zamowienia
|
||||
- Select z aktywnymi konfiguracjami (name + number_format)
|
||||
- Tabela pozycji zamowienia (readonly): nazwa, ilosc, cena, suma
|
||||
- Podsumowanie kwoty brutto
|
||||
- Podglad danych sprzedawcy (readonly z company_settings)
|
||||
- Pole daty wystawienia (input date, domyslnie dzis)
|
||||
- Przycisk "Wystaw paragon" + CSRF token
|
||||
|
||||
3. **routes/web.php:**
|
||||
- Dodaj use statements: `ReceiptController`, `ReceiptRepository` (z `App\Modules\Accounting`)
|
||||
- Utworz instancje: `$receiptRepository = new ReceiptRepository($app->db())`
|
||||
- Utworz kontroler: `$receiptController = new ReceiptController($template, $translator, $auth, $receiptRepository, $receiptConfigRepository, $companySettingsRepository, new OrdersRepository($app->db()))`
|
||||
- Zarejestruj trasy:
|
||||
- `GET /orders/{id}/receipt/create` → `[$receiptController, 'create']`
|
||||
- `POST /orders/{id}/receipt/store` → `[$receiptController, 'store']`
|
||||
|
||||
4. **resources/lang/pl.php:**
|
||||
- Dodaj klucze `receipts.create.title`, `receipts.create.select_config`, `receipts.create.issue_date`, `receipts.create.submit`, `receipts.create.seller_data`, `receipts.create.items`, `receipts.create.total`, `receipts.create.back`
|
||||
|
||||
Wzorzec kontrolera: analogicznie do ReceiptConfigController (Csrf::token(), Csrf::validate(), Flash::set/get, Request::input()).
|
||||
NIE uzywaj natywnych alert()/confirm() — OrderProAlerts juz jest w uzyciu.
|
||||
</action>
|
||||
<verify>
|
||||
- `php -l src/Modules/Accounting/ReceiptController.php`
|
||||
- `php -l resources/views/orders/receipt-create.php`
|
||||
- Otworz /orders/{id}/receipt/create w przegladarce — formularz sie wyswietla
|
||||
</verify>
|
||||
<done>AC-2, AC-3, AC-5 spelnione: formularz, zapis, walidacja</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Integracja z widokiem zamowienia — przycisk + zakladka Dokumenty</name>
|
||||
<files>
|
||||
src/Modules/Orders/OrdersController.php,
|
||||
resources/views/orders/show.php,
|
||||
routes/web.php
|
||||
</files>
|
||||
<action>
|
||||
1. **OrdersController::show():**
|
||||
- Dodaj zaleznosc: `ReceiptConfigRepository` i `ReceiptRepository` (przez konstruktor lub przekazanie w widoku)
|
||||
- UWAGA: OrdersController ma juz 5 parametrow konstruktora. Zamiast rozszerzac konstruktor, przekaz dane przez nowe instancje w routes/web.php:
|
||||
- W web.php: pobierz aktywne configs i receipts w zamknieciu routera GET /orders/{id} LUB
|
||||
- Prostsze: dodaj `?ReceiptRepository` i `?ReceiptConfigRepository` do konstruktora OrdersController
|
||||
- W metodzie show(): pobierz `$receiptConfigs = $this->receiptConfigs->listAll()` (filtruj aktywne)
|
||||
- Pobierz `$receipts = $this->receipts->findByOrderId($orderId)`
|
||||
- Przekaz do widoku: `'receiptConfigs' => $activeConfigs, 'receipts' => $receipts`
|
||||
|
||||
2. **orders/show.php — przycisk "Wystaw paragon":**
|
||||
- W sekcji `.order-details-actions` (linia ~47-54):
|
||||
- Dodaj przycisk miedzy "Przygotuj przesylke" a "Platnosc":
|
||||
```php
|
||||
<?php if (($receiptConfigs ?? []) !== []): ?>
|
||||
<a href="/orders/<?= $e((string) ($orderId ?? 0)) ?>/receipt/create" class="btn btn--secondary">Wystaw paragon</a>
|
||||
<?php endif; ?>
|
||||
```
|
||||
- Przycisk widoczny tylko gdy sa aktywne konfiguracje (AC-1, AC-5)
|
||||
|
||||
3. **orders/show.php — zakladka Dokumenty:**
|
||||
- Zastap pusty placeholder w `data-order-tab-panel="documents"` (linia ~516-521):
|
||||
- Tabela paragonow: Numer, Data wystawienia, Kwota brutto, Konfiguracja, Akcje
|
||||
- Jesli brak paragonow: "Brak dokumentow"
|
||||
- Akcja: link "Podglad" (na razie `#` — placeholder do fazy 11)
|
||||
- Zaktualizuj licznik w zakladce: `Dokumenty (N)` gdzie N = count($receipts)
|
||||
|
||||
4. **routes/web.php:**
|
||||
- Dodaj `use App\Modules\Accounting\ReceiptRepository;` na gorze
|
||||
- Przekaz `$receiptRepository` i `$receiptConfigRepository` do konstruktora `$ordersController`
|
||||
|
||||
5. **DOCS/ARCHITECTURE.md:**
|
||||
- Dodaj modul Accounting z klasami ReceiptRepository, ReceiptController
|
||||
- Dodaj trasy GET/POST /orders/{id}/receipt/*
|
||||
</action>
|
||||
<verify>
|
||||
- Otworz /orders/{id} — przycisk "Wystaw paragon" widoczny (jesli sa aktywne configs)
|
||||
- Kliknij zakladke "Dokumenty" — tabela paragonow wyswietla sie
|
||||
- Po wystawieniu paragonu — pojawia sie na liscie w zakladce Dokumenty
|
||||
</verify>
|
||||
<done>AC-1, AC-4 spelnione: przycisk w widoku zamowienia + lista paragonow w Dokumentach</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking">
|
||||
<what-built>Wystawianie paragonow z poziomu zamowienia — pelny flow: przycisk → formularz → zapis → lista w Dokumentach</what-built>
|
||||
<how-to-verify>
|
||||
1. Otworz dowolne zamowienie /orders/{id}
|
||||
2. Sprawdz: przycisk "Wystaw paragon" jest widoczny w akcjach
|
||||
3. Kliknij "Wystaw paragon" — formularz sie otwiera
|
||||
4. Wybierz konfiguracje, sprawdz podglad pozycji i danych sprzedawcy
|
||||
5. Kliknij "Wystaw paragon" w formularzu
|
||||
6. Sprawdz: redirect na zamowienie z flash "Paragon wystawiony: PAR/001/03/2026"
|
||||
7. Kliknij zakladke "Dokumenty" — paragon widoczny na liscie
|
||||
8. Wystaw drugi paragon — numer powinien byc PAR/002/03/2026
|
||||
</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 — tabele juz istnieja z fazy 08)
|
||||
- src/Modules/Settings/ReceiptConfigRepository.php (gotowe z fazy 09)
|
||||
- src/Modules/Settings/ReceiptConfigController.php (gotowe z fazy 09)
|
||||
- resources/views/settings/accounting.php (gotowe z fazy 09)
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Brak podgladu/wydruku paragonu — to faza 11
|
||||
- Brak edycji/anulowania paragonu — poza zakresem v0.3
|
||||
- Brak generowania PDF — to faza 11
|
||||
- Paragony nie rozdzielaja netto/brutto (total_net = total_gross) — uproszczenie dla paragonow
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] `php -l src/Modules/Accounting/ReceiptRepository.php` — brak bledow
|
||||
- [ ] `php -l src/Modules/Accounting/ReceiptController.php` — brak bledow
|
||||
- [ ] Przycisk "Wystaw paragon" widoczny w /orders/{id} gdy sa aktywne konfiguracje
|
||||
- [ ] Formularz /orders/{id}/receipt/create wyswietla pozycje zamowienia i konfiguracje
|
||||
- [ ] Po wystawieniu paragonu: redirect + flash + rekord w bazie
|
||||
- [ ] Numer paragonu generowany atomowo (kolejne numery nie powtarzaja sie)
|
||||
- [ ] Zakladka Dokumenty wyswietla wystawione paragony
|
||||
- [ ] Brak bledow w konsoli PHP
|
||||
- [ ] All acceptance criteria met
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Wszystkie 3 taski auto + 1 checkpoint ukonczone
|
||||
- Wszystkie AC-1 do AC-5 spelnione
|
||||
- Brak bledow PHP (php -l na wszystkich nowych plikach)
|
||||
- Weryfikacja manualna przez uzytkownika (checkpoint)
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/10-receipt-issue/10-01-SUMMARY.md`
|
||||
</output>
|
||||
142
.paul/phases/10-receipt-issue/10-01-SUMMARY.md
Normal file
142
.paul/phases/10-receipt-issue/10-01-SUMMARY.md
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
phase: 10-receipt-issue
|
||||
plan: 01
|
||||
subsystem: accounting
|
||||
tags: [php, receipts, orders, crud, snapshots, atomic-numbering]
|
||||
|
||||
requires:
|
||||
- phase: 08-db-foundation
|
||||
provides: receipts, receipt_configs, receipt_number_counters tables
|
||||
- phase: 09-receipt-config
|
||||
provides: ReceiptConfigRepository CRUD, active configs
|
||||
provides:
|
||||
- Wystawianie paragonow z poziomu zamowienia
|
||||
- ReceiptRepository (CRUD + atomowe numerowanie)
|
||||
- ReceiptController (formularz + zapis ze snapshotami)
|
||||
- Przycisk "Wystaw paragon" w widoku zamowienia
|
||||
- Lista paragonow + dokumentow zewnetrznych w zakladce Dokumenty
|
||||
- Activity log entry po wystawieniu paragonu
|
||||
affects: [11-receipt-print, 12-accounting-list]
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns: [snapshot-json-pattern for seller/buyer/items, atomic-counter-pattern for receipt numbering]
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- src/Modules/Accounting/ReceiptRepository.php
|
||||
- src/Modules/Accounting/ReceiptController.php
|
||||
- resources/views/orders/receipt-create.php
|
||||
modified:
|
||||
- src/Modules/Orders/OrdersController.php
|
||||
- resources/views/orders/show.php
|
||||
- routes/web.php
|
||||
- resources/lang/pl.php
|
||||
- DOCS/ARCHITECTURE.md
|
||||
|
||||
key-decisions:
|
||||
- "ReceiptRepository w App\\Modules\\Accounting (nowy modul, nie w Settings)"
|
||||
- "Snapshot pattern: seller/buyer/items jako JSON w momencie wystawienia"
|
||||
- "Atomowe numerowanie: INSERT ON DUPLICATE KEY UPDATE na receipt_number_counters"
|
||||
- "total_net = total_gross (paragony nie rozdzielaja netto/brutto)"
|
||||
- "OrdersController rozszerzony o opcjonalne ?ReceiptRepository i ?ReceiptConfigRepository"
|
||||
|
||||
patterns-established:
|
||||
- "Modul Accounting: osobny namespace dla funkcjonalnosci ksiegowych"
|
||||
- "Snapshot przy tworzeniu dokumentu: dane zamrazane w JSON, niezalezne od przyszlych zmian zrodla"
|
||||
- "Activity log: recordActivity() po kazdej akcji generujacej dokument"
|
||||
|
||||
duration: ~25min
|
||||
completed: 2026-03-15
|
||||
---
|
||||
|
||||
# Phase 10 Plan 01: Wystawianie paragonow z zamowienia Summary
|
||||
|
||||
**Pelny flow wystawiania paragonow: przycisk w zamowieniu, formularz z podgladem pozycji/sprzedawcy, zapis z atomowym numerowaniem i snapshotami, lista w zakladce Dokumenty + wpis w historii.**
|
||||
|
||||
## Performance
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Duration | ~25min |
|
||||
| Completed | 2026-03-15 |
|
||||
| Tasks | 3 auto + 1 checkpoint |
|
||||
| Files created | 3 |
|
||||
| Files modified | 5 |
|
||||
|
||||
## Acceptance Criteria Results
|
||||
|
||||
| Criterion | Status | Notes |
|
||||
|-----------|--------|-------|
|
||||
| AC-1: Przycisk "Wystaw paragon" w widoku zamowienia | Pass | Widoczny tylko gdy sa aktywne konfiguracje |
|
||||
| AC-2: Formularz wystawiania paragonu | Pass | Select konfiguracji, tabela pozycji, podglad sprzedawcy, data wystawienia |
|
||||
| AC-3: Zapis paragonu z atomowym numerowaniem | Pass | INSERT ON DUPLICATE KEY UPDATE, snapshoty JSON |
|
||||
| AC-4: Lista paragonow w zakladce Dokumenty | Pass | Paragony + dokumenty zewnetrzne w osobnych sekcjach |
|
||||
| AC-5: Walidacja — brak duplikatow i brak pustych konfiguracji | Pass | Przycisk ukryty bez konfiguracji, walidacja config_id |
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- Nowy modul `App\Modules\Accounting` z ReceiptRepository i ReceiptController
|
||||
- Atomowe numerowanie paragonow przez receipt_number_counters (INSERT ON DUPLICATE KEY UPDATE)
|
||||
- Snapshoty seller/buyer/items jako JSON — dane zamrozone w momencie wystawienia
|
||||
- Zakladka Dokumenty wyswietla zarowno paragony jak i dokumenty zewnetrzne z marketplace
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
| File | Change | Purpose |
|
||||
|------|--------|---------|
|
||||
| `src/Modules/Accounting/ReceiptRepository.php` | Created | CRUD na receipts + atomowe numerowanie |
|
||||
| `src/Modules/Accounting/ReceiptController.php` | Created | Formularz tworzenia + zapis paragonu + activity log |
|
||||
| `resources/views/orders/receipt-create.php` | Created | Widok formularza wystawiania paragonu |
|
||||
| `src/Modules/Orders/OrdersController.php` | Modified | Dodano ?ReceiptRepository, ?ReceiptConfigRepository do konstruktora + show() |
|
||||
| `resources/views/orders/show.php` | Modified | Przycisk "Wystaw paragon", zakladka Dokumenty z paragony + dokumenty zewnetrzne |
|
||||
| `routes/web.php` | Modified | Instancje ReceiptRepository/ReceiptController, 2 nowe trasy |
|
||||
| `resources/lang/pl.php` | Modified | Tlumaczenia receipts.create.*, receipts.documents.*, receipt_issued |
|
||||
| `DOCS/ARCHITECTURE.md` | Modified | Klasy Accounting, przeplyw wystawiania paragonu |
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Summary
|
||||
|
||||
| Type | Count | Impact |
|
||||
|------|-------|--------|
|
||||
| Scope additions | 2 | User feedback — activity log + dokumenty zewnetrzne |
|
||||
|
||||
**Total impact:** Dwa uzasadnione rozszerzenia poza planem, poprawiajace UX.
|
||||
|
||||
### Scope Additions
|
||||
|
||||
**1. Activity log po wystawieniu paragonu**
|
||||
- **Source:** User feedback podczas checkpoint
|
||||
- **Issue:** Brak wpisu w historii zmian zamowienia po wystawieniu paragonu
|
||||
- **Fix:** Dodano recordActivity() z typem `receipt_issued` + tlumaczenie
|
||||
- **Files:** ReceiptController.php, resources/lang/pl.php
|
||||
|
||||
**2. Dokumenty zewnetrzne w zakladce Dokumenty**
|
||||
- **Source:** User feedback — licznik Dokumenty(2) ale widoczny tylko 1 paragon
|
||||
- **Issue:** Zakladka wyswietlala tylko paragony, nie dokumenty z order_documents
|
||||
- **Fix:** Dodano sekcje "Dokumenty zewnetrzne" z tabela order_documents
|
||||
- **Files:** resources/views/orders/show.php
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
| Issue | Resolution |
|
||||
|-------|------------|
|
||||
| Duplikacja instancji ReceiptConfigRepository/ReceiptRepository w web.php | Przeniesiono tworzenie przed ordersController, usunieto duplikaty |
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
**Ready:**
|
||||
- ReceiptRepository::findById() gotowe pod podglad paragonu (faza 11)
|
||||
- Snapshoty JSON (seller, buyer, items) gotowe do renderowania HTML/PDF
|
||||
- receipt_number unikalne — gotowe do wyswietlania
|
||||
|
||||
**Concerns:**
|
||||
- Brak
|
||||
|
||||
**Blockers:**
|
||||
- Brak
|
||||
|
||||
---
|
||||
*Phase: 10-receipt-issue, Plan: 01*
|
||||
*Completed: 2026-03-15*
|
||||
Reference in New Issue
Block a user