Birden fazla depo işletmek, WooCommerce’in doğal olarak ele almak üzere tasarlanmadığı bir karmaşıklığı beraberinde getirir. WooCommerce ürün başına tek bir stok miktarını takip eder. ERP’in ise 3, 5 veya 20 lokasyonda stok takip eder. Açık konuşayım: bu açığı kapatmanın kolay bir düğmesi yok — envanterin nasıl toplandığı, siparişlerin nasıl yönlendirildiği ve müşterinin kullanılabilirliği nasıl gördüğü hakkında dikkatli mimari kararlar gerektiriyor.
Çok depolu depo zorluğu
ERP’in şunu gösterir:
Product: SKU-1234 "Blue Widget"
├── Warehouse A (New York): 50 units
├── Warehouse B (Los Angeles): 30 units
├── Warehouse C (Chicago): 0 units
└── Total Available: 80 units
WooCommerce ne göstermeli? Seçenekler:
- Toplam kullanılabilir (80) — en basit, ancak başka yerde taahhüt edilmiş stoğu vaat edebilir
- En yakın depo — sepete eklemeden önce müşteri konumunu bilmeyi gerektirir
- Yalnızca karşılama deposu — sadece çevrimiçi siparişler için belirlenmiş depodan stoğu göster
- Kullanılabilir eksi tampon — toplam eksi güvenlik marjı (örn. 72 = 80 – %10)
Mimari
ERP (multi-warehouse stock)
→ Aggregation Logic (middleware)
→ WooCommerce (single stock number per product)
WooCommerce (order placed)
→ Routing Logic (middleware)
→ ERP (assign to optimal warehouse)
Middleware, ERP’in çok lokasyonlu modeli ile WooCommerce’in tek lokasyonlu modeli arasındaki uyumsuzluğu ele alır. Bütün oyun burada dönüyor: WooCommerce’i basit tutuyorsun, karmaşıklığı aradaki katmana yıkıyorsun.
Envanter toplama stratejileri
Strateji 1: Tüm depoları topla
function aggregateStock(erpItem) {
const totalStock = erpItem.warehouses.reduce(
(sum, wh) => sum + wh.available, 0
);
return {
sku: erpItem.sku,
stock_quantity: totalStock,
stock_status: totalStock > 0 ? 'instock' : 'outofstock'
};
}
Artıları: Satılabilir envanteri maksimize eder.
Eksileri: Depoya özel taahhütler takip edilmiyorsa aşırı satış yapabilir.
Strateji 2: Ana depo + taşma
Çevrimiçi siparişler için ana karşılama merkezi olarak bir depo belirle. Stokunu göster, ancak ikincil depolardan taşmaya izin ver:
function aggregateStock(erpItem, primaryWarehouseId) {
const primary = erpItem.warehouses.find(w => w.id === primaryWarehouseId);
const overflow = erpItem.warehouses
.filter(w => w.id !== primaryWarehouseId)
.reduce((sum, w) => sum + w.available, 0);
// Show primary stock + 50% of overflow (buffer for retail/wholesale)
const displayStock = (primary?.available || 0) + Math.floor(overflow * 0.5);
return {
sku: erpItem.sku,
stock_quantity: displayStock,
stock_status: displayStock > 0 ? 'instock' : 'outofstock'
};
}
Strateji 3: Bölgesel gösterim (ileri seviye)
Müşterinin tespit edilen bölgesine göre farklı stok seviyelerini göster:
async function getRegionalStock(erpItem, customerRegion) {
const regionWarehouseMap = {
'east': ['WH-NYC', 'WH-ATL'],
'west': ['WH-LAX', 'WH-SEA'],
'central': ['WH-CHI', 'WH-DAL']
};
const relevantWarehouses = regionWarehouseMap[customerRegion] || Object.values(regionWarehouseMap).flat();
const regionalStock = erpItem.warehouses
.filter(w => relevantWarehouses.includes(w.id))
.reduce((sum, w) => sum + w.available, 0);
return { stock_quantity: regionalStock };
}
Bu, frontend’de dinamik stok gösterimi gerektirir — genellikle müşterinin konumunu tespit ettikten sonra bir AJAX çağrısı aracılığıyla.
Sipariş yönlendirme
Bir sipariş geldiğinde, middleware’in hangi deponun onu karşılayacağına karar vermelidir:
function routeOrder(order, warehouseStock) {
const shippingState = order.shipping.state;
const items = order.line_items;
// 1. Find warehouses that can fulfill the entire order
const candidates = warehouseStock.filter(wh =>
items.every(item =>
wh.inventory[item.sku] >= item.quantity
)
);
if (candidates.length === 0) {
// No single warehouse can fulfill — need split shipment
return splitShipment(order, warehouseStock);
}
// 2. Score candidates
const scored = candidates.map(wh => ({
warehouse: wh,
score: calculateScore(wh, shippingState, items)
}));
// 3. Select best warehouse
return scored.sort((a, b) => b.score - a.score)[0].warehouse;
}
function calculateScore(warehouse, customerState, items) {
let score = 0;
// Proximity (shipping zone distance)
const distance = getDistance(warehouse.state, customerState);
score += (1000 - distance) * 2; // Closer = higher score
// Stock depth (prefer warehouses with more stock)
const minStockRatio = Math.min(
...items.map(item => warehouse.inventory[item.sku] / item.quantity)
);
score += minStockRatio * 100;
// Workload (prefer less busy warehouses)
score -= warehouse.pendingOrders * 5;
return score;
}
Bölünmüş kargolar
Hiçbir depo tek başına tüm siparişi karşılayamadığında:
function splitShipment(order, warehouses) {
const shipments = [];
const remaining = [...order.line_items];
// Greedy algorithm: assign items to nearest warehouse with stock
while (remaining.length > 0) {
const item = remaining[0];
const warehouse = warehouses
.filter(wh => wh.inventory[item.sku] >= item.quantity)
.sort((a, b) =>
getDistance(a.state, order.shipping.state) -
getDistance(b.state, order.shipping.state)
)[0];
if (!warehouse) {
throw new Error(`Cannot fulfill ${item.sku}: insufficient stock across all warehouses`);
}
// Find or create shipment for this warehouse
let shipment = shipments.find(s => s.warehouseId === warehouse.id);
if (!shipment) {
shipment = { warehouseId: warehouse.id, items: [] };
shipments.push(shipment);
}
shipment.items.push(item);
warehouse.inventory[item.sku] -= item.quantity;
remaining.shift();
}
return shipments;
}
Bölünmüş kargolar için müşteri iletişimi:
- Müşteriye siparişinin birden fazla pakette geleceğini bildir
- Kargo başına ayrı takip numaraları sağla
- Ekstra kargo ücreti alma (maliyeti karşıla)
WooCommerce uygulaması
Plugin yaklaşımı
WooCommerce’e depo başına stok takibi ekleyen bir çok depolu plugin (ATUM veya WooCommerce Multi-Warehouse gibi) kullan. ERP senkronizasyonun her deponun stok seviyesini günceller.
Özel meta yaklaşımı
Depo seviyesindeki verileri ürün meta’sında sakla:
// Store per-warehouse stock in product meta
update_post_meta($product_id, '_warehouse_stock', json_encode([
'WH-NYC' => 50,
'WH-LAX' => 30,
'WH-CHI' => 0
]));
// Display stock is the aggregated number
update_post_meta($product_id, '_stock', 80);
update_post_meta($product_id, '_stock_status', 'instock');
Fazla satışın gerçek maliyeti ve güvenlik tamponu
Şimdi bir dakikalığına strateji tablosundan çıkıp işletme tarafına bakalım, çünkü çok depolu kurulumlarda insanların kendini asıl yaktığı yer burası. Toplam stoğu (yukarıdaki Strateji 1) göstermek kâğıt üzerinde en çok satışı vaat eder; pratikte ise en sık fazla satışa yol açan seçenek de odur. Sebep basit: 80 birimin 30’u Los Angeles deposunda başka bir kanala, bir toptancıya ya da bir mağaza içi rezervasyona söz verilmiş olabilir. Sistem bunu bilmez, sen “stokta” gösterirsin, müşteri sipariş verir, ve depoda o birim yoktur. O andan itibaren ya siparişi iptal edip özür dilersin ya da bir yerden acil tedarik ararsın — ikisi de para ve güven kaybı.
Ben olsam her toplama stratejisinin üstüne küçük bir güvenlik tamponu koyardım — toplamın yüzde beş ila onunu görünür stoktan düşerdim. Evet, kâğıt üzerinde birkaç satışı masada bırakırsın; ama iptal, geç kalan kargo ve “sipariş ettim, gelmedi” e-postalarının maliyeti neredeyse her zaman o birkaç kaçan satıştan yüksektir. Tamponu sabit bir sayı olarak değil, deponun geçmiş hata payına göre ayarla: envanteri sık kayan bir depo daha büyük tampon hak eder. Bu sıkıcı bir ayar gibi görünür, ama fazla satışın müşteri hizmetlerinde açtığı yarayı bir kez yaşayan herkes neden buna değdiğini bilir.
Çok depolu operasyonları izleme
| Metrik | Neyi takip etmeli |
|---|---|
| Stok doğruluğu | ERP stoku vs WooCommerce gösterilen stok |
| Yönlendirme verimliliği | En yakın depodan karşılanan siparişlerin % oranı |
| Bölünmüş kargo oranı | Bölünmüş kargo gerektiren siparişlerin % oranı (hedef: < %5) |
| Depoya göre karşılama süresi | Yavaş depoları tespit et |
| Stok tükenmesi olayları | Toplam stok sıfıra düştüğünde |
Sonuç
Çok depolu WooCommerce temelde middleware aracılığıyla çözülen bir ERP problemidir. WooCommerce basitleştirilmiş bir görünüm sergiler; ERP’in karmaşıklığı yönetir. Temel kararlar — toplama stratejisi, yönlendirme mantığı ve bölünmüş kargo işleme — senin spesifik lojistik kurulumuna bağlıdır. En basit toplama ile başla (toplam veya ana depo), temel yönlendirme uygula ve karmaşıklığı yalnızca veriler buna ihtiyacın olduğunu gösterdiğinde ekle. Bunu haklı çıkaracak sipariş hacmine sahip olmadan önce depo mantığını aşırı mühendislik yapmak, geliştirme zamanını boşa harcar. Otuz yıldır aynı dersi görüyorum: sistemi karmaşıklaştıran değil, karmaşıklığı gerçekten gerektiği ana kadar erteleyen ekip kazanıyor.
Last modified: Ağustos 2, 2026
United States / English
Slovensko / Slovenčina
Canada / Français
Türkiye / Türkçe