Zákazník u kterékoli své objednávky klikne na Objednat znovu. Její položky se přidají do košíku v aktuálních cenách, zaokrouhlené na balení. Co už nesmí koupit, se vynechá a řekne mu to.
Velkoobchodní odběratel opakuje většinu objednávek. Dnes musí každou položku znovu najít v katalogu. Starý B2B umí objednávku zkopírovat, ale jen pro hlavní účet, bez odkazu v šablonách a tak, že napřed vysype košík.
Kam patří. Jádro MasterShopu (větev front-api): endpoint, který z objednávky naplní košík. Opakovaná objednávka se hodí každému klientovi na headlessu, klasické jádro kopii objednávky už má. Obálka: tlačítko Objednat znovu a výsledkové okno v SFX. Názvy nových tabulek a endpointů jsou pracovní, v jádru je pojmenuje programátor.
Nic z toho nebrání začít. K1 a D1 se dají rozhodnout během vývoje, D2 je nález mimo tuto funkci.
| # | Otázka a náš návrh |
|---|---|
| K1 | Smí Objednat znovu i podúčet, nebo jen hlavní účet jako dnes? Návrh: ano, každý účet u objednávek, které vidí. Podúčet vidí jen objednávky na své doručovací adresy, takže nic cizího nezkopíruje. |
| # | Otázka |
|---|---|
| D1 | Zaokrouhlení na balení: jádro počet při vložení do košíku samo zaokrouhlí nahoru na násobek balení a vrátí varování s velikostí balení. Endpoint po vložení přečte skutečný počet z košíku a vrátí ho jako countAdded. Ověřeno čtením kódu, ne během: otestovat na B2B účtu, až padne bloker košíku. |
| D2 | Detail objednávky GET /api-orders/order/{hash} v jádře nevyžaduje JWT a neověřuje vlastníka. Nový endpoint to nesmí zopakovat. Oprava detailu v jádře je mimo tuto funkci, ale je to bezpečnostní nález k založení. |
| D3 | Seznam objednávek vrací plné detaily včetně položek, výchozí stránka 10. Pro tlačítko v seznamu to stačí. Pokud SFX bude načítat víc, zvážit odlehčené DTO. |
NOT_AVAILABLE. Zákazník NEPOZNÁ rozdíl mezi „neexistuje" a „není ve vašem sortimentu". Je to záměr, sortiment jiných zákazníků se neprozrazuje.NOT_PURCHASABLE.⚠️ Dev: jádrový endpoint košíku množství u existující položky přepisuje, nesčítá. Součet musí udělat nový endpoint před zápisem.
NOT_PURCHASABLE.Nesahat na jádrovou třídu kopírování objednávky ze starého frontu. Je svázaná se Smarty a vyprazdňuje košík. Nový endpoint ji NEPOUŽIJE, jen převezme pravidlo výběru položek.
Dvě místa v uživatelské zóně a jedno výsledkové okno. Vzhled podle design systému ALBI, chování podle prototypu, obrazovka Objednávky.
| Stav | Co zákazník vidí |
|---|---|
| Klid | Tlačítko „Objednat znovu". |
| Načítání | Tlačítko neaktivní s indikátorem. Nelze kliknout dvakrát. |
| Vše přidáno | Okno: „Přidáno 5 položek do košíku." Seznam položek s množstvím. Tlačítka „Přejít do košíku" (primární) a „Zavřít". |
| Část přidána | Okno: „Přidáno 4 z 5 položek." Dva bloky: přidané; vynechané s důvodem slovy („Není ve vašem sortimentu", „Momentálně nejde objednat"). U zaokrouhlených položek poznámka „upraveno na 12 ks, balení má 6 ks". |
| Nic nepřidáno | Okno: „Z této objednávky teď nejde nic objednat." Seznam vynechaných s důvody. Jen „Zavřít". Košík se nezměnil. |
| Chyba | Hláška „Objednávku se nepodařilo zopakovat, zkuste to znovu." Košík se nezměnil. |
Nový prvek: sekundární tlačítko v patičce karty. Zbytek karty je stávající SFX komponenta OrderCard.
| Produkt | Množství | Poznámka |
|---|---|---|
| Puzzle Karak 500 dílků | 12 ks (2 bal.) | |
| Hrnek Kočka 330 ml | 18 ks (3 bal.) | |
| Přání k narozeninám | 25 ks (1 bal.) | upraveno ze 7 ks, balení má 25 |
| Dárková taška střední | 50 ks (1 bal.) |
| Kalendář Kočky 2026 | Není ve vašem sortimentu | |
Důvody se překládají z kódů odpovědi: NOT_AVAILABLE → „Není ve vašem sortimentu", NOT_PURCHASABLE → „Momentálně nejde objednat". Texty jsou překladové klíče SFX ve čtyřech mutacích.
Jeden nový endpoint v jádru MasterShopu, modul FrontApi vedle existujících endpointů košíku. Atribut #[AsRoute], vlastní DTO a registrace tagu v EndpointTagType.php. Bez registrace tagu endpoint tiše vypadne.
| Endpoint | Stav | K čemu |
|---|---|---|
POST /api-carts/carts/{cartToken}/reorder | nový | Naplní košík z objednávky. Tělo { "orderHash": "…" }, nebo { "items": [ { "productId", "count" } ] } pro blok Doobjednat vše na nástěnce (F03). Vyžaduje JWT zákazníka. Vrací přidané a vynechané položky, v obou případech stejně. |
GET /api-orders/orders/{userId} | existuje | Seznam objednávek s položkami. SFX z něj má hash objednávky pro tlačítko. Filtr na datum a stav umí, řazení ne. |
GET /api-orders/order/{hash} | existuje | Detail objednávky. Položky nesou objectId, objectCode, count a aktuální produktovou kartu s příznakem prodejnosti. V jádře bez JWT. D2 |
PUT /api-carts/carts/{cartToken} | existuje | Vložení jedné položky. Nový endpoint ho NEVOLÁ přes HTTP, používá stejnou službu jádra pro košík uvnitř. |
{
"cartToken": "c3f1…",
"added": [
{ "productId": 4412, "productCode": "P-4412", "name": "Puzzle Karak 500 dílků",
"countOrdered": 12, "countAdded": 12, "rounded": false },
{ "productId": 6601, "productCode": "P-6601", "name": "Přání k narozeninám",
"countOrdered": 7, "countAdded": 25, "rounded": true, "piecesInPackage": 25 }
],
"skipped": [
{ "productCode": "D-2612", "name": "Kalendář Kočky 2026", "reason": "NOT_AVAILABLE" }
]
}
countAdded je množství, o které se položka v košíku navýšila, ne celkové množství v košíku.name bere z objednávky, ne z produktu. Produkt nemusí existovat.reason má dvě hodnoty: NOT_AVAILABLE (neexistuje nebo není v sortimentu zákazníka) a NOT_PURCHASABLE (existuje, ale nejde koupit).pieces_in_package_b2b). Produktová karta FrontAPI ji dnes nenese, endpoint si ji vezme přímo z produktu.Nic nepřibývá. Funkce nemá nastavení, není co zapínat ani konfigurovat. Záměrně: každý přepínač je práce navíc a klient o žádný nežádal.
NOT_AVAILABLE. Stejně jako neexistující produkt.rounded: true). D1