feat(attributes-import): import product attributes from shopPRO API into personalization
extractPersonalization() now reads both 'attributes' and 'custom_fields' fields from the shopPRO API response, joining non-empty values with newline separator. Previously only custom_fields was imported, causing product attributes like "Woreczek jutowy", "Kolor koperty", "Zakrętka" to be lost during sync. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
120
.paul/phases/71-attributes-import/71-01-PLAN.md
Normal file
120
.paul/phases/71-attributes-import/71-01-PLAN.md
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
phase: 71-attributes-import
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified: [src/Modules/Settings/ShopproOrderMapper.php]
|
||||
autonomous: true
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Dodanie importu pola `attributes` z API shopPRO do personalizacji produktow w orderPRO. Obecnie importowane jest tylko `custom_fields`, a `attributes` (np. "Woreczek jutowy: Nie", "Kolor koperty: Biala") jest ignorowane.
|
||||
|
||||
## Purpose
|
||||
Klienci nie widza pelnych danych produktu z zamowienia shopPRO. Atrybuty takie jak wariant produktu, kolor, dodatkowe opcje sa tracone przy imporcie.
|
||||
|
||||
## Output
|
||||
Zmodyfikowany `ShopproOrderMapper::extractPersonalization()` ktory laczy `attributes` i `custom_fields` w jedno pole `personalization`.
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
|
||||
## Source Files
|
||||
@src/Modules/Settings/ShopproOrderMapper.php (linie 590-602 - extractPersonalization)
|
||||
</context>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: Atrybuty produktu importowane do personalizacji
|
||||
```gherkin
|
||||
Given zamowienie w shopPRO ma produkt z polem attributes = "<b>Woreczek jutowy</b>: Nie"
|
||||
When zamowienie jest synchronizowane do orderPRO
|
||||
Then pole personalization zawiera "Woreczek jutowy: Nie"
|
||||
```
|
||||
|
||||
## AC-2: Polaczenie attributes i custom_fields
|
||||
```gherkin
|
||||
Given produkt ma attributes = "<b>Kolor tekstu</b>: Bialy<br><b>Zakretka</b>: Zlota" i custom_fields = "<b>Imiona</b>: Jan i Anna"
|
||||
When zamowienie jest synchronizowane
|
||||
Then personalization zawiera oba bloki oddzielone nowa linia (najpierw attributes, potem custom_fields)
|
||||
```
|
||||
|
||||
## AC-3: Puste pola nie generuja pustych linii
|
||||
```gherkin
|
||||
Given produkt ma attributes = "" i custom_fields = "<b>Imie</b>: Jan"
|
||||
When zamowienie jest synchronizowane
|
||||
Then personalization zawiera tylko "Imie: Jan" (bez pustych linii na poczatku)
|
||||
```
|
||||
|
||||
## AC-4: Oba pola puste zwracaja null
|
||||
```gherkin
|
||||
Given produkt ma attributes = "" i custom_fields = ""
|
||||
When zamowienie jest synchronizowane
|
||||
Then personalization = null (bez zmian wzgledem obecnego zachowania)
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Rozszerzenie extractPersonalization o pole attributes</name>
|
||||
<files>src/Modules/Settings/ShopproOrderMapper.php</files>
|
||||
<action>
|
||||
W metodzie `extractPersonalization()` (linia 590):
|
||||
1. Odczytaj pole `attributes` z $row (readPath z kluczem 'attributes')
|
||||
2. Odczytaj pole `custom_fields` z $row (juz istniejace)
|
||||
3. Dla kazdego niepustego pola: zamien <br> na \n, strip_tags, html_entity_decode, trim
|
||||
4. Polacz niepuste czesci separatorem "\n" (attributes first, potem custom_fields)
|
||||
5. Zwroc polaczony tekst lub null jesli oba puste
|
||||
|
||||
Nie zmieniac logiki parsowania HTML (str_replace br, strip_tags, html_entity_decode) - tylko rozszerzyc o drugie pole.
|
||||
Nie dodawac naglowkow "Atrybuty:" / "Personalizacja:" - traktowac dane jednorodnie.
|
||||
</action>
|
||||
<verify>
|
||||
Sprawdzenie w bazie danych po resync zamowienia 11776:
|
||||
SELECT personalization FROM order_items WHERE order_id = (SELECT id FROM orders WHERE source_order_id = '11776')
|
||||
Powinno zwrocic "Woreczek jutowy: Nie"
|
||||
</verify>
|
||||
<done>AC-1, AC-2, AC-3, AC-4 satisfied</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- Logika `mapItems()` poza wywolaniem `extractPersonalization()`
|
||||
- Struktura bazy danych (kolumna `personalization` juz istnieje)
|
||||
- Widok wyswietlania personalizacji (show.php)
|
||||
- ShopproOrdersSyncService, ShopproApiClient
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Tylko zmiana parsera - bez migracji DB
|
||||
- Bez zmian w widoku (wyswietlanie juz dziala)
|
||||
- Bez resyncu wszystkich zamowien (to recznie po deploy)
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] PHP syntax OK: `php -l src/Modules/Settings/ShopproOrderMapper.php`
|
||||
- [ ] Zamowienie 11776 po resync ma personalization = "Woreczek jutowy: Nie"
|
||||
- [ ] Zamowienia z samym custom_fields dzialaja jak dotychczas (brak regresji)
|
||||
- [ ] Zamowienia z obu polami maja polaczone dane
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- extractPersonalization() czyta zarowno attributes jak i custom_fields
|
||||
- Istniejace zamowienia z custom_fields nie tracą danych
|
||||
- Pole attributes jest poprawnie parsowane (HTML stripped, br -> newline)
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/71-attributes-import/71-01-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user