23 KiB
Generowanie projektów graficznych z zamówień
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ę odOP+ cyfry) → filtro.internal_order_number = '<wartość>'. - Klient — imię/nazwisko lub fragment (np.
Kowalska,Anna Kowalska) → filtroa.name LIKE '%<wartość>%'. - Produkt — fragment nazwy produktu (np.
buteleczka,pudelko chrzest) → filtroi.original_name LIKE '%<wartość>%'.
Rozpoznanie typu argumentu:
- Jeśli pasuje do regex
^OP\d+$(po znormalizowaniu case) → numer zamówienia. - W przeciwnym razie spróbuj jako klient (
oa.name LIKE). Jeśli wynik pusty → spróbuj jako produkt (oi.original_name LIKE). - Jeśli użytkownik jawnie napisał
klient:<x>/zamowienie:<x>/produkt:<x>— użyj dokładnie tego typu bez zgadywania. - Brak argumentu → standardowy tryb (wszystkie pasujące pozycje).
Zawsze raportuj w wstępie: "Filtr: = <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
Wczytaj dane z pliku .env w katalogu projektu:
DB_HOST_REMOTE— host bazy (użyj remote, nie localhost)DB_DATABASE,DB_USERNAME,DB_PASSWORD,DB_PORT
Użyj "C:/xampp/mysql/bin/mysql.exe" do zapytań (z flagą --default-character-set=utf8mb4).
2. Pobierz aktywne mapowania
SELECT id, product_name_pattern, script_name, output_dir, requires_photo
FROM project_mappings
WHERE is_active = 1;
Jeśli brak mapowań — poinformuj użytkownika i zakończ.
3. Znajdź zamówienia do generacji (z dopasowaniem do mapowań)
Schemat bazy danych — kluczowe kolumny:
orders.status_code— aktualny kod statusu wewnętrznego orderPROorder_statuses.code— kody statusów, wiązanie:orders.status_code = order_statuses.codeorder_statuses.group_id→order_status_groups.id— grupy statusóworder_items.original_name— nazwa produktuorder_items.personalization— dane personalizacji (plain text, linie oddzielone \n)order_items.project_generated— 0 = nie wygenerowano, 1 = wygenerowanoorder_addresses.address_type— typ adresu ('customer', 'delivery', 'invoice')order_addresses.name— pełne imię i nazwisko kupującegoorder_notes.note_type = 'message'— wiadomość od klienta do zamówienia (polecomment), traktowana jako dodatkowy kontekst do personalizacji
Jedno zapytanie łączy zamówienia z mapowaniami (JOIN eliminuje produkty bez mapowania):
SELECT
oi.id AS item_id,
oi.original_name AS product_name,
oi.personalization,
oi.quantity,
o.id AS order_id,
o.internal_order_number,
o.status_code AS status_code,
oa.name AS buyer_name,
oa.email AS buyer_email,
pm.script_name,
pm.output_dir,
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
JOIN order_status_groups osg ON os.group_id = osg.id
JOIN project_mappings pm ON pm.is_active = 1
AND oi.original_name = pm.product_name_pattern
LEFT JOIN order_addresses oa ON o.id = oa.order_id AND oa.address_type = 'customer'
WHERE osg.id = 2
AND oi.project_generated = 0
AND oi.personalization IS NOT NULL
AND oi.personalization <> ''
-- {{OPTIONAL_FILTER}}
ORDER BY o.id;
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
personalizationzorder_itemsORAZcustomer_message(wiadomość klienta do zamówienia zorder_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:
python tools/generowanie/email_message_fetcher.py --email "{buyer_email}" --days 60 --json
- Skrypt przeszukuje wyłącznie INBOX skrzynki
EMAIL_01i 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_messagez bazy, tylko późniejsze w czasie). Przy sprzecznościach: najnowszy mail > starsze maile >customer_messagez 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_messagezawiera 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"
- Życzenia — opcjonalny tekst (np. "Na zdrowie!", "Dziękujemy!"). Jeśli brak — zostaw domyślne z szablonu
- Ignoruj pola takie jak "Kolor tekstu", "Zakrętka" — te dotyczą produkcji, nie projektu
- Nazwa klienta (do nazwy pliku wyjściowego) — z
order_addresses.name(polebuyer_namew zapytaniu)
WAŻNE — semantyczny podział pola "Kto składa życzenia" na naglowek + od_kogo:
Pole Kto składa życzenia w personalizacji klienta NIE jest jednoznacznie = --od-kogo. Szablony pudełek chrzest/komunia mają dwa osobne teksty nad i pod życzeniami: naglowek (fraza życzeniowa, np. "Z najlepszymi życzeniami") oraz od_kogo (podpis, np. "Matka Chrzestna"). Klienci często wklejają w jedno pole frazę życzeniową + podpis — trzeba to semantycznie rozdzielić, bazując na znajomości języka polskiego.
Zasady:
- Czysty podpis (krótki, typu "Twoja chrzestna", "Ciocia Gabi i wujek Filip", "Rodzice Chrzestni") → cały tekst jako
--od-kogo,naglowekdomyślny z szablonu. - Fraza życzeniowa + podpis (np. "Z miłością i modlitwą w dniu Chrztu Świętego – Matka Chrzestna z rodziną") → podziel:
- Część życzeniowa →
--naglowek("Z miłością i modlitwą w dniu Chrztu Świętego") - Podpis →
--od-kogo("Matka Chrzestna z rodziną")
- Część życzeniowa →
- Rola rodzinna + konkretne osoby (np. "Rodzice Chrzestni - Ciocia Ania i Wujek Wojtek") → zostaw jako całość w
--od-kogo. "Rodzice Chrzestni" to rola, nie fraza życzeniowa.
Separatorem może być myślnik (–, —, -), nowa linia, dwukropek, przecinek, lub nic — decyduj semantycznie, nie mechanicznie.
Heurystyki rozpoznania frazy życzeniowej (→ naglowek):
- zawiera słowa typu: "z miłością", "z modlitwą", "z najlepszymi życzeniami", "w dniu", "błogosławieństwa", "na pamiątkę"
- ma charakter uroczysty, długości >20 znaków
- nie wskazuje konkretnej osoby ani roli rodzinnej
Heurystyki rozpoznania podpisu (→ od_kogo):
- role rodzinne: Matka/Ojciec Chrzestny, Rodzice Chrzestni, Ciocia, Wujek, Babcia, Dziadek
- imiona własne, "z rodziną"
W razie wątpliwości — pokaż użytkownikowi obie interpretacje w planie (opcja A/B) i zapytaj, zamiast zgadywać.
WAŻNE — łączenie wielu pozycji jednego zamówienia w jeden plik (prośby o bycie chrzestnym):
Dla produktów mapujących się na skrypt prosba_chrzestny_*.py — szablon ma dwie ścianki (matka + ojciec) i skrypt akceptuje oba zestawy parametrów jednocześnie.
Kluczowa zasada: grupowanie po (order_id, script_name), nie po nazwie produktu. Produkty w bazie mają różne nazwy dla matki i ojca (np. "Akrylowa prośba o zostanie Ojcem Chrzestnym lustrzana złota - Dłonie" i "Akrylowa prośba o zostanie Matką Chrzestną lustrzana złota - Dłonie"), ale mapują się na ten sam skrypt. Dlatego mapowania w project_mappings muszą mieć OSOBNY wpis dla każdej nazwy produktu wskazujący na ten sam script_name.
Algorytm dla skryptów prosba_chrzestny_*:
- Po pobraniu listy zamówień pogrupuj pozycje po
(order_id, script_name). - Dla każdej grupy (jedno zamówienie + jeden skrypt):
- Rozpoznaj po nazwie produktu lub treści personalizacji, która pozycja to ojciec, a która matka (słowa-klucze: "Ojcem Chrzestnym", "Wujku", "moim" → ojciec; "Matką Chrzestną", "Ciociu", "moją" → matka).
--imie-dzieckajest wspólne — wyciągnij z personalizacji (zwykle jedno imię dziecka powtarza się w obu pozycjach).--matka-wolacz/--ojciec-wolacz— z odpowiadających pozycji.- Uruchom skrypt raz z obydwoma parametrami.
- Wygenerowany zostanie jeden plik PSD zawierający obie karty na A3.
- Oznacz obie pozycje
order_itemsjakoproject_generated = 1po sukcesie (update poid IN (item_id_matka, item_id_ojciec)).
Pozostałe przypadki:
- 1× matka + 1× ojciec → jeden plik z obojgiem.
- tylko 1× matka → jeden plik z samą matką (DP ukryty).
- tylko 1× ojciec → jeden plik z samym ojcem (DL ukryty).
- 2× ta sama strona (np. 2× matka) → jeden plik z matką;
quantitydecyduje o liczbie wydruków, nie liczba plików PSD; oznacz obie pozycje jako generowane.
Przykład (OP000000385): 2 pozycje — Akrylowa prośba o zostanie Ojcem Chrzestnym... (Wujku Adi, Laura) + Akrylowa prośba o zostanie Matką Chrzestną... (Ciociu Dario, Laura). Wynik: JEDEN plik Natalia Kwapisz.psd z --imie-dziecka "Laura" --ojciec-wolacz "Wujku Adi" --matka-wolacz "Ciociu Dario".
Rozpoznawanie matka/ojciec — po treści personalizacji, NIE po nazwie produktu:
Klienci często mylą się przy wyborze produktu i zamawiają np. 2× "Matką Chrzestną", ale w personalizacji jedna z pozycji ma treść męską ("Wujku..."). Nie sugeruj się nazwą produktu — analizuj treść personalizacji i rozpoznaj:
"Wujku [imię]","Wujek","moim Ojcem","Ojcem Chrzestnym"→ ojciec (--ojciec-wolacz)"Ciociu [imię]","Ciocia","moją Matką","Matką Chrzestną"→ matka (--matka-wolacz)
Jeśli w jednym zamówieniu klient wybrał 2× ten sam produkt, ale personalizacje wskazują na matkę + ojca — zinterpretuj jako 1 plik z obojgiem chrzestnych.
Normalizacja wołaczy — klient podaje tylko imię w mianowniku:
Szablon oczekuje formy typu "Ciociu Kasiu" / "Wujku Darku" (prefiks roli + wołacz imienia). Jeśli klient podał tylko imię w mianowniku (np. "Imię cioci: Paulina", "Wujek: Dawid", "Ciocia: Julia") — automatycznie przekształć:
- Z imienia w mianowniku utwórz wołacz polski (Paulina → Paulino, Dawid → Dawidzie, Julia → Julio, Kasia → Kasiu, Darek → Darku, Michał → Michale, Ola → Olu, itd.).
- Dodaj prefiks roli:
"Ciociu "dla matki,"Wujku "dla ojca. - Finalny format:
"Ciociu Paulino","Wujku Dawidzie","Ciociu Julio".
Wyjątek: Jeśli klient wyraźnie pisze że ma być bez zwrotu (np. "bez Ciociu", "tylko imię", "samo imię"), wtedy wstawiaj surowe imię bez prefiksu. W każdym innym przypadku — zawsze dodawaj Ciociu/Wujku.
Jeśli klient już podał pełną formę ("Ciociu Paulino", "Wujku Dawidzie") — zostaw dosłownie, nie modyfikuj.
Te reguły (rozpoznawanie płci po treści + auto-wołacz) są domyślne — NIE pytaj użytkownika za każdym razem, tylko raportuj w planie co zrobiono (oryginał → przekształcenie), żeby mógł zweryfikować.
WAŻNE — zaproszenia akrylowe (skrypt zaproszenie_chrzest_*.py):
Szablon ma 4 ścianki na A3 (DP, DL, GP, GL) — 4 zaproszenia na arkusz. Wspólne dla wszystkich ścianek: imię dziecka, miejsce_data, poczęstunek. Różne: od_kogo (każda ścianka = jedna osoba zapraszana).
Grupowanie wielu pozycji zamówienia (analogicznie do próśb o chrzestnego):
W jednym zamówieniu może być kilka pozycji tego samego (lub mapującego się na ten sam skrypt) produktu zaproszeń. NIE generuj pliku per pozycja. Zasady:
- Pogrupuj pozycje po
(order_id, script_name). - Dla każdej grupy zbierz wszystkie osoby zapraszane ze wszystkich pozycji (z
personalizationkażdej pozycji, + uwzględnijquantityjeśli klient w jednej pozycji podał wiele osób z quantity > 1). - Połącz w jedną listę
od_kogo. - Wspólne dane (imię dziecka, miejsce_data, poczęstunek) — wyciągnij raz, z pierwszej pozycji (powinny być identyczne we wszystkich pozycjach grupy, jeśli nie — zapytaj użytkownika).
- Zastosuj batching po 4: podziel listę
od_kogona partie po 4 i wywołaj skrypt N razy z numerowanymi nazwami plików. - Po sukcesie oznacz wszystkie pozycje grupy jako
project_generated = 1.
Batching przy quantity > 4: 1 plik PSD = max 4 zaproszenia. Jeśli klient zamawia więcej osób (np. 17 zaproszeń), silnik dzieli listę na partie po 4 i wywołuje skrypt wielokrotnie z numerowanymi nazwami plików:
- 17 zaproszeń → 5 plików:
Klient 01.psd(4),Klient 02.psd(4),Klient 03.psd(4),Klient 04.psd(4),Klient 05.psd(1). - 4 zaproszenia → 1 plik
Klient.psd(bez numeracji). - 6 zaproszeń → 2 pliki:
Klient 01.psd(4) +Klient 02.psd(2).
Numerowanie nadawane przez silnik (nie przez skrypt). Zderzenia nazw w _gotowe/ są rozstrzygane normalnym sufiksem.
Interpretacja skrótowej personalizacji klienta:
Klienci wpisują dane skrótowo, trzeba je rozwinąć patrząc na oryginalne placeholdery w szablonie. Przykłady:
Wejście klienta:
Imię dziecka: Teodor Surma
Imię i nazwisko proszonego gościa: Matkę Chrzestną Wiktorię Igras
na Chrzest Święty w Parafia pw. Świętej Jadwigi Śląskiej w Hedwiżynie 45A
Data i godzina: 18 Kwiecień 2026 Godzina 13.00
Miejsce przyjęcia: "Kresovia Biłgoraj - Sala Balowa, Okrągłe 1C, 23-400 Biłgoraj"
Przekształcenie na parametry skryptu:
--imie-dziecka "Teodora"(mianownik "Teodor" → dopełniacz, bo szablon: "uroczystość przyjęcia Sakramentu Chrztu Świętego [kogo?] Teodora")--miejsce-data "W dniu 18.04.2026\ro godzinie 13:00\rParafia pw. Świętej Jadwigi Śląskiej\rw Hedwiżynie 45A"(format jak w oryginale: "W dniu DD.MM.RRRR o godzinie HH:MM\rParafia...\rulica")--poczestunek "Po uroczystości serdecznie zapraszamy\rna poczęstunek do Kresovia Biłgoraj - Sala Balowa\rOkrągłe 1C, 23-400 Biłgoraj"(format jak w oryginale)--od-kogo-1 "Matkę Chrzestną Wiktorię Igras"(poprawiam literówki "Chszestną" → "Chrzestną")
Zasady rozwijania danych:
- Daty:
"18 Kwiecień 2026 Godzina 13.00"→"W dniu 18.04.2026\ro godzinie 13:00"(miesiąc po polsku → numer, "Godzina 13.00" → "o godzinie 13:00", dodany prefiks "W dniu"). - Parafia:
"Parafia pw. X w Y 45A"→ zostaw bez zmian, złącz łamaniem linii w logiczne miejsca. - Miejsce przyjęcia: osadź w formule "Po uroczystości serdecznie zapraszamy na poczęstunek do [NAZWA]\r[ULICA, KOD MIASTO]".
- Imię dziecka: zawsze dopełniacz (szablon: "Chrztu Świętego [kogo?]").
- Literówki klienta (
"Chszestną"→"Chrzestną","Chszestnego"→"Chrzestnego") — poprawiaj automatycznie. - Nazwisko zapraszanego gościa: zostaw w formie jaką podał klient (nie odmieniaj jeśli nie jesteś pewny).
Jeśli klient nie podał czegoś (np. brak miejsca przyjęcia = brak poczęstunku) → --poczestunek pomiń, warstwa zostanie ukryta.
Formatowanie daty — specyficzne dla szablonu:
Niektóre szablony mają nietypowy format daty (np. "10 | 05 | 2026" z pipe'ami). Skrypt przyjmuje datę dosłownie — silnik /wygeneruj-projekty musi przekształcić standardowy format klienta (DD.MM.RRRR lub DD-MM-RRRR) na format oczekiwany przez szablon, zanim wywoła skrypt.
Obecne wzorce formatów daty per skrypt:
pudelko_komunia_kwiaty_wzor2.py→ format"DD | MM | RRRR"(np."10 | 05 | 2026"). Silnik:"10.05.2026"→"10 | 05 | 2026".pudelko_komunia_golabek_uv.py→ format"DD | MM | RRRR"(np."10 | 05 | 2026"). Silnik:"10.05.2026"→"10 | 05 | 2026".- Wszystkie pozostałe
pudelko_komunia_*,pudelko_chrzest_*,buteleczki_slub_*→ format"DD.MM.RRRR"(standardowy).
Dodaj nowe wzory tu, gdy będą tworzone nowe skrypty z nietypowymi formatami.
6. Przedstaw plan i generuj
Wyświetl tabelę z planem:
Zamówienie | Produkt | Imię żeńskie | Imię męskie | Data | Życzenia | Klient (nazwa pliku)
OP000123 | Buteleczka... | Kinga | Łukasz | 30.04.2026 | (domyślne) | Kinga Klimczak
Autonomia przy generowaniu:
- Jeśli wszystkie interpretacje są jasne lub wątpliwości minimalne (rutynowe przekształcenia: dopełniacz imienia, format daty, auto-wołacz, podział naglowek/od_kogo zgodnie z regułami) → generuj od razu po wyświetleniu planu, bez pytania o potwierdzenie. Raportuj w planie co zostało przekształcone, żeby użytkownik mógł zweryfikować po fakcie.
- Jeśli wątpliwość jest istotna (np. brakujące imię męskie w buteleczkach ślubnych, niejasne przypisanie matka/ojciec przy próśbach, dwuznaczny podział naglowek/od_kogo, dziwny format daty, klient wyraźnie pomylił produkt, treść zawierająca rażące dubluje lub sprzeczność między polami) → zatrzymaj się i zapytaj użytkownika, prezentując opcje.
Kierunkowskaz: "czy jestem pewny że wynik będzie akceptowalny?" Jeśli tak — jedź. Jeśli nie — pytaj.
7. Uruchom generowanie
Przed generowaniem sprawdź czy Photoshop jest uruchomiony:
tasklist //FI "IMAGENAME eq Photoshop.exe" 2>/dev/null | grep -i photoshop
Jeśli Photoshop nie jest uruchomiony — poinformuj użytkownika i poczekaj aż go uruchomi.
Pobranie zdjęcia od klienta (jeśli requires_photo = 1):
Dla mapowań z requires_photo = 1 przed wywołaniem generatora pobierz zdjęcie z poczty klienta:
python tools/generowanie/email_photo_fetcher.py --email "{buyer_email}" --out "C:/tmp/orderpro_photos" --days 365
- Skrypt zwraca ścieżkę pobranego pliku albo komunikat
BRAK(exit code 1). - Jeśli zdjęcie się pobrało — przekaż ścieżkę do generatora przez
--zdjecie. - Jeśli zdjęcia nie znaleziono — generator i tak ma być wywołany bez
--zdjecie(wstawi zielony placeholder jako sygnał "klient nie przysłał foto"). NIE blokuj generacji. - Zaraportuj w tabeli planu (kolumna "Zdjęcie") status: ścieżka /
BRAK (zielony placeholder).
WAŻNE — rozpoznawanie płci dziecka (dla skryptów z parametrem --plec):
Niektóre skrypty (np. akrylowe_podziekowanie_matka_chrzestna_wzor2.py) mają dwa warianty szablonu (chłopiec/dziewczynka) i wymagają parametru --plec m lub --plec k. Rozpoznaj płeć na podstawie personalizacji:
- Imię proste (Fabian, Wojciech, Kacper →
m; Blanka, Zosia, Wiktoria →k) — standardowa wiedza o polskich imionach. - Imię odmienione (np. "Wojtusia", "Kacpra" →
m; "Blanki", "Zosi", "Wiktorii" →k) — rozpoznaj mianownik i z niego określ płeć. - Kontekst — jeśli w personalizacji pojawia się "mój Chrześniak", "Drogi Synku", "malutki" →
m; "moja Chrześniaczka", "Droga Córeczko", "malutka" →k. - W razie wątpliwości — wyświetl surowe dane klientowi i zapytaj.
WAŻNE — łamanie linii w tekstach wielolinijkowych (życzenia, podziękowanie, itp.):
Photoshop jako znak łamania linii w warstwach tekstowych rozpoznaje \r (CR), NIE \n (LF). Jeśli przekażesz \n, Photoshop wyświetli go jako śmieciowy kwadrat z literą "n". W bashu użyj ANSI-C quoting: $'linia1\rlinia2\rlinia3' do budowy wartości --zyczenia / --podziekowanie i przekaż ją w cudzysłowach do skryptu.
Dla każdego potwierdzonego produktu:
- 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 indeksem01,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. - 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ówmagnes_*dorzuć--liczba {order_items.quantity}— szablony mają N slotów na arkuszu A3, nadmiar ma być ukrywany żeby nie drukować pustych kopii) - Jeśli mapowanie ma
output_dir— skrypt powinien zapisać tam (jeśli obsługuje)
8. Oznacz w bazie
Po udanym generowaniu:
UPDATE order_items
SET project_generated = 1, project_generated_at = NOW()
WHERE id = {item_id};
9. Raport końcowy
Wyświetl podsumowanie:
- Ile projektów wygenerowano
- Ile pominięto (brak mapowania, brak personalizacji)
- Ewentualne błędy
Ważne zasady
- Zawsze pytaj o potwierdzenie przed generowaniem
- Photoshop musi być uruchomiony — sprawdź przed generowaniem
- Nie oznaczaj jako wygenerowane jeśli skrypt zwrócił błąd
- Jeśli nie potrafisz zinterpretować personalizacji — wyświetl surowe dane i zapytaj użytkownika
- Skrypty generujące znajdują się w
tools/generowanie/w katalogu projektu orderPRO