18 KiB
18 KiB
Technical Changelog
2026-05-16 - Phase 130 Plan 01: Erli Shipments + Labels
Co zrobiono:
- Rozszerzono
carrier_delivery_method_mappingsosource_service_idisource_vendor_code, zeby mapowanie Erli przechowywalo osobno metode marketplace i vendora wymaganego przezPOST /shipping/external. - Dodano zakladke Dostawy w
/settings/integrations/erliorazErliDeliveryMappingControllerdo mapowania metod z zamowien Erli na lokalne uslugi InPost/Apaczka. - Rozszerzono
ErliApiCliento slowniki shipping/delivery/vendor/cenniki i tworzenie paczek zewnetrznych przezPOST /shipping/external. ShipmentControlleruzywa mapowan Erli przy przygotowaniu przesylki i po uzyskaniu tracking number wywolujeErliExternalShipmentService.ErliExternalShipmentServicerejestruje paczke zewnetrzna w Erli, zapisuje odpowiedz wshipment_packages.payload_json.erli_external_parceli loguje bledy jako niekrytyczne.
Dlaczego:
- Operator chce nadawac zamowienia Erli z orderPRO, ale bez wymuszania nadawania na umowie Erli. Etykiety pozostaja u lokalnych providerow, a Erli dostaje informację o zewnetrznej paczce/tracking number.
BREAKING / migracja:
- Wymagana migracja
20260516_000117_extend_delivery_mappings_for_erli_shipping.sql. - Brak breaking changes w istniejacych mapowaniach Allegro/shopPRO; nowe kolumny sa opcjonalne.
2026-05-16 - Erli Settings Tabs UI Fix
Co zrobiono:
- Ujednolicono
/settings/integrations/erliz innymi integracjami przez dodanie zakladek Integracja, Statusy i Ustawienia. - Dodano obsluge aktywnej zakladki przez parametr
taborazreturn_tow formularzach Erli, zeby po zapisie wracac do wlasciwego panelu.
Dlaczego:
- Ekran Erli po Phase 129 mial wszystkie sekcje jedna pod druga, przez co odstawal od Allegro/shopPRO i byl trudniejszy do skanowania.
2026-05-16 - Phase 129 Plan 01: Erli Status Mapping + Sync
Co zrobiono:
- Dodano migracje
20260515_000116_add_erli_status_mapping_sync.sqlz tabelamierli_order_status_mappings,erli_order_status_pull_mappings, kolumnaintegration_order_sync_state.last_status_pushed_at, seedami statusow Erli oraz cronemerli_status_sync. - Rozszerzono ustawienia Erli o mapowania Erli -> orderPRO, orderPRO -> Erli, kierunek synchronizacji statusow i interwal crona.
- Dodano
ErliStatusMappingRepository,ErliPullStatusMappingRepository,ErliStatusSyncServiceorazErliStatusSyncHandler. - Rozszerzono
ErliApiClientoPATCH /orders/{id}/statusorazErliOrdersSyncServiceo discovery surowych statusow z inboxa. ErliOrderMapperkorzysta teraz z konfigurowalnych pull mappings, zachowujac fallbacki z Phase 128.- Dodano testy jednostkowe
tests/Unit/ErliStatusSyncServiceTest.phpi rozszerzonoErliOrderMapperTest.
Dlaczego:
- Phase 128 importowala zamowienia Erli, ale statusy byly mapowane domyslnie. Operator potrzebuje kontrolowac pull/push statusow analogicznie do Allegro/shopPRO.
- Push jest ograniczony do recznych zmian statusu (
order_status_history.change_source='manual'), zeby uniknac petli po automatyzacjach i reimportach.
BREAKING / migracja:
- Brak breaking changes. Nowy cron jest domyslnie wylaczony w migracji; zapis ustawien Erli wlacza go zgodnie z aktywnoscia integracji.
- Manual smoke po wdrozeniu:
php bin/migrate.php, sprawdz widok/settings/integrations/erli, zapisz mapowania, ustaworderPRO -> Erli, zmien recznie status zamowienia Erli i uruchom cronerli_status_sync.
2026-05-15 - Phase 128 Plan 01: Erli Orders Import
Co zrobiono:
- Dodano migracje
20260515_000115_add_erli_orders_import_schedule.sql, ktora zapewnia kolumny kursora wintegration_order_sync_statei seedujecron_schedules.job_type='erli_orders_import'jako disabled. - Rozszerzono ustawienia Erli o wlaczenie importu zamowien, date startu, interwal crona oraz reczna akcje
POST /settings/integrations/erli/import. - Rozszerzono
ErliApiClientofetchInbox()(GET /inbox) oraz bezpieczny ACKmarkInboxRead()(POST /inbox/mark-read, bodylastMessageId) potwierdzony z oficjalnego swaggera Erli. - Dodano
ErliOrderMapper,ErliOrderSyncStateRepository,ErliOrdersSyncServiceiErliOrdersImportHandler. - Import wspiera zdarzenia
orderCreated,orderStatusChanged,orderSellerStatusChanged, zapisuje order aggregate przezOrderImportRepository, ustawiainvoice_requestedprzy danych firmowych/NIP, zapisuje activity log i emitujeorder.importedorazpayment.status_changed. - Dodano testy jednostkowe
tests/Unit/ErliOrderMapperTest.php.
Dlaczego:
- Erli ma zaczac realnie dostarczac zamowienia do orderPRO po fundamencie konfiguracji z Phase 127.
/inboxjest rekomendowanym zrodlem zdarzen Erli; ACK jest wykonywany dopiero po bezblednym batchu, zeby nie zgubic zamowien przy czesciowej awarii.
BREAKING / migracja:
- Brak breaking changes. Nowy cron jest domyslnie wylaczony do czasu wlaczenia importu w ustawieniach Erli.
- Manual smoke po wdrozeniu:
php bin/migrate.php, zapis aktywnej konfiguracji Erli, wlaczenie importu, klikImportuj zamowienia teraz, kontrolaorders.source='erli'i licznikow importu.
2026-05-15 - Phase 127 Plan 01: Erli Integration Foundation
Co zrobiono:
- Dodano migracje
20260515_000114_create_erli_integration_settings.sqlz pojedyncza globalna konfiguracjaerli_integration_settingsi bazowym wpisemintegrations.type='erli'. - Dodano
ErliIntegrationRepositoryz szyfrowaniem klucza API przezIntegrationSecretCipheri zachowaniem sekretu przy pustym polu edycji. - Dodano
ErliApiClient, ktory testuje polaczenie realnymGET https://erli.pl/svc/shop-api/inboxz naglowkiemAuthorization: Bearer ...iUser-Agent. - Dodano
ErliIntegrationController, routes/settings/integrations/erli,/save,/testoraz widokresources/views/settings/erli.php. - Dodano Erli do hubu integracji
/settings/integrationsz informacja o konfiguracji, aktywnosci i ostatnim tescie.
Dlaczego:
- Erli ma byc trzecim kanalem sprzedazy, ale potrzebuje najpierw bezpiecznego fundamentu konfiguracji i potwierdzenia dostepu do API.
- Na podstawie decyzji operatora integracja startuje jako jedna globalna konfiguracja, bez przelacznika sandbox.
- Test polaczenia realnie odpytuje API, ale nie importuje zamowien i nie oznacza inboxa jako przeczytanego.
BREAKING / migracja:
- Brak breaking changes. Nowa tabela i nowy wpis integracji sa dodatkiem. Import zamowien, synchronizacja statusow, etykiety i tracking Erli sa odlozone do kolejnych faz v3.8.
2026-05-12 - SMSPLANET Inbound Webhook Fix
Co zrobiono:
- Poprawiono dopasowanie przychodzacych SMSPLANET po telefonie:
SmsMessageRepository::findLatestOrderIdByPhones()nie odwoluje sie juz do nieistniejacej w produkcyjnej bazie kolumnyorders.buyer_phone, tylko doorder_addresses.phone. - Dodano obsluge
GET /webhooks/smsplanet/inboundobok POST, bo sekcja odbierania SMS 2WAY w dokumentacji SMSPLANET opisuje przekierowanie na URL bez jednoznacznego kontraktu metody. SmsplanetWebhookControllerobsluguje format 2WAYPOST application/x-www-form-urlencodedz parametremmessage=<JSON>, scala JSON z body z parametrami requestu takze wtedy, gdy URL ma query string, i po sukcesie zwraca plain textOK.
Dlaczego:
- Publiczny endpoint byl osiagalny jako POST, ale odpowiedz SMS nie mogla zostac zapisana przez blad SQL
Unknown column 'o.buyer_phone'. GET na ten sam URL zwracal 404.
BREAKING / migracja:
- Brak migracji. Zmiana usuwa bledne zalozenie o schemacie produkcyjnej tabeli
orders.
2026-05-12 - Phase 122 Plan 01: SMSPLANET Default SMS Footer
Co zrobiono:
- Dodano migracje
20260512_000111_smsplanet_default_footer.sqlz kolumnasmsplanet_integration_settings.default_footer. - Rozszerzono konfiguracje SMSPLANET o opcjonalna stopke SMS z limitem 300 znakow i zapisem oddzielnym od danych autoryzacji/nadawcy.
- Testowa wysylka SMSPLANET oraz wysylka SMS z zamowienia dopinaja stopke przez pusta linie, waliduja finalna tresc w limicie 918 znakow i nie wywoluja API przy przekroczeniu limitu.
- Historia
sms_messages.bodyzapisuje finalna tresc wyslana do SMSPLANET, czyli razem ze stopka, gdy jest skonfigurowana. - Widok rozmowy SMS w zamowieniu pokazuje kompaktowa informacje, ze stopka zostanie dodana automatycznie.
Dlaczego:
- Operator ma utrzymywac jeden wspolny podpis firmy bez recznego kopiowania go do kazdej wiadomosci SMS.
BREAKING / migracja:
- Brak. Pusta stopka zachowuje dotychczasowe tresci SMS bez zmian.
2026-05-12 - Phase 121 Plan 01: SMSPLANET Conversation + Notifications
Co zrobiono:
- Dodano migracje
20260512_000110_smsplanet_conversation_notifications.sqlz tabelamisms_messages,notificationsoraz polamisender_modeisender_phonewsmsplanet_integration_settings. - Rozszerzono SMSPLANET o wybor nadawcy: nadpis albo numer 2WAY, bez tymczasowego override testowego numeru.
- Dodano publiczny webhook
/webhooks/smsplanet/inbound, zapis przychodzacych SMS, dopasowanie do ostatniego zamowienia po telefonie i tworzenie globalnego powiadomienia. - Dodano zakladke SMS w szczegolach zamowienia z historia rozmowy i formularzem wysylki.
- Dodano centrum powiadomien
/notifications, API pollingu/api/notifications/unread, badge w topbarze i progresywne powiadomienia przegladarki. - Poprawiono migracje po pierwszej probie na bazie: rzeczywiste
orders.idma typBIGINT UNSIGNED, wiecsms_messages.order_idinotifications.related_order_idtez musza miecBIGINT UNSIGNED.
Dlaczego:
- Operator ma prowadzic dwukierunkowa rozmowe SMSPLANET bez opuszczania zamowienia, a nowe odpowiedzi klientow maja byc widoczne globalnie.
BREAKING / migracja:
- Brak. Webhook SMSPLANET w tej fazie celowo nie weryfikuje podpisu.
2026-05-12 - SMSPLANET Test Sender Override
Co zrobiono:
- Tymczasowo ustawiono testowa wysylke SMSPLANET na
from=48532963363wSmsplanetIntegrationController::test(). - Zapis konfiguracji SMSPLANET pozostaje bez zmian; override dotyczy tylko endpointu
/settings/integrations/smsplanet/test.
Dlaczego:
- Operator sprawdza odbior odpowiedzi SMS z numeru 2WAY zamiast tekstowego nadpisu.
2026-05-12 - Phase 118 Plan 01: Fakturownia Single Instance
Co zrobiono:
- Dodano migracje
20260512_000109_fakturownia_single_instance.sql, ktora wybiera aktywna instancje Fakturowni, przepina delegowaneinvoice_configs.integration_idna jeden globalny rekord i usuwa nadmiarowe konta Fakturowni po przepieciu zaleznosci. - Przebudowano
FakturowniaIntegrationRepositoryna model jednej globalnej konfiguracji (getSettings(),saveSettings(),getIntegrationId(),getCredentials()), z kompatybilnymfindAll()zwracajacym jeden element. - Uproszczono
FakturowniaIntegrationControlleri widok/settings/integrations/fakturowniado pojedynczego formularza konfiguracji i testu polaczenia. - Hub integracji pokazuje Fakturownie jako jedna instancje, bez licznika kont.
- Zapis delegowanej konfiguracji faktury ustawia
invoice_configs.integration_idna globalny rekord Fakturowni; UI konfiguracji faktury nie pokazuje juz selecta kont. - Zaktualizowano
DOCS/DB_SCHEMA.mdiDOCS/ARCHITECTURE.mdo kontrakt pojedynczej Fakturowni.
Dlaczego:
- Operator chce obslugiwac Fakturownie tak jak HostedSMS/SMSPLANET: jedna konfiguracja globalna zamiast wielu instancji.
- Zachowanie
invoice_configs.integration_idogranicza ryzyko regresji wInvoiceServicei historii faktur, a jednoczesnie usuwa wieloinstancyjny wybor z UI.
BREAKING / migracja:
- Po migracji nie ma juz wielu kont Fakturowni w UI. Jesli baza miala wiele rekordow
integrations.type='fakturownia', zachowany zostaje aktywny rekord (fallback: uzywany przez konfiguracje faktur, potem najnizsze id), a pozostale sa usuwane.
2026-05-12 - Phase 117 Plan 01: SMSPLANET Integration Settings + Test SMS
Co zrobiono:
- Dodano migracje
20260512_000108_create_smsplanet_integration_settings.sqlz pojedyncza konfiguracjasmsplanet_integration_settingsi bazowym wpisemintegrationstypusmsplanet. - Dodano
SmsplanetIntegrationRepositoryz obsluga metod autoryzacjitokenorazkey_passwordi szyfrowaniem sekretow przezIntegrationSecretCipher. - Dodano
SmsplanetApiClientdla SMSPLANET (POST https://api2.smsplanet.pl/sms) z obsluga Bearer token orazkey+password. - Dodano
SmsplanetIntegrationControlleri trasy/settings/integrations/smsplanet,/save,/test. - Dodano widok
resources/views/settings/smsplanet.phpz konfiguracja i realna wysylka testowego SMS z edytowalna trescia oraz panelem ostatniego testu (OK, HTTP,messageId). - Dodano SMSPLANET do hubu integracji
/settings/integrations. - Poprawiono import
IntegrationSecretCipher, aby rzucal istniejacyApp\Core\Exceptions\IntegrationConfigException.
Dlaczego:
- Operator potrzebuje drugiej bramki SMS analogicznej do HostedSMS, ale bez uruchamiania jeszcze automatyzacji lub historii wysylek.
- SMSPLANET wspiera dwa warianty autoryzacji, wiec konfiguracja przechowuje wszystkie sekrety w formie szyfrowanej i waliduje wymagania zalezne od wyboru operatora.
- Test uzywa rzeczywistej wysylki, bo celem tej fazy jest potwierdzenie realnej sciezki API.
2026-05-12 - Phase 116 Plan 01: HostedSMS Integration Settings + Test SMS
Co zrobiono:
- Dodano migracje
20260512_000107_create_hostedsms_integration_settings.sqlz pojedyncza konfiguracjahostedsms_integration_settingsi bazowym wpisemintegrationstypuhostedsms. - Dodano
HostedSmsIntegrationRepositoryz szyfrowaniem hasla przezIntegrationSecretCipher. - Dodano
HostedSmsApiClientdla HostedSMS SimpleAPI (POST https://api.hostedsms.pl/SimpleApi). - Dodano
HostedSmsIntegrationControlleri trasy/settings/integrations/hostedsms,/save,/test. - Dodano widok
resources/views/settings/hostedsms.phpz konfiguracja i realna wysylka testowego SMS z edytowalna trescia oraz czytelnym panelem ostatniego testu (OK, HTTP, MessageId). - Dodano HostedSMS do hubu integracji
/settings/integrations.
Dlaczego:
- Operator potrzebuje najpierw zapisac dane HostedSMS i sprawdzic realna wysylke SMS, zanim integracja zostanie wykorzystana w automatyzacjach lub komunikacji z klientami.
- Test uzywa rzeczywistej wysylki, bo SimpleAPI nie udostepnia osobnego endpointu ping/test.
- Haslo nie jest ujawniane po zapisie; UI pokazuje tylko status zapisanego sekretu.
2026-04-28 - Phase 110 Plan 01: Statistics Summary
Co zrobiono:
/statistics/summary- nowy widok podsumowania w menuStatystyki -> Podsumowanie.OrdersStatisticsController::summary()- buduje miesieczny view-model dla wykresow liczby i wartosci zamowien.OrdersStatisticsRepository::aggregateByMonth()- agreguje istniejace zamowienia po miesiacu i kanale/integracji.public/assets/js/modules/statistics-summary-charts.js- renderer dwoch interaktywnych wykresow liniowych oparty o Chart.js 4.4.8 CDN.resources/views/statistics/summary.php- filtry zgodne z raportem dziennym, dwa wykresy obok siebie na desktopie oraz dwie tabele fallback pod nimi.- Domyslny poczatek historii ustawiony na
2026-04-01(04-2026) mimo starszych danych.
Dlaczego:
- Operator potrzebuje szybkiego trendu miesiecznego przed przejsciem do szczegolowych dziennych statystyk.
- Wykresy uzywaja obecnych tabel
orders,integrations,order_status_groupsiorder_statuses, wiec migracja DB nie jest potrzebna. - Seria
Razemjest liczona z tych samych danych co serie integracji, co ulatwia sprawdzenie sum miesiecznych.
2026-04-28 - Phase 109 Plan 01: Checkbox Multiselect Filters
Co zrobiono:
public/assets/js/modules/checkbox-multiselect.js- nowy vanilla JS enhancer dla natywnych<select multiple data-checkbox-multiselect>.resources/views/layouts/app.php- globalne podpiecie modulu z cache busting przezfilemtime().resources/views/statistics/orders.php- filtrychannels[]istatus_groups[]oznaczone do progresywnego ulepszenia bez zmiany nazw pol formularza.resources/scss/app.scss- kompaktowe style dropdownu z checkboxami i opcja "Wszystkie".
Dlaczego:
- Natywne selecty multiple byly malo czytelne i zajmowaly za duzo miejsca w filtrach statystyk.
- Zachowanie oryginalnego selecta w DOM utrzymuje obecny kontrakt GET i fallback bez JavaScript.
- Brak zmian w schemacie DB i logice agregacji statystyk.
Chronologiczny log zmian technicznych — co i dlaczego.
2026-04-27 — Phase 108 Plan 02: Automation Dropdowns z DB
Co zrobiono:
AutomationController— usunięto stałąSHIPMENT_STATUS_OPTIONS(8 grupowych kluczy)- Dropdown statusów w warunku
shipment_statusi akcjiupdate_shipment_statusładuje statusy z DB przezDeliveryStatus::getAllOptions() - Walidacja w
parseConditionValue()iparseActionConfig()używaDeliveryStatus::getAllStatuses() AutomationService— usunięto stałąSHIPMENT_STATUS_OPTION_MAP; ewaluacjaevaluateShipmentStatusCondition()porównuje klucze bezpośrednioresolveStatusFromActionKey()— bezpośredni klucz statusu z DB jako target (zamiast pierwszego z grupy)
Dlaczego:
- Zamknięcie integracji z Plan 01 — operator dodaje status w
/settings/delivery-statusesi jest on od razu dostępny w dropdownach automatyzacji bez deploymentu - Eliminacja kolizji semantycznej: stary klucz grupowy
picked_upmapował nadelivered(paczka odebrana przez klienta), nowy klucz DBpicked_upto "Odebrana przez kuriera" (od nadawcy) - BREAKING: stare reguły z grupowymi kluczami (
registered,courier_pickup,dropped_at_point,unclaimed,picked_up_return, orazpicked_up/ready_for_pickup/cancelledw starym znaczeniu) nie matchują — wymagają ręcznego odtworzenia z nowymi kluczami DB
2026-04-27 — Phase 108 Plan 01: Delivery Status Management
Co zrobiono:
- Tabela
delivery_statusesz seedem 11 statusów (migracja20260427_000103) DeliveryStatusRepository— CRUD + per-request cacheDeliveryStatus.php— dynamiczne ładowanie statusów z DB (setRepository())- Panel
/settings/delivery-statusesz CRUD (zakładka "Statusy") i mapowaniem (zakładka "Mapowanie dostawy") - Sidebar: "Statusy" → "Statusy zamówień", nowe "Statusy przesyłek" z badge niezmapowanych
- Badge przesyłek: inline CSS custom property
--status-colordla niestandardowych statusów
Dlaczego:
- Dodanie nowego statusu wymagało zmiany kodu + deploymentu; teraz z UI
- Operator może definiować własne statusy znormalizowane bez ingerencji w kod