- Implemented a new PHP script to retrieve insights for the last N days (default 30). - Supports command-line options for token, account ID, days, API version, and output file. - Fetches data at campaign, adset, and ad levels, with filtering for active statuses. - Handles JSON output and optional file saving, including directory creation if necessary. - Includes error handling for cURL requests and JSON responses.
427 lines
21 KiB
Markdown
427 lines
21 KiB
Markdown
# 2026-02-20 - Obsluga statusu ACTIVE dla klientow
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/controls/class.Clients.php`
|
|
- `save()` zapisuje teraz pole `active` (domyslnie `1`, gdy brak wartosci z formularza).
|
|
- Dodana nowa akcja `set_active()` pod endpoint `/clients/set_active` do szybkiej zmiany statusu klienta AJAX-em.
|
|
- `force_sync()` ma dodatkowa walidacje:
|
|
- nie pozwala kolejkowac synchronizacji dla klienta nieaktywnego (`active != 1`),
|
|
- nadal blokuje klienta usunietego (`deleted = 1`) i klienta bez wymaganych ID.
|
|
- Kompatybilnosc schematu `clients` bez kolumny `deleted`:
|
|
- helpery `clients_has_deleted_column()` i `sql_clients_not_deleted()`,
|
|
- `force_sync()` i `sync_status()` nie wywalaja sie, gdy w bazie nie ma kolumny `deleted`.
|
|
|
|
- `templates/clients/main_view.php`
|
|
- Tabela klientow ma nowa kolumne `Status` (Aktywny/Nieaktywny).
|
|
- Wiersz klienta trzyma `data-active` do obslugi UI i synchronizacji.
|
|
- Dodany przycisk toggle (ikona `fa-toggle-on/off`) do natychmiastowej aktywacji/dezaktywacji.
|
|
- Przyciski synchronizacji (kampanie/produkty/merchant) sa blokowane (`disabled`) dla nieaktywnego klienta i odblokowywane po aktywacji.
|
|
- Formularz Dodaj/Edytuj klienta ma nowe pole `Status klienta` (`active`).
|
|
- JS:
|
|
- `toggleClientActive()` wysyla POST na `/clients/set_active`,
|
|
- `updateClientStatusUI()` odswieza status i stan komorki Sync bez przeladowania strony,
|
|
- `loadSyncStatus()` pomija paski postepu dla nieaktywnych klientow i pokazuje `nieaktywny`.
|
|
|
|
## Gdzie to jest wykorzystywane
|
|
|
|
- Zarzadzanie statusem klienta:
|
|
- UI listy i formularza: `templates/clients/main_view.php`
|
|
- Backend zapisu i toggle: `autoload/controls/class.Clients.php`
|
|
- Ograniczenie recznego wymuszenia synchronizacji do klientow aktywnych:
|
|
- `autoload/controls/class.Clients.php` (`force_sync()`)
|
|
|
|
# 2026-02-20 - CRON kampanii (nowy przebieg, stare jako archiwum)
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/controls/class.Cron.php`
|
|
- Dodany nowy `cron_campaigns()` jako glowny endpoint pod nowy przeplyw.
|
|
- Stary kod zostal zachowany jako archiwum: `cron_campaigns_archive()`.
|
|
- Nowy przebieg:
|
|
- bierze tylko aktywnych klientow (`active = 1`) z Google Ads Customer ID,
|
|
- liczy okno dat na podstawie `google_ads_conversion_window_days` z `config.php` (z fallbackiem),
|
|
- konczy okno na `przedwczoraj` (bez pobierania danych dzisiejszych),
|
|
- przechodzi po datach dzien po dniu (rosnaco),
|
|
- zapisuje/aktualizuje kampanie do `campaigns`,
|
|
- zapisuje/aktualizuje historie dzienne do `campaigns_history` (upsert po `campaign_id + date_add`),
|
|
- zapisuje grupy reklam / groupy PMAX do `campaign_ad_groups`.
|
|
- po zakonczeniu kampanii + ad groups dla klienta, dla calego okna dat pobiera search terms dzienne do `campaign_search_terms_history`,
|
|
- po pobraniu historii search terms wykonuje agregacje do `campaign_search_terms` (zanim przejdzie do kolejnego klienta).
|
|
- Dodany krok syncu fraz dodanych i wykluczonych:
|
|
- tabele docelowe: `campaign_keywords` i `campaign_negative_keywords`,
|
|
- uruchamiany raz na cykl klienta (po ostatnim dniu okna), nie x razy dla kazdego dnia.
|
|
- Kampanie produktowe / PMAX:
|
|
- nie maja fraz dodanych, wiec w `campaign_keywords` moga miec 0 rekordow,
|
|
- frazy wykluczone sa dalej synchronizowane do `campaign_negative_keywords`.
|
|
|
|
# 2026-02-20 - Produkty: przygotowanie schematu bazy
|
|
|
|
## Zmienione pliki
|
|
|
|
- `migrations/016_products_model_unification.sql`
|
|
- Dodane kolumny produktowe bezposrednio do `products`:
|
|
- `custom_label_4`, `custom_label_3`, `title`, `description`, `google_product_category`, `product_url`.
|
|
- Backfill danych z `products_data` -> `products` (tylko gdy pole w `products` jest puste).
|
|
- Dodana nowa tabela agregacyjna `products_aggregate`:
|
|
- scope: `product_id + campaign_id + ad_group_id` (unikalne),
|
|
- metryki `*_30` i `*_all_time`,
|
|
- `date_sync` (kiedy agregat byl przeliczony).
|
|
|
|
- `docs/database.sql`
|
|
- Zaktualizowana definicja `products` o nowe kolumny danych produktu.
|
|
- Dodana definicja tabeli `products_aggregate`.
|
|
|
|
## Ustalenie projektowe
|
|
|
|
- `products` staje sie glowna tabela danych produktu.
|
|
- `products_data` zostaje tymczasowo dla kompatybilnosci starego kodu; dane sa migrowane do `products`.
|
|
- Agregaty dla widokow `/products` powinny docelowo byc czytane z `products_aggregate` zamiast liczenia w locie.
|
|
|
|
# 2026-02-20 - Produkty: przepiecie na `products` + agregaty
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/factory/class.Products.php`
|
|
- `get_product_data()`:
|
|
- najpierw czyta pola produktowe z `products` (`custom_label_4`, `custom_label_3`, `title`, `description`, `google_product_category`, `product_url`),
|
|
- fallback do `products_data` dla kompatybilnosci.
|
|
- `set_product_data()`:
|
|
- zapisuje pole glownie do `products`,
|
|
- rownolegle mirroruje zapis do `products_data` (kompatybilnosc starego kodu).
|
|
|
|
- `autoload/controls/class.Cron.php`
|
|
- `sync_products_fetch_for_client()`:
|
|
- import produktow zapisuje dane produktowe bezposrednio do `products` (w tym `title`, `product_url`),
|
|
- usuniete poleganie na `products_data` podczas samego fetchu.
|
|
- `aggregate_products_history_30_for_client()`:
|
|
- po przeliczeniu `products_history_30` odpala przebudowe agregatow `products_aggregate` dla klienta i dnia.
|
|
- Dodana metoda `rebuild_products_aggregate_for_client( $client_id, $date_sync )`:
|
|
- liczy metryki `*_30` i `*_all_time` z `products_history`,
|
|
- zapisuje scope (`product_id + campaign_id + ad_group_id`) do `products_aggregate`.
|
|
- `rebuild_products_temp_for_client()`:
|
|
- przestawione z liczenia bezposrednio po `products_history` na odczyt z `products_aggregate`,
|
|
- zmniejsza liczenie "w locie" dla widoku `/products`.
|
|
- `cron_product_history_30_save()`:
|
|
- `products_history_30` przechowuje teraz srednie dzienne wartosci z okna do 30 dni (zamiast sumy okna),
|
|
- nadal zapisuje `roas_all_time` dla danego dnia.
|
|
- `generate_custom_feed_for_client()`:
|
|
- zrodlo danych produktowych przepiete na `products` (bez wymaganego `INNER JOIN products_data`).
|
|
- diagnostyka i pobieranie brakujacych URL (`cron_products_urls`):
|
|
- logika "ma URL / brak URL" bierze pod uwage `products.product_url` z fallbackiem do `products_data`.
|
|
|
|
## Gdzie to jest wykorzystywane
|
|
|
|
- Pipeline produktowy:
|
|
- `/cron/cron_products`
|
|
- etap `fetch` -> `products_history`,
|
|
- etap agregacji -> `products_history_30` + `products_aggregate`,
|
|
- etap finalny -> `products_temp` budowane z `products_aggregate`.
|
|
- Widok tabeli produktow `/products`:
|
|
- dane nadal czytane z `products_temp`, ale `products_temp` jest teraz zasilane agregatami z `products_aggregate`.
|
|
- Dodany helper `sync_campaigns_snapshot_for_client()` dla nowego przebiegu kampanii.
|
|
- Dodany helper `sync_campaign_terms_backfill_for_client()` dla kroku fraz (history + agregacja).
|
|
- Tryb wykonania nowego pipeline kampanii: 1 dzien = 1 wywolanie CRON.
|
|
- Na jednym wywolaniu: kampanie + ad groups + search terms history + agregacja search terms dla jednego dnia.
|
|
- Kolejne wywolanie przechodzi do kolejnego dnia dla tego samego klienta.
|
|
- Tryb debug dla nowego CRON:
|
|
- `?debug=true` zwraca czytelny HTML (podsumowanie + pelny payload),
|
|
- bez debug zwracany jest standardowy JSON.
|
|
- Dodany helper `cleanup_pipeline_rows_outside_window()` aby pipeline kampanii trzymal tylko aktualne okno dat.
|
|
- Filtry klientow w nowym CRON kampanii sa odporne na stare dane (`NULL`): `COALESCE(active,0)`, `COALESCE(deleted,0)`, `TRIM(COALESCE(google_ads_customer_id,''))`.
|
|
- Dodana kompatybilnosc schematu `clients` bez kolumny `deleted`:
|
|
- helpery: `clients_has_column()`, `sql_clients_not_deleted()`, `sql_clients_deleted()`,
|
|
- nowy pipeline kampanii (`cron_campaigns`/`cron_universal`) nie wywala sie na bazie bez `deleted`.
|
|
- `get_conversion_window_days( $prefer_config = false )` uwzglednia teraz konfiguracje z `config.php`.
|
|
- `sync_campaign_ad_groups_for_client()` dostal parametr `as_of_date`.
|
|
|
|
- `autoload/services/class.GoogleAdsApi.php`
|
|
- `get_ad_groups_30_days()` wspiera teraz parametr `as_of_date` i zakres dat `[as_of_date-29, as_of_date]`.
|
|
- `get_ad_groups_all_time()` wspiera teraz parametr `as_of_date` (filtr `segments.date <= as_of_date` z fallbackiem).
|
|
|
|
## Gdzie to jest wykorzystywane
|
|
|
|
- Głowny CRON kampanii: `/cron/cron_campaigns` -> `\controls\Cron::cron_campaigns()`.
|
|
- Uniwersalny CRON pipeline (zalecany endpoint): `/cron/cron_universal` -> `\controls\Cron::cron_universal()` (aktualnie deleguje do kroku kampanii).
|
|
- Archiwalny CRON kampanii (stara logika): `/cron/cron_campaigns_archive`.
|
|
- Dane do wykresow/tabel kampanii pozostaja pobierane z `campaigns_history`.
|
|
|
|
# 2026-02-20 - CRON uniwersalny jako glowny endpoint (1 dzien na wywolanie)
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/controls/class.Cron.php`
|
|
- `cron_universal()` nie deleguje juz do `cron_campaigns()`.
|
|
- W jednym wywolaniu realizuje sekwencje:
|
|
- `kampanie` (snapshot + ad groups + search terms + agregacja),
|
|
- `produkty` (fetch + `products_history_30` + `products_aggregate` + `products_temp`).
|
|
- Tryb pracy pozostaje: `1 wywolanie = 1 klient + 1 dzien`.
|
|
- Status dnia jest zapisywany do `cron_sync_status` dla obu pipeline:
|
|
- `campaigns`,
|
|
- `products`.
|
|
- Gdy krok kampanii zwroci blad, krok produktow dla tego dnia jest pomijany (`products_sync_skipped_reason=campaigns_failed`).
|
|
|
|
## Gdzie to jest wykorzystywane
|
|
|
|
- Docelowy adres CRON:
|
|
- `/cron/cron_universal?debug=true`
|
|
- Stare endpointy (`/cron/cron_campaigns`, `/cron/cron_products`) pozostaja w kodzie, ale nie sa docelowa sciezka wykonywania.
|
|
|
|
# 2026-02-20 - Poprawka niezaleznosci pipeline w `cron_universal`
|
|
|
|
## Problem
|
|
|
|
- `campaigns` mialo juz 100% (`done`) i `cron_universal` konczyl wykonanie, mimo ze `products` mial jeszcze zalegle daty.
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/controls/class.Cron.php`
|
|
- `cron_universal()` wybiera teraz aktywnego klienta niezaleznie dla obu pipeline:
|
|
- `campaigns`,
|
|
- `products`.
|
|
- Zakonczenie "wszyscy przetworzeni" następuje dopiero, gdy **oba** pipeline nie maja juz aktywnych pozycji.
|
|
- Dodane osobne liczenie pozostalych dat:
|
|
- `campaigns_remaining_dates`,
|
|
- `products_remaining_dates`.
|
|
- Statusy `done/pending` sa zapisywane osobno dla kazdego pipeline; produkty nie sa juz blokowane przez sam fakt, ze kampanie sa skonczone globalnie.
|
|
- Ujednolicenie trybu `client_id`:
|
|
- kampanie i produkty wykonują sie niezaleznie (w tym samym wywolaniu), a bledy sa laczone tylko w odpowiedzi.
|
|
|
|
# 2026-02-20 - Usuniecie `products_data`
|
|
|
|
## Zmienione pliki
|
|
|
|
- `migrations/017_drop_products_data.sql`
|
|
- Dodana migracja usuwajaca tabele `products_data`.
|
|
|
|
- `autoload/factory/class.Products.php`
|
|
- `get_product_data()` czyta dane tylko z `products`.
|
|
- `set_product_data()` zapisuje dane tylko do `products`.
|
|
|
|
- `autoload/controls/class.Cron.php`
|
|
- diagnostyka URL i wybieranie produktow bez URL opiera sie juz tylko o `products.product_url`.
|
|
|
|
- `docs/database.sql`
|
|
- usunieta definicja tabeli `products_data`.
|
|
|
|
- `migrations/demo_data.sql`
|
|
- usuniete operacje `INSERT/DELETE` na `products_data`,
|
|
- etykiety demo (`custom_label_4`) sa ustawiane bezposrednio w `products`.
|
|
|
|
## Gdzie to jest wykorzystywane
|
|
|
|
- Dane produktowe (`title`, `description`, `google_product_category`, `custom_label_3`, `custom_label_4`, `product_url`) sa trzymane tylko w `products`.
|
|
|
|
# 2026-02-20 - Ostatni krok `cron_universal`: URL z Merchant + alerty brakow
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/controls/class.Cron.php`
|
|
- Dodany helper `sync_products_urls_and_alerts_for_client()`.
|
|
- Na koncu przebiegu `cron_universal` (zarowno tryb automatyczny, jak i `client_id`) wykonywany jest krok:
|
|
- pobranie URL produktow z Google Merchant Center dla produktow bez URL,
|
|
- zapis URL do `products.product_url`.
|
|
- Gdy `offer_id` nie istnieje w Merchant Center, tworzony/aktualizowany jest alert w `campaign_alerts`:
|
|
- `alert_type = products_missing_in_merchant_center`,
|
|
- scope techniczny: `campaign_external_id = 0`, `ad_group_external_id = 0`,
|
|
- `meta_json` zawiera m.in. listy `missing_offer_ids` i `missing_product_ids`.
|
|
- Gdy w danym dniu brak brakujacych produktow, dzienny alert tego typu jest czyszczony.
|
|
- Do odpowiedzi cron dodane pola diagnostyczne:
|
|
- `merchant_urls_checked`,
|
|
- `merchant_urls_updated`,
|
|
- `merchant_missing_in_mc_count`,
|
|
- `merchant_missing_offer_ids`.
|
|
- `cron_universal` ma dodatkowy fallback niezalezny od pipeline `campaigns/products`:
|
|
- gdy oba pipeline sa zakonczone, ale sa jeszcze produkty bez URL, uruchamia sam krok Merchant URL + alerty (`merchant_only=1`),
|
|
- dopiero brak takich produktow daje komunikat "Wszyscy aktywni klienci zostali przetworzeni...".
|
|
- Krok Merchant URL nie jest wykonywany dla kazdego dnia okna; dziala jako osobny etap po zakonczeniu `campaigns/products`.
|
|
- Do zapytan do GMC trafiaja tylko produkty z `products.product_url IS NULL` i `merchant_url_not_found = 0`.
|
|
- Na jedno wywolanie wykonywana jest jedna paczka sprawdzen (limit z `config.php`: `cron_products_urls_limit_per_client`, ustawiony na `100`).
|
|
- Produkty, ktorych GMC nie zwraca (brak URL), sa oznaczane:
|
|
- `products.merchant_url_not_found = 1`,
|
|
- `products.merchant_url_last_check = NOW()`,
|
|
- dzieki temu nie sa wysylane ponownie w nieskonczonosc.
|
|
- Alert `products_missing_in_merchant_center` jest liczony na podstawie calej aktualnej puli `merchant_url_not_found = 1` (nie tylko bieżącej paczki), wiec nie znika przy `checked_products = 0`.
|
|
- Alerty sa per produkt (1 alert = 1 produkt):
|
|
- dla kazdego produktu bez URL i z `merchant_url_not_found = 1` tworzony jest osobny wpis w `campaign_alerts`,
|
|
- tresc alertu zawiera nazwe produktu (fallback: `name`, dalej `offer_id`) i `offer_id`,
|
|
- technicznie: `campaign_external_id = products.id`, co stabilizuje unikalnosc wpisu.
|
|
|
|
- `migrations/018_products_merchant_url_flags.sql`
|
|
- Dodane kolumny w `products`:
|
|
- `merchant_url_not_found` (TINYINT, domyslnie 0),
|
|
- `merchant_url_last_check` (DATETIME).
|
|
- Normalizacja: puste/sztuczne `product_url` (`'', '0', '-', 'null'`) ustawiane na `NULL`.
|
|
|
|
- `autoload/factory/class.Products.php`
|
|
- Przy zapisie `product_url`:
|
|
- ustawiany jest `merchant_url_last_check`,
|
|
- dla poprawnego URL resetowane jest `merchant_url_not_found = 0`.
|
|
|
|
# 2026-02-20 - Alerty na stronie `/products` dla klient + kampania
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/factory/class.Products.php`
|
|
- `get_scope_alerts()` nie wymaga juz wybranej grupy reklam:
|
|
- minimalny scope: `client_id + campaign_id`,
|
|
- filtr `ad_group_id` jest stosowany tylko opcjonalnie (gdy grupa jest wybrana).
|
|
|
|
- `templates/products/main_view.php`
|
|
- `load_scope_alerts()` pobiera alerty juz dla kombinacji `klient + kampania`.
|
|
- Sekcja alertow ma zaktualizowany opis: kampania + opcjonalna grupa reklam.
|
|
|
|
## Gdzie to jest wykorzystywane
|
|
|
|
- `/products`
|
|
- Panel alertow pod filtrami pokazuje alerty:
|
|
- dla calej kampanii (gdy grupa reklam nie jest wybrana),
|
|
- lub zawezone do konkretnej grupy (gdy grupa reklam jest wybrana).
|
|
|
|
# 2026-02-20 - Etykietowanie alertow Merchant (bez falszywej kampanii)
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/controls/class.Cron.php`
|
|
- Dla alertu `products_missing_in_merchant_center` nie jest juz zapisywany `product_id` w `campaign_external_id`.
|
|
- Pola scope kampanii/grupy sa zapisywane jako `0` (alert produktowy, bez przypisania do kampanii).
|
|
|
|
- `templates/campaign_alerts/main_view.php`
|
|
- Dla alertu `products_missing_in_merchant_center` tabela alertow pokazuje:
|
|
- Kampania: `Produkt (Merchant Center)`,
|
|
- Grupa reklam: `---`.
|
|
- Dla pozostalych alertow fallback `Kampania #...` / `Grupa reklam #...` dziala tylko dla dodatnich external_id; dla `0` pokazuje neutralne etykiety.
|
|
|
|
# 2026-02-20 - Powiazanie `campaign_alerts` z `products`
|
|
|
|
## Zmienione pliki
|
|
|
|
- `migrations/019_campaign_alerts_product_id.sql`
|
|
- Dodana kolumna `campaign_alerts.product_id` (NULL) oraz indeks `idx_alert_product`.
|
|
|
|
- `autoload/controls/class.Cron.php`
|
|
- Alerty `products_missing_in_merchant_center` zapisuja `product_id` w tabeli `campaign_alerts`.
|
|
- Dla zachowania unikalnosci dziennej per produkt, techniczny `campaign_external_id` pozostaje rowny `product_id`.
|
|
|
|
- `autoload/factory/class.CampaignAlerts.php`
|
|
- `get_alerts()` zwraca teraz rowniez pole `product_id`.
|
|
|
|
- `docs/database.sql`
|
|
- Dodana aktualna definicja tabeli `campaign_alerts` z kolumna `product_id`.
|
|
|
|
# 2026-02-20 - CRON produktow: `title` nie jest uzupelniany automatycznie
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/controls/class.Cron.php`
|
|
- W syncu produktow do tabeli `products` CRON nie zapisuje juz pola `title`.
|
|
- Dla nowych produktow CRON zapisuje tylko `name` (bez `title`).
|
|
- Dla istniejacych produktow usunieto automatyczne uzupelnianie pustego `title`.
|
|
|
|
## Gdzie to jest wykorzystywane
|
|
|
|
- `/cron/cron_universal`
|
|
- automatyczny import produktow nie nadpisuje ani nie uzupelnia `products.title`,
|
|
- `title` pozostaje polem do recznej edycji i wysylki do GMC.
|
|
|
|
# 2026-02-20 - Lista produktow z 0 wyswietlen (30 dni) na `/products`
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/factory/class.Products.php`
|
|
- Dodana metoda `get_products_without_impressions_30( $client_id, $campaign_id, $limit )`.
|
|
- Zwraca produkty z wybranej kampanii, ktore maja sume `impressions_30 = 0` na podstawie `products_aggregate`.
|
|
- Dodatkowy filtr `ad_group_id` (opcjonalny), aby lista byla zgodna z aktualnym filtrem grupy reklam na widoku.
|
|
|
|
- `autoload/controls/class.Products.php`
|
|
- Dodany endpoint `get_products_without_impressions_30()`.
|
|
- Zwraca JSON: `status`, `products[]`, `count` i przyjmuje opcjonalnie `ad_group_id`.
|
|
|
|
- `templates/products/main_view.php`
|
|
- Dodana sekcja nad tabela produktow:
|
|
- "Produkty do sprawdzenia (0 wyswietlen w ostatnich 30 dniach)".
|
|
- Sekcja pojawia sie dla wybranego `klient + kampania`.
|
|
- Lista odswieza sie przy zmianie klienta/kampanii/grupy oraz po zaladowaniu strony.
|
|
|
|
## Gdzie to jest wykorzystywane
|
|
|
|
- `/products`
|
|
- pomocnicza lista produktow potencjalnie nieistniejacych / wymagajacych weryfikacji (0 wyswietlen w 30 dni dla wybranej kampanii).
|
|
|
|
# 2026-02-20 - Ustawienia CRON: poprawka licznika klientow + usuniecie "Krok 1/Krok 2"
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/controls/class.Users.php`
|
|
- Licznik `Klienci z Google Ads ID` liczy teraz klientow z:
|
|
- `COALESCE(active, 0) = 1`,
|
|
- `TRIM(COALESCE(google_ads_customer_id, '')) <> ''`.
|
|
- Analogicznie poprawione filtry dla klientow Merchant i zapytan pomocniczych (wg `active`).
|
|
- Harmonogram krokow (`Krok 1`, `Krok 2`) w danych dashboardu CRON jest pusty.
|
|
|
|
- `templates/users/settings.php`
|
|
- Usunieta sekcja wizualna harmonogramu krokow CRON (`Krok 1` / `Krok 2`).
|
|
- Usunieta obsluga renderowania tej sekcji w JS odswiezajacym status CRON.
|
|
|
|
## Gdzie to jest wykorzystywane
|
|
|
|
- `/settings?settings_tab=cron`
|
|
- licznik klientow z Google Ads ID pokazuje poprawna wartosc na podstawie aktywnych klientow (`active = 1`),
|
|
- brak sekcji "Krok 1 / Krok 2".
|
|
|
|
# 2026-02-20 - `/products` czyta bezposrednio z `products_aggregate`
|
|
|
|
## Zmienione pliki
|
|
|
|
- `autoload/factory/class.Products.php`
|
|
- Zapytania dla listy produktow i licznikow zostaly przepiete z `products_temp` na `products_aggregate`:
|
|
- `get_products()`,
|
|
- `get_roas_bounds()`,
|
|
- `get_records_total_products()`,
|
|
- `get_product_full_context()`.
|
|
- Metryki all-time sa liczone z pol:
|
|
- `impressions_all_time`, `clicks_all_time`, `cost_all_time`, `conversions_all_time`, `conversion_value_all_time`.
|
|
- Metryki 30d sa czytane z:
|
|
- `impressions_30`, `clicks_30`.
|
|
|
|
## Gdzie to jest wykorzystywane
|
|
|
|
- `/products`
|
|
- tabela i liczniki nie zaleza juz od `products_temp`; biora dane bezposrednio z `products_aggregate`.
|
|
|
|
# 2026-02-20 - `custom_label_4` tylko z tabeli `products`
|
|
|
|
## Ustalenie
|
|
|
|
- Etykieta `custom_label_4` jest czytana i zapisywana z tabeli `products`.
|
|
- Agregaty (`products_aggregate`) nie sa zrodlem dla pola `custom_label_4`.
|
|
|
|
# 2026-02-20 - Usuniecie funkcjonalnosci `bestseller_min_roas`
|
|
|
|
## Zmienione pliki
|
|
|
|
- `templates/products/main_view.php`
|
|
- Usuniety filtr UI: pole `Bestseller min ROAS` (`#bestseller_min_roas`).
|
|
- Usuniety frontendowy loader wartosci progu (`load_client_bestseller_min_roas`).
|
|
- Usuniete wywolania loadera przy zmianie klienta i przy inicjalizacji strony.
|
|
- Usuniety zapis AJAX progu klienta na blur (`/products/save_client_bestseller_min_roas/`).
|
|
|
|
- `autoload/controls/class.Products.php`
|
|
- Usuniete endpointy:
|
|
- `get_client_bestseller_min_roas()`
|
|
- `save_client_bestseller_min_roas()`
|
|
|
|
- `autoload/factory/class.Products.php`
|
|
- Usuniete metody dostepu do progu ROAS klienta:
|
|
- `get_client_bestseller_min_roas( $client_id )`
|
|
- `save_client_bestseller_min_roas( $client_id, $min_roas )`
|
|
|
|
- `autoload/controls/class.Cron.php`
|
|
- W `rebuild_products_temp_for_client()` usunieta logika automatycznej zmiany `custom_label_4` oparta o prog `bestseller_min_roas`.
|
|
- Funkcja pozostaje jako krok diagnostyczny zwracajacy liczbe scope z `products_aggregate`.
|
|
|
|
## Efekt
|
|
|
|
- Aplikacja nie odczytuje, nie zapisuje i nie wykorzystuje juz `bestseller_min_roas` w UI, endpointach ani w CRON.
|
|
- Automatyczne oznaczanie `custom_label_4 = bestseller` na podstawie tego progu zostalo wycofane.
|