# stats

Robocza dokumentacja modułu `stats`, utrzymywana według tego samego schematu co dokumentacja modułu `package`.

## Kontekst systemowy

`stats` to moduł analityczno-kontrolny dla sprzedaży, kosztów, kursów walut i wybranych obszarów rozchodowo-produkcyjnych.

Powiązane moduły ekosystemu:

- `package`
- `oms`
- `wms`
- `pim`
- `erp`

Moduł pracuje na własnych tabelach z prefiksem głównie `wms_stats_*` oraz `wms_cost_*`, ale korzysta też z tabel współdzielonych, zwłaszcza:

- `wms_dict_*`
- `wms_towar*`
- `wms_user`
- wybranych tabel modułu `package` przy generowaniu dokumentów WZ

## Aktualna wersja

- Wersja aplikacji: `0.5.1`
- Źródło wersji: plik `VERSION`
- Wczytanie wersji do aplikacji: `config/config.php` i `app/Lib/App.php`

## Zakres obecnej części projektu

Ta część aplikacji obsługuje przede wszystkim:

- przeglądanie i filtrowanie zamówień sprzedażowych,
- statystyki sprzedaży i agregacje per kanał / dzień / produkt / kategoria,
- analizy rozchodów i prognoz zapotrzebowania,
- raporty okresowe,
- raport kosztow i korekty punktowe rekordow kosztowych,
- importy kosztów, kursów walut, sprzedawców, faktur sprzedaży i mapowań,
- przeliczanie kosztów i wartości bazowych,
- kontrolę jakości danych i audyt schematu,
- wybrane operacje administracyjne powiązane z kosztami i WZ.

Obszar `Cenniki` jest prowadzony w tabelach z prefiksem `pim_`, bo docelowo ma przejsc do przyszlego modulu PIM.

W tej warstwie utrzymujemy tez wlasny slownik skladnikow kosztu `pim_dict_cost_component`, zeby obszar `pricing` nie zalezal juz od slownikow `wms_*`.
Slownik kosztow ma tez tylko dwa poziomy organizacji: grupa glowna i podgrupa.

Cennik przechowuje tez wlasna liste skladnikow kosztowych uwzglednianych przy kalkulacji ceny. To pozwala organizowac logike wyceny per rodzaj cennika, niezaleznie od samego faktu istnienia kosztu na symbolu.
Naglowek cennika przechowuje tez stawke VAT i flage zaokraglania wartosci brutto, a pozycja cennika przechowuje wartosc netto i brutto.
Widok `/pricing` jest widokiem prezentacyjnym, a formularze importow, regul i recznych checkow trafiaja do `/pricing/settings`.
Liczba pozycji cennika oraz liczba rekordow/symboli w rejestrach kosztowych sa cache'owane w tabelach `pim_*`, zamiast byc liczone na zywo na ekranie glownym.

Ustalenie techniczne dla kart zamówień:

- sekcja rozbicia kompletów na składniki nie powinna liczyć BOM na żywo z poziomu zamówienia,
- źródłem tej sekcji jest rejestr WZ `package_doc_wz` / `package_doc_wz_item`,
- okresowa przebudowa danych odbywa się przez generator WZ w `admin/cost/generate-wz`.

## Struktura

- `app/Controllers` - warstwa HTTP i orkiestracja ekranów.
- `app/Repositories` - warstwa odczytu i agregacji danych.
- `app/Services` - procesy domenowe i zadania przebudowy / generacji.
- `app/Lib` - bootstrap aplikacji, router, request/response, auth i DB.
- `app/Views` - widoki modułu.
- `sql/007.sql` - aktualny znany zrzut schematu dla modułu i tabel powiązanych.
- `sql/008_single_category_per_product.sql` - migracja przejściowa upraszczająca kategorie towarów do pojedynczego przypisania.
- `sql/009_single_model_per_product.sql` - migracja przejściowa dodająca pojedynczy model towaru na podstawie pierwszej sekcji symbolu.
- `sql/010_sales_market_assignments.sql` - migracja przejściowa dodająca market place do kanałów i zamówień oraz wstępne uzupełnienie danych.
- `sql/stats_towar_series.sql` - aktualna struktura słownika serii towarów w warstwie `stats`.
- `docs/glossary.md` - słownik pojęć roboczych i punkt wejścia do dokumentacji dla człowieka.
- `docs/controllers.yaml` - opis kontrolerów, tras i odpowiedzialności metod.
- `docs/database.yaml` - skrótowa mapa głównych tabel wykorzystywanych przez moduł.
- `docs/costs_and_imports.yaml` - opis procesów kosztowych, walutowych i importowych.
- `docs/reporting_workflow.yaml` - opis przepływu danych raportowych, statystycznych i demand.
- `docs/pricing_workflow.yaml` - ogolne zasady rejestru kosztow kalkulacyjnych, cennikow, VAT i kalkulacji brutto.
- `sql/018_pricing_foundation.sql` - fundament tabel obszaru `Cenniki` / przyszlego `PIM`.
- `sql/019_pricing_symbol_registry_tech_import.sql` - uzupelnienie rejestru symboli cennikowych z technicznej tabeli `towar_ceny_sprzedazy`.
- `sql/020_pricing_cost_component_dict.sql` - wlasny slownik skladnikow kosztu `pricing`, odciety od `wms`.
- `sql/024_pricing_cost_component_parent_groups.sql` - uzupelnienie slownika kosztow o hierarchie `grupa glowna -> podgrupa`.
- `sql/021_pricing_calc_cost_component_1.sql` - pierwszy wsad kosztu kalkulacyjnego z tabeli technicznej (`tw_koszt_towar` -> skladnik 1).
- `sql/023_pricing_calc_cost_component_6.sql` - kolejny wsad kosztu kalkulacyjnego z tabeli technicznej (`tw_koszt_operacje` -> skladnik 6).
- `sql/025_pricing_calc_cost_component_8.sql` - kolejny wsad kosztu kalkulacyjnego z tabeli technicznej (`tw_koszt_operacje_detluz` -> skladnik 8).
- `sql/026_pricing_calc_cost_component_9.sql` - kolejny wsad kosztu kalkulacyjnego z tabeli technicznej (`tw_koszt_operacje_hurtkpl` -> skladnik 9).
- `sql/027_pricing_calc_cost_component_10.sql` - kolejny wsad kosztu kalkulacyjnego z tabeli technicznej (`tw_koszt_operacje_hurtluz` -> skladnik 10).
- `sql/029_pricing_cached_stats.sql` - dodanie i pierwsze uzupelnienie licznikow cache dla list cennikow i skladnikow kosztowych.

## Rozszerzenie rejestrow raportowych 2026-05

Aktualny model raportow okresowych obejmuje juz nie tylko:

- produkt,
- skladnik,
- real issue,
- dokument / zamowienie,

ale takze wspolny rejestr wymiarow raportowych:

- model,
- seria,
- kategoria,
- kanal sprzedazy,
- marketplace,
- kraj.

Najwazniejsze zasady:

- rejestry dzienne i okresowe przechowuja teraz takze `weight_total`,
- rejestry okresowe produktu / skladnika / real przechowuja `active_days`,
- regularnosc w raportach liczona jest jako `active_days / liczba dni w okresie`,
- nowe przekroje wymiarowe sa zapisywane do wspolnych tabel `wms_stats_daily_issue_dim` i `wms_stats_period_issue_dim`,
- zrodlem przebudowy pozostaje WZ, czyli `package_doc_wz` oraz `package_doc_wz_item`.

## Ustalenia po przeglądzie kosztów 2026-04

Najważniejsze ustalenia robocze:

- aktywny koszt sprzedaży, WZ i raportów jest dziś liczony z miesięcznego cache `wms_cost_month_product`,
- kolejność źródeł kosztu w aktywnym runtime to: `PZ` -> `CALC z BOM` -> `MANUAL w cache miesięcznym`,
- importer zapisuje także dane do `wms_cost_product`, `wms_cost_order_override` i `wms_cost_item_override`, ale bieżący runtime nie wykorzystuje tych tabel jeszcze do liczenia kosztu zamówień ani WZ,
- przypisanie kosztu do zamówienia działa obecnie po `YYYY-MM` z daty zamówienia, a nie według reguły "najbliższy koszt przed datą, a jeśli brak to po dacie",
- `wms_cost_growth_index` jest używane tylko w obszarze `demand`; gdy brak wpisu, kod stosuje domyślny indeks `1.1`,
- formularz "Koszty — zakres miesięcy" działa już na wejściu typu `month`; backend dodatkowo normalizuje zakres do formatu `YYYY-MM`,
- od 2026-04 aktywny runtime dopuszcza także koszt `carry` w `wms_cost_month_product`, czyli koszt przepisany z najbliższego wcześniejszego miesiąca z realnym kosztem,
- importy `PZ`, `product_cost` i `bom` ustawiają flagę `csr_flag_needs_recalc`, a admin/checki pokazują zadania odświeżenia cache miesięcznego.

Wniosek praktyczny:

- miesięczny cache i BOM są spięte z analizą,
- warstwa kosztów "czasowych" zasila już cache miesięczny przez operację odświeżenia,
- override'y zamówienia i pozycji dalej pozostają poza aktywnym runtime kosztów.

## Wersjonowanie

Przyjęty mechanizm:

1. Plik `VERSION` przechowuje `VERSION` i `BUILD`.
2. `app/Lib/App.php` wczytuje tę informację do aplikacji.
3. Endpoint `/health` zwraca wersję aplikacji.
4. Dokumentacja w `docs/` opisuje stan zgodny z bieżącym routerem i strukturą kodu.

## Proponowany sposób dalszej pracy

- aktualizować `docs/controllers.yaml` przy każdej zmianie tras albo odpowiedzialności kontrolera,
- dopisywać do `docs/database.yaml` nowe tabele lub ważne zależności współdzielone,
- dokumentować większe procesy analityczne i importowe w osobnych plikach YAML,
- utrzymywać `stats` w tym samym stylu dokumentacji co `package`, aby kolejne moduły dało się opisać jednym schematem.

## Fundament runtime towaru 2026-04-29

Bezpieczny etap przejsciowy przed odcieciem `stats` od `wms_towar*`:

- `wms_stats_towar` zostaje glowna karta produktu dla `stats`,
- `stw_id` pozostaje lokalnym identyfikatorem modulu,
- `symbol` pozostaje kluczem komunikacyjnym i mostem importowym,
- `stw_tw_id` przechowuje historyczne powiazanie do aktualnego `wms_towar.tw_id`, ustalone po `symbolu`,
- `wms_stats_towar_komplet` przechowuje BOM modulu `stats` po `stw_id`,
- ekran `admin/towar-integrity` sluzy do porownania `legacy BOM` i `stats BOM` po `symbolach` i `ilosciach` jeszcze przed przepieciem runtime.
- migracja `sql/014_register_ids_to_stats_towar.sql` zachowuje stare identyfikatory w `*_old_tw_id`, ale od tego momentu `pdwi_tw_id` w WZ oraz `*_tw_id` w rejestrach przechowuja juz `wms_stats_towar.stw_id`.

Wazne ograniczenia tego etapu:

- `stw_id` nie jest tozsame z `tw_id`,
- przyszle importy moga zostawiac `stw_tw_id = NULL`,
- runtime kosztow, WZ i kart moze jeszcze czytac `wms_towar*` dopoki nie zakonczymy fazy przepiecia.

## Standard UTF i kolacji

Przyjmujemy jako standard techniczny dla nowych tabel i nowych kolumn tekstowych w `stats`:

- `CHARSET utf8mb4`
- `COLLATE utf8mb4_unicode_ci`

Zasady praktyczne:

- nowe migracje i nowe tabele tworzymy w `utf8mb4_unicode_ci`,
- mieszanie `utf8mb4_general_ci` i `utf8mb4_unicode_ci` traktujemy jako blad techniczny,
- przy bledach SQL na porownaniach lub joinach po polach tekstowych najpierw sprawdzamy kolacje tabel i kolumn.
