From 2b12fde248619dff4d60cbb788aa84fb0bfd17dc Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Sun, 8 Mar 2026 23:45:10 +0100 Subject: [PATCH] feat(shipments): add ShipmentProviderInterface and ShipmentProviderRegistry - Introduced ShipmentProviderInterface to define the contract for shipment providers. - Implemented ShipmentProviderRegistry to manage and retrieve shipment providers. - Added a new tool for probing Apaczka order_send payload variants, enhancing debugging capabilities. --- .../ftp-kr.diff.tmp_fix_invoice_order21.2.php | 1 + DOCS/ARCHITECTURE.md | 32 + DOCS/DB_SCHEMA.md | 69 ++ DOCS/TECH_CHANGELOG.md | 95 ++ ...carrier_delivery_method_mappings_table.sql | 84 ++ ...0308_000045_extend_apaczka_credentials.sql | 39 + ...extend_company_settings_contact_person.sql | 3 + public/assets/css/app.css | 2 +- resources/lang/pl.php | 24 +- resources/scss/app.scss | 30 + resources/views/orders/list.php | 1 + resources/views/orders/show.php | 10 + resources/views/settings/allegro.php | 157 +++- resources/views/settings/apaczka.php | 32 +- resources/views/settings/company.php | 5 + resources/views/settings/shoppro.php | 138 ++- resources/views/shipments/prepare.php | 164 +++- routes/web.php | 48 +- .../Settings/AllegroIntegrationController.php | 127 ++- src/Modules/Settings/ApaczkaApiClient.php | 239 +++++ .../Settings/ApaczkaIntegrationController.php | 35 +- .../Settings/ApaczkaIntegrationRepository.php | 147 ++- ...CarrierDeliveryMethodMappingRepository.php | 219 +++++ .../Settings/CompanySettingsController.php | 1 + .../Settings/CompanySettingsRepository.php | 7 + .../Settings/IntegrationsHubController.php | 5 +- .../ShopproIntegrationsController.php | 107 ++- .../Settings/ShopproOrdersSyncService.php | 120 ++- .../Shipments/AllegroShipmentService.php | 7 +- .../Shipments/ApaczkaShipmentService.php | 882 ++++++++++++++++++ src/Modules/Shipments/ShipmentController.php | 144 ++- .../Shipments/ShipmentProviderInterface.php | 30 + .../Shipments/ShipmentProviderRegistry.php | 40 + tools/apaczka_probe_order.php | 474 ++++++++++ 34 files changed, 3285 insertions(+), 233 deletions(-) create mode 100644 .vscode/ftp-kr.diff.tmp_fix_invoice_order21.2.php create mode 100644 database/migrations/20260308_000044_create_carrier_delivery_method_mappings_table.sql create mode 100644 database/migrations/20260308_000045_extend_apaczka_credentials.sql create mode 100644 database/migrations/20260308_000046_extend_company_settings_contact_person.sql create mode 100644 src/Modules/Settings/ApaczkaApiClient.php create mode 100644 src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php create mode 100644 src/Modules/Shipments/ApaczkaShipmentService.php create mode 100644 src/Modules/Shipments/ShipmentProviderInterface.php create mode 100644 src/Modules/Shipments/ShipmentProviderRegistry.php create mode 100644 tools/apaczka_probe_order.php diff --git a/.vscode/ftp-kr.diff.tmp_fix_invoice_order21.2.php b/.vscode/ftp-kr.diff.tmp_fix_invoice_order21.2.php new file mode 100644 index 0000000..3808eb4 --- /dev/null +++ b/.vscode/ftp-kr.diff.tmp_fix_invoice_order21.2.php @@ -0,0 +1 @@ +c:\visual studio code\projekty\orderPRO\tools\tmp_fix_invoice_order21.php \ No newline at end of file diff --git a/DOCS/ARCHITECTURE.md b/DOCS/ARCHITECTURE.md index 971d7df..4c762d7 100644 --- a/DOCS/ARCHITECTURE.md +++ b/DOCS/ARCHITECTURE.md @@ -2,6 +2,7 @@ ## Status - Projekt po resecie do trybu `users-only`. +- UI korzysta z globalnego standardu naglowkow sekcji (`h2/h3/h4.section-title`) definiowanego centralnie w `resources/scss/app.scss` i buildowanego do `public/assets/css/app.css`. ## Moduly aktywne - `App\Modules\Auth` @@ -44,6 +45,7 @@ - `GET /settings/integrations/allegro/oauth/callback` - `GET /settings/integrations/apaczka` - `POST /settings/integrations/apaczka/save` +- `POST /settings/integrations/apaczka/test` - `GET /settings/integrations/inpost` - `POST /settings/integrations/inpost/save` - `GET /settings/integrations/shoppro` @@ -92,6 +94,8 @@ - `App\Modules\Users\UserRepository` - `App\Modules\Settings\ApaczkaIntegrationController` - `App\Modules\Settings\ApaczkaIntegrationRepository` +- `App\Modules\Settings\ApaczkaApiClient` +- `App\Modules\Settings\CarrierDeliveryMethodMappingRepository` - `App\Modules\Settings\InpostIntegrationController` - `App\Modules\Settings\InpostIntegrationRepository` - `App\Modules\Settings\IntegrationsHubController` @@ -106,6 +110,9 @@ - `App\Modules\Settings\AllegroOrdersSyncService` - `App\Modules\Settings\AllegroOrderSyncStateRepository` - `App\Modules\Settings\AllegroStatusSyncService` +- `App\Modules\Shipments\ShipmentProviderInterface` +- `App\Modules\Shipments\ShipmentProviderRegistry` +- `App\Modules\Shipments\ApaczkaShipmentService` ## Przeplyw Zamowienia > Lista zamowien - `GET /orders/list`: @@ -220,6 +227,29 @@ - `shoppro_order_status_sync` -> `ShopproStatusSyncHandler::handle(...)` (synchronizacja statusow shopPRO wg kierunku ustawionego per instancja). - `shoppro_payment_status_sync` -> `ShopproPaymentStatusSyncHandler::handle(...)` (odswiezanie statusu platnosci zamowien shopPRO na podstawie flagi `paid`). +## Przeplyw tworzenia przesylki +- `GET /orders/{id}/shipment/prepare`: + - `ShipmentController::prepare(Request): Response`, + - laduje uslugi dostawy providerow z `ShipmentProviderRegistry` (aktualnie: `allegro_wza`, `apaczka`), + - pobiera automatyczne mapowanie formy dostawy przez `CarrierDeliveryMethodMappingRepository` (`source_system` + `source_integration_id` + `order_delivery_method`), + - dla dostaw punktowych (`parcel_external_id`/`parcel_name`) prefillem `receiver_name` sa dane klienta (a nie nazwa punktu/metody dostawy), + - gdy mapowanie nie zostanie znalezione, buduje komunikat diagnostyczny (brak mapowan dla instancji lub brak mapowania konkretnej metody) i przekazuje go do widoku. +- `POST /orders/{id}/shipment/create`: + - `ShipmentController::create(Request): Response`, + - wybiera providera dynamicznie po `provider_code` i deleguje do `ShipmentProviderInterface::createShipment(...)`, + - dla `apaczka` waliduje wymagane punkty odbioru/nadania wg definicji uslugi (`service_structure`) i przy bledzie wyceny zwraca rozszerzona diagnostyke parametrow, + - `apaczka` uzupelnia i wysyla `contact_person` dla nadawcy (z `Ustawienia > Dane firmy`) i odbiorcy (fallback z danych zamowienia), + - `apaczka` ustawia jawnie `pickup.type` (`SELF`/`COURIER`) na podstawie uslugi i obecnosci `sender_point_id`; dla `COURIER` dopelnia tez `pickup.date`, `pickup.hours_from`, `pickup.hours_to`, + - dla uslug punktowych `apaczka` payload adresu zawiera aliasy identyfikatora punktu (`point`, `foreign_address_id`, `point_id`) dla nadania i odbioru, + - `ApaczkaShipmentService::buildReceiverAddress(...)` sklada dane odbiorcy z fallbackami (formularz -> delivery -> punkt odbioru z `parcel_name` -> customer), a dla przesylek punktowych dodatkowo probuje uzupelnic adres punktu przez API `points`; przy dalszych brakach dopelnia minimum techniczne, aby nie blokowac tworzenia. +- `GET /orders/{id}/shipment/{packageId}/status`: + - `ShipmentController::checkStatus(Request): Response`, + - wybiera providera po `shipment_packages.provider` i deleguje `checkCreationStatus(...)`. +- `POST /orders/{id}/shipment/{packageId}/label`: + - `ShipmentController::label(Request): Response`, + - wybiera providera po `shipment_packages.provider` i deleguje `downloadLabel(...)`, + - dla Apaczka bledy typu `Label is not available for this order` oznaczaja paczke jako `error`, aby nie ponawiac nieskutecznych prob pobrania. + ## Przeplyw Ustawienia > Integracje > Allegro - `GET /settings/integrations/allegro`: - `AllegroIntegrationController::index(Request): Response` @@ -394,6 +424,8 @@ - pobiera liste zamowien i (opcjonalnie) szczegoly zamowienia z API shopPRO, - mapuje kwoty z fallbackami (`summary`, `paid`, `transport_cost`) oraz ceny pozycji (`price_brutto`), - uzupelnia `order_items.media_url` przez pobranie `products/get` po `product_id`, gdy zamowienie nie zawiera obrazu. + - wykrywa zadanie faktury takze po obecnosci danych firmowych (`firm_*`) i ustawia `orders.is_invoice`, + - mapuje adres faktury do `order_addresses.address_type=invoice` (firma/NIP/adres) na podstawie pol `invoice`/`billing*`/`firm_*`, - mapuje punkty odbioru (`inpost_paczkomat` / `orlen_point`) do adresu `delivery` (`parcel_external_id`, `parcel_name`, ulica/kod/miasto), - uzupelnia `delivery` o telefon/e-mail klienta i etykiete metody dostawy z kosztem (`transport_cost`). - `ShopproStatusSyncService`: diff --git a/DOCS/DB_SCHEMA.md b/DOCS/DB_SCHEMA.md index 4b29894..4a7c1e8 100644 --- a/DOCS/DB_SCHEMA.md +++ b/DOCS/DB_SCHEMA.md @@ -45,6 +45,32 @@ - tabela przechowuje mapowanie formy shopPRO na usluge Allegro WZA/InPost (`allegro_delivery_method_id`, `allegro_credentials_id`, `allegro_carrier_id`, `allegro_service_name`, `carrier`). - 2026-03-08: Poprawiono mapowanie importu zamowien shopPRO (kwoty i miniatury pozycji) - bez zmian schematu bazy. - 2026-03-08: Poprawiono mapowanie danych wysylki shopPRO (paczkomat/punkt odbioru + kontakt klienta + koszt transportu) - bez zmian schematu bazy. +- 2026-03-08: Dodano migracje `20260308_000044_create_carrier_delivery_method_mappings_table.sql`: + - nowa tabela `carrier_delivery_method_mappings` (wspolne mapowanie form dostawy dla roznych zrodel zamowien i providerow wysylek), + - migracja backfilluje dane z `allegro_delivery_method_mappings` i `shoppro_delivery_method_mappings`. +- 2026-03-08: Dodano migracje `20260308_000045_extend_apaczka_credentials.sql`: + - rozszerzenie `apaczka_integration_settings` o `app_id` i `app_secret_encrypted`, + - migracja przenosi legacy sekret z `api_key_encrypted` do `app_secret_encrypted`. +- 2026-03-08: Poprawiono mapowanie danych faktury w imporcie shopPRO - bez zmian schematu: + - `orders.is_invoice` jest wykrywany takze po polach firmowych (`firm_*`), + - adres faktury jest zapisywany do istniejacej tabeli `order_addresses` (`address_type=invoice`, `company_name`, `company_tax_number`). +- 2026-03-08: Poprawiono diagnostyke tworzenia przesylek Apaczka - bez zmian schematu: + - payload tworzenia przesylki przekazuje punkty odbioru/nadania (`receiver.point`, `sender.point`) z danych formularza, + - komunikaty bledow tworzenia zawieraja rozszerzona diagnostyke parametrow wyceny. +- 2026-03-08: Poprawiono obsluge bledow etykiet Apaczka - bez zmian schematu: + - przy odpowiedzi API `Label is not available for this order` rekord `shipment_packages` jest oznaczany statusem `error` i zachowuje tresc bledu. +- 2026-03-08: Poprawiono fallback danych odbiorcy dla przesylek punktowych Apaczka (Orlen/InPost) - bez zmian schematu: + - brakujace dane adresowe odbiorcy sa uzupelniane na etapie budowania payloadu z danych zamowienia (`delivery`, `customer`) oraz metadanych punktu (`parcel_name`). +- 2026-03-08: Rozszerzono fallback adresu odbiorcy dla przesylek punktowych Apaczka - bez zmian schematu: + - serwis probuje uzupelnic adres punktu przez API `points` po `receiver_point_id`, + - przy dalszych brakach danych dla przesylki punktowej dopelniane jest minimum techniczne wymagane przez lokalna walidacje payloadu. +- 2026-03-08: Poprawiono przekazywanie punktow w payloadzie Apaczka (nadanie/odbior) - bez zmian schematu: + - payload wysyla aliasy identyfikatora punktu (`point`, `foreign_address_id`, `point_id`) dla zgodnosci z wariantami API. +- 2026-03-08: Uzupelniono payload odbioru kurierem Apaczka (`pickup.date`, `pickup.hours_from`, `pickup.hours_to`) - bez zmian schematu. +- 2026-03-08: Dodano migracje `20260308_000046_extend_company_settings_contact_person.sql`: + - rozszerzenie `company_settings` o `sender_contact_person` (osoba kontaktowa nadawcy), + - wykorzystywane w payloadzie Apaczka jako `address.sender.contact_person`. +- 2026-03-08: Ujednolicono styl naglowkow sekcji UI (`section-title`) - bez zmian schematu bazy. ## Tabele @@ -218,9 +244,29 @@ - Kolumny: - `id` (PK, tinyint unsigned), - `integration_id` (int unsigned, UNIQUE, FK -> `integrations.id`), + - `app_id` (varchar 128, nullable), + - `app_secret_encrypted` (text, nullable), - `api_key_encrypted` (text, nullable), - `created_at`, `updated_at`. +### `carrier_delivery_method_mappings` +- Wspolne mapowanie form dostawy zamowien na providerow wysylek (model docelowy pod wielu kurierow: `allegro_wza`, `apaczka`, kolejne). +- Kolumny: + - `id` (PK, int unsigned, AI), + - `source_system` (varchar 32; np. `allegro`, `shoppro`), + - `source_integration_id` (int unsigned; `0` dla mapowan globalnych, np. Allegro), + - `order_delivery_method` (varchar 200), + - `provider` (varchar 50; np. `allegro_wza`, `apaczka`), + - `provider_service_id` (varchar 128), + - `provider_account_id` (varchar 128, nullable), + - `provider_carrier_id` (varchar 128, nullable), + - `provider_service_name` (varchar 255, nullable), + - `created_at`, `updated_at`. +- Indeksy: + - `carrier_dm_mapping_unique` (UNIQUE: `source_system`, `source_integration_id`, `order_delivery_method`), + - `carrier_dm_mapping_provider_idx` (`provider`), + - `carrier_dm_mapping_source_idx` (`source_system`, `source_integration_id`). + ### `inpost_integration_settings` - Tabela ustawien specyficznych InPost ShipX (`id = 1`); token API utrzymywany bazowo w `integrations.api_key_encrypted`. - Kolumny: @@ -238,6 +284,29 @@ - `weekend_delivery`, `auto_insurance_value`, `multi_parcel` (tinyint 0/1), - `created_at`, `updated_at`. +### `company_settings` +- Ustawienia firmy/nadawcy wykorzystywane m.in. przy tworzeniu przesylek. +- Kolumny: + - `id` (PK, tinyint unsigned), + - `company_name` (varchar 200, nullable), + - `person_name` (varchar 200, nullable), + - `sender_contact_person` (varchar 200, nullable), + - `street` (varchar 200, nullable), + - `city` (varchar 128, nullable), + - `postal_code` (varchar 16, nullable), + - `country_code` (char 2, default `PL`), + - `phone` (varchar 64, nullable), + - `email` (varchar 128, nullable), + - `tax_number` (varchar 64, nullable), + - `bank_account` (varchar 64, nullable), + - `bank_owner_name` (varchar 200, nullable), + - `default_package_length_cm` (decimal 8,1), + - `default_package_width_cm` (decimal 8,1), + - `default_package_height_cm` (decimal 8,1), + - `default_package_weight_kg` (decimal 8,3), + - `default_label_format` (varchar 8), + - `created_at`, `updated_at`. + ## Zasady aktualizacji - Po kazdej migracji dopisz: - nowe/zmienione tabele i kolumny, diff --git a/DOCS/TECH_CHANGELOG.md b/DOCS/TECH_CHANGELOG.md index 0ec5092..1cb78ea 100644 --- a/DOCS/TECH_CHANGELOG.md +++ b/DOCS/TECH_CHANGELOG.md @@ -1,6 +1,101 @@ # Tech Changelog ## 2026-03-08 +- Poprawiono date podjazdu kuriera w payloadzie Apaczka: + - `pickup.date` dla trybu `COURIER` jest normalizowane tak, aby nie wypadal w niedziele (niedziela -> poniedzialek), + - `pickup.hours_to` jest ograniczane do `16:00` (wg limitu API), a okno godzinowe jest korygowane do poprawnej relacji `hours_from < hours_to`, + - eliminuje blad API `Field PickupLocation->MaxPickupDate cannot be set to Sunday`. +- Dodano pole firmy `sender_contact_person` (osoba kontaktowa nadawcy): + - nowa migracja `20260308_000046_extend_company_settings_contact_person.sql`, + - UI `Ustawienia > Dane firmy` ma nowe pole `Osoba kontaktowa nadawcy`, + - `ApaczkaShipmentService` wysyla `contact_person` dla nadawcy z ustawien firmy. +- Uzupelniono kontakt odbiorcy w payloadzie Apaczka: + - `ApaczkaShipmentService` wysyla `receiver.contact_person` (fallback na dane odbiorcy/klienta z zamowienia), + - eliminuje blad API: `Osoba kontaktowa nadawcy/odbiorcy: Pole jest wymagane`. +- Dla tworzenia przesylek Apaczka dodano jawne pole `pickup.type` w payloadzie `order_send`: + - gdy podano `sender_point_id` ustawiane jest `SELF`, + - gdy brak punktu nadania i usluga dopuszcza odbior kurierem ustawiane jest `COURIER`. +- Poprawiono obsluge punktow nadania/odbioru w payloadzie Apaczka: + - adres `sender` i `receiver` wysyla teraz komplet aliasow punktu (`point`, `foreign_address_id`, `point_id`), + - rozszerzono diagnostyke dla bledu API `Niepoprawny sposob nadania przesylki` o wskazowke dot. `sender_point_id` / doboru uslugi. +- Wzmocniono fallback adresu odbiorcy dla przesylek punktowych Apaczka (Orlen/InPost): + - `ApaczkaShipmentService` probuje teraz dodatkowo uzupelnic adres punktu (`street`, `postal_code`, `city`) przez API `points` na podstawie `receiver_point_id`, + - jezeli zamowienie punktowe dalej nie ma kompletu danych adresowych, serwis uzupelnia techniczne minimum (`line1`, `city`, `postal_code`) zamiast blokowac tworzenie przesylki bledem walidacji lokalnej. +- Ujednolicono i wzmocniono naglowki sekcji UI (`h2/h3/h4.section-title`) w widokach: + - naglowki sekcyjne maja teraz wyrazniejszy styl (akcent lewy, delikatne tlo, obramowanie), + - zmiana jest globalna (SCSS), obejmuje m.in. `Zamowienia > Przygotuj przesylke` oraz pozostale ekrany korzystajace z `section-title`. +- Poprawiono fallback danych odbiorcy dla przesylek punktowych Apaczka (w tym Orlen Paczka): + - `ApaczkaShipmentService::buildReceiverAddress(...)` uzupelnia brakujace pola z wielu zrodel w kolejnosci: + - dane z formularza, + - adres `delivery` z zamowienia, + - dane punktu z `parcel_name` (`ulica`, `kod`, `miasto`), + - dane klienta (`name`, `phone`, `email`, `country`), + - adres ulicy sklada teraz `street_name + street_number`, + - naprawiono fallback `receiver_point_id` (uzywa `delivery.parcel_external_id`, usunieto bledne odwolanie do niezdefiniowanej zmiennej). +- Poprawiono obsluge usunietych/nieosiagalnych etykiet Apaczka: + - gdy API zwraca `Label is not available for this order`, rekord paczki jest oznaczany jako `error` i zapisywany jest `error_message`, + - dzieki temu przycisk etykiety nie jest ponownie pokazywany dla tego rekordu. +- Ujednolicono flow etykiet w `Zamowienia > Przygotuj przesylke` (dla wszystkich providerow): + - po statusie `created` etykieta jest generowana automatycznie przez cykliczne sprawdzanie statusu (backend probuje `downloadLabel`), + - UI nie pokazuje juz przycisku `Generuj etykiete`; do czasu gotowosci widoczny jest stan `Generowanie etykiety...`, + - przycisk `Pobierz` pojawia sie dopiero po zapisaniu pliku etykiety (`label_path`). +- Uzgodniono payload `order_send` Apaczka z dokumentacja API v2: + - `ApaczkaShipmentService` wysyla teraz strukture `address.sender/receiver` + `shipment[]` (`dimension1/2/3`, `weight` w kg), + - `cod` jest przekazywany jako obiekt (`amount`, `currency`), a wartosc ubezpieczenia przez `shipment_value` + `shipment_currency`, + - punkty sa przekazywane jako `foreign_address_id` (z aliasami diagnostycznymi), + - naprawilo to blad wyceny dla zamowienia testowego `#21` (utworzenie przesylki zakonczone sukcesem). +- Dodano techniczny skrypt diagnostyczny `tools/apaczka_probe_order.php`: + - wykonuje automatyczne proby `order_send` dla wskazanego zamowienia (bez klikania w UI), + - testuje kombinacje uslug i wariantow pol punktu, raportujac sukces/blad per proba. +- Rozszerzono payload punktow w tworzeniu przesylki Apaczka: + - oprocz `point` przekazywane sa teraz aliasy `foreign_address_id` i `point_id` (dla odbiorcy i nadawcy), + - cel: kompatybilnosc z wariantami API wymagajacymi innej nazwy pola punktu. +- Korekta walidacji punktu odbioru Apaczka: + - usunieto twarde blokowanie tworzenia przesylki na podstawie prefiksu punktu (`POP-`), + - informacja o prefiksie punktu pozostaje tylko jako sugestia diagnostyczna. +- Poprawiono prefill danych odbiorcy na ekranie `Zamowienia > Przygotuj przesylke`: + - `ShipmentController` dla dostaw do punktu (`parcel_external_id`/`parcel_name`) ustawia `receiver_name` na dane klienta (`address_type=customer`), + - eliminuje przypadek podstawiania nazwy punktu/metody dostawy w polu `Imie i nazwisko`. +- Poprawiono diagnostyke bledow tworzenia przesylki Apaczka: + - `ApaczkaShipmentService` przekazuje teraz `receiver_point_id` do payloadu `receiver.point` (oraz `sender_point_id` do `sender.point`), + - dodano walidacje wymagan uslugi na podstawie `service_structure` (np. wymagany punkt odbioru/nadania), + - dla bledu API `Brak wyceny dla podanych parametrów zamówienia` komunikat zawiera rozszerzona diagnostyke (service_id/nazwa/supplier, punkt odbioru/nadania, gabaryt/waga) i hint o niedopasowaniu uslugi do typu punktu. +- Poprawiono import danych faktury z shopPRO: + - `ShopproOrdersSyncService` wykrywa fakture nie tylko po `is_invoice`/`invoice.required`, ale takze po danych firmowych (`firm_name`/`firm_nip`), + - `ShopproOrdersSyncService::mapAddresses(...)` zapisuje adres `invoice` (firma, NIP, adres) na podstawie pol `invoice`/`billing*`/`firm_*`, + - widok `orders/show` wyswietla teraz `company_name` i `company_tax_number` dla adresu faktury. +- Fix prewyboru uslugi Apaczka na ekranie `Zamowienia > Przygotuj przesylke`: + - widok `resources/views/shipments/prepare.php` odczytuje ID uslugi Apaczka z fallbackiem `service_id -> id`, + - naprawia przypadek, gdy przewoznik (`Apaczka`) byl wybierany poprawnie, ale usluga dostawy pozostawala pusta mimo mapowania. +- Poprawiono diagnostyke mapowania form dostawy na ekranie `Zamowienia > Przygotuj przesylke`: + - `ShipmentController` zwraca teraz komunikat diagnostyczny, gdy brak mapowania metody dostawy, + - komunikat rozroznia brak mapowan dla instancji `shopPRO` (`source_integration_id`) od braku mapowania konkretnej metody, + - widok `resources/views/shipments/prepare.php` wyswietla ten komunikat bezposrednio pod informacja o metodzie z zamowienia. +- Poprawiono UX wyszukiwania w selectach mapowania form dostawy (zakladki `Formy dostawy`): + - `resources/views/settings/allegro.php` przeszlo z przebudowy opcji ` - + +
- - - + + + + -
- +
+
-- -- @@ -376,6 +388,29 @@ $orderproStatuses = is_array($orderproStatuses ?? null) ? $orderproStatuses : []
+
+ +
Brak uslug Apaczka (sprawdz konfiguracje App ID/App Secret).
+ + + +
+
@@ -395,7 +430,7 @@ $orderproStatuses = is_array($orderproStatuses ?? null) ? $orderproStatuses : [] value="" data-credentials-id="" data-carrier-id="" - > + > @@ -404,7 +439,7 @@ $orderproStatuses = is_array($orderproStatuses ?? null) ? $orderproStatuses : []
-
+
@@ -474,6 +509,60 @@ $orderproStatuses = is_array($orderproStatuses ?? null) ? $orderproStatuses : [] })(); (function () { + function attachSelectFilter(selectEl) { + if (!selectEl || selectEl.dataset.enhanced === '1') { + return; + } + selectEl.dataset.enhanced = '1'; + + var parent = selectEl.parentNode; + if (!parent) { + return; + } + + var filterInput = document.createElement('input'); + filterInput.type = 'text'; + filterInput.className = 'form-control'; + filterInput.placeholder = 'Szukaj...'; + filterInput.autocomplete = 'off'; + filterInput.style.marginBottom = '8px'; + parent.insertBefore(filterInput, selectEl); + + function focusFirstMatch(term) { + var query = term.toLowerCase().trim(); + if (query === '') { + return; + } + + var matchedIndex = -1; + Array.prototype.forEach.call(selectEl.options, function (opt, idx) { + if (matchedIndex >= 0) { + return; + } + if (opt.textContent.toLowerCase().indexOf(query) !== -1) { + matchedIndex = idx; + } + }); + + if (matchedIndex >= 0 && selectEl.selectedIndex !== matchedIndex) { + selectEl.selectedIndex = matchedIndex; + selectEl.dispatchEvent(new Event('change', { bubbles: true })); + } + } + + filterInput.addEventListener('input', function () { + focusFirstMatch(filterInput.value); + }); + + selectEl._syncTrigger = function () { + // Keep select untouched; filter only suggests matching option. + }; + } + + document.querySelectorAll('.dm-inpost-select, .dm-apaczka-select').forEach(function (selectEl) { + attachSelectFilter(selectEl); + }); + // Carrier switching logic document.querySelectorAll('.dm-carrier-select').forEach(function (carrierSelect) { var rowIdx = carrierSelect.getAttribute('data-row'); @@ -482,8 +571,10 @@ $orderproStatuses = is_array($orderproStatuses ?? null) ? $orderproStatuses : [] var allegroPanel = serviceWrap.querySelector('.dm-allegro-panel'); var inpostPanel = serviceWrap.querySelector('.dm-inpost-panel'); + var apaczkaPanel = serviceWrap.querySelector('.dm-apaczka-panel'); var emptyPanel = serviceWrap.querySelector('.dm-empty-panel'); var hiddenMethodId = serviceWrap.querySelector('.dm-hidden-method-id'); + var hiddenApaczkaMethodId = serviceWrap.querySelector('.dm-hidden-apaczka-method-id'); var hiddenCredentialsId = serviceWrap.querySelector('.dm-hidden-credentials-id'); var hiddenCarrierId = serviceWrap.querySelector('.dm-hidden-carrier-id'); var hiddenServiceName = serviceWrap.querySelector('.dm-hidden-service-name'); @@ -491,23 +582,42 @@ $orderproStatuses = is_array($orderproStatuses ?? null) ? $orderproStatuses : [] function showPanel(carrier) { if (allegroPanel) allegroPanel.style.display = carrier === 'allegro' ? '' : 'none'; if (inpostPanel) inpostPanel.style.display = carrier === 'inpost' ? '' : 'none'; + if (apaczkaPanel) apaczkaPanel.style.display = carrier === 'apaczka' ? '' : 'none'; if (emptyPanel) emptyPanel.style.display = carrier === '' ? '' : 'none'; } + showPanel(carrierSelect.value); + carrierSelect.addEventListener('change', function () { var carrier = carrierSelect.value; showPanel(carrier); // Clear hidden values when switching carrier if (hiddenMethodId) hiddenMethodId.value = ''; + if (hiddenApaczkaMethodId) hiddenApaczkaMethodId.value = ''; if (hiddenCredentialsId) hiddenCredentialsId.value = ''; if (hiddenCarrierId) hiddenCarrierId.value = ''; if (hiddenServiceName) hiddenServiceName.value = ''; // Reset Allegro search input var allegroInput = allegroPanel ? allegroPanel.querySelector('.dm-search-input') : null; - if (allegroInput) allegroInput.value = ''; + if (allegroInput) { + allegroInput.value = ''; + allegroInput.blur(); + } + var allegroDropdown = allegroPanel ? allegroPanel.querySelector('.dm-dropdown') : null; + if (allegroDropdown) { + allegroDropdown.classList.remove('is-open'); + } // Reset InPost select var inpostSelect = inpostPanel ? inpostPanel.querySelector('.dm-inpost-select') : null; - if (inpostSelect) inpostSelect.value = ''; + if (inpostSelect) { + inpostSelect.value = ''; + if (inpostSelect._syncTrigger) inpostSelect._syncTrigger(); + } + var apaczkaSelect = apaczkaPanel ? apaczkaPanel.querySelector('.dm-apaczka-select') : null; + if (apaczkaSelect) { + apaczkaSelect.value = ''; + if (apaczkaSelect._syncTrigger) apaczkaSelect._syncTrigger(); + } }); // InPost select change -> update hidden fields @@ -516,10 +626,29 @@ $orderproStatuses = is_array($orderproStatuses ?? null) ? $orderproStatuses : [] inpostSelect.addEventListener('change', function () { var opt = inpostSelect.options[inpostSelect.selectedIndex]; if (hiddenMethodId) hiddenMethodId.value = inpostSelect.value; + if (hiddenApaczkaMethodId) hiddenApaczkaMethodId.value = ''; if (hiddenCredentialsId) hiddenCredentialsId.value = opt ? (opt.getAttribute('data-credentials-id') || '') : ''; if (hiddenCarrierId) hiddenCarrierId.value = opt ? (opt.getAttribute('data-carrier-id') || '') : ''; if (hiddenServiceName) hiddenServiceName.value = opt ? opt.textContent.trim() : ''; }); + if (inpostSelect.value !== '') { + inpostSelect.dispatchEvent(new Event('change', { bubbles: true })); + } + } + + var apaczkaSelect = apaczkaPanel ? apaczkaPanel.querySelector('.dm-apaczka-select') : null; + if (apaczkaSelect) { + apaczkaSelect.addEventListener('change', function () { + var opt = apaczkaSelect.options[apaczkaSelect.selectedIndex]; + if (hiddenMethodId) hiddenMethodId.value = ''; + if (hiddenApaczkaMethodId) hiddenApaczkaMethodId.value = apaczkaSelect.value; + if (hiddenCredentialsId) hiddenCredentialsId.value = ''; + if (hiddenCarrierId) hiddenCarrierId.value = opt ? (opt.getAttribute('data-carrier-id') || '') : ''; + if (hiddenServiceName) hiddenServiceName.value = opt ? opt.textContent.trim() : ''; + }); + if (apaczkaSelect.value !== '') { + apaczkaSelect.dispatchEvent(new Event('change', { bubbles: true })); + } } }); @@ -531,6 +660,7 @@ $orderproStatuses = is_array($orderproStatuses ?? null) ? $orderproStatuses : [] if (!searchInput || !dropdown || !serviceWrap) return; var hiddenMethodId = serviceWrap.querySelector('.dm-hidden-method-id'); + var hiddenApaczkaMethodId = serviceWrap.querySelector('.dm-hidden-apaczka-method-id'); var hiddenCredentialsId = serviceWrap.querySelector('.dm-hidden-credentials-id'); var hiddenCarrierId = serviceWrap.querySelector('.dm-hidden-carrier-id'); var hiddenServiceName = serviceWrap.querySelector('.dm-hidden-service-name'); @@ -540,6 +670,7 @@ $orderproStatuses = is_array($orderproStatuses ?? null) ? $orderproStatuses : [] function selectOption(opt) { hiddenMethodId.value = opt.getAttribute('data-value') || ''; + if (hiddenApaczkaMethodId) hiddenApaczkaMethodId.value = ''; hiddenCredentialsId.value = opt.getAttribute('data-credentials-id') || ''; hiddenCarrierId.value = opt.getAttribute('data-carrier-id') || ''; hiddenServiceName.value = opt.getAttribute('data-label') || ''; diff --git a/resources/views/settings/apaczka.php b/resources/views/settings/apaczka.php index 8ac8a05..b1480b8 100644 --- a/resources/views/settings/apaczka.php +++ b/resources/views/settings/apaczka.php @@ -1,6 +1,9 @@
@@ -18,17 +21,38 @@ $hasApiKey = (bool) ($integration['has_api_key'] ?? false);

+
+ : + + | + : + + + | : + +
+
+ +
+ +
+ + +
diff --git a/resources/views/settings/company.php b/resources/views/settings/company.php index c62c0c2..4e97b80 100644 --- a/resources/views/settings/company.php +++ b/resources/views/settings/company.php @@ -31,6 +31,11 @@ $s = is_array($settings ?? null) ? $settings : [];
+ +