VECTON Raktárkezelési Rendszer (WMS) — Műszaki Rendszerterv
Verzió: 4.2 Utolsó frissítés: 2026-03-19 Státusz: Tervezési fázis Backend:
tenant-backend-warehouse(Laravel) +tenant-backend-crm(cég/kapcsolat kezelés) Frontend:tenant-frontend(Vue 3 + Vuetify)
Tartalomjegyzék
- Jelenlegi állapot
- Rendszer alapelvek
- Raktár típusok
- Cég típusok és beszállítói kapcsolat (CRM integráció)
- Beszállítói katalógus (Supplier Catalog)
- Lokáció menedzsment és Layout Editor
- Készletkezelési modell
- Előrendelés és termék elérhetőség (Pre-orders)
- Rendelés-routing (Order Fulfillment Routing)
- Készletmozgások (Inventory Transactions)
- Áruátvétel (Receiving / Inbound)
- Komissiózás és rendelés-teljesítés (Picking & Fulfillment)
- Csomagolás és kiszállítás (Packing & Shipping)
- Dropshipping
- Beszerzés (Procurement)
- Visszáru kezelés (RMA)
- Leltározás (Inventory Audit / Cycle Count)
- Termék életút-követés (Traceability)
- Teljesítmény és gyorsítótár
- Címke generálás (Label Generator)
- Integrációk
- Adatbázis séma
- API végpontok
- Megvalósítási fázisok
1. Jelenlegi állapot
Ami már kész van (production-ready)
| Modul | Backend | Web Frontend |
|---|---|---|
| Warehouse CRUD | ✅ | ✅ |
| Layout Editor (gráf-alapú) | ✅ (verziózás, SVG) | ✅ (SVG editor) |
| Route Planning (TSP) | ✅ (single + multi-warehouse) | ✅ (vizualizáció) |
| Label Generation (QR) | ✅ (PDF, thermal, sticker) | ✅ (preview + letöltés) |
| Product Model | ✅ DB séma (webshop backend) | — |
| CRM Cégek (Companies) | ✅ CRUD + címek + kontaktok | ✅ |
Ami hiányzik (a WMS mag)
- Cég típusok — beszállító/vevő/mindkettő megkülönböztetés a CRM-ben
- Raktár típusok — fizikai, virtuális (beszállítói), dropship
- Beszállítói katalógus — melyik beszállítónál melyik termék elérhető, milyen áron, prioritással
- Order routing — honnan teljesítsük a rendelést (saját raktár / beszállítói rendelés / dropship)
- Összevárás és batch rendelés — rendelések gyűjtése, majd napi/időszakos PO generálás beszállítóknak
- Beszállítói export PDF — összesített megrendelés PDF a nagykernek
- Dropshipping — beszállító közvetlenül a vevőhöz szállít
- Előrendelés — termékek elérhetővé tétele jövőbeli dátumra (beszerzési ETA alapján)
- Virtuális készlet küszöbök — biztonsági tartalék beszállítói készleten is
- Inventory management — készlet nyilvántartás, készletmozgások
- Location hierarchy — SHELF-ROW-SPACE-BOX
- Layout Editor → Lokáció — a layout editor = lokáció kezelő
- Áruátvétel, Komissiózás, Csomagolás, Beszerzés, RMA, Leltár
- Label Generator átdolgozás — csak regisztrált lokációkra
2. Rendszer alapelvek
2.1. Fizikai vs. logikai készlet szétválasztás
A rendszer alapja a fizikai valóság (mi van ténylegesen a polcon) és a logikai állapot (mi van lefoglalva, zárolt, stb.) szigorú elkülönítése. A fizikai készlet soha nem mehet mínuszba. A virtuális (úton lévő, vagy beszállítónál lévő) készlet igen.
2.2. Eseményvezérelt architektúra
Minden készletmozgás egy InventoryTransaction rekord, ami immutable. Az inventory_summary tábla csak gyorsítótár — bármikor újraépíthető a tranzakciókból.
2.3. Atomi műveletek
Készletmozgások adatbázis-tranzakcióban futnak. Nincs félig végrehajtott mozgás.
2.4. Tenant izoláció
Minden tenant külön service-ként fut külön adatbázissal. Nincs tenant_id a táblákban.
2.5. Layout Editor = Lokáció kezelő
A layout editor és a lokáció rendszer egy és ugyanaz. A layout editor közvetlenül a locations táblát kezeli. API-n keresztül is lehet lokációt létrehozni.
2.6. Pontos helykövető rendszer
Minden fizikai hely regisztrált lokáció. Nincs ad-hoc hely, nincs szabad szöveges lokáció kód. A QR címke generátor kizárólag regisztrált lokációkra dolgozik.
2.7. Multi-forrás teljesítés
Egy rendelés tételei különböző forrásokból teljesíthetők:
- Saját fizikai raktár → normál pick/pack/ship
- Beszállítói rendelés (virtuális raktár) → PO → áruátvétel → ship, VAGY összevárás
- Dropship → PO a beszállítónak a vevő címével
A rendszer automatikusan vagy manuálisan dönti el a forrást a rendelés-routing szabályok alapján.
2.8. CRM = Cég/Partner nyilvántartás
A beszállítók, vevők, partnerek nem külön táblában vannak, hanem a CRM companies táblát bővítjük típusokkal. Egy cég lehet egyszerre beszállító ÉS vevő (kétirányú kapcsolat).
3. Raktár típusok
3.1. Áttekintés
| Típus | Kód | Fizikai lokációk | Layout Editor | Készlet | Leírás |
|---|---|---|---|---|---|
| Fizikai | physical | ✅ SHELF/ROW/SPACE/BOX | ✅ | Valós polcon | Saját raktár, minden WMS funkció elérhető |
| Virtuális | virtual | ❌ nincs | ❌ | Beszállítónál lévő logikai készlet | Nagykereskedő/beszállító raktára, amit mi nem kezelünk fizikailag |
| Dropship | dropship | ❌ nincs | ❌ | Beszállítónál, közvetlen kiszállítás | Beszállító közvetlenül a vevőnek szállít |
A warehouses.type mező határozza meg a típust. Egy rendszerben bármennyi raktár lehet, bármilyen kombinációban.
3.2. Fizikai raktár (physical)
A jelenlegi raktár koncepció. Teljes WMS funkcionalitás:
- Layout editor / lokáció kezelés
- Készlet nyilvántartás fizikai lokációkon
- Áruátvétel, komissiózás, csomagolás, szállítás
- Route planning, label generation
- Leltározás
- Biztonsági tartalék (safety stock)
3.3. Virtuális raktár (virtual)
Egy beszállító/nagyker készletét reprezentálja logikailag. Nincs fizikai lokáció, nincs layout.
Mire jó:
- A webshopban megjelenik a termék mint "elérhető" (a beszállítónál van)
- Rendelés beérkezésekor a rendszer tudja, hogy innen kell rendelni
- Az összevárási logika erre az "elérhető" készletre épül
Készletkezelés virtuális raktárban:
- Nincs
locationstábla kapcsolat - Az
inventory_summarytáblawarehouse_id-je mutat a virtuális raktárra - A készlet szint karbantartása:
- Manuális: admin frissíti a beszállítói készletet (pl. kapott egy Excel-t)
- API: beszállító API-n keresztül szinkronizálja (ha van ilyen)
- Import: CSV/Excel import a beszállítói árlista alapján
- A virtuális készlet a webshop felé
available-ként jelenhet meg (konfig alapján)
Virtuális raktár biztonsági küszöb (min_sellable_stock):
A virtuális raktárban is van biztonsági küszöb logika — ha a beszállítónál a készlet egy adott szint alá esik, nem értékesítjük tovább:
Példa:
- Widget X beszállítói készlet: 50 db
- min_sellable_stock (supplier_products-on): 5 db
- Effektíven értékesíthető: 50 - 5 = 45 db
Ha a készlet leesik 3-ra:
- 3 < min_sellable_stock (5)
- Webshop felé: 0 db elérhető (nem listázzuk!)
Miért kell ez? A beszállítói készlet "ígéret" — gyorsan fogyhat, és ha a beszállítónál már alig van, nagy az esélye, hogy mire megrendeljük, elfogyott. A küszöb véd az overselling ellen.
Fontos: A virtuális raktárban a készlet "ígéret" — a beszállító azt mondja van, de nem mi ellenőrizzük. Ezért a foglalás és teljesítés logikája más mint a fizikainál.
3.4. Dropship raktár (dropship)
Speciális virtuális raktár, ahol a beszállító közvetlenül a vevőhöz szállít.
- Nincs fizikai készlet nálunk, nincs lokáció
- Rendeléskor PO jön létre a beszállítónak a vevő szállítási címével
- A csomagolás és szállítás a beszállító dolga
- Mi csak a tracking számot és a státuszt követjük
- Profit = eladási ár - beszállítói ár (- egyéb költségek)
Részletek a 14. Dropshipping fejezetben.
3.5. Raktár-beszállító kapcsolat
Minden virtuális és dropship raktár pontosan egy CRM céghez (beszállítóhoz) tartozik:
warehouses.company_id → companies.id (NULL fizikai raktárnál)
A companies táblán a types jelzi, hogy az adott cég beszállító-e (lásd 4. fejezet).
Egy beszállító cégnek lehet:
- Egy virtuális raktára (a készletük)
- Egy dropship raktára (amit dropshippelnek)
- Vagy mindkettő
4. Cég típusok és beszállítói kapcsolat (CRM integráció)
4.1. Jelenlegi állapot (CRM companies)
A CRM-ben már létezik a companies tábla:
- name, tax_number, registration_number, industry, phone, email, website
company_addresses(billing, shipping, hq, branch, other)contacts(személyek a céghez rendelve)communication_logs(email, hívás, meeting, stb.)- Status:
active,inactive,prospect
Ami hiányzik: Nincs cég típus → nem tudjuk megmondani, ki a beszállító és ki a vevő.
4.2. Cég típusok (Company Types)
Egy cégnek több típusa is lehet egyszerre (pl. egy cég egyszerre beszállító ÉS vevő):
| Típus | Kód | Leírás |
|---|---|---|
| Vevő | customer | Tőlünk vásárol |
| Beszállító | supplier | Tőle vásárolunk |
| Gyártó | manufacturer | Terméket gyárt (lehet egyben beszállító is) |
| Szállítmányozó | carrier | Futárszolgálat / szállítmányozó |
| Partner | partner | Egyéb üzleti partner |
Megvalósítás: company_types pivot tábla (many-to-many), mert egy cég több típusú is lehet, és a típusok nem zárják ki egymást.
companies ←→ company_types (pivot) → type: 'customer' | 'supplier' | 'manufacturer' | 'carrier' | 'partner'
Nem kell előre megadni — amikor valaki először rendel tőlünk, automatikusan customer, amikor mi rendelünk tőle, automatikusan supplier. De manuálisan is beállítható.
4.3. Beszállítói bővítmény (Supplier Extension)
Ha egy cégnek van supplier típusa, a warehouse backend-ben kiegészítő adatokat tárolunk róla:
company_supplier_details: beszállító-specifikus adatok a CRM cégen túl
| Mező | Leírás |
|---|---|
company_id | FK → CRM companies |
code | Rövid belső azonosító (pl. "TECHDATA", "OMEGA") |
currency_code | Alapértelmezett pénznem |
payment_terms_days | Fizetési határidő (nap) |
lead_time_days | Alapértelmezett szállítási idő (nap) |
procurement_type | DOMESTIC / EU_COMMUNITY / THIRD_COUNTRY |
order_email | Email cím ahova a rendelési PDF-et küldjük |
order_method | Rendelés módja: email / api / portal / manual |
min_order_value | Minimum rendelési érték (ha van) |
eu_vat_number | EU VAT szám (közösségi beszerzésnél) |
Miért külön tábla? A CRM companies tábla a CRM backenben van, a warehouse-specifikus beszállítói adatokat a warehouse backendben tároljuk. A company_id cross-service FK (UUID).
4.4. Vevői bővítmény (Customer Extension) — későbbi fázis
Hasonlóan, ha a webshop-ban szükséges vevő-specifikus beállítás (kedvezmény, fizetési feltételek, hitelkeret), az a webshop backendben lesz company_customer_details táblaként. Ez nem része a WMS tervnek.
4.5. CRM felületen
A cég szerkesztő oldalon új szekció: Típusok — checkbox-ok a típusokhoz. Ha supplier be van pipálva, megjelenik egy "Beszállítói beállítások" panel a warehouse-specifikus mezőkkel.
5. Beszállítói katalógus (Supplier Catalog)
5.1. Termék-Beszállító kapcsolat (Supplier Products)
Egy terméknek több beszállítója lehet, mindegyiknek saját ára, MOQ-ja, cikkszáma, prioritása.
supplier_products: melyik beszállítónál melyik termék elérhető
| Mező | Leírás |
|---|---|
company_id | FK → CRM companies (beszállító cég) |
product_id | FK → products |
variant_id | FK → product_variants (nullable) |
supplier_sku | A beszállító saját cikkszáma (ami az ő rendszerében van) |
unit_price | Beszerzési egységár |
currency_code | Pénznem |
moq | Minimum Order Quantity (min. rendelési mennyiség) |
order_unit | Rendelési egység (pl. 1 = darab, 10 = csomag, 100 = karton) |
lead_time_days | Szállítási idő (felülírja a supplier szintű default-ot) |
priority | Prioritási sorrend (1 = elsődleges, 2 = másodlagos, stb.) |
is_dropship_eligible | Ez a beszállító tud dropshippelni ezzel a termékkel |
supplier_stock_qty | Beszállítónál elérhető mennyiség (utolsó frissítés szerint) |
min_sellable_stock | Minimális beszállítói készlet amitől még értékesítjük (alatta: 0 elérhető) |
stock_updated_at | Mikor frissült utoljára a beszállítói készlet |
is_active | Aktív-e ez a termék-beszállító kapcsolat |
notes | Megjegyzés |
5.2. Prioritásos beszállító kiválasztás
Minden termékhez rendezett prioritási lánc tartozik a beszállítók között:
Beszállító kiválasztási algoritmus (termékenként):
1. Lekérjük a termék aktív beszállítóit, rendezve priority ASC (1 = legelső)
2. FOREACH beszállító a prioritási sorrendben:
a. Van-e elég beszállítói készlet?
- Ha supplier_stock_qty IS NOT NULL:
- Effektív elérhető = supplier_stock_qty - min_sellable_stock
- Ha effektív elérhető < igényelt qty → SKIP, következő beszállító
- Ha supplier_stock_qty IS NULL: → nem ismert, feltételezzük van
b. Lead time elfogadható? (sürgős rendelésnél szűrés)
c. → KIVÁLASZTVA: ez a beszállító teljesíti
3. Ha egyetlen beszállítónál sincs elég:
a. Részleges teljesítés: több beszállítótól szét bontva
b. VAGY: BACKORDER (nincs elérhető forrás)
Admin mindig manuálisan felülírhatja a beszállító kiválasztást a PO létrehozásakor.
5.3. Beszállítói készlet küszöb — részletes logika
A min_sellable_stock mező a supplier_products táblán határozza meg, mekkora készlet alatt nem értékesítjük a beszállítói terméket:
Webshop felé mutatott elérhető készlet (per beszállítói termék):
IF supplier_stock_qty IS NULL:
→ Elérhető = ∞ (nem tudjuk, feltételezzük van)
IF supplier_stock_qty <= min_sellable_stock:
→ Elérhető = 0 (NEM ÉRTÉKESÍTJÜK, nem jelenik meg)
ELSE:
→ Elérhető = supplier_stock_qty - min_sellable_stock
Példák:
| Beszállítói készlet | min_sellable_stock | Effektíven elérhető | Webshop megjelenés |
|---|---|---|---|
| 50 | 5 | 45 | "45 db elérhető" |
| 5 | 5 | 0 | Nem jelenik meg |
| 3 | 5 | 0 | Nem jelenik meg |
| NULL | 5 | ∞ | "Elérhető" (mennyiség nélkül) |
| 100 | 0 | 100 | "100 db elérhető" |
5.4. Beszállítói árlista import
Beszállítók rendszeresen küldenek frissített árlistát (CSV, Excel, API).
Import flow:
1. Admin feltölti az árlistát (CSV/Excel) vagy API-ból jön
2. Rendszer match-eli a supplier_sku alapján a meglévő supplier_products-hoz
3. Frissíti: unit_price, supplier_stock_qty, stock_updated_at
4. Új tételek → supplier_products rekord létrehozás (manuális jóváhagyás után)
5. Törölt tételek → is_active = false (de a rekord megmarad)
6. Lokáció menedzsment és Layout Editor
Csak fizikai raktárakra (
physical) vonatkozik. Virtuális és dropship raktáraknak nincs lokációja.
6.1. Hierarchia: 4 szint
SHELF (salgó/állvány)
└── ROW (sor/polc)
└── SPACE (hely)
└── BOX (doboz)
- SHELF: Egy fizikai állvány/salgó egység. Ez a legmagasabb szint.
- ROW: Az állvány egy sora (polca). Egy shelf-en belül függőlegesen egymás felett.
- SPACE: Egy hely a soron belül. Vízszintesen egymás mellett.
- BOX: Egy doboz/rekesz a helyen belül. A legkisebb egység.
6.2. Helykód formátum
VECTON-{WAREHOUSE_CODE}-{SHELF}-{ROW}-{SPACE}-{BOX}
Példák:
| Kód | Jelentés |
|---|---|
VECTON-W1-A-3-2-01 | W1 raktár, A salgó, 3. sor, 2. hely, 01 doboz |
VECTON-W1-B-1-4-0 | W1 raktár, B salgó, 1. sor, 4. hely, nincs doboz |
VECTON-W1-RECEIVING-1-0-0 | W1 raktár, RECEIVING terület |
VECTON-W1-SHIPPING-1-0-0 | W1 raktár, SHIPPING terület |
VECTON-W1-RMA-1-0-0 | W1 raktár, RMA karantén |
VECTON-W1-SCRAP-1-0-0 | W1 raktár, selejt terület |
Szabályok:
- SHELF szint: string (betű vagy speciális név:
A,B,RECEIVING,SHIPPING,RMA,SCRAP) - ROW, SPACE, BOX: számok (0 = nincs ilyen albontás)
6.3. Layout Editor = Lokáció CRUD
A layout editor közvetlenül a locations táblát kezeli. Két nézet:
Felülnézet (Top-down floor plan)
- Node hozzáadása =
locationsrekord létrehozás (SHELF szint) - Node törlése = deaktiválás (ha üres) vagy TILTOTT (ha van készlet)
- Node mozgatása = x, y frissítés
- Link hozzáadása/törlése =
location_linksrekord
Elölnézet (Rack Detail View)
SHELF node-ra kattintva frontális 2D előnézet:
┌─────────────────────────────────────────────────────┐
│ VECTON-W1-A állvány │
│ Típus: Salgó │ Max terhelés: 2000 kg │
├─────────────────────────────────────────────────────┤
│ ┌────────┬────────┬────────┬────────┐ ← 4. sor │
│ │ A-4-1 │ A-4-2 │ A-4-3 │ A-4-4 │ h: 30cm │
│ │ ░░░░░░ │ │ ░░▓▓░░ │ ░░░░░░ │ max: 50kg│
│ │ 12 db │ üres │ 4 db │ 8 db │ │
│ └────────┴────────┴────────┴────────┘ │
│ ┌────────┬────────┬────────┬────────┐ ← 3. sor │
│ │ A-3-1 │ A-3-2 │ A-3-3 │ A-3-4 │ h: 40cm │
│ │ ▓▓▓▓▓▓ │ ▓▓▓▓▓▓ │ ░░░░░░ │ │ max: 80kg│
│ │ 24 db │ 30 db │ 6 db │ üres │ │
│ └────────┴────────┴────────┴────────┘ │
│ ┌────────┬────────┬────────┬────────┐ ← 2. sor │
│ │ A-2-1 │ A-2-2 │ A-2-3 │ A-2-4 │ h: 50cm │
│ │ ▓▓▓▓▓▓ │ ▓▓▓▓▓▓ │ ▓▓▓▓▓▓ │ ▓▓▓▓▓▓ │ max:120kg│
│ │ TELE │ TELE │ TELE │ 45 db │ │
│ └────────┴────────┴────────┴────────┘ │
│ ┌────────┬────────┬────────┬────────┐ ← 1. sor │
│ │ A-1-1 │ A-1-2 │ A-1-3 │ A-1-4 │ h: 60cm │
│ │ ▓▓▓▓▓▓ │ ░░▓▓▓▓ │ ▓▓▓▓▓▓ │ ▓▓▓▓▓▓ │ max:200kg│
│ │ TELE │ 15 db │ TELE │ TELE │ │
│ └────────┴────────┴────────┴────────┘ │
│ ══════════════════════════════════════ ← padló │
│ │
│ Összesen: 16 hely │ 12 foglalt │ 3 üres │ 1 tele │
│ Telítettség: 78% │ Súly: 1420/2000 kg │
└─────────────────────────────────────────────────────┘
Méretarányos a height_cm, width_cm alapján. Szín-kódolt telítettség (üres=fehér, részben=zöld, tele=narancs, túl=piros, zárolt=szürke, foglalt=kék csík). Kattintható helyek, drag & drop áthelyezés.
Shelf Properties panel
┌─────────────────────────────────┐
│ Shelf Properties │
├─────────────────────────────────┤
│ Kód: [A] │
│ Név: [A salgó] (opcionális)│
│ Max összterhelés: [2000] kg │
│ │
│ ── Sorok ── │
│ │ # │ Mag.(cm) │ Szél.(cm) │ Mély.(cm) │ Teher(kg) │ Helyek │
│ │ 4 │ [30] │ [120] │ [60] │ [50] │ [4] │
│ │ 3 │ [40] │ [120] │ [60] │ [80] │ [4] │
│ │ 2 │ [50] │ [120] │ [60] │ [120] │ [4] │
│ │ 1 │ [60] │ [120] │ [60] │ [200] │ [4] │
│ │
│ [+ Sor hozzáadása] │
│ [Elölnézet] [Címke generálás] │
└─────────────────────────────────┘
6.4. Lokáció törlés védelem
| Művelet | Szabály | Hibaüzenet |
|---|---|---|
| Shelf törlés | Minden gyerek üres | "Nem törölhető: {qty} db készlet van az állványon" |
| Row törlés | Minden space/box üres | "Nem törölhető: {qty} db készlet van a soron" |
| Space/Box törlés | SUM(qty) > 0 → TILTOTT | "Nem törölhető: {qty} db készlet van a helyen" |
| Warehouse törlés | Minden location üres és inaktív | "A raktárban még van készlet" |
Törlés = deaktiválás (is_active = false). Lokáció rekord soha nem törlődik fizikailag.
6.5. Layout verziózás
A warehouse_layouts tábla snapshot-okat tárol (locations + links JSON dump). Restore = snapshot visszaállítás.
7. Készletkezelési modell
7.1. Készlet állapotok
┌─────────────────────────────────────────────────────────┐
│ PHYSICAL (fizikai raktárban van) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│ │ AVAILABLE│ │ RESERVED │ │ BLOCKED │ │ BUFFER │ │
│ │ (szabad) │ │(foglalt) │ │ (zárolt) │ │(tartalék)│ │
│ └──────────┘ └──────────┘ └──────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ SUPPLIER_STOCK (beszállítónál van) │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ AVAILABLE │ │ RESERVED │ ← virtuális raktár │
│ │ (rendelhető) │ │ (PO-hoz kötve)│ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────┐
│ IN_TRANSIT (úton) │ ← beszállítótól felénk, vagy dropship esetén a vevőhöz
└─────────────────────┘
┌─────────────────────┐
│ UNDER_INVESTIGATION │ ← leltárhiány vizsgálat alatt
└─────────────────────┘
┌─────────────────────┐
│ SCRAPPED (selejtezett)│
└─────────────────────┘
7.2. Elérhető készlet számítás
Fizikai raktár:
Available = Physical - Reserved - Blocked - Buffer
Virtuális raktár (beszállítói készlet):
Effektív = MAX(0, supplier_stock_qty - min_sellable_stock)
Available = Effektív - Reserved_for_pending_POs
⚠ Ha supplier_stock_qty <= min_sellable_stock → Available = 0
Összesített elérhető (webshop felé):
Total_Available = SUM(fizikai) + SUM(virtuális * include_virtual_policy) + SUM(in_transit * include_transit_policy)
7.3. Biztonsági tartalék (Safety Stock)
Fizikai raktár: stock_purpose = BUFFER_SAFETY → ezek a darabok nem elérhetők eladásra, csak tartalék.
Virtuális raktár: min_sellable_stock a supplier_products táblán → a beszállítónál ennyi darab kell maradjon (nem rendeljük meg). Ha a valós készlet ez alá esik, az egész termék elérhetetlenné válik erről a beszállítóról.
7.4. Készlet struktúra
| Mező | Leírás |
|---|---|
product_id | Termék FK |
variant_id | Termékvariáns FK (nullable) |
location_id | Lokáció FK (NULL virtuális raktárnál) |
warehouse_id | Raktár FK (mindig kitöltve — fizikai ÉS virtuálisnál is) |
qty | Mennyiség |
status | AVAILABLE / RESERVED / BLOCKED / UNDER_INVESTIGATION / SCRAPPED |
stock_purpose | SELLABLE / BUFFER_RMA / BUFFER_SAFETY |
serial_number | Egyedi azonosító |
batch_lot_number | Sarzs szám |
expiry_date | Lejárat (FEFO) |
received_at | Bevételezés dátuma (FIFO) |
unit_cost | Egységár |
procurement_item_id | FK → procurement_items.id |
8. Előrendelés és termék elérhetőség (Pre-orders)
8.1. A probléma
Egy termék még nem elérhető, de tudjuk, hogy egy jövőbeli dátumtól lesz — mert van egy futó beszerzés (PO) ami várhatóan akkor érkezik meg.
Példák:
- Könyv megjelenik 2026-05-01-én → előrendelhető
- Beszállítótól 100 db Widget várható 2026-04-15-re → előrendelhető
- Új termék launch: 2026-06-01-ig nincs készleten
8.2. Termék elérhetőségi dátum (Product Availability)
A product_availability tábla határozza meg, mikortól rendelhető/értékesíthető egy termék:
product_availability: termékenként vagy variánsonként mikor lesz elérhető
| Mező | Leírás |
|---|---|
product_id | FK → products |
variant_id | FK → product_variants (nullable) |
available_from | Mikortól elérhető / megrendelhető |
available_until | Meddig elérhető (nullable — ha van end-of-life) |
pre_order_enabled | Előrendelés engedélyezve? (true = megvásárolható a dátum előtt is) |
pre_order_limit | Max előrendelhető mennyiség (nullable = korlátlan) |
expected_qty | Várható mennyiség (ha ismert) |
source_type | Honnan várjuk: PROCUREMENT / PRODUCTION / MANUAL |
source_id | FK → procurements.id (ha PROCUREMENT) |
notes | Megjegyzés (pl. "Könyv megjelenés", "Szezontermék") |
8.3. Előrendelés flow
Előrendelés lifecycle:
1. Admin létrehozza a termék elérhetőséget:
- Manuálisan: available_from = 2026-05-01, pre_order_enabled = true
- VAGY automatikusan: PO létrehozásakor, ha a terméknek nincs még készlete:
→ product_availability auto-létrehozás:
available_from = procurement.expected_delivery_at
source_type = PROCUREMENT
source_id = procurement.id
2. Webshop megjelenés:
IF now() < available_from AND pre_order_enabled:
→ "Előrendelhető — Várható szállítás: 2026-05-01"
→ Kosárba tehető, de rendelés státusza: PRE_ORDER
IF now() >= available_from AND van készlet:
→ Normál "Elérhető" megjelenés
IF now() >= available_from AND nincs készlet:
→ Normál elfogyott logika
3. Előrendelés beérkezik:
- Rendelés létrejön, fulfillment source = AWAITING_STOCK
- A tétel a procurement_queue-ba kerül (ha nincs még PO)
VAGY a meglévő PO-hoz kötődik (source_id)
4. PO megérkezik (áruátvétel):
- Normál RECEIVE flow
- Rendszer automatikusan kiosztja az előrendelt tételekhez:
→ RESERVE → PICKING → normál flow
- Kiosztás sorrendje: rendelés dátuma (FIFO az előrendelések között)
5. Ha a PO késik:
- expected_delivery_at módosul → available_from is frissül
- Érintett előrendelők értesítést kapnak (email/push)
8.4. PO → Elérhetőség automatikus kapcsolat
Amikor egy beszerzés (PO) létrejön olyan termékre, aminek nincs jelenlegi készlete:
PO létrehozás:
- Ha a terméknek NINCS aktív product_availability rekordja:
→ Automatikusan létrehozunk egyet:
available_from = procurement.expected_delivery_at
pre_order_enabled = konfig (procurement.auto_enable_preorder)
source_type = PROCUREMENT
source_id = procurement.id
expected_qty = SUM(procurement_items.qty_ordered WHERE product_id = X)
- Ha VAN aktív product_availability:
→ Frissítjük az expected_qty-t és available_from-ot ha a PO-nak korábbi ETA-ja van
8.5. Előrendelés korlátozás
Az előrendelhető mennyiséget a rendszer korlátozhatja:
Maximális előrendelhető mennyiség:
= product_availability.pre_order_limit -- ha manuálisan beállítva
VAGY = product_availability.expected_qty -- ha PO alapján auto
- SUM(már leadott előrendelések qty) -- mínusz eddig előrendelt
Ha 0 vagy negatív → "Előrendelés betelt"
Ha NULL → korlátlan előrendelés (kockázatosabb, admin dönti el)
8.6. Rendelés állapotok előrendelés esetén
Normál rendelés: PENDING → CONFIRMED → PICKING → SHIPPED → DELIVERED
Előrendelés: PENDING → PRE_ORDER → [PO megérkezik] → CONFIRMED → PICKING → SHIPPED → DELIVERED
↓
Ha PO késik → DELAYED_PRE_ORDER → ügyfél értesítés
9. Rendelés-routing (Order Fulfillment Routing)
9.1. A probléma
Egy beérkező rendelés tételeit különböző forrásokból kell teljesíteni:
- Termék A → saját fizikai raktárban van → pick/pack/ship
- Termék B → nincs saját készleten, de a beszállítónál van → PO létrehozás, összevárás, majd áruátvétel+ship
- Termék C → dropship termék → PO a beszállítónak a vevő címével
- Termék D → nem elérhető, de lesz 2 hét múlva → előrendelés, backorder
9.2. Fulfillment Source meghatározás — Prioritási lánc
Minden rendelési tételhez a rendszer a következő prioritási láncot futtatja végig:
Order Item routing algorithm:
1. Van-e AVAILABLE készlet saját fizikai raktárban?
→ IGEN: source = PHYSICAL, warehouse_id = fizikai raktár
→ NEM: tovább
2. Van-e a terméknek aktív product_availability (pre_order)?
ÉS now() < available_from ÉS pre_order_enabled = true?
→ IGEN: source = PRE_ORDER, available_from = dátum
→ NEM: tovább
3. Van-e a terméknek virtuális raktárban ELÉRHETŐ készlete?
(supplier_stock_qty - min_sellable_stock > igényelt qty)
→ IGEN: beszállító kiválasztás prioritás alapján (5.2. fejezet)
a. Van-e dropship opció (is_dropship_eligible = true ÉS rendelés engedi)?
→ IGEN: source = DROPSHIP, company_id = dropship beszállító
b. Nincs dropship / nem engedi:
→ source = SUPPLIER_ORDER, company_id = legjobb prioritású beszállító
→ NEM: tovább
4. Nincs semmilyen forrás:
→ source = BACKORDER (nincs sehol készlet, nincs ETA)
→ Admin értesítés: "Nincs elérhető forrás"
Admin manuálisan felülírhatja a routing-ot tétel szinten.
9.3. Fulfillment típusok
| Típus | Kód | Leírás | Fizikai mozgás |
|---|---|---|---|
| Saját raktár | PHYSICAL | Normál pick/pack/ship | Polcról szedés → csomagolás → szállítás |
| Beszállítói rendelés | SUPPLIER_ORDER | PO → áruátvétel → ship | Beszállító → mi → vevő |
| Dropship | DROPSHIP | PO a vevő címével | Beszállító → vevő (mi nem nyúlunk hozzá) |
| Előrendelés | PRE_ORDER | Várunk a készletre (PO ETA ismert) | PO megérkezés → normál flow |
| Backorder | BACKORDER | Nincs készlet sehol, nincs ETA | Várakozás → értesítés amikor lesz |
9.4. Összevárás (Batch Procurement / Order Batching)
Ha egy rendelési tétel SUPPLIER_ORDER forrású, a rendszer nem azonnal rendel a beszállítótól, hanem összevárja a rendeléseket:
Összevárás logika:
1. Rendelés beérkezik → tétel source = SUPPLIER_ORDER
2. Tétel bekerül a "procurement_queue"-ba (pending beszerzési sor)
3. Az ütemező (konfig alapján) rendszeresen generál PO-t:
- Ütemezés típusok:
a. DAILY: naponta egyszer (pl. 14:00-kor)
b. INTERVAL: X óránként
c. THRESHOLD: ha az összegyűlt tételek értéke eléri a minimum rendelési értéket
d. MANUAL: admin manuálisan indítja
4. PO generálás:
- Csoportosítás beszállítónként
- Összesítés: 3 rendelésben 5+3+5 db "Widget X" = 13 db a PO-n
- MOQ ellenőrzés (ha kevesebb mint MOQ → kitöltés MOQ-ra, vagy várakozás)
- Min. rendelési érték ellenőrzés
5. PO jóváhagyás (manuális vagy automatikus)
6. Beszállítói export PDF generálás és küldés
9.5. Beszállítói export PDF
A PO-ból generált PDF, amit a beszállítónak küldünk (email-ben vagy letölthető):
┌─────────────────────────────────────────────────┐
│ VECTON – Megrendelés │
│ │
│ PO szám: PO-2026-0342 │
│ Dátum: 2026-03-19 │
│ Beszállító: TechData Hungary Kft. │
│ │
│ ┌────┬──────────────┬────────┬──────┬──────────┐│
│ │ # │ Cikkszám │ Termék │ Menny│ Egységár ││
│ ├────┼──────────────┼────────┼──────┼──────────┤│
│ │ 1 │ TD-WDG-001 │ Widget │ 13 db│ 2.450 Ft ││
│ │ 2 │ TD-GAD-055 │ Gadget │ 7 db │ 8.900 Ft ││
│ │ 3 │ TD-SPR-012 │ Spring │ 25 db│ 340 Ft ││
│ ├────┼──────────────┼────────┼──────┼──────────┤│
│ │ │ │ Összesen│ │95.850 Ft ││
│ └────┴──────────────┴────────┴──────┴──────────┘│
│ │
│ Szállítási cím: [saját raktár címe] │
│ Fizetési mód: átutalás, 30 nap │
│ Megjegyzés: Kérjük a TD-WDG-001 tételt külön │
│ csomagolni. │
│ │
│ Megrendelő: VECTON Kft. │
│ Aláírás: ________________________ │
└─────────────────────────────────────────────────┘
A PDF-en a beszállító saját cikkszáma (supplier_sku) jelenik meg, nem a mi belső SKU-nk.
9.6. Rendelés-tétel állapotok (order items fulfillment lifecycle)
PENDING_ROUTING → ROUTED → AWAITING_PROCUREMENT → PO_CREATED → IN_TRANSIT → RECEIVED → PICKING → SHIPPED
│ │
│ └── (összevárás alatt)
│
├── PHYSICAL: → PICKING → SHIPPED
├── DROPSHIP: → PO_CREATED → IN_TRANSIT → DELIVERED
├── PRE_ORDER: → AWAITING_STOCK → [PO arrives] → PICKING → SHIPPED
└── BACKORDER: → várakozás → újra routing amikor készlet lesz
10. Készletmozgások (Inventory Transactions)
10.1. Tranzakció típusok
| Típus | Leírás | Forrás → Cél |
|---|---|---|
RECEIVE | Áruátvétel (PO-ból) | — → fizikai lokáció |
PUTAWAY | Betárolás | RECEIVING → STORAGE |
PICK | Komissiózás | STORAGE → SHIPPING/PACK |
PACK | Csomagolás | PICK → csomag |
SHIP | Kiszállítás | SHIPPING → — |
MOVE | Áthelyezés | lokáció A → lokáció B |
ADJUST_UP | Korrekció felfelé | — → lokáció |
ADJUST_DOWN | Korrekció lefelé | lokáció → — |
RESERVE | Foglalás | állapotváltás |
UNRESERVE | Foglalás feloldás | állapotváltás |
BLOCK | Zárolás | állapotváltás |
UNBLOCK | Feloldás | állapotváltás |
RMA_RECEIVE | Visszáru beérkezés | — → RMA lokáció |
RMA_RESTOCK | Visszáru visszapolcozás | RMA → STORAGE |
SCRAP | Selejtezés | lokáció → SCRAP |
CROSS_DOCK | Átrakó | RECEIVING → SHIPPING |
TRANSFER | Raktárközi transzfer | W1 → W2 |
VIRTUAL_RESERVE | Virtuális készlet foglalás | virtuális raktár állapotváltás |
VIRTUAL_RELEASE | Virtuális foglalás feloldás | virtuális raktár állapotváltás |
DROPSHIP_ORDER | Dropship rendelés a beszállítónak | virtuális → in_transit |
DROPSHIP_DELIVER | Dropship kiszállítva a vevőnek | in_transit → — |
PRE_ORDER_RESERVE | Előrendelés foglalás (jövőbeli készletre) | logikai foglalás |
PRE_ORDER_FULFILL | Előrendelés teljesítés (PO megérkezett) | → normál RESERVE |
10.2. Immutable Audit Log
Minden tranzakció egy inventory_transactions rekord. Nem törölhető, nem módosítható. Korrekció = új ellentétes tranzakció.
11. Áruátvétel (Receiving / Inbound)
11.1. Workflow
PO státusz: IN_TRANSIT → ARRIVED → RECEIVING → RECEIVED (partially/fully)
1. Beszállító megérkezik → PO kiválasztás
2. Tételes átvétel: scan + mennyiség beütés + eltérés rögzítés
3. Minőségellenőrzés (opcionális) → QUALITY-CONTROL lokáció
4. Betárolás (Putaway): rendszer javasol lokációt, raktáros megerősíti
11.2. Putaway stratégiák
| Stratégia | Logika |
|---|---|
FIXED | Termékhez rögzített lokáció |
CLOSEST_AVAILABLE | Legközelebbi szabad hely (Dijkstra) |
ZONE_BASED | Termékkategória → shelf mapping |
CONSOLIDATE | Oda, ahol már van ugyanabból |
ABC_CLASS | A-osztály közel a SHIPPING-hez |
11.3. Részleges átvétel
Egy PO több alkalommal is átvehető. procurement_items.qty_received kumulatívan nő. Státuszok: PARTIALLY_RECEIVED → RECEIVED → CLOSED.
11.4. Összevárásból érkező áru kiosztása
Amikor egy összevárásból generált PO áruátvétele megtörténik:
1. PO tétel átvéve (pl. 13 db Widget)
2. Rendszer megkeresi az eredeti rendeléseket, amikből ez a PO jött:
- Rendelés #101: 5 db Widget
- Rendelés #105: 3 db Widget
- Rendelés #108: 5 db Widget
3. Automatikus foglalás (RESERVE) a rendelésekhez
4. Ha marad felesleg (MOQ kitöltés miatt): AVAILABLE készletbe kerül
5. A hozzárendelt rendelések automatikusan PICKING státuszba lépnek
11.5. Előrendelés teljesítés áruátvételkor
Ha a PO-hoz előrendelések kötődnek (product_availability.source_id = procurement.id):
1. PO áruátvétel megtörténik
2. Rendszer összegyűjti az előrendeléseket (PRE_ORDER státuszú order items)
3. FIFO sorrendben (rendelés dátuma) kiosztja a beérkezett készletet
4. Kiosztott tételek: PRE_ORDER → CONFIRMED → PICKING
5. Ha nem jött elég: maradék tételek PRE_ORDER maradnak, új PO szükséges
6. product_availability rekord frissítése (expected_qty csökkentés)
12. Komissiózás és rendelés-teljesítés (Picking & Fulfillment)
12.1. Picking workflow
Order státusz: CONFIRMED → PICKING → PICKED → PACKING → SHIPPED
1. Készletfoglalás (RESERVE)
2. Pick list generálás + útvonal-optimalizálás (TSP)
3. Szedés: scan lokáció → scan termék → mennyiség
4. PICKED → packing station-re
12.2. Szedési stratégiák
| Stratégia | Leírás | Mikor |
|---|---|---|
FIFO | Legrégebben bevételezett először | Alapértelmezett |
FEFO | Leghamarabb lejáró először | Lejáratos termék |
LIFO | Legutóbb bevételezett először | Speciális eset |
NONE | Bármelyik lokációról | Nem lejáratos |
12.3. Picking módok
- Single Order: Egy rendelés → egy szedés
- Batch Picking: Több rendelés összevont szedése → sorting station
- Wave Picking: Időablakos batch
12.4. Rendelés-foglalás (Reservation)
Foglalás + timeout (konfig: reservation_timeout_hours). Ha nincs elég → partial reservation + backorder.
13. Csomagolás és kiszállítás (Packing & Shipping)
13.1. Packing workflow
1. Szedett tételek a pack station-re
2. Scan rendelés → tartalom megjelenik
3. Scan tételek a csomagba → kipipálás
4. Csomagolóanyag kiválasztás
5. Csomag lezárás: shipping label + súly/méret rögzítés
13.2. Shipping integráció
| Futárszolgálat | Típus | Prioritás |
|---|---|---|
| GLS Hungary | Csomagküldés | P1 |
| MPL (Magyar Posta) | Csomagküldés | P1 |
| DPD | Csomagküldés | P2 |
| FoxPost | Csomagautomata | P2 |
| Packeta | Csomagpont | P2 |
| Saját futár | Lokális kiszállítás | P2 |
13.3. Multi-colli
Egy rendelés több csomagban szállítható. Rendelés csak akkor SHIPPED, ha minden csomag feladva.
14. Dropshipping
14.1. Dropship koncepció
A beszállító közvetlenül a vevőhöz szállít. Nálunk nincs fizikai készletmozgás, de az egész folyamatot mi menedzseljük:
Dropship flow:
1. Vevő rendelés beérkezik
2. Order routing: tétel source = DROPSHIP
3. Rendszer automatikusan (vagy admin manuálisan) PO-t hoz létre:
- Beszállító: a termék dropship beszállítója (CRM company)
- Tételek: a vevő rendeléséből
- Szállítási cím: a VEVŐ szállítási címe (nem a mi raktárunk!)
- A PO-n a supplier_sku jelenik meg
4. PO elküldése a beszállítónak (email PDF, API, portál)
5. Beszállító szállít közvetlenül a vevőnek
6. Beszállító visszajelzi a tracking számot (webhook, email, manuális)
7. Tracking szám átíródik a vevő rendeléséhez
8. Állapotkövetés: ORDERED → SHIPPED_BY_SUPPLIER → DELIVERED
14.2. Dropship PO sajátosságok
| Mező | Normál PO | Dropship PO |
|---|---|---|
| Szállítási cím | Saját raktár | Vevő címe |
| Csomagolás | Mi csomagolunk | Beszállító csomagol |
| Shipping label | Mi generáljuk | Beszállító generálja (vagy mi, ha az ő rendszere engedi) |
| Tracking | Saját futár tracking | Beszállító tracking → passthrough a vevőnek |
| Készletmozgás | RECEIVE → PUTAWAY → PICK → SHIP | Nincs fizikai mozgás (DROPSHIP_ORDER → DROPSHIP_DELIVER) |
| Számlázás | Mi számlázunk a vevőnek | Mi számlázunk a vevőnek, beszállító nekünk |
14.3. Dropship profitszámítás
Dropship profit = Vevő fizet (eladási ár) - Beszállító ár - Egyéb költségek
Egyéb költségek:
- Platform fee (ha marketplace)
- Payment processing fee
- Esetleges szállítási felár
14.4. Dropship + Normál vegyes rendelés
Egy rendelésben lehetnek dropship ÉS normál tételek:
Rendelés #201:
- Termék A: 2 db → PHYSICAL (saját raktár) → pick/pack/ship
- Termék B: 1 db → DROPSHIP (TechData) → PO a vevő címével
Eredmény: a vevő 2 csomagot kap:
1. Tőlünk: Termék A
2. TechData-tól: Termék B (dropship)
A rendelés csak akkor COMPLETED, ha mindkét csomag megérkezett.
14.5. Dropship visszáru
Ha a vevő visszaküldi a dropship terméket:
- A vevő nekünk küldi vissza (mi vagyunk az eladó)
- Mi fogadjuk be (RMA flow) — vagy ha a beszállítóval van megállapodás, közvetlenül nekik
- A garancia és liability logika ugyanúgy működik mint normál RMA-nál
15. Beszerzés (Procurement)
15.1. PO Lifecycle
DRAFT → SUBMITTED → CONFIRMED → IN_TRANSIT → CUSTOMS_CLEARANCE* → ARRIVED → RECEIVING → RECEIVED → CLOSED
↑
(csak EU-n kívüli import)
Dropship PO:
DRAFT → SUBMITTED → CONFIRMED → SHIPPED_BY_SUPPLIER → DELIVERED → CLOSED
15.2. PO típusok
| Típus | Kód | Leírás | Szállítási cím |
|---|---|---|---|
| Normál | STANDARD | Hagyományos beszerzés → saját raktárba | Saját raktár |
| Összevárásból | BATCHED | Több rendelésből összesítve generált | Saját raktár |
| Dropship | DROPSHIP | Közvetlen kiszállítás a vevőnek | Vevő címe |
15.3. Összevárás (Procurement Batching)
A procurement_queue gyűjti az összevárásra váró tételeket:
-- Pending tételek (rendelésből jöttek, de még nincs PO)
procurement_queue:
id, order_id, order_item_id, product_id, variant_id,
company_id, supplier_product_id,
qty, status (PENDING / ASSIGNED_TO_PO / CANCELLED),
procurement_id (NULL amíg nincs PO),
created_at
Ütemezési stratégiák (konfig: procurement.batch_strategy):
| Stratégia | Leírás |
|---|---|
DAILY | Naponta egyszer, beállított időpontban (pl. 14:00) |
INTERVAL | X óránként (pl. 4 óránként) |
THRESHOLD | Amikor az összegyűlt érték eléri a company_supplier_details.min_order_value-t |
MANUAL | Csak admin indításra |
15.4. Batch PO generálás
Batch PO generálás flow:
1. Ütemező trigger (vagy admin gomb)
2. FOREACH beszállító WHERE van PENDING procurement_queue tétel:
a. Tételek összegyűjtése beszállítónként
b. Összesítés termék + variáns szinten: qty = SUM(queue.qty)
c. MOQ ellenőrzés:
- Ha összesített qty < MOQ → döntés:
i. Kitöltés MOQ-ra (extra készlet lesz)
ii. Várakozás (nem generálunk PO-t, marad a queue-ban)
→ Konfig: `procurement.moq_strategy` = 'fill' | 'wait'
d. Min. rendelési érték ellenőrzés:
- Ha total < company_supplier_details.min_order_value → várakozás
e. PO létrehozás (DRAFT státuszban)
f. procurement_queue tételek ASSIGNED_TO_PO + procurement_id kitöltve
3. PO-k listázása admin-nak → jóváhagyás
4. Jóváhagyás után: SUBMITTED + PDF generálás + email küldés beszállítónak
15.5. Adózási körök
| Típus | ÁFA | Dokumentumok |
|---|---|---|
| Belföldi | Magyar ÁFA (27%) | Számla |
| EU Közösségi | 0% (Reverse Charge) | Számla + Intrastat |
| Harmadik ország | Import ÁFA + Vám | Számla + Vámáru-nyilatkozat + CE tanúsítvány |
15.6. Landed Cost (Bekerülési érték)
unit_landed_cost = unit_price + (allocated_shipping + allocated_duty + allocated_other) / qty
Allokációs módszerek: érték / súly / mennyiség alapú.
15.7. Beszerzési dokumentumok
Dinamikusan bővíthető (document_types szótártábla): Számla, Szállítólevél, Vámáru-nyilatkozat, CE tanúsítvány, Minőségi tanúsítvány, MSDS.
16. Visszáru kezelés (RMA)
16.1. RMA State Machine
REQUESTED → APPROVED → RECEIVED → INSPECTING → GRADED → RESOLVED
↓ ↓ ↓
REJECTED CANCELLED ┌───┴───┐
│ │
RESTOCKED SCRAPPED
16.2. Grading
| Grade | Leírás | Művelet |
|---|---|---|
| A | Újra eladható | Visszapolcozás → AVAILABLE |
| B | Csökkentett áron eladható | Visszapolcozás → outlet |
| C | Javítandó | Szerviz → újra grading |
| SCRAP | Nem javítható | Selejtezés |
16.3. Fotó policy
products.min_rma_photos → kötelező kategóriák: PACKAGE_OUTER, PACKAGE_INNER, PRODUCT_DAMAGE, SERIAL_NUMBER.
16.4. Pénzügyi felelősség
warranty_liability: SUPPLIER / COMPANY / CUSTOMER — automatikus meghatározás a garanciális dátumok alapján.
17. Leltározás (Inventory Audit / Cycle Count)
Csak fizikai raktárakra vonatkozik.
17.1. Típusok
- Full Inventory: Teljes raktár (éves)
- Cycle Count: Forgó leltár (ABC osztályozás)
- Spot Check: Eseti ellenőrzés
17.2. Workflow
- Lokációk zárolása → 2. Számolás (scan + beütés, opcionálisan blind count) → 3. Eltérés kezelés (recount / writeoff / surplus) → 4. Lezárás + riport
18. Termék életút-követés (Traceability)
- Egyedi (S/N) vs Sarzs (Lot/Batch) —
products.is_unique - Garancia: supplier_warranty_until / customer_warranty_until → automatikus liability
- Lejárat: FEFO szedés, automatikus BLOCKED lejárt terméknél
19. Teljesítmény és gyorsítótár
19.1. Inventory Summary
Termékenként és raktáranként aggregált készlet (fizikai ÉS virtuális raktárakra is).
19.2. Frissítés
- Egyedi tranzakció: szinkron trigger (0ms)
- Tömeges: aszinkron queue job (< 500ms)
- Teljes újraépítés: artisan command
19.3. Overselling védelem
SELECT ... FOR UPDATE az inventory_summary soron foglalásnál.
20. Címke generálás (Label Generator)
Csak fizikai raktárakra vonatkozik.
20.1. Új működés (Location-driven)
A label generator kizárólag a locations táblából dolgozik. Szabad szöveges range/manual mód MEGSZŰNIK.
1. Raktár kiválasztás
2. Lokáció-fa betöltés (SHELF → ROW → SPACE → BOX)
3. Lokáció kiválasztás (checkbox fa, szintenként, szűréssel)
4. QR generálás: VECTON-{full_code}
5. label_printed_at = NOW()
20.2. API
POST /api/warehouse/warehouses/{id}/labels/preview
POST /api/warehouse/warehouses/{id}/labels/generate
body: { location_ids: [uuid, ...], design, orientation }
Régi range/manual paraméterek törlendők.
21. Integrációk
21.1. Webshop szinkron
| Irány | Adat | Trigger |
|---|---|---|
| Webshop → Warehouse | Rendelés | Webhook / RabbitMQ |
| Warehouse → Webshop | Készlet szint (fizikai + virtuális) | Inventory summary változás |
| Webshop → Warehouse | Termék adatok | Szinkron / webhook |
21.2. Külső webshop platformok
Shopify, WooCommerce, Shoprenter, Unas: rendelés import, készlet push, tracking push.
21.3. Futárszolgálat API
interface ShippingProvider {
public function createShipment(Order $order, Package $package): ShipmentResult;
public function getLabel(string $shipmentId): LabelResult;
public function getTracking(string $shipmentId): TrackingResult;
public function cancelShipment(string $shipmentId): bool;
}
21.4. Beszállítói integráció
| Mód | Leírás |
|---|---|
| Email PDF | PO export PDF generálás + email küldés company_supplier_details.order_email-re |
| API | Beszállító REST API-ján keresztül PO beküldés (egyedi implementáció per beszállító) |
| Portál | Admin manuálisan rendel a beszállító webes felületén |
| EDI | Elektronikus adatcsere (nagy beszállítóknál, későbbi fázis) |
21.5. CRM szinkron
| Irány | Adat | Trigger |
|---|---|---|
| CRM → Warehouse | Cég adatok (cím, kontakt, típus) | API / webhook |
| Warehouse → CRM | PO-k, szállítási infók | API / webhook |
A warehouse backend a CRM company_id-t használja FK-ként. A cég részletes adatai (név, cím, kontaktok) a CRM-ből jönnek API hívással amikor szükséges (pl. PO PDF generálásnál).
21.6. Mérleg integráció (opcionális)
Pack station USB/soros mérleg, súly validáció.
22. Adatbázis séma
22.1. CRM bővítések (tenant-backend-crm)
-- Cég típusok (many-to-many pivot)
CREATE TABLE company_types (
id UUID PRIMARY KEY,
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
type VARCHAR(50) NOT NULL, -- 'customer', 'supplier', 'manufacturer', 'carrier', 'partner'
assigned_at TIMESTAMP DEFAULT NOW(),
assigned_by UUID NULL,
UNIQUE(company_id, type),
INDEX(type)
);
22.2. Raktárak (MÓDOSUL — type + company_id)
-- A meglévő warehouses tábla kiegészítése:
ALTER TABLE warehouses ADD COLUMN type ENUM('physical','virtual','dropship') DEFAULT 'physical';
ALTER TABLE warehouses ADD COLUMN company_id UUID NULL;
-- company_id: virtuális és dropship raktáraknál kötelező (CRM cég), fizikainál NULL
22.3. Beszállítói bővítmény (warehouse backend)
CREATE TABLE company_supplier_details (
id UUID PRIMARY KEY,
company_id UUID NOT NULL, -- FK → CRM companies (cross-service)
code VARCHAR(50),
currency_code CHAR(3) DEFAULT 'HUF',
payment_terms_days INT DEFAULT 30,
lead_time_days INT NULL,
procurement_type ENUM('DOMESTIC','EU_COMMUNITY','THIRD_COUNTRY') DEFAULT 'DOMESTIC',
order_email VARCHAR(255) NULL,
order_method ENUM('email','api','portal','manual') DEFAULT 'email',
min_order_value DECIMAL(18,4) NULL,
eu_vat_number VARCHAR(50) NULL,
notes TEXT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP,
updated_at TIMESTAMP,
UNIQUE(company_id)
);
22.4. Beszállítói termék katalógus
CREATE TABLE supplier_products (
id UUID PRIMARY KEY,
company_id UUID NOT NULL, -- FK → CRM companies (beszállító)
product_id UUID NOT NULL,
variant_id UUID NULL,
supplier_sku VARCHAR(100) NOT NULL,
unit_price DECIMAL(18,4) NOT NULL,
currency_code CHAR(3) DEFAULT 'HUF',
moq INT DEFAULT 1,
order_unit INT DEFAULT 1,
lead_time_days INT NULL,
priority INT DEFAULT 1, -- 1 = elsődleges, 2 = másodlagos, stb.
is_dropship_eligible BOOLEAN DEFAULT FALSE,
supplier_stock_qty DECIMAL(12,4) NULL,
min_sellable_stock INT DEFAULT 0, -- alatta nem értékesítjük
stock_updated_at TIMESTAMP NULL,
is_active BOOLEAN DEFAULT TRUE,
notes TEXT NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP,
UNIQUE(company_id, product_id, variant_id),
INDEX(product_id, is_active),
INDEX(company_id, is_active),
INDEX(product_id, priority)
);
22.5. Lokációk (csak fizikai raktárakhoz)
CREATE TABLE locations (
id UUID PRIMARY KEY,
warehouse_id UUID NOT NULL REFERENCES warehouses(id),
parent_id UUID NULL REFERENCES locations(id),
level_type ENUM('SHELF','ROW','SPACE','BOX') NOT NULL,
code VARCHAR(50) NOT NULL,
full_code VARCHAR(150) NOT NULL,
name VARCHAR(255) NULL,
height_cm INT NULL,
width_cm INT NULL,
depth_cm INT NULL,
position_index INT DEFAULT 0,
max_items INT NULL,
max_weight DECIMAL(10,2) NULL,
max_volume DECIMAL(10,4) NULL,
x DECIMAL(10,2) NULL,
y DECIMAL(10,2) NULL,
is_active BOOLEAN DEFAULT TRUE,
is_locked_for_audit BOOLEAN DEFAULT FALSE,
locked_by_user_id UUID NULL,
locked_at TIMESTAMP NULL,
label_printed_at TIMESTAMP NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP,
-- NINCS deleted_at — soha nem törlődik, csak is_active = false
UNIQUE(warehouse_id, full_code)
);
CREATE INDEX idx_locations_parent ON locations(parent_id);
CREATE INDEX idx_locations_warehouse ON locations(warehouse_id);
CREATE INDEX idx_locations_active ON locations(warehouse_id, is_active);
22.6. Lokáció linkek
CREATE TABLE location_links (
id UUID PRIMARY KEY,
warehouse_id UUID NOT NULL REFERENCES warehouses(id),
from_location_id UUID NOT NULL REFERENCES locations(id),
to_location_id UUID NOT NULL REFERENCES locations(id),
weight DECIMAL(10,2) DEFAULT 1,
is_bidirectional BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP,
updated_at TIMESTAMP,
UNIQUE(from_location_id, to_location_id)
);
22.7. Layout verziók
CREATE TABLE warehouse_layouts (
id UUID PRIMARY KEY,
warehouse_id UUID NOT NULL REFERENCES warehouses(id),
version INT NOT NULL,
name VARCHAR(255) NULL,
is_active BOOLEAN DEFAULT FALSE,
location_snapshot JSON NOT NULL,
link_snapshot JSON NOT NULL,
created_by UUID NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP,
deleted_at TIMESTAMP NULL,
UNIQUE(warehouse_id, version)
);
22.8. Készlet
CREATE TABLE inventory (
id UUID PRIMARY KEY,
product_id UUID NOT NULL,
variant_id UUID NULL,
warehouse_id UUID NOT NULL REFERENCES warehouses(id),
location_id UUID NULL REFERENCES locations(id), -- NULL virtuális raktárnál
qty DECIMAL(12,4) NOT NULL DEFAULT 0,
status ENUM('AVAILABLE','RESERVED','BLOCKED','UNDER_INVESTIGATION','SCRAPPED'),
stock_purpose ENUM('SELLABLE','BUFFER_RMA','BUFFER_SAFETY') DEFAULT 'SELLABLE',
serial_number VARCHAR(255) NULL,
batch_lot_number VARCHAR(100) NULL,
expiry_date DATE NULL,
received_at TIMESTAMP NULL,
unit_cost DECIMAL(18,4) NULL,
currency_code CHAR(3) NULL,
procurement_item_id UUID NULL REFERENCES procurement_items(id),
reserved_order_id UUID NULL,
reserved_at TIMESTAMP NULL,
release_date DATE NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP,
INDEX(product_id, status),
INDEX(warehouse_id, product_id),
INDEX(location_id),
INDEX(product_id, variant_id, status)
);
22.9. Készlet összesítő
CREATE TABLE inventory_summary (
id UUID PRIMARY KEY,
product_id UUID NOT NULL,
variant_id UUID NULL,
warehouse_id UUID NOT NULL,
physical_qty DECIMAL(12,4) DEFAULT 0,
reserved_qty DECIMAL(12,4) DEFAULT 0,
blocked_qty DECIMAL(12,4) DEFAULT 0,
buffer_qty DECIMAL(12,4) DEFAULT 0,
in_transit_qty DECIMAL(12,4) DEFAULT 0,
available_qty DECIMAL(12,4) DEFAULT 0,
last_movement_at TIMESTAMP NULL,
updated_at TIMESTAMP,
UNIQUE(product_id, variant_id, warehouse_id)
);
22.10. Készletmozgás napló
CREATE TABLE inventory_transactions (
id UUID PRIMARY KEY,
transaction_type ENUM('RECEIVE','PUTAWAY','PICK','PACK','SHIP','MOVE',
'ADJUST_UP','ADJUST_DOWN','RESERVE','UNRESERVE',
'BLOCK','UNBLOCK','RMA_RECEIVE','RMA_RESTOCK',
'SCRAP','CROSS_DOCK','TRANSFER',
'VIRTUAL_RESERVE','VIRTUAL_RELEASE',
'DROPSHIP_ORDER','DROPSHIP_DELIVER',
'PRE_ORDER_RESERVE','PRE_ORDER_FULFILL'),
product_id UUID NOT NULL,
variant_id UUID NULL,
warehouse_id UUID NULL,
inventory_id UUID NULL REFERENCES inventory(id),
from_location_id UUID NULL REFERENCES locations(id),
to_location_id UUID NULL REFERENCES locations(id),
from_location_code VARCHAR(150) NULL,
to_location_code VARCHAR(150) NULL,
qty DECIMAL(12,4) NOT NULL,
reference_type VARCHAR(50) NULL,
reference_id UUID NULL,
correlation_id VARCHAR(100) NULL,
user_id UUID NULL,
device_id VARCHAR(100) NULL,
notes TEXT NULL,
created_at TIMESTAMP NOT NULL,
INDEX(created_at),
INDEX(product_id, created_at),
INDEX(transaction_type, created_at),
INDEX(correlation_id),
INDEX(reference_type, reference_id),
INDEX(warehouse_id, created_at)
);
-- Immutable!
22.11. Termék elérhetőség (Pre-orders)
CREATE TABLE product_availability (
id UUID PRIMARY KEY,
product_id UUID NOT NULL,
variant_id UUID NULL,
available_from DATE NOT NULL, -- mikortól elérhető
available_until DATE NULL, -- meddig (NULL = végtelen)
pre_order_enabled BOOLEAN DEFAULT FALSE, -- előrendelés engedélyezve?
pre_order_limit INT NULL, -- max előrendelhető qty (NULL = korlátlan)
expected_qty INT NULL, -- várhatóan ennyi jön
source_type ENUM('PROCUREMENT','PRODUCTION','MANUAL') DEFAULT 'MANUAL',
source_id UUID NULL, -- FK → procurements.id (ha PROCUREMENT)
status ENUM('UPCOMING','ACTIVE','FULFILLED','CANCELLED') DEFAULT 'UPCOMING',
-- UPCOMING: available_from a jövőben
-- ACTIVE: available_from <= now(), pre_order_enabled, van még limit
-- FULFILLED: minden előrendelés teljesítve
-- CANCELLED: visszavonva
notes TEXT NULL,
created_by UUID NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP,
INDEX(product_id, status),
INDEX(available_from),
INDEX(source_type, source_id)
);
22.12. Beszerzés
CREATE TABLE procurements (
id UUID PRIMARY KEY,
company_id UUID NOT NULL, -- FK → CRM companies (beszállító)
warehouse_id UUID NOT NULL REFERENCES warehouses(id),
po_number VARCHAR(50) NOT NULL,
po_type ENUM('STANDARD','BATCHED','DROPSHIP') DEFAULT 'STANDARD',
status ENUM('DRAFT','SUBMITTED','CONFIRMED','IN_TRANSIT',
'CUSTOMS_CLEARANCE','ARRIVED','RECEIVING',
'PARTIALLY_RECEIVED','RECEIVED',
'SHIPPED_BY_SUPPLIER','DELIVERED',
'CLOSED','CANCELLED'),
procurement_type ENUM('DOMESTIC','EU_COMMUNITY','THIRD_COUNTRY') NOT NULL,
currency_code CHAR(3) NOT NULL,
exchange_rate DECIMAL(12,6) NULL,
shipping_cost DECIMAL(18,4) DEFAULT 0,
customs_duty DECIMAL(18,4) DEFAULT 0,
other_costs DECIMAL(18,4) DEFAULT 0,
cost_allocation_method ENUM('VALUE','WEIGHT','QUANTITY') DEFAULT 'VALUE',
total_landed_cost DECIMAL(18,4) DEFAULT 0,
is_customs_cleared BOOLEAN DEFAULT FALSE,
customs_cleared_at TIMESTAMP NULL,
-- Dropship szállítási cím (vevő címe)
ship_to_name VARCHAR(255) NULL,
ship_to_address1 VARCHAR(255) NULL,
ship_to_address2 VARCHAR(255) NULL,
ship_to_city VARCHAR(100) NULL,
ship_to_zip VARCHAR(20) NULL,
ship_to_country VARCHAR(2) NULL,
ship_to_phone VARCHAR(50) NULL,
-- Dropship tracking
supplier_tracking_number VARCHAR(200) NULL,
-- Kapcsolat az eredeti rendeléshez (dropship)
order_id UUID NULL,
expected_delivery_at DATE NULL,
received_at TIMESTAMP NULL,
notes TEXT NULL,
created_by UUID NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP,
deleted_at TIMESTAMP NULL,
UNIQUE(po_number)
);
CREATE TABLE procurement_items (
id UUID PRIMARY KEY,
procurement_id UUID NOT NULL REFERENCES procurements(id) ON DELETE CASCADE,
product_id UUID NOT NULL,
variant_id UUID NULL,
supplier_product_id UUID NULL REFERENCES supplier_products(id),
supplier_sku VARCHAR(100) NULL,
qty_ordered DECIMAL(12,4) NOT NULL,
qty_received DECIMAL(12,4) DEFAULT 0,
unit_price DECIMAL(18,4) NOT NULL,
unit_landed_cost DECIMAL(18,4) NULL,
supplier_warranty_until DATE NULL,
customer_warranty_until DATE NULL,
warranty_liability ENUM('SUPPLIER','COMPANY','CUSTOMER') NULL,
batch_lot_number VARCHAR(100) NULL,
expiry_date DATE NULL,
notes TEXT NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE TABLE document_types (
id UUID PRIMARY KEY,
name VARCHAR(255) NOT NULL,
is_required BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE TABLE procurement_documents (
id UUID PRIMARY KEY,
procurement_id UUID NOT NULL REFERENCES procurements(id) ON DELETE CASCADE,
document_type_id UUID NOT NULL REFERENCES document_types(id),
file_path VARCHAR(500) NOT NULL,
created_at TIMESTAMP
);
22.13. Összevárás sor (Procurement Queue)
CREATE TABLE procurement_queue (
id UUID PRIMARY KEY,
order_id UUID NOT NULL,
order_item_id UUID NOT NULL,
product_id UUID NOT NULL,
variant_id UUID NULL,
company_id UUID NOT NULL, -- FK → CRM companies (beszállító)
supplier_product_id UUID NULL REFERENCES supplier_products(id),
qty DECIMAL(12,4) NOT NULL,
status ENUM('PENDING','ASSIGNED_TO_PO','CANCELLED') DEFAULT 'PENDING',
procurement_id UUID NULL REFERENCES procurements(id),
created_at TIMESTAMP,
updated_at TIMESTAMP,
INDEX(status, company_id),
INDEX(order_id),
INDEX(company_id, status)
);
22.14. Rendelés-teljesítés (Fulfillment)
CREATE TABLE picking_tasks (
id UUID PRIMARY KEY,
warehouse_id UUID NOT NULL REFERENCES warehouses(id),
order_id UUID NULL,
picking_mode ENUM('SINGLE','BATCH','WAVE') DEFAULT 'SINGLE',
wave_id UUID NULL,
status ENUM('PENDING','ASSIGNED','IN_PROGRESS','COMPLETED',
'PARTIALLY_COMPLETED','CANCELLED'),
priority INT DEFAULT 0,
assigned_to UUID NULL,
assigned_at TIMESTAMP NULL,
started_at TIMESTAMP NULL,
completed_at TIMESTAMP NULL,
route_plan_id UUID NULL REFERENCES route_plans(id),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE TABLE picking_task_items (
id UUID PRIMARY KEY,
picking_task_id UUID NOT NULL REFERENCES picking_tasks(id) ON DELETE CASCADE,
product_id UUID NOT NULL,
variant_id UUID NULL,
inventory_id UUID NOT NULL REFERENCES inventory(id),
location_id UUID NOT NULL REFERENCES locations(id),
qty_requested DECIMAL(12,4) NOT NULL,
qty_picked DECIMAL(12,4) DEFAULT 0,
pick_sequence INT NOT NULL,
status ENUM('PENDING','PICKED','SHORT_PICKED','SKIPPED'),
picked_at TIMESTAMP NULL,
picked_by UUID NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE TABLE packages (
id UUID PRIMARY KEY,
order_id UUID NOT NULL,
package_number VARCHAR(50) NOT NULL,
status ENUM('PACKING','PACKED','LABELLED','SHIPPED','DELIVERED','RETURNED'),
weight DECIMAL(10,3) NULL,
width DECIMAL(10,2) NULL,
height DECIMAL(10,2) NULL,
depth DECIMAL(10,2) NULL,
shipping_provider VARCHAR(50) NULL,
tracking_number VARCHAR(100) NULL,
shipping_label_url VARCHAR(500) NULL,
shipping_cost DECIMAL(18,4) NULL,
packed_by UUID NULL,
packed_at TIMESTAMP NULL,
shipped_at TIMESTAMP NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE TABLE package_items (
id UUID PRIMARY KEY,
package_id UUID NOT NULL REFERENCES packages(id) ON DELETE CASCADE,
product_id UUID NOT NULL,
variant_id UUID NULL,
inventory_id UUID NOT NULL,
qty DECIMAL(12,4) NOT NULL,
serial_number VARCHAR(255) NULL,
created_at TIMESTAMP
);
22.15. Visszáru (RMA)
CREATE TABLE rma_tickets (
id UUID PRIMARY KEY,
order_id UUID NULL,
order_item_id UUID NULL,
product_id UUID NOT NULL,
variant_id UUID NULL,
inventory_id UUID NULL,
status ENUM('REQUESTED','APPROVED','RECEIVED','INSPECTING',
'GRADED','RESOLVED','REJECTED','CANCELLED'),
reason_category ENUM('DEFECTIVE','WRONG_ITEM','DAMAGED_SHIPPING',
'CUSTOMER_REMORSE','WARRANTY','OTHER'),
reason_notes TEXT NULL,
grade_result ENUM('A','B','C','SCRAP') NULL,
resolution ENUM('RESTOCKED','SCRAPPED','REPAIRED','REFUNDED','REPLACED') NULL,
liability ENUM('SUPPLIER','COMPANY','CUSTOMER') NULL,
location_id UUID NULL REFERENCES locations(id),
is_dropship_origin BOOLEAN DEFAULT FALSE,
received_at TIMESTAMP NULL,
inspected_at TIMESTAMP NULL,
resolved_at TIMESTAMP NULL,
resolved_by UUID NULL,
created_by UUID NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE TABLE rma_photos (
id UUID PRIMARY KEY,
rma_ticket_id UUID NOT NULL REFERENCES rma_tickets(id) ON DELETE CASCADE,
photo_category ENUM('PACKAGE_OUTER','PACKAGE_INNER','PRODUCT_DAMAGE','SERIAL_NUMBER'),
file_path VARCHAR(500) NOT NULL,
uploaded_by UUID NULL,
created_at TIMESTAMP
);
22.16. Leltár
CREATE TABLE inventory_audits (
id UUID PRIMARY KEY,
warehouse_id UUID NOT NULL REFERENCES warehouses(id),
audit_type ENUM('FULL','CYCLE_COUNT','SPOT_CHECK'),
status ENUM('PLANNED','IN_PROGRESS','PENDING_REVIEW','COMPLETED','CANCELLED'),
name VARCHAR(255) NULL,
is_blind_count BOOLEAN DEFAULT FALSE,
started_at TIMESTAMP NULL,
completed_at TIMESTAMP NULL,
started_by UUID NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE TABLE inventory_audit_items (
id UUID PRIMARY KEY,
audit_id UUID NOT NULL REFERENCES inventory_audits(id) ON DELETE CASCADE,
location_id UUID NOT NULL REFERENCES locations(id),
product_id UUID NOT NULL,
variant_id UUID NULL,
expected_qty DECIMAL(12,4) NOT NULL,
counted_qty DECIMAL(12,4) NULL,
variance_qty DECIMAL(12,4) NULL,
status ENUM('PENDING','COUNTED','PENDING_RECOUNT','RECOUNTED',
'PENDING_APPROVAL','APPROVED_WRITEOFF','APPROVED_SURPLUS','TRANSFERRED'),
counted_by UUID NULL,
counted_at TIMESTAMP NULL,
recounted_by UUID NULL,
recounted_at TIMESTAMP NULL,
approved_by UUID NULL,
approved_at TIMESTAMP NULL,
resolution_notes TEXT NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
22.17. Konfiguráció
-- tenant_configs kulcsok:
wms.reservation_timeout_hours = 48
wms.backorder_policy = 'notify'
wms.virtual_stock_in_available = true
wms.include_in_transit_in_available = false
wms.default_picking_mode = 'single'
wms.expiry_warning_days = 30
wms.auto_block_expired = true
wms.blind_count_default = false
wms.putaway_strategy = 'consolidate'
wms.cycle_count_a_frequency_days = 30
wms.cycle_count_b_frequency_days = 90
wms.cycle_count_c_frequency_days = 180
-- Beszerzés összevárás
procurement.batch_strategy = 'daily'
procurement.batch_time = '14:00'
procurement.batch_interval_hours = 4
procurement.moq_strategy = 'fill'
procurement.auto_approve_po = false
procurement.auto_send_po = false
procurement.auto_enable_preorder = false -- PO létrehozásnál auto előrendelés?
-- Dropship
dropship.enabled = true
dropship.auto_create_po = true
-- Előrendelés
preorder.enabled = true
preorder.default_limit = NULL -- alapértelmezett limit (NULL = korlátlan)
preorder.notify_on_delay = true -- értesítés ha ETA változik
23. API végpontok
23.1. Meglévő (MÓDOSUL)
GET/POST/PUT/DELETE /api/warehouse/warehouses[/{id}]
↑ type mező: 'physical' | 'virtual' | 'dropship'
↑ company_id mező virtuális/dropship-nél
POST /api/warehouse/warehouses/{id}/plan-route
POST /api/warehouse/plan-multi-route
POST /api/warehouse/warehouses/{id}/labels/preview
POST /api/warehouse/warehouses/{id}/labels/generate
↑ body: { location_ids, design, orientation }
23.2. CRM bővítés (tenant-backend-crm)
-- Cég típusok kezelése
GET /api/crm/companies/{id}/types
POST /api/crm/companies/{id}/types -- { type: 'supplier' }
DELETE /api/crm/companies/{id}/types/{type}
-- Szűrés típus alapján
GET /api/crm/companies?type=supplier
GET /api/crm/companies?type=customer
GET /api/crm/companies?type=supplier,customer -- mindkettő
23.3. Beszállítói katalógus (warehouse backend)
-- Beszállítói bővítmény (supplier details)
GET/POST/PUT /api/warehouse/company-supplier-details/{companyId}
-- Termék-beszállító kapcsolatok
GET/POST /api/warehouse/companies/{companyId}/products -- supplier_products CRUD
PUT/DELETE /api/warehouse/supplier-products/{id}
POST /api/warehouse/companies/{companyId}/products/import -- árlista CSV/Excel import
GET /api/warehouse/products/{productId}/suppliers -- termékhez tartozó beszállítók (prioritás sorrendben)
PUT /api/warehouse/products/{productId}/suppliers/priority -- prioritás átrendezés
23.4. Lokációk
GET /api/warehouse/warehouses/{id}/locations
GET /api/warehouse/warehouses/{id}/locations/tree
GET /api/warehouse/warehouses/{id}/locations/flat
POST /api/warehouse/warehouses/{id}/locations
PUT /api/warehouse/locations/{id}
DELETE /api/warehouse/locations/{id} -- deaktiválás, csak ha üres
GET /api/warehouse/locations/{id}
GET /api/warehouse/locations/{id}/inventory
GET /api/warehouse/locations/{id}/children
GET /api/warehouse/locations/{id}/history
GET /api/warehouse/locations/{id}/rack-detail
POST /api/warehouse/locations/{id}/lock
POST /api/warehouse/locations/{id}/unlock
GET/POST/DELETE /api/warehouse/warehouses/{id}/location-links
GET/POST /api/warehouse/warehouses/{id}/layouts
POST /api/warehouse/warehouses/{id}/layouts/{id}/restore
DELETE /api/warehouse/warehouses/{id}/layouts/{id}
23.5. Készlet
GET /api/warehouse/inventory
GET /api/warehouse/inventory/summary
GET /api/warehouse/inventory/summary/combined -- fizikai + virtuális összesítve (webshop felé)
GET /api/warehouse/inventory/{id}
POST /api/warehouse/inventory/move
POST /api/warehouse/inventory/adjust
POST /api/warehouse/inventory/reserve
POST /api/warehouse/inventory/unreserve
POST /api/warehouse/inventory/block
POST /api/warehouse/inventory/unblock
GET /api/warehouse/inventory/transactions
GET /api/warehouse/inventory/transactions/{id}
23.6. Előrendelés & Elérhetőség
GET/POST /api/warehouse/product-availability
GET/PUT/DELETE /api/warehouse/product-availability/{id}
GET /api/warehouse/products/{productId}/availability -- termék elérhetőség lekérdezés
POST /api/warehouse/product-availability/{id}/cancel -- előrendelés visszavonás
23.7. Rendelés-routing
POST /api/warehouse/orders/{orderId}/route -- order items routing (auto)
PUT /api/warehouse/orders/{orderId}/items/{itemId}/route -- manuális routing override
GET /api/warehouse/orders/{orderId}/fulfillment-status -- teljesítési állapot összesítő
23.8. Beszerzés & Összevárás
GET/POST /api/warehouse/procurements
GET/PUT/DELETE /api/warehouse/procurements/{id}
POST /api/warehouse/procurements/{id}/submit
POST /api/warehouse/procurements/{id}/confirm
POST /api/warehouse/procurements/{id}/customs-clear
POST /api/warehouse/procurements/{id}/cancel
GET /api/warehouse/procurements/{id}/export-pdf
POST /api/warehouse/procurements/{id}/send-to-supplier
GET/POST /api/warehouse/procurements/{id}/items
PUT/DELETE /api/warehouse/procurements/{id}/items/{itemId}
POST /api/warehouse/procurements/{id}/documents
DELETE /api/warehouse/procurements/{id}/documents/{docId}
-- Összevárás
GET /api/warehouse/procurement-queue
POST /api/warehouse/procurement-queue/generate-pos
GET /api/warehouse/procurement-queue/preview
DELETE /api/warehouse/procurement-queue/{id}
23.9. Áruátvétel
POST /api/warehouse/receiving/start
POST /api/warehouse/receiving/{sessionId}/scan
POST /api/warehouse/receiving/{sessionId}/confirm
POST /api/warehouse/receiving/{sessionId}/complete
POST /api/warehouse/receiving/{sessionId}/putaway
GET /api/warehouse/receiving/suggest-location
23.10. Komissiózás
GET/POST /api/warehouse/picking/tasks
GET /api/warehouse/picking/tasks/{id}
POST /api/warehouse/picking/tasks/{id}/assign
POST /api/warehouse/picking/tasks/{id}/start
POST /api/warehouse/picking/tasks/{id}/items/{itemId}/pick
POST /api/warehouse/picking/tasks/{id}/complete
POST /api/warehouse/picking/waves
GET /api/warehouse/picking/waves/{id}
23.11. Csomagolás & Szállítás
POST /api/warehouse/packing/start
POST /api/warehouse/packing/{sessionId}/scan
POST /api/warehouse/packing/{sessionId}/close-package
GET /api/warehouse/packing/{sessionId}
POST /api/warehouse/shipping/create-shipment
GET /api/warehouse/shipping/label/{packageId}
POST /api/warehouse/shipping/ship/{packageId}
GET /api/warehouse/shipping/tracking/{packageId}
23.12. RMA & Leltár
GET/POST /api/warehouse/rma
GET/PUT /api/warehouse/rma/{id}
POST /api/warehouse/rma/{id}/approve|receive|inspect|grade|resolve
POST /api/warehouse/rma/{id}/photos
GET/POST /api/warehouse/audits
GET/PUT /api/warehouse/audits/{id}
POST /api/warehouse/audits/{id}/start|complete
POST /api/warehouse/audits/{id}/items/{itemId}/count|recount|approve
GET /api/warehouse/audits/{id}/report
24. Megvalósítási fázisok
Fázis 1 — Lokációk, Layout Editor átdolgozás, Készlet mag ⏱️ ~5-7 hét
| # | Feladat | Prioritás |
|---|---|---|
| 1.1 | locations tábla (SHELF/ROW/SPACE/BOX) + CRUD API | P0 |
| 1.2 | location_links tábla + CRUD API | P0 |
| 1.3 | Layout Editor refactor: JSON → locations + location_links | P0 |
| 1.4 | Helykód: VECTON-{WAREHOUSE}-{SHELF}-{ROW}-{SPACE}-{BOX} | P0 |
| 1.5 | Törlés védelem (inventory check) | P0 |
| 1.6 | inventory + inventory_transactions + inventory_summary | P0 |
| 1.7 | Alapvető mozgások: MOVE, ADJUST_UP, ADJUST_DOWN | P0 |
| 1.8 | Label generator: location_ids input, range/manual törlés | P0 |
| 1.9 | Web UI: lokáció fa + készlet nézet + címke generátor | P1 |
| 1.10 | 2D elölnézet (rack detail) + Shelf Properties panel | P1 |
| 1.11 | Route planner átállítás location_links-re | P1 |
| 1.12 | Layout verziózás (snapshot) | P1 |
Fázis 2 — CRM bővítés, Beszállítók, Katalógus, Virtuális raktár ⏱️ ~5-6 hét
| # | Feladat | Prioritás |
|---|---|---|
| 2.1 | CRM company_types pivot tábla + API | P0 |
| 2.2 | company_supplier_details tábla (warehouse backend) + CRUD | P0 |
| 2.3 | supplier_products tábla + CRUD + prioritásos sorrend | P0 |
| 2.4 | Warehouses type mező: physical / virtual / dropship + company_id | P0 |
| 2.5 | Virtuális raktár: inventory_summary virtuális raktárakra | P0 |
| 2.6 | min_sellable_stock logika (beszállítói küszöb) | P0 |
| 2.7 | Beszállítói árlista import (CSV/Excel) | P1 |
| 2.8 | Összesített elérhető készlet (fizikai + virtuális, küszöbökkel) | P1 |
| 2.9 | Web UI: cég típusok, beszállító panel, termék-beszállító kezelés, prioritás drag & drop | P0 |
Fázis 3 — Beszerzés, Összevárás, Export PDF, Előrendelés ⏱️ ~6-7 hét
| # | Feladat | Prioritás |
|---|---|---|
| 3.1 | procurements + procurement_items + PO lifecycle | P0 |
| 3.2 | procurement_queue + összevárás logika | P0 |
| 3.3 | Batch PO generálás (daily/interval/threshold/manual) | P0 |
| 3.4 | Beszállítói export PDF generálás (supplier_sku-val!) | P0 |
| 3.5 | PO email küldés beszállítónak | P1 |
| 3.6 | Áruátvételi workflow (RECEIVE → PUTAWAY) | P0 |
| 3.7 | Összevárásból érkező áru automatikus kiosztás a rendelésekhez | P1 |
| 3.8 | product_availability tábla + előrendelés logika | P1 |
| 3.9 | PO → automatikus product_availability létrehozás | P1 |
| 3.10 | Előrendelés teljesítés áruátvételkor (FIFO kiosztás) | P1 |
| 3.11 | Landed cost kalkuláció | P2 |
| 3.12 | Web UI: PO kezelés, queue nézet, áruátvétel, előrendelés kezelés | P0 |
Fázis 4 — Rendelés-routing, Dropshipping ⏱️ ~4-5 hét
| # | Feladat | Prioritás |
|---|---|---|
| 4.1 | Order fulfillment routing logika (PHYSICAL / PRE_ORDER / SUPPLIER_ORDER / DROPSHIP / BACKORDER) | P0 |
| 4.2 | Prioritásos beszállító kiválasztás (5.2. algoritmus) | P0 |
| 4.3 | Dropship PO generálás (vevő címével) | P0 |
| 4.4 | Dropship tracking passthrough | P1 |
| 4.5 | Vegyes rendelés kezelés (dropship + fizikai + előrendelés) | P1 |
| 4.6 | Dropship profit számítás | P2 |
| 4.7 | Web UI: routing nézet, dropship kezelés | P0 |
Fázis 5 — Komissiózás, Csomagolás, Szállítás ⏱️ ~4-6 hét
| # | Feladat | Prioritás |
|---|---|---|
| 5.1 | RESERVE/UNRESERVE logika + timeout | P0 |
| 5.2 | picking_tasks + picking_task_items | P0 |
| 5.3 | Pick list generálás (FIFO/FEFO) + route planner | P0 |
| 5.4 | packages + package_items (packing) | P0 |
| 5.5 | ShippingProvider interface + GLS + MPL | P0 |
| 5.6 | Shipping label + tracking visszaírás | P0 |
| 5.7 | Batch/Wave picking | P2 |
| 5.8 | Web UI: picking, packing station, shipping | P0 |
Fázis 6 — RMA, Leltár, Haladó ⏱️ ~3-4 hét + folyamatos
| # | Feladat | Prioritás |
|---|---|---|
| 6.1 | RMA state machine + grading + fotók | P0 |
| 6.2 | Dropship visszáru kezelés | P1 |
| 6.3 | Leltár (full / cycle count / spot check) | P0 |
| 6.4 | Blind count mód | P2 |
| 6.5 | Vámkezelés workflow | P2 |
| 6.6 | Raktárközi transzfer | P2 |
| 6.7 | Dashboard & riportok | P1 |
| 6.8 | Beszállítói API integráció (EDI) | P3 |
| 6.9 | Lejárat figyelő cron + auto zárolás | P1 |
Összefoglaló
A rendszer kulcs tervezési döntései:
- CRM integráció: Beszállítók/vevők a CRM
companiestáblában,company_typespivot-tal (egy cég lehet mindkettő) - Beszállítói bővítmény: Warehouse-specifikus adatok
company_supplier_details-ben (cross-service FK) - 3 raktár típus: Fizikai (saját), Virtuális (beszállítói készlet), Dropship (közvetlenül a vevőhöz)
- Prioritásos beszállító kiválasztás: Termékenként rendezett prioritási lánc (
prioritymező), nem csak "preferred" flag - Beszállítói készlet küszöb:
min_sellable_stock— ha a beszállítónál kevés van, nem értékesítjük (overselling védelem) - Előrendelés rendszer:
product_availabilitytábla, PO ETA-ból automatikus available_from, FIFO kiosztás érkezéskor - Összevárás: Rendelések gyűjtése → napi/időszakos batch PO generálás beszállítónként → export PDF
- Order routing: PHYSICAL → PRE_ORDER → SUPPLIER_ORDER (prioritásos) → DROPSHIP → BACKORDER
- Dropshipping: Beszállító szállít a vevőnek, mi menedzseljük a folyamatot, tracking passthrough
- Layout Editor = Lokáció kezelő: Közvetlenül a
locationstáblát kezeli, nincs szinkron - VECTON-{W}-{SHELF}-{ROW}-{SPACE}-{BOX}: Egységes hierarchia, minden hely regisztrált
- Címke = regisztrált hely: QR generátor kizárólag
locationstáblából - Immutable audit trail: Minden mozgás naplózva, befagyasztott kódokkal
- Tenant izoláció infrastruktúra szinten: Nincs tenant_id