Odběratel nakupuje po baleních, vidí ceny bez DPH, adresy jen ke čtení a zadává požadované datum dodání a své číslo objednávky. Starý B2B to umí, FrontAPI pro B2B zákazníka dnes košík ani objednávku nedokončí.
Nový B2B běží na jádru s FrontAPI a na SFX. Jádro pro B2B zákazníka košík ani objednávku přes FrontAPI nedokončí, vyhodí výjimku. Zadání popisuje, co starý B2B v košíku ukazuje navíc proti B2C, a co se kvůli tomu doplní.
Kam patří. Jádro MasterShopu (větev front-api): B2B větev objednávky ve FrontAPI, B2B pole objednávky, balení a zaokrouhlení, volba aktivní adresy. B2B košík přes FrontAPI potřebuje každý B2B klient na headlessu. Dnes obálka: výpočet součtů AlbiB2BPricesService, seskupení podle cost levelu, volitelná povinná pole, vypnutí slev. U každého kusu je níže uvedeno, kde je dnes. Kde to není jasné, rozhodne produkt PragueBest. Názvy nových polí a kódů jsou pracovní, v jádru je pojmenuje programátor.
Otázky jsou jen pro vývoj. Žádná nebrání začít s odblokováním B2B objednávky ve FrontAPI.
Otázky pro ALBI nejsou, chování se přebírá ze starého B2B.
| # | Otázka |
|---|---|
| D1 | Jak FrontAPI pozná aktivní doručovací adresu: košík, hlavička, nebo token (varianty v 05). Drží FrontAPI mezi voláními session, nebo padne vždy na výchozí adresu? Neověřeno během. Společné s S02. |
| D2 | B2B pole v POST /api-orders/order ploše v kořeni, nebo v objektu b2b. |
| D3 | Rozšíření DTO košíku v jádře, nebo přepisem v obálce. Balení a maximum jsou jádro, cost level a seskupení podle něj dnes obálka. |
| D4 | Balení: dnes jádro počet zaokrouhlí a zároveň vrátí varování. Chyba FrontApiCartItemUnsupportedDivisionB2BError existuje, ale nic ji nevytváří. Zůstat u varování + zaokrouhlení, nebo vrátit chybu bez úpravy košíku. |
| D5 | Slevové kódy pro B2B: PUT …/discount-codes vrátí chybu, nebo se endpoint pro B2B nezaregistruje. |
| D6 | Stav „objednávku nelze dokončit" jako pole v GET košíku, nebo samostatný endpoint. Musí sedět s S04. |
| D7 | Když nová obálka převezme přepis košíku s AlbiB2BPricesService, součty v DTO košíku se mají propsat samy. Ověřeno čtením kódu, ne během. Ověřit i SK (položky na 3 desetinná místa). |
Čtyři kroky jako starý B2B. Předpoklad: zákazník je přihlášený na B2B prezentaci a má zvolenou doručovací adresu (S02). Košík patří této adrese.
isOrderAllowed = false): alert s hláškou podle důvodu, „Pokračovat" je neaktivní, další kroky nejsou klikací. Košík jde dál upravovat. Dlužník: S04. Neaktivní adresa, zákazník nebo blokovaný uzel: „Nelze provést objednávku". Adresa bez povolené platby: „Pro Váš účet neevidujeme žádnou povolenou dopravu."Jádro SFX má kroky košíku, součet bez DPH a zobrazení varování z FrontAPI. B2B podobu skládá obálka SFX. Vzhled podle design systému ALBI, chování podle prototypu.
Prototyp ukazuje přepínač adresy v košíku a volbu kompletní zásilky. Platí zadání, prototyp se opraví.
| Krok B2B | Trasa jádra SFX | Co obálka změní |
|---|---|---|
| 1 Přehled košíku | /cart | Řádek položky s balením, cena bez DPH hlavní, bez slevového kódu, alert blokace. |
| 2 Dodací podmínky | /shipping-and-payment | Pod dopravu a platbu přidá adresy jen ke čtení a B2B pole. |
| 3 Souhrn objednávky | /shipping-address | Formulář adres (BasketOrderForm) nahradí souhrn: cost levely, přehled DPH, údaje firmy. Souhlas s podmínkami jako věta. |
| 4 Objednávka odeslána | /order-confirmation | Doplní ceny bez DPH, interní číslo a požadované datum. |
Názvy kroků ve stepperu jsou překladové klíče BASKET_STEPPER.steps.*. Kroky „Přehled košíku", „Dodací podmínky", „Souhrn objednávky", „Objednávka odeslána" jako dnes.
Čárkovaný rámeček = B2B prvek, který jádro SFX nemá.

Řádek: kód | cost level | EAN, sklad, „X ks v balení". Pole množství má krok = balení. Tlačítka přičtou 1 a 2 balení, popisek je počet kusů jako dnes. Hlavní cena je bez DPH. Pole pro slevový kód NENÍ. Při blokaci je nad položkami červený alert a „Pokračovat" je šedé.

Adresy NEJSOU formulář, jen text. Data z GET /api-users/users/{userId}/billing-address a aktivní doručovací adresy. Kalendář má rozsah od deliveryDate do maxDeliveryDate zvolené dopravy. „Pouze kompletní zásilka" NENÍ, stejně jako starý B2B.


Karta cost levelu: kód v kruhu (prázdný kód = „PP", „Produkty podpory"), název cost levelu, počet kusů, cena bez a s DPH. Data z costLevelSummary[] a vatSummary[]. Blok „K objednávce" zopakuje B2B pole z kroku 2. Seskupení a přehled DPH stejně jako starý B2B.
| Část | Stav | Poznámka |
|---|---|---|
| Kroky košíku, stepper, spodní navigace | převzít | BasketStepper, BasketStickyNavigationSimple. Texty kroků přes překlady. |
| Součet bez DPH | převzít | TOTAL_PRICE má řádek bez DPH zapnutý, ale jako doplňkový pod cenou s DPH. Obálka prohodí důraz. |
| Varování z FrontAPI jako toast | převzít | BasketCard-quantity chytí varování po změně počtu a přeloží klíčem WARNINGS.UPDATE_CART.{typ}. Doplnit klíč WARNING_CART_COUNT_ERROR_PIECES_IN_PACKAGE_B2B (proměnné currentValue, b2bDivisorValue, itemName). Bez něj se ukáže holý klíč. |
| Poznámka k objednávce | převzít | Jde do message. |
| Cena položky bez DPH | upravit | Mapper položky bere cenu z karty produktu, cenu položky bez DPH z DTO nečte. |
| Pole množství po baleních | upravit | Dnes min 0, max = sklad, bez kroku. Doplnit krok, minimum a maximum z košíku, tlačítka „+1" a „+2" balení. |
| Načtení košíku po změně počtu | upravit | Odpověď PUT SFX nečte, košík přenačte jen v chybové větvi. Po zaokrouhlení se musí přenačíst vždy. |
| Adresy jen ke čtení | nové | Formulář kroku 3 počítá s ručním vyplněním a nákupem bez registrace. B2B ho nepoužije. |
| B2B pole objednávky | nové | Typ vstupů objednávky ani payload je nemají. |
| Cost level, seskupení, přehled DPH | nové | Typy košíku a položky je nemají. |
| Blokace objednávky | nové | Alert v kroku 1, neaktivní „Pokračovat". Blok BasketAlerts je dnes prázdný. Dlužník: S04. |
Pořadí = závislosti. Bez bodu 1 nefunguje nic dalšího. Kde je víc cest, rozhodne programátor.
| Endpoint | Stav | Co se mění |
|---|---|---|
POST /api-orders/order | rozšířit | B2B větev bez výjimky, B2B pole, adresy ze serveru, nové chybové kódy. |
GET /api-carts/carts/{token} | rozšířit | Balení, maximum, cost level u položky. Aktivní adresa, přehled DPH, seskupení, stav objednatelnosti u košíku. |
PUT /api-carts/carts/{token} | rozšířit | Sjednotit varování o balení. D4 |
GET /api-transports/transports/{token} | rozšířit | K deliveryDate přidat maxDeliveryDate. |
PUT /api-carts/carts/{token}/discount-codes | rozšířit | Pro B2B chyba, nebo nezaregistrovat. D5 |
| Volba aktivní doručovací adresy | nový podle varianty | Varianta a) přidá endpoint, b) a c) ne. D1 |
GET /api-carts/carts/{token}/free-shipping | existuje | Lišta „Máte dopravu zdarma". Beze změny. |
GET /api-payments/payments/{token}/{transportId} | existuje | Platby. Filtr podle adresy dodá obálka. Beze změny. |
GET /api-users/users/{userId}/billing-address, …/delivery-addresses | existuje | Adresy ke čtení v kroku 2 a 3. Beze změny. |
GET /api-orders/order/{hash} | existuje | Potvrzení: customerOrderCode, požadované datum, priceToPay. Beze změny. |
BaseNBasket::getBasketBasketOrderData() pro B2B zákazníka se zapnutým FrontAPI vyhodí výjimku „FrontAPI is not yet implemented for B2B customer types." Objednávka spadne obecnou chybou serveru. Totéž každé vyprázdnění košíku.Bez aktivní adresy nefunguje ceník, katalog, dopravy ani platby. Jádro ji dnes nastaví při ověření tokenu na výchozí adresu. Podúčet má jedinou, hlavní účet dostane nejnovější a přepnout ji přes FrontAPI nejde. Varianty, rozhodne programátor: D1
PUT /api-carts/carts/{token}/delivery-address s { "addressId" }. Uloží adresu k DB košíku (sloupec existuje), všechny endpointy s tokenem z ní nastaví kontext.Vary cache.{
"deliveryAddressId": 812,
"isOrderAllowed": true,
"orderBlockReasons": [],
"cartItems": [
{ "productId": "4412", "code": "P-4412", "inCartCount": 12,
"piecesInPackage": 6, "maxOrderCount": 600, "costLevelCode": "K12" }
],
"vatSummary": [
{ "vatRate": 21, "priceWithoutVat": 4230.00, "priceWithVat": 5118.30 },
{ "vatRate": 12, "priceWithoutVat": 725.00, "priceWithVat": 812.00 }
],
"costLevelSummary": [
{ "code": "K12", "name": "Puzzle", "count": 12,
"priceWithoutVat": 1548.00, "priceWithVat": 1873.08 }
]
}
| Pole | Kde dnes | Význam |
|---|---|---|
piecesInPackage | jádro | Kusů v balení pro B2B. Také do karty produktu, ať ji SFX má i na detailu. |
maxOrderCount | jádro | Maximum na produkt, zarovnané dolů na balení. Také do karty produktu. |
costLevelCode | dnes obálka | Cost level produktu. Produkt má právě jeden. |
deliveryAddressId | jádro | Aktivní doručovací adresa košíku. |
vatSummary[] | dnes obálka | Součty po sazbách DPH. Hodnoty stejně jako starý B2B, tedy výpočet obálky jako AlbiLine. Jádrová tabulka DPH košíku se NEPOUŽIJE. |
costLevelSummary[] | dnes obálka | Kód, název, počet kusů, ceny bez a s DPH za cost level. Prázdný kód = „PP". |
isOrderAllowed, orderBlockReasons[] | jádro + dnes obálka | Hodnoty BAD_PAYER (S04), CUSTOMER_BLOCKED (neaktivní adresa, zákazník nebo uzel), NO_ALLOWED_PAYMENT, NO_DELIVERY_ADDRESS. Které důvody do jádra, rozhodne produkt PragueBest. D6 |
Rozšíření v jádře, nebo přepisem DTO v obálce: D3. Obálka albi.eu už podobně přepisuje DTO i služby FrontAPI.
{
"cartToken": "c3f1…",
"paymentId": 7,
"transport": { "id": 3 },
"message": "Prosíme dodat do 10:00.",
"customerOrderCode": "OBJ-2026-114",
"requestedDeliveryDate": "2026-10-14"
}
customerOrderCode (text, nepovinné) → interní číslo objednávky. Do AlbiLine jde jako CustomerReferenceCode, převod dnes v obálce funguje.requestedDeliveryDate (Y-m-d, nepovinné) → požadované datum. Validace v jádře už běží i pro FrontAPI, chybí jen vstup. Do AlbiLine jde jako DeliveryDate.onlyCompleteConsignment se NEPŘIDÁVÁ. Starý B2B volbu nenabízí a do AlbiLine ji neposílá.b2b: D2. Jádro.customer s adresami je pro B2B nepovinný a server ho ignoruje (bod 1).Dnes FrontAPI všechny chyby validace objednávky vrací jako ORDER_CUSTOMER_INVALID_ADDRESS. Chyba data dodání by tak přišla jako „neplatná adresa". Kódy a HTTP status rozhodne programátor, níže pracovní názvy.
| Kód | Stav | Kdy |
|---|---|---|
ORDER_CUSTOMER_BAD_PAYER | nový | Firma je dlužník. Detail S04. |
ORDER_CUSTOMER_BLOCKED | nový | Neaktivní adresa, zákazník nebo blokovaný uzel. |
ORDER_INVALID_REQUESTED_DELIVERY_DATE | nový | Datum není pracovní den nebo je mimo rozsah zvolené dopravy. |
ORDER_PAYMENT_NOT_AVAILABLE | existuje | Platba není na adrese povolená. |
ORDER_TRANSPORT_NOT_AVAILABLE | existuje | Doprava není pro adresu nebo skupinu povolená. |
maxDeliveryDate = konec rozsahu pro výběr požadovaného data. Jádro ho dnes počítá jako dnešek + 1 rok. Jádro.PUT košíku dnes vrací varování WARNING_CART_COUNT_ERROR_PIECES_IN_PACKAGE_B2B a počet zároveň zaokrouhlí. Varování se počítá z požadovaného počtu. Sjednotit. D4AlbiB2BPricesService převzít do nové obálky beze změny. Dnes obálka. D7Beze změny. Nic nového se nepřidává.
b2b_validate_basket_customer_data), nápověda „V případě, že je aktivní, je prováděna validace obsahu FA a DA v košíku." Dnes ji definuje stará obálka (albi-envelope-master/Local/Modules/Customers/config/config.module.php:45-50). Nová obálka ji převezme beze změny textu.MasterShop-front-api-php85/app/Modules/Orders/src/admin/orders/config.php:173-175). Hodnoty se ukládají do objednávky a jdou do AlbiLine. Zobrazení v administraci se NEMĚNÍ.D nebo H v AlbiLine zaokrouhlí na celé Kč. Dnes obálka.pieces_in_package_b2b).maxDeliveryDate. Obálka backendu: součty, cost level, seskupení, vypnutí slev, volitelná povinná pole. Obálka SFX: obrazovky.ORDER_CUSTOMER_BLOCKED.