update
This commit is contained in:
@@ -2,6 +2,24 @@
|
||||
|
||||
Jesteś silnikiem generowania projektów graficznych dla zamówień w orderPRO. Twoje zadanie to znaleźć zamówienia wymagające generacji, zinterpretować dane klienta i uruchomić odpowiedni skrypt.
|
||||
|
||||
## Opcjonalne parametry filtrowania
|
||||
|
||||
Komenda przyjmuje opcjonalny argument (wolnotekstowy) zawężający zakres generacji:
|
||||
|
||||
- **Numer zamówienia** — np. `OP000123`, `OP000000385` (pattern: zaczyna się od `OP` + cyfry) → filtr `o.internal_order_number = '<wartość>'`.
|
||||
- **Klient** — imię/nazwisko lub fragment (np. `Kowalska`, `Anna Kowalska`) → filtr `oa.name LIKE '%<wartość>%'`.
|
||||
- **Produkt** — fragment nazwy produktu (np. `buteleczka`, `pudelko chrzest`) → filtr `oi.original_name LIKE '%<wartość>%'`.
|
||||
|
||||
**Rozpoznanie typu argumentu:**
|
||||
1. Jeśli pasuje do regex `^OP\d+$` (po znormalizowaniu case) → numer zamówienia.
|
||||
2. W przeciwnym razie spróbuj jako klient (`oa.name LIKE`). Jeśli wynik pusty → spróbuj jako produkt (`oi.original_name LIKE`).
|
||||
3. Jeśli użytkownik jawnie napisał `klient:<x>` / `zamowienie:<x>` / `produkt:<x>` — użyj dokładnie tego typu bez zgadywania.
|
||||
4. Brak argumentu → standardowy tryb (wszystkie pasujące pozycje).
|
||||
|
||||
Zawsze raportuj w wstępie: "Filtr: <typ> = <wartość>" albo "Filtr: brak (wszystkie zamówienia)".
|
||||
|
||||
**WAŻNE:** Filtry zawężają tylko wybór pozycji — pozostałe reguły (status grupy 2, `project_generated = 0`, wymagana personalizacja, aktywne mapowanie) **obowiązują nadal**. Jeśli filtr nie zwróci nic — poinformuj użytkownika wprost, że żadna pasująca pozycja nie wymaga generacji.
|
||||
|
||||
## Przepływ
|
||||
|
||||
### 1. Połącz się z bazą danych
|
||||
@@ -33,6 +51,7 @@ Schemat bazy danych — kluczowe kolumny:
|
||||
- `order_items.project_generated` — 0 = nie wygenerowano, 1 = wygenerowano
|
||||
- `order_addresses.address_type` — typ adresu ('customer', 'delivery', 'invoice')
|
||||
- `order_addresses.name` — pełne imię i nazwisko kupującego
|
||||
- `order_notes.note_type = 'message'` — wiadomość od klienta do zamówienia (pole `comment`), traktowana jako dodatkowy kontekst do personalizacji
|
||||
|
||||
Jedno zapytanie łączy zamówienia z mapowaniami (JOIN eliminuje produkty bez mapowania):
|
||||
|
||||
@@ -49,7 +68,12 @@ SELECT
|
||||
oa.email AS buyer_email,
|
||||
pm.script_name,
|
||||
pm.output_dir,
|
||||
pm.requires_photo
|
||||
pm.requires_photo,
|
||||
(
|
||||
SELECT GROUP_CONCAT(n.comment SEPARATOR '\n---\n')
|
||||
FROM order_notes n
|
||||
WHERE n.order_id = o.id AND n.note_type = 'message'
|
||||
) AS customer_message
|
||||
FROM order_items oi
|
||||
JOIN orders o ON oi.order_id = o.id
|
||||
JOIN order_statuses os ON o.status_code = os.code
|
||||
@@ -61,15 +85,38 @@ WHERE osg.id = 2
|
||||
AND oi.project_generated = 0
|
||||
AND oi.personalization IS NOT NULL
|
||||
AND oi.personalization <> ''
|
||||
-- {{OPTIONAL_FILTER}}
|
||||
ORDER BY o.id;
|
||||
```
|
||||
|
||||
Jeśli brak wyników — poinformuj użytkownika że nie ma zamówień do generacji pasujących do aktywnych mapowań.
|
||||
**Podstawienie filtra** (patrz sekcja "Opcjonalne parametry filtrowania"):
|
||||
- Numer zamówienia: `AND o.internal_order_number = '<wartość>'`
|
||||
- Klient: `AND oa.name LIKE '%<wartość>%'`
|
||||
- Produkt: `AND oi.original_name LIKE '%<wartość>%'`
|
||||
- Brak argumentu: usuń marker, nie dodawaj nic.
|
||||
|
||||
Escape'uj apostrofy w wartości (zamień `'` na `''`) zanim wstawisz do SQL.
|
||||
|
||||
Jeśli brak wyników — poinformuj użytkownika że nie ma zamówień do generacji pasujących do aktywnych mapowań (przy aktywnym filtrze — wskaż, że żadna pozycja nie pasuje do podanego filtra).
|
||||
|
||||
### 5. Zinterpretuj dane klienta (AI normalizacja)
|
||||
|
||||
Dla każdego pasującego produktu:
|
||||
- Przeczytaj pole `personalization` z `order_items`
|
||||
- Przeczytaj pole `personalization` z `order_items` **ORAZ** `customer_message` (wiadomość klienta do zamówienia z `order_notes.note_type = 'message'`) **ORAZ** wiadomości mailowe od klienta z INBOX (patrz niżej).
|
||||
|
||||
**Sprawdzanie maili od klienta (analogicznie do zdjęć):**
|
||||
|
||||
Jeśli zamówienie ma `buyer_email`, przed interpretacją uruchom:
|
||||
```bash
|
||||
python tools/generowanie/email_message_fetcher.py --email "{buyer_email}" --days 60 --json
|
||||
```
|
||||
- Skrypt przeszukuje **wyłącznie INBOX** skrzynki `EMAIL_01` i zwraca JSON z listą wiadomości (`date`, `subject`, `body`), od najnowszej do najstarszej.
|
||||
- Exit 0 + JSON = są maile; exit 1 + `BRAK` = brak wiadomości (to normalny przypadek — nie blokuj generacji).
|
||||
- Jeśli są wiadomości — wczytaj treści i traktuj jako dodatkowe źródło korekt/uwag klienta (tak samo jak `customer_message` z bazy, tylko późniejsze w czasie). Przy sprzecznościach: **najnowszy mail > starsze maile > `customer_message` z bazy > `personalization`**.
|
||||
- Odfiltruj maile ewidentnie niezwiązane z zamówieniem (np. automatyczne odpowiedzi, tematy typu "Re: faktura", zapytania o zupełnie inny produkt). Zostaw tylko te wyglądające na poprawki/uzupełnienia personalizacji.
|
||||
- Raportuj w planie w kolumnie "Mail klienta": `BRAK` / `N wiadomości — najnowsza: {krótkie streszczenie}` — żeby użytkownik widział, że sprawdziłaś.
|
||||
- **Traktuj oba źródła łącznie.** Wiadomość klienta do zamówienia często zawiera doprecyzowania, korekty, dodatkowe życzenia, preferencje zapisu imion, poprawki literówek, prośby typu "zamiast Kasia wpiszcie Kasiu", uzupełnienia brakujących pól (np. data, życzenia). Jeśli wiadomość klienta i personalizacja są **sprzeczne**, preferuj wiadomość klienta (jest późniejsza, bardziej świadoma) — ale zaraportuj konflikt w planie.
|
||||
- Jeśli `customer_message` zawiera treści niezwiązane z personalizacją (np. "proszę o szybką wysyłkę", "dziękuję") — zignoruj do celów generacji, ale odnotuj w planie w kolumnie "Wiadomość klienta" żeby użytkownik widział że sprawdziłaś.
|
||||
- Zinterpretuj dane kontekstowo. Typowe dane to:
|
||||
- **Imię żeńskie i męskie** — mogą być w formacie "Kasia i Tomek", "Imiona: Kasia, Tomek", "Imię żeńskie: Kasia\nImię męskie: Tomek", "Imiona młodej pary: Kasia i Tomek", itp.
|
||||
- **Data uroczystości** — format DD.MM.YYYY, może być opisana jako "Data: 30.04.2026" lub "Data uroczystości: 30.04.2026" lub po prostu "30.04.2026"
|
||||
@@ -255,7 +302,7 @@ Photoshop jako znak łamania linii w warstwach tekstowych rozpoznaje **`\r` (CR)
|
||||
|
||||
Dla każdego potwierdzonego produktu:
|
||||
1. **Sprawdź kolizję nazwy pliku** w katalogu wyjściowym. Jeśli plik `{klient}.psd` (lub inne rozszerzenie używane przez skrypt) już istnieje — dodaj do nazwy klienta sufiks z indeksem `01`, `02`, ... (np. `Anna Rak` → `Anna Rak 01`, a jeśli i to zajęte → `Anna Rak 02`). Inkrementuj aż znajdziesz wolną nazwę. Dopiero wtedy przekaż wynik jako `--klient`.
|
||||
2. Uruchom skrypt: `python tools/generowanie/{script_name} --klient "Imię Nazwisko" ...` (parametry zależne od skryptu — dla buteleczek/pudełek zwykle `--imie/--imiona`, `--data`, opcjonalnie `--zyczenia`/`--podziekowanie`; dla produktów ze zdjęciem dorzuć `--zdjecie /sciezka/do/foto.jpg`)
|
||||
2. Uruchom skrypt: `python tools/generowanie/{script_name} --klient "Imię Nazwisko" ...` (parametry zależne od skryptu — dla buteleczek/pudełek zwykle `--imie/--imiona`, `--data`, opcjonalnie `--zyczenia`/`--podziekowanie`; dla produktów ze zdjęciem dorzuć `--zdjecie /sciezka/do/foto.jpg`; **dla skryptów `magnes_*` dorzuć `--liczba {order_items.quantity}`** — szablony mają N slotów na arkuszu A3, nadmiar ma być ukrywany żeby nie drukować pustych kopii)
|
||||
3. Jeśli mapowanie ma `output_dir` — skrypt powinien zapisać tam (jeśli obsługuje)
|
||||
|
||||
### 8. Oznacz w bazie
|
||||
|
||||
Reference in New Issue
Block a user