Skip to main content

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

  1. Jelenlegi állapot
  2. Rendszer alapelvek
  3. Raktár típusok
  4. Cég típusok és beszállítói kapcsolat (CRM integráció)
  5. Beszállítói katalógus (Supplier Catalog)
  6. Lokáció menedzsment és Layout Editor
  7. Készletkezelési modell
  8. Előrendelés és termék elérhetőség (Pre-orders)
  9. Rendelés-routing (Order Fulfillment Routing)
  10. Készletmozgások (Inventory Transactions)
  11. Áruátvétel (Receiving / Inbound)
  12. Komissiózás és rendelés-teljesítés (Picking & Fulfillment)
  13. Csomagolás és kiszállítás (Packing & Shipping)
  14. Dropshipping
  15. Beszerzés (Procurement)
  16. Visszáru kezelés (RMA)
  17. Leltározás (Inventory Audit / Cycle Count)
  18. Termék életút-követés (Traceability)
  19. Teljesítmény és gyorsítótár
  20. Címke generálás (Label Generator)
  21. Integrációk
  22. Adatbázis séma
  23. API végpontok
  24. Megvalósítási fázisok

1. Jelenlegi állapot

Ami már kész van (production-ready)

ModulBackendWeb 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ípusKódFizikai lokációkLayout EditorKészletLeírás
Fizikaiphysical✅ SHELF/ROW/SPACE/BOXValós polconSaját raktár, minden WMS funkció elérhető
Virtuálisvirtual❌ nincsBeszállítónál lévő logikai készletNagykereskedő/beszállító raktára, amit mi nem kezelünk fizikailag
Dropshipdropship❌ nincsBeszállítónál, közvetlen kiszállításBeszá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 locations tábla kapcsolat
  • Az inventory_summary tábla warehouse_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ípusKódLeírás
VevőcustomerTőlünk vásárol
BeszállítósupplierTőle vásárolunk
GyártómanufacturerTerméket gyárt (lehet egyben beszállító is)
SzállítmányozócarrierFutárszolgálat / szállítmányozó
PartnerpartnerEgyé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_idFK → CRM companies
codeRövid belső azonosító (pl. "TECHDATA", "OMEGA")
currency_codeAlapértelmezett pénznem
payment_terms_daysFizetési határidő (nap)
lead_time_daysAlapértelmezett szállítási idő (nap)
procurement_typeDOMESTIC / EU_COMMUNITY / THIRD_COUNTRY
order_emailEmail cím ahova a rendelési PDF-et küldjük
order_methodRendelés módja: email / api / portal / manual
min_order_valueMinimum rendelési érték (ha van)
eu_vat_numberEU 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_idFK → CRM companies (beszállító cég)
product_idFK → products
variant_idFK → product_variants (nullable)
supplier_skuA beszállító saját cikkszáma (ami az ő rendszerében van)
unit_priceBeszerzési egységár
currency_codePénznem
moqMinimum Order Quantity (min. rendelési mennyiség)
order_unitRendelési egység (pl. 1 = darab, 10 = csomag, 100 = karton)
lead_time_daysSzállítási idő (felülírja a supplier szintű default-ot)
priorityPrioritási sorrend (1 = elsődleges, 2 = másodlagos, stb.)
is_dropship_eligibleEz a beszállító tud dropshippelni ezzel a termékkel
supplier_stock_qtyBeszállítónál elérhető mennyiség (utolsó frissítés szerint)
min_sellable_stockMinimális beszállítói készlet amitől még értékesítjük (alatta: 0 elérhető)
stock_updated_atMikor frissült utoljára a beszállítói készlet
is_activeAktív-e ez a termék-beszállító kapcsolat
notesMegjegyzé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észletmin_sellable_stockEffektíven elérhetőWebshop megjelenés
50545"45 db elérhető"
550Nem jelenik meg
350Nem jelenik meg
NULL5"Elérhető" (mennyiség nélkül)
1000100"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ódJelentés
VECTON-W1-A-3-2-01W1 raktár, A salgó, 3. sor, 2. hely, 01 doboz
VECTON-W1-B-1-4-0W1 raktár, B salgó, 1. sor, 4. hely, nincs doboz
VECTON-W1-RECEIVING-1-0-0W1 raktár, RECEIVING terület
VECTON-W1-SHIPPING-1-0-0W1 raktár, SHIPPING terület
VECTON-W1-RMA-1-0-0W1 raktár, RMA karantén
VECTON-W1-SCRAP-1-0-0W1 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 = locations rekord 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_links rekord

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űveletSzabályHibaüzenet
Shelf törlésMinden gyerek üres"Nem törölhető: {qty} db készlet van az állványon"
Row törlésMinden space/box üres"Nem törölhető: {qty} db készlet van a soron"
Space/Box törlésSUM(qty) > 0 → TILTOTT"Nem törölhető: {qty} db készlet van a helyen"
Warehouse törlésMinden 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_idTermék FK
variant_idTermékvariáns FK (nullable)
location_idLokáció FK (NULL virtuális raktárnál)
warehouse_idRaktár FK (mindig kitöltve — fizikai ÉS virtuálisnál is)
qtyMennyiség
statusAVAILABLE / RESERVED / BLOCKED / UNDER_INVESTIGATION / SCRAPPED
stock_purposeSELLABLE / BUFFER_RMA / BUFFER_SAFETY
serial_numberEgyedi azonosító
batch_lot_numberSarzs szám
expiry_dateLejárat (FEFO)
received_atBevételezés dátuma (FIFO)
unit_costEgységár
procurement_item_idFK → 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_idFK → products
variant_idFK → product_variants (nullable)
available_fromMikortól elérhető / megrendelhető
available_untilMeddig elérhető (nullable — ha van end-of-life)
pre_order_enabledElőrendelés engedélyezve? (true = megvásárolható a dátum előtt is)
pre_order_limitMax előrendelhető mennyiség (nullable = korlátlan)
expected_qtyVárható mennyiség (ha ismert)
source_typeHonnan várjuk: PROCUREMENT / PRODUCTION / MANUAL
source_idFK → procurements.id (ha PROCUREMENT)
notesMegjegyzé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ípusKódLeírásFizikai mozgás
Saját raktárPHYSICALNormál pick/pack/shipPolcról szedés → csomagolás → szállítás
Beszállítói rendelésSUPPLIER_ORDERPO → áruátvétel → shipBeszállító → mi → vevő
DropshipDROPSHIPPO a vevő címévelBeszállító → vevő (mi nem nyúlunk hozzá)
ElőrendelésPRE_ORDERVárunk a készletre (PO ETA ismert)PO megérkezés → normál flow
BackorderBACKORDERNincs készlet sehol, nincs ETAVá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ípusLeírásForrás → Cél
RECEIVEÁruátvétel (PO-ból)— → fizikai lokáció
PUTAWAYBetárolásRECEIVING → STORAGE
PICKKomissiózásSTORAGE → SHIPPING/PACK
PACKCsomagolásPICK → csomag
SHIPKiszállításSHIPPING → —
MOVEÁthelyezéslokáció A → lokáció B
ADJUST_UPKorrekció felfelé— → lokáció
ADJUST_DOWNKorrekció lefelélokáció → —
RESERVEFoglalásállapotváltás
UNRESERVEFoglalás feloldásállapotváltás
BLOCKZárolásállapotváltás
UNBLOCKFeloldásállapotváltás
RMA_RECEIVEVisszáru beérkezés— → RMA lokáció
RMA_RESTOCKVisszáru visszapolcozásRMA → STORAGE
SCRAPSelejtezéslokáció → SCRAP
CROSS_DOCKÁtrakóRECEIVING → SHIPPING
TRANSFERRaktárközi transzferW1 → W2
VIRTUAL_RESERVEVirtuális készlet foglalásvirtuális raktár állapotváltás
VIRTUAL_RELEASEVirtuális foglalás feloldásvirtuális raktár állapotváltás
DROPSHIP_ORDERDropship rendelés a beszállítónakvirtuális → in_transit
DROPSHIP_DELIVERDropship kiszállítva a vevőnekin_transit → —
PRE_ORDER_RESERVEElőrendelés foglalás (jövőbeli készletre)logikai foglalás
PRE_ORDER_FULFILLElő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égiaLogika
FIXEDTermékhez rögzített lokáció
CLOSEST_AVAILABLELegközelebbi szabad hely (Dijkstra)
ZONE_BASEDTermékkategória → shelf mapping
CONSOLIDATEOda, ahol már van ugyanabból
ABC_CLASSA-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égiaLeírásMikor
FIFOLegrégebben bevételezett előszörAlapértelmezett
FEFOLeghamarabb lejáró előszörLejáratos termék
LIFOLegutóbb bevételezett előszörSpeciális eset
NONEBármelyik lokációrólNem 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álatTípusPrioritás
GLS HungaryCsomagküldésP1
MPL (Magyar Posta)CsomagküldésP1
DPDCsomagküldésP2
FoxPostCsomagautomataP2
PacketaCsomagpontP2
Saját futárLokális kiszállításP2

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 PODropship PO
Szállítási címSaját raktárVevő címe
CsomagolásMi csomagolunkBeszállító csomagol
Shipping labelMi generáljukBeszállító generálja (vagy mi, ha az ő rendszere engedi)
TrackingSaját futár trackingBeszállító tracking → passthrough a vevőnek
KészletmozgásRECEIVE → PUTAWAY → PICK → SHIPNincs fizikai mozgás (DROPSHIP_ORDER → DROPSHIP_DELIVER)
SzámlázásMi számlázunk a vevőnekMi 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ípusKódLeírásSzállítási cím
NormálSTANDARDHagyományos beszerzés → saját raktárbaSaját raktár
ÖsszevárásbólBATCHEDTöbb rendelésből összesítve generáltSaját raktár
DropshipDROPSHIPKözvetlen kiszállítás a vevőnekVevő 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égiaLeírás
DAILYNaponta egyszer, beállított időpontban (pl. 14:00)
INTERVALX óránként (pl. 4 óránként)
THRESHOLDAmikor az összegyűlt érték eléri a company_supplier_details.min_order_value-t
MANUALCsak 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ÁFADokumentumok
BelföldiMagyar ÁFA (27%)Számla
EU Közösségi0% (Reverse Charge)Számla + Intrastat
Harmadik országImport ÁFA + VámSzá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

GradeLeírásMűvelet
AÚjra eladhatóVisszapolcozás → AVAILABLE
BCsökkentett áron eladhatóVisszapolcozás → outlet
CJavítandóSzerviz → újra grading
SCRAPNem 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

  1. 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ányAdatTrigger
Webshop → WarehouseRendelésWebhook / RabbitMQ
Warehouse → WebshopKészlet szint (fizikai + virtuális)Inventory summary változás
Webshop → WarehouseTermék adatokSzinkron / 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ódLeírás
Email PDFPO export PDF generálás + email küldés company_supplier_details.order_email-re
APIBeszállító REST API-ján keresztül PO beküldés (egyedi implementáció per beszállító)
PortálAdmin manuálisan rendel a beszállító webes felületén
EDIElektronikus adatcsere (nagy beszállítóknál, későbbi fázis)

21.5. CRM szinkron

IrányAdatTrigger
CRM → WarehouseCég adatok (cím, kontakt, típus)API / webhook
Warehouse → CRMPO-k, szállítási infókAPI / 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

#FeladatPrioritás
1.1locations tábla (SHELF/ROW/SPACE/BOX) + CRUD APIP0
1.2location_links tábla + CRUD APIP0
1.3Layout Editor refactor: JSON → locations + location_linksP0
1.4Helykód: VECTON-{WAREHOUSE}-{SHELF}-{ROW}-{SPACE}-{BOX}P0
1.5Törlés védelem (inventory check)P0
1.6inventory + inventory_transactions + inventory_summaryP0
1.7Alapvető mozgások: MOVE, ADJUST_UP, ADJUST_DOWNP0
1.8Label generator: location_ids input, range/manual törlésP0
1.9Web UI: lokáció fa + készlet nézet + címke generátorP1
1.102D elölnézet (rack detail) + Shelf Properties panelP1
1.11Route planner átállítás location_links-reP1
1.12Layout 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

#FeladatPrioritás
2.1CRM company_types pivot tábla + APIP0
2.2company_supplier_details tábla (warehouse backend) + CRUDP0
2.3supplier_products tábla + CRUD + prioritásos sorrendP0
2.4Warehouses type mező: physical / virtual / dropship + company_idP0
2.5Virtuális raktár: inventory_summary virtuális raktárakraP0
2.6min_sellable_stock logika (beszállítói küszöb)P0
2.7Beszá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.9Web UI: cég típusok, beszállító panel, termék-beszállító kezelés, prioritás drag & dropP0

Fázis 3 — Beszerzés, Összevárás, Export PDF, Előrendelés ⏱️ ~6-7 hét

#FeladatPrioritás
3.1procurements + procurement_items + PO lifecycleP0
3.2procurement_queue + összevárás logikaP0
3.3Batch PO generálás (daily/interval/threshold/manual)P0
3.4Beszállítói export PDF generálás (supplier_sku-val!)P0
3.5PO email küldés beszállítónakP1
3.6Áruátvételi workflow (RECEIVE → PUTAWAY)P0
3.7Összevárásból érkező áru automatikus kiosztás a rendelésekhezP1
3.8product_availability tábla + előrendelés logikaP1
3.9PO → automatikus product_availability létrehozásP1
3.10Előrendelés teljesítés áruátvételkor (FIFO kiosztás)P1
3.11Landed cost kalkulációP2
3.12Web UI: PO kezelés, queue nézet, áruátvétel, előrendelés kezelésP0

Fázis 4 — Rendelés-routing, Dropshipping ⏱️ ~4-5 hét

#FeladatPrioritás
4.1Order fulfillment routing logika (PHYSICAL / PRE_ORDER / SUPPLIER_ORDER / DROPSHIP / BACKORDER)P0
4.2Prioritásos beszállító kiválasztás (5.2. algoritmus)P0
4.3Dropship PO generálás (vevő címével)P0
4.4Dropship tracking passthroughP1
4.5Vegyes rendelés kezelés (dropship + fizikai + előrendelés)P1
4.6Dropship profit számításP2
4.7Web UI: routing nézet, dropship kezelésP0

Fázis 5 — Komissiózás, Csomagolás, Szállítás ⏱️ ~4-6 hét

#FeladatPrioritás
5.1RESERVE/UNRESERVE logika + timeoutP0
5.2picking_tasks + picking_task_itemsP0
5.3Pick list generálás (FIFO/FEFO) + route plannerP0
5.4packages + package_items (packing)P0
5.5ShippingProvider interface + GLS + MPLP0
5.6Shipping label + tracking visszaírásP0
5.7Batch/Wave pickingP2
5.8Web UI: picking, packing station, shippingP0

Fázis 6 — RMA, Leltár, Haladó ⏱️ ~3-4 hét + folyamatos

#FeladatPrioritás
6.1RMA state machine + grading + fotókP0
6.2Dropship visszáru kezelésP1
6.3Leltár (full / cycle count / spot check)P0
6.4Blind count módP2
6.5Vámkezelés workflowP2
6.6Raktárközi transzferP2
6.7Dashboard & riportokP1
6.8Beszállítói API integráció (EDI)P3
6.9Lejárat figyelő cron + auto zárolásP1

Összefoglaló

A rendszer kulcs tervezési döntései:

  • CRM integráció: Beszállítók/vevők a CRM companies táblában, company_types pivot-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 (priority mező), 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_availability tá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 locations tá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 locations táblából
  • Immutable audit trail: Minden mozgás naplózva, befagyasztott kódokkal
  • Tenant izoláció infrastruktúra szinten: Nincs tenant_id