Files
orderPRO/.paul/phases/105-orders-statistics/105-01-SUMMARY.md
2026-04-19 22:43:02 +02:00

8.3 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established completed
105-orders-statistics 01 statistics
statistics
orders
reporting
filters
ui
mysql-collation
vat-fallback
phase provides
none existing orders + status dictionaries
new menu section Statistics -> Orders
daily orders report by channel with totals
filters
date range, channels multiselect, status groups multiselect
net amount fallback (23% VAT) when source channel does not expose net
orders analytics workflow
added patterns
daily SQL aggregation with dynamic channel columns
explicit COLLATE utf8mb4_unicode_ci on CAST expressions to avoid collation mix in mixed-charset schemas
brutto->netto deterministic fallback (/ 1.23) as last resort when source net is missing
created modified
src/Modules/Statistics/OrdersStatisticsController.php
src/Modules/Statistics/OrdersStatisticsRepository.php
resources/views/statistics/orders.php
.paul/TODO.md
routes/web.php
resources/views/layouts/app.php
resources/lang/pl.php
resources/scss/app.scss
public/assets/css/app.css
.paul/docs/ARCHITECTURE.md
.paul/docs/DB_SCHEMA.md
.paul/docs/TECH_CHANGELOG.md
Channel split: allegro as one channel, shopPRO by integration_id (shoppro:{id})
Default status groups: all active except group normalized to 'anulowane'
No DB migration - feature based on existing schema
Net fallback: gross / 1.23 when orders.total_without_tax is NULL or 0 (shopPRO does not send net)
Explicit COLLATE utf8mb4_unicode_ci on channel CASE (avoids 1271 Illegal mix of collations with CAST integer->CHAR)
Statistics module pattern (Controller + Repository + dedicated view)
Filter presence hidden flags to distinguish defaults from explicit empty multiselect
Post-APPLY hotfix pattern: collation bug caught by catching Throwable in repo → silently empty response; require explicit COLLATE on any CAST(int AS CHAR) used in IN clauses
2026-04-19

Phase 105 Plan 01: Orders Statistics Summary

Dodano nowa sekcje Statystyki -> Zamowienia z dziennym raportem ilosci/netto/brutto, filtrami (daty, kanaly multiselect, grupy statusow multiselect) oraz stopka Podsumowanie. Po poczatkowym wdrozeniu poprawiono bug kolizji collation w MySQL (widok zwracal pusta tabele) oraz dodano fallback wyliczania netto z brutto dla zrodel (shopPRO) ktore nie wysylaja kwoty netto.

Acceptance Criteria Results

Criterion Status Notes
AC-1: Nowa pozycja menu i routing Pass /statistics/orders + nowy blok menu
AC-2: Filtry dat/kanalow/grup statusow Pass Date range + multiselect + domyslne wykluczenie anulowane
AC-3: Tabela dzienna + wiersz podsumowania Pass Dynamiczne kolumny per kanal, stopka Podsumowanie
AC-4: Rozbicie na Allegro i shopPRO per integracja Pass allegro i shoppro:{integration_id}

Files Created/Modified

File Change Purpose
src/Modules/Statistics/OrdersStatisticsController.php Created Parsowanie filtrow, budowa view-modelu, render strony
src/Modules/Statistics/OrdersStatisticsRepository.php Created Agregacja dzienna SQL + diagnostics + fallback netto
resources/views/statistics/orders.php Created Widok formularza filtrow i tabeli dziennej
routes/web.php Modified Route GET /statistics/orders za AuthMiddleware
resources/views/layouts/app.php Modified Sidebar: grupa Statystyki -> Zamowienia
resources/lang/pl.php Modified Klucze navigation.statistics*, statistics.orders.*
resources/scss/app.scss Modified Kompaktowy layout filtrow i tabeli statystyk
public/assets/css/app.css Modified Build SCSS
.paul/docs/ARCHITECTURE.md Modified Opis modulu Statistics + endpoint
.paul/docs/DB_SCHEMA.md Modified Adnotacja: feature bez migracji
.paul/docs/TECH_CHANGELOG.md Modified Wpis + hotfix collation + hotfix fallback netto
.paul/TODO.md Created Tag STAT-NET: docelowy netto z shopPRO / order_items.tax_rate

Decisions Made

Decision Rationale Impact
Explicit COLLATE utf8mb4_unicode_ci na CASE zwracajacym channel_key CAST(integration_id AS CHAR) zwracal utf8mb4_bin, przez co IN (...) z parametrami (utf8mb4_general_ci) rzucal 1271 Illegal mix of collations. Repo lapalo Throwable i zwracalo [], widok byl pusty. Statystyki dzialaja; pattern udokumentowany dla przyszlych agregacji po integration_id
Fallback netto ROUND(gross / 1.23, 2) gdy total_without_tax puste shopPRO nie przesyla netto ani na poziomie zamowienia, ani pozycji (order_items.original_price_without_tax = NULL); bez fallbacku kolumna Netto pokazywala 0 Kolumna Netto pokazuje sensowne wartosci; docelowe rozwiazanie (STAT-NET) zapisane w TODO
Status codes pozostaja order_statuses.code (LOWER-normalized) Mapping Allegro zachowuje zgodnosc z OrdersRepository dzieki allegro_order_status_mappings Spojna semantyka statusow w module Orders i Statistics

Deviations from Plan

Summary

Type Count Impact
Auto-fixed 1 Essential — zerowe wyniki zanim hotfix
Scope additions 1 Uzasadnione — brak fallback netto byl pokazywany jako bug
Deferred 1 STAT-NET w .paul/TODO.md

Auto-fixed Issues

1. [SQL] Kolizja collation w channelSql() — statystyki zwracaly pusta tabele

  • Found during: Post-APPLY walidacja — user zglosil "strona statystyk nie pokazuje zamowien"
  • Issue: CAST(o.integration_id AS CHAR) daje utf8mb4_bin, CONCAT("shoppro:", ...) + IN (:ch0,:ch1) rzuca SQLSTATE[HY000] 1271. try/catch(Throwable) polykal blad → puste dane.
  • Fix: COLLATE utf8mb4_unicode_ci na CAST(...) oraz na calym wyrazeniu CASE zwracajacym channel_key.
  • Files: src/Modules/Statistics/OrdersStatisticsRepository.php (channelSql)
  • Verification: End-to-end test na produkcyjnym DB (host700513) — 41 wierszy zagregowanych dla 2026-04-01..30, kanaly: allegro, shoppro:5, shoppro:6, shoppro:7.

Scope Additions

1. [Feature] Fallback netto 23% VAT

  • Why: shopPRO nie wysyla total_without_tax; order_items.original_price_without_tax rowniez NULL. Bez fallbacku kolumna Netto byla bezuzyteczna (same zera).
  • Scope: netAmountSql() rozszerzony o CASE ... WHEN total_without_tax > 0 THEN total_without_tax ... WHEN total_with_tax > 0 THEN ROUND(total_with_tax/1.23, 2) ELSE 0 END.
  • Files: src/Modules/Statistics/OrdersStatisticsRepository.php, .paul/docs/TECH_CHANGELOG.md, .paul/TODO.md

Deferred Items

  • STAT-NET: Pobieranie netto z shopPRO (API) lub dokladne wyliczanie z order_items.tax_rate (unikniecie sztywnego 23%). Backfill historycznych rekordow. Zapisane w .paul/TODO.md.

Verification Executed

  • php -l src/Modules/Statistics/OrdersStatisticsRepository.php
  • php -l src/Modules/Statistics/OrdersStatisticsController.php
  • php -l routes/web.php
  • php -l resources/views/layouts/app.php
  • php -l resources/views/statistics/orders.php
  • php -l resources/lang/pl.php
  • npm run build:css
  • End-to-end on production DB (post-hotfix): 41 agregowanych wierszy dla 2026-04, netto/brutto zgodne (np. shoppro:7 2026-04-19: orders=17, net=989.45, gross=1217.05).

Skill Audit

Expected Invoked Notes
sonar-scanner (required) o Gap — nie uruchomiony podczas tej sesji UNIFY. .scannerwork/report-task.txt pokazuje modyfikacje wczesniej; skan dedykowany do tej zmiany nie wykonany.
/feature-dev (optional) o Nie uzywany
/frontend-design (optional) o Nie uzywany
/code-review (optional) o Nie uzywany
/simplify (optional) o Nie uzywany

Next Phase Readiness

Ready:

  • Modul Statistics dziala; schemat patternu dla kolejnych raportow (per-kanalowych).
  • TODO STAT-NET przechowane z konkretnym planem realizacji.

Concerns:

  • Kolumna Netto na kanalach shopPRO jest obecnie estymatem (sztywne 23% VAT). Jesli pojawia sie produkty o innej stawce (5%, 8%, 0%), agregat bedzie zawyzal netto dla tych pozycji.

Blockers:

  • None.

Phase: 105-orders-statistics, Plan: 01 Completed: 2026-04-19