--- phase: 75-pull-status-mapping plan: 01 subsystem: settings, orders tags: [status-mapping, shoppro, pull, import, payment-transition] requires: - phase: 74-reverse-status-mapping provides: push mapping with UNIQUE on orderpro_status_code provides: - dedicated pull status mapping table (order_status_pull_mappings) - pull mapping UI section in shopPRO integration settings - status protection on re-import (only nieoplacone→w_realizacji transition allowed) affects: [shoppro-import, status-sync, automation] tech-stack: added: [] patterns: [separate push/pull mapping tables, payment-transition guard on re-import] key-files: created: - database/migrations/20260407_000079_pull_status_mappings.sql - src/Modules/Settings/ShopproPullStatusMappingRepository.php modified: - src/Modules/Settings/ShopproIntegrationsController.php - src/Modules/Settings/ShopproOrdersSyncService.php - src/Modules/Orders/OrderImportRepository.php - src/Modules/Cron/CronHandlerFactory.php - resources/views/settings/shoppro.php - resources/lang/pl.php - routes/web.php key-decisions: - "Separate pull table instead of is_pull_target flag — cleaner separation of concerns" - "Status protection on re-import: only nieoplacone+paid=2 triggers status change" - "Fallback to push table if pull repo not injected — backward compatibility" patterns-established: - "Pull mapping: UNIQUE on (integration_id, shoppro_status_code) — one orderPRO status per shopPRO code" - "Re-import status guard: getCurrentStatus() check before updateOrder()" duration: ~45min started: 2026-04-07T12:00:00Z completed: 2026-04-07T12:45:00Z --- # Phase 75 Plan 01: Pull Status Mapping — Summary **Rozdzielenie mapowania statusow shopPRO na push/pull + ochrona statusu przy re-imporcie (tylko nieoplacone→w_realizacji przy potwierdzeniu platnosci)** ## Performance | Metric | Value | |--------|-------| | Duration | ~45min | | Tasks | 3 planned + 1 extension (status protection) | | Files modified | 12 | | DB migration | Executed on remote | ## Acceptance Criteria Results | Criterion | Status | Notes | |-----------|--------|-------| | AC-1: Nowa tabela pull mappings | Pass | Tabela utworzona z UNIQUE, 18 rows pre-populated | | AC-2: Sekcja pull mapping w UI | Pass | Dwie sekcje: push ("Wysylka statusow") + pull ("Mapowanie przy imporcie") | | AC-3: Import uzywa pull mappings | Pass | buildStatusMap() czyta z pull tabeli, fallback na push | | AC-4: Naprawa zamowien 211-214 | Pass | Statusy juz poprawione (w_realizacji) | ## Accomplishments - Nowa tabela `order_status_pull_mappings` z UNIQUE na `(integration_id, shoppro_status_code)` — eliminuje bug "first wins" z Phase 74 - UI w Ustawienia > shopPRO > Statusy ma dwie sekcje: push (orderPRO→shopPRO) i pull (shopPRO→orderPRO) z jasnymi etykietami kierunku - Ochrona statusu przy re-imporcie: `updateOrder()` nie nadpisuje `external_status_id` CHYBA ZE obecny status = `nieoplacone` i `payment_status = 2` (platnosc potwierdzona) - Przy payment transition: importowane sa rowniez dane platnosci (`replacePayments`) - Activity log rozroznia payment transition: "Platnosc potwierdzona z shopPRO — zmiana statusu na w realizacji" ## Files Created/Modified | File | Change | Purpose | |------|--------|---------| | `database/migrations/20260407_000079_pull_status_mappings.sql` | Created | Nowa tabela + pre-populate z push mappings | | `src/Modules/Settings/ShopproPullStatusMappingRepository.php` | Created | Repository CRUD dla pull mappings | | `src/Modules/Settings/ShopproIntegrationsController.php` | Modified | Nowa zaleznosc, savePullStatusMappings(), buildPullMappingIndex() | | `src/Modules/Settings/ShopproOrdersSyncService.php` | Modified | buildStatusMap() z pull tabeli, payment transition log | | `src/Modules/Orders/OrderImportRepository.php` | Modified | Status protection + payment transition logic + getCurrentStatus() | | `src/Modules/Cron/CronHandlerFactory.php` | Modified | Wstrzykniecie ShopproPullStatusMappingRepository | | `resources/views/settings/shoppro.php` | Modified | Sekcja pull mapping, zmieniony tytul push | | `resources/lang/pl.php` | Modified | Klucze pull.*, zmieniony tytul/opis push | | `routes/web.php` | Modified | Nowa route POST .../statuses/save-pull | | `DOCS/DB_SCHEMA.md` | Modified | Dokumentacja nowej tabeli | | `DOCS/ARCHITECTURE.md` | Modified | Nowy endpoint save-pull | | `DOCS/TECH_CHANGELOG.md` | Modified | Wpis Phase 75 | ## Decisions Made | Decision | Rationale | Impact | |----------|-----------|--------| | Osobna tabela pull zamiast flagi is_pull_target | Czysta separacja push/pull, brak ryzyka kolizji | Dodatkowa tabela ale prosta logika | | Status protection: tylko nieoplacone+paid=2 | User chce push-only z jednym wyjatkiem: platnosc | Re-import nie nadpisuje recznych zmian statusu | | Fallback na push table jesli pull repo null | Backward compatibility dla kodu ktory nie wstrzykuje pull repo | Bezpieczna migracja | ## Deviations from Plan ### Summary | Type | Count | Impact | |------|-------|--------| | Scope additions | 1 | Ochrona statusu przy re-imporcie (na zadanie usera) | | Auto-fixed | 1 | Naprawa order 180 ze statusem "7" | **Total impact:** Rozszerzenie scope o kluczowa logike biznesowa — status protection ### Scope Addition: Status Protection on Re-import - **Requested by:** User during APPLY - **Issue:** Re-import z shopPRO nadpisywal recznie zmienione statusy (np. order 180: "wyslane" → "7") - **Fix:** `upsertOrderAggregate()` zachowuje current status chyba ze nieoplacone + payment confirmed - **Files:** `src/Modules/Orders/OrderImportRepository.php` ### Auto-fixed: Order 180 status "7" - **Found during:** Investigation - **Issue:** Surowy kod shopPRO "7" (nieznany status) nadpisal "wyslane" - **Fix:** Status juz poprawiony (wyslane). Nowa logika zapobiega powtorzeniu. ## Next Phase Readiness **Ready:** - Pull mapping w pelni funkcjonalne i konfigurowalne - Status protection chroni reczne zmiany w orderPRO - Push sync (ShopproStatusSyncService) niezmodyfikowany — dziala jak dotychczas **Concerns:** - shopPRO status "7" nie ma mapowania — user powinien zsynchronizowac statusy (przycisk w UI) lub dodac recznie - Allegro mappings nie maja analogicznego pull — jesli potrzebne, osobna faza **Blockers:** - None — kod wymaga deploy na serwer (FTP) --- *Phase: 75-pull-status-mapping, Plan: 01* *Completed: 2026-04-07*