Modüllere Dön

HAMMADDE — HAM MALZEME YÖNETİMİ

Satın alma siparişinden QR kodlu envantere uzanan tedarik zinciri. Fabrika kapısından giren her gram bakır, kalay, plastik, katalizör, boya, palet ve makara — anlık takip altında.

Şubat 2026 • Solen Kablo • Yaşayan Doküman

Hammadde, fiziksel malzemenin dijital takiple buluştuğu yerdir. Bir kablo fabrikası sekiz kategori hammadde tüketir: bakır tel çubukları, kalay külçeleri, plastik granüller, katalizörler, boyalar, anti-kemirgen bileşikler, paletler (ahşap nakliye platformları) ve makaralar (kablo tamburları). Her biri bir tedarikçiden gelir, tartılır, fotoğraflanır, benzersiz bir QR kodu atanır ve sisteme girilir. O andan itibaren malzeme izlenebilirdir — üretim tüketiminden kalan ağırlık takibine ve makaradaki bitmiş kabloya kadar. Hammadde ayrıca tüm satın alma sipariş yaşam döngüsünü yönetir: sipariş oluşturmadan teslimat tarihlerini takibe, tarih değişikliği nedenlerini kaydetmeye ve teslimat sonrası tedarikçi performansını puanlamaya kadar.

4
ALT MODÜL
~30
API ENDPOINT
6
VERİTABANI TABLOSU
5100+
SATIR FRONTEND

İÇİNDEKİLER

1. Hammadde Ne Yapar 2. Veri Akışı 3. Veritabanı Katmanı 4. Backend Mimarisi 5. Frontend 6. Alt Modüller 6.1 Tedarikçi Yönetimi 6.2 Hammadde Sipariş 6.3 Hammadde Girişi 6.4 Hammaddeler Listesi 7. Sonuç

1. HAMMADDE NE YAPAR

Hammadde modülü, fabrikanın tedarik zincirinin bağlı olduğu dört soruyu yanıtlar:

  1. Stokta hangi hammaddeler var? — Malzeme Girişi gelen her sevkiyatı kaydeder. Bakır paletler halinde gelir (teslimat başına birden fazla), kalay tek tartımlı külçe olarak ve plastik/katalizör/boya/antirodent lot bazlı girişler olarak. Her birine QR kodu atanır (A=bakır, B=kalay, C=plastik, D=katalizör, E=boya, F=antirodent, I=palet, H=makara), teslimat ve test fotoğrafları eklenir ve satın alma siparişine bağlanır.
  2. Her gram malzeme şu anda nerede? — Hammaddeler Listesi lazy-load fotoğraf önizlemeleri, durum takibi (received → approved → in_use → consumed/rejected), üretim sonrası kalan ağırlık ve malzeme oluşturma/değiştirme/silme sırasında gerçek zamanlı WebSocket güncellemeleriyle tam envanter görünümü sunar.
  3. Ne sipariş ettik ve ne zaman gelecek? — Hammadde Sipariş, sipariş grup kodları (R1, R2, R3...), beklenen teslimat tarihleri, gerçek teslimat tarihleri, nedenli tarih değişikliği geçmişi (tedarikçi/solen/diğer), teslim edilen miktar takibi ve teslimat sonrası tedarikçi puanlaması (0.5–5 yıldız) ile her satın almayı izler.
  4. Tedarikçilerimiz kim ve ne sağlıyorlar? — Tedarikçi Yönetimi bire-çok ilişki yönetir: bir tedarikçi şirket birden fazla malzeme türü sağlayabilir (bakır, plastik, boya vb.), her biri yoğunluk (g/cm³), boyut ve makara tipi (yazılı/yazısız) gibi malzemeye özgü özellikler taşır.

Alt akış tüketicisi. Hammadde, Teknik modülünün Kablo Veritabanı’nın birincil tüketicisidir. Sipariş modülü bir sipariş için malzeme gereksinimlerini hesapladığında (bakır ağırlığı, kalay kaplama, plastik hacimler, katalizör/boya yüzdeleri), Teknik’ten kablo özelliklerini okuyan ve Hammadde’nin karşılaması gereken tedarik miktarlarını üreten material_calculator servisini kullanır. Malzeme Girişi sayfası ayrıca gelen teslimatları doğrudan Malzeme Siparişlerine bağlayarak “ne sipariş edildi” ile “gerçekte ne geldi” arasındaki döngüyü kapatır.

2. VERİ AKIŞI

Veri, Hammadde modülünde net bir tedarik-tüketim döngüsünde akar:

Tedarik Akışı

TEDARİKÇİ
Sisteme kayıtlı
SİPARİŞ
R1, R2... oluşturulur
TESLİMAT
Tarih takibi
GİRİŞ
QR + fotoğraf

Tüketim Akışı

MALZEME
Durum: teslim alındı
ONAYLANDI
Lab onayı
KULLANIMDA
Üretim hattında
TÜKETİLDİ
remaining_weight = 0

Sipariş-Giriş Bağlantısı

Malzeme teslimatı geldiğinde, Malzeme Girişi sayfası gelen malzemeyi doğrudan bekleyen satın alma siparişine bağlayabilir. Bu, siparişin delivered_quantity değerini günceller, durumunu delivered olarak ayarlar ve delivered_date kaydeder. Bu sıkı bağlantı sayesinde sistem her zaman bilir: sipariş edilen her kilogram için gerçekte ne kadar geldi ve ne zaman.

Her yerde gerçek zamanlı. Her malzeme oluşturma, güncelleme ve silme bir WebSocket olayı yayınlar. Hammaddeler Listesi sayfası polling olmadan otomatik yenilenir. Tedarikçi Yönetimi sayfası da aynı şekilde. Bu, birden fazla kullanıcının (lab teknisyenleri, satın alma personeli) tüm ekranlarında değişiklikleri anında görmesi anlamına gelir.

3. VERİTABANI KATMANI

Hammadde modülüne 6 tablo hizmet eder. Üç gruba ayrılırlar:

Malzeme Tabloları (2)

raw_materials

Merkezi tablo. Fabrikaya giren her fiziksel malzeme — türü ne olursa olsun — burada bir satır alır.

KolonTipAmaç
idINTEGER PKOtomatik artan birincil anahtar
material_typeVARCHAR(50)raw_copper, raw_tin, raw_plastic, raw_catalyst, raw_dye, raw_antirodent, raw_palette, raw_reel
material_nameVARCHAR(200)Tedarikçi kataloğundan spesifik malzeme adı (ör. HFX500, K388)
sequence_numberINTEGERTür bazlı sayaç — her material_type için ayrı sıra
qr_codeVARCHAR(50) UNIQUEOluşturulan kod: ön ek + sıra (A1, B7, C23, I145...)
supplier_idFK → suppliersBu malzemeyi hangi tedarikçi sağladı
material_order_idFK → material_ordersSatın alma siparişine bağlantı (teslimat takibi için)
lot_numberVARCHAR(100)Tedarikçinin lot numarası (veya kalay için otomatik: TIN-N)
weightFLOATTeslim alındığında ölçülen ağırlık (kg)
remaining_weightFLOATÜretim tüketimi sonrası kalan ağırlık (kg)
form_weightFLOATResmi form ağırlığı (bakır paletler için)
quantityINTEGERLot bazlı malzemeler için adet (plastik/katalizör/boya/antirodent)
statusVARCHAR(50)received → approved → in_use → consumed | rejected
entered_byFK → usersMalzemeyi sisteme kim girdi
notesTEXTSerbest notlar
received_dateDATETIMEMalzemenin fiziksel olarak teslim alındığı zaman
created_atDATETIMEKayıt oluşturma zaman damgası
updated_atDATETIMESon güncelleme zaman damgası (değişiklikte otomatik)

material_photos

Lazy loading performansı için fotoğraflar ayrı tabloda tutulur. Binlerce malzeme varken, her liste sorgusunda base64 fotoğraf verisi yüklemek felaket olurdu. Bunun yerine liste sadece fotoğraf ID’lerini döner ve frontend gerçek fotoğraf verisini talep üzerine çeker.

KolonTipAmaç
idINTEGER PKFotoğraf tanımlayıcısı
material_idFK → raw_materials (CASCADE)Bu fotoğraf hangi malzemeye ait
photo_typeVARCHAR(20)‘delivery’ veya ‘test’
sequenceINTEGER1, 2 veya 3 (tür başına en fazla 3 fotoğraf)
photo_dataTEXTBase64 kodlanmış görüntü verisi
created_atDATETIMEYükleme zaman damgası

Performans deseni: Eski tasarım fotoğrafları doğrudan raw_materials tablosunda base64 dizilerinin JSON dizileri olarak saklıyordu. Bu, liste sorgularını dayanılmaz derecede yavaşlatıyordu. Ayrı bir material_photos tablosuna geçiş ve bireysel fotoğraf endpoint’leri (GET /materials/photo/{id}) üzerinden lazy loading ile bu sorun tamamen çözüldü. Eski kolonlar (delivery_form_photo, test_report_photo, delivery_form_photos, test_report_photos) geriye uyumluluk için tutulur ancak artık kullanılmaz.

Sipariş Tabloları (2)

material_orders

Satın alma siparişlerini takip eder. Resmi ERP satın alma siparişleri değil — malzemelerin ne zaman gelmesinin beklendiğine dair dahili takip kayıtlarıdır.

KolonTipAmaç
idINTEGER PKSipariş tanımlayıcısı
order_group_codeVARCHAR(20)Gruplama kodu (R1, R2...) — aynı sevkiyattan siparişler bunu paylaşır
material_typeVARCHAR(50)Ne sipariş ediliyor (bakır, plastik vb.)
supplier_idFK → suppliersSiparişi hangi tedarikçi karşılıyor
supplier_material_idFK → supplier_materialsSipariş edilen spesifik malzeme
quantityFLOATSipariş edilen miktar
delivered_quantityFLOATGerçekte teslim edilen miktar (malzeme girişi bağlandığında güncellenir)
unitVARCHAR(20)Malzemeler için ‘kg’, palet/makara için ‘adet’
order_dateDATESiparişin verildiği tarih
expected_dateDATETeslimatın beklendiği tarih (değişebilir — takip edilir)
delivered_dateDATEGerçek teslimat tarihi
statusVARCHAR(20)pending → shipped → delivered | cancelled
ratingFLOATTeslimat sonrası puan (0.5–5 yıldız, yarım artışlarla)
rating_noteTEXTPuanlama yorumu
notesTEXTSipariş notları
created_byFK → usersBu siparişi kim oluşturdu

material_order_date_changes

Beklenen teslimat tarihi değişiklikleri için denetim izi. Birisi beklenen tarihi her değiştirdiğinde, sistem nedenini kaydeder.

KolonTipAmaç
idINTEGER PKDeğişiklik kaydı tanımlayıcısı
order_idFK → material_orders (CASCADE)Hangi sipariş değiştirildi
old_dateDATEÖnceki beklenen tarih
new_dateDATEYeni beklenen tarih
reason_typeVARCHAR(20)‘supplier’ | ‘solen’ | ‘other’
reason_detailTEXTManuel açıklama (‘other’ için zorunlu)
changed_byFK → usersTarihi kim değiştirdi
created_atDATETIMEDeğişikliğin kaydedildiği zaman

Tedarikçi Tabloları (2)

suppliers

Şirket düzeyinde tedarikçi kayıtları. Her tedarikçi, iletişim bilgileriyle birlikte tek bir şirkettir.

KolonTipAmaç
idINTEGER PKTedarikçi tanımlayıcısı
nameVARCHAR(200) UNIQUEŞirket adı (BÜYÜK HARF olarak saklanır)
contact_personVARCHAR(100)Birincil iletişim kişisi
phoneVARCHAR(50)Otomatik biçimlendirilen Türk telefon numarası
emailVARCHAR(100)E-posta (regex doğrulamalı)
addressTEXTFiziksel adres
tax_numberVARCHAR(50)Vergi sicil numarası
is_activeBOOLEANYumuşak silme bayrağı (aktif/pasif geçişi)
notesTEXTSerbest notlar

supplier_materials

Bire-çok ilişki. Bir tedarikçi birden fazla malzeme türü sağlayabilir, her biri türe özgü özellikler taşır.

KolonTipAmaç
idINTEGER PKTedarikçi-malzeme bağlantı tanımlayıcısı
supplier_idFK → suppliersHangi tedarikçi
material_typeVARCHAR(50)copper, tin, plastic, catalyst, dye, antirodent, palette, reel
material_nameVARCHAR(100)Spesifik ürün adı (HF-500, CAT-203 vb.)
densityFLOATPlastik/katalizör/boya/antirodent için (g/cm³)
boyutVARCHAR(100)Palet/makara için boyutlar
reel_typeVARCHAR(20)Makaralar için: Yazılı/Yazısız (etiketli/etiketsiz)
is_activeBOOLEANBu malzemenin hâlâ sunulup sunulmadığı

Varlık ilişki özeti: suppliers 1—N supplier_materials (ne satıyorlar), suppliers 1—N raw_materials (ne teslim ettiler), material_orders N—1 suppliers (kimden sipariş ettik), material_orders N—1 supplier_materials (tam olarak ne), raw_materials N—1 material_orders (bağlı teslimat), raw_materials 1—N material_photos (lazy-loaded), material_orders 1—N material_order_date_changes (denetim izi).

4. BACKEND MİMARİSİ

Backend FastAPI ile inşa edilmiş olup 4 route dosyası, 4 model, 2 şema dosyası ve 1 servisten oluşur. Toplam backend kodu: ~3.200 satır.

4.1 Route Organizasyonu

material_routes.py (986 satır)

Router ön eki: /api/materials
Ana malzeme CRUD. Bakır girişi (çoklu palet), kalay girişi (tekli), lot bazlı giriş (plastik/katalizör/boya/antirodent), fotoğraf alma, listeleme, güncelleme, baskı önizleme, yazıcı yönetimi, QR yazdırma, durum geçişi ve kalıcı silme. palette_routes alt yönlendiricisini içerir.

material_order_routes.py (478 satır)

Router ön eki: /api/material-orders
Sipariş yaşam döngüsü yönetimi. Filtreli listeleme, tedarikçi/tarihe göre gruplanmış bekleyen siparişler (Malzeme Girişi bağlantısı için), tekli veya toplu oluşturma (otomatik R kodları), tarih değişikliği takipli güncelleme, tarih değişikliği geçmişi alma, teslimat puanlama ve silme.

palette_routes.py (316 satır)

material_routes içinde yer alır (ayrı ön ek yok).
Palet ve makara giriş endpoint’leri. lot-entry’ye benzer ancak envanter kalemleri için özelleştirilmiş: paletler QR ön eki I, makaralar H alır. Her ikisi de sipariş bağlama ve fotoğraf yüklemeyi destekler.

supplier_routes.py (435 satır)

Router ön eki: /api/suppliers
Tam tedarikçi yaşam döngüsü: iç içe malzemelerle oluşturma, eager-loaded malzemelerle listeleme, malzeme türüne göre filtreleme, benzersiz malzeme listesi (tekilleştirilmiş özellikler), tekil tedarikçi alma, malzeme değişimiyle güncelleme, bağımlılık kontrolüyle kalıcı silme ve durum geçişi.

4.2 QR Kod Sistemi

Her malzeme, tür ön eki ve sıra numarasına dayalı deterministik bir QR kodu alır:

def generate_qr_code(material_type: str, sequence_number: int) -> str:
    prefix_map = {
        "raw_copper":     "A",   # A1, A2, A3...
        "raw_tin":        "B",   # B1, B2, B3...
        "raw_plastic":    "C",   # C1, C2, C3...
        "raw_catalyst":   "D",   # D1, D2, D3...
        "raw_dye":        "E",   # E1, E2, E3...
        "raw_antirodent": "F",   # F1, F2, F3...
        "raw_palette":    "I",   # I1, I2, I3...
        "raw_reel":       "H",   # H1, H2, H3...
    }
    prefix = prefix_map.get(material_type, "X")
    return f"{prefix}{sequence_number}"

Sıra numarası tür bazlıdır: sistem o material_type için maksimum sequence_number değerini sorgular ve artırır. Bu, A1 ve B1’in birlikte var olabileceği anlamına gelir — her türün kendi bağımsız sayacı vardır.

4.3 Malzeme Giriş Mantığı

Giriş endpoint’i, malzeme türüne göre temelden farklı üç akışı yönetir:

Malzeme TürüGiriş YöntemiTemel Davranış
Bakır (raw_copper)POST /materials/entryPalet başına bir satır oluşturur. 5 paletlik tek teslimat 5 raw_materials satırı oluşturur, her birinin kendi QR kodu (A1, A2...), lot numarası ve ölçülen ağırlığı olur.
Kalay (raw_tin)POST /materials/entryTek satır oluşturur. Tek ağırlık girişi. Lot numarası otomatik: TIN-{sıra}.
Plastik, Katalizör, Boya, AntirodentPOST /materials/lot-entryLot başına bir satır oluşturur. Her lotun kendi test fotoğrafları, ağırlığı ve adedi olur. Malzeme adı supplier_materials tablosundan çözümlenir.
PaletPOST /materials/palette-entryPalet tipi başına bir satır oluşturur. QR ön eki I. Lot otomatik: PALET-{sıra}.
MakaraPOST /materials/reel-entryMakara tipi başına bir satır oluşturur. QR ön eki H. Lot otomatik: REEL-{sıra}.

4.4 Sipariş Grup Kodları

Malzeme siparişleri oluştururken, sistem mevcut en yüksek R numarasını bulup artırarak bir grup kodu (R1, R2, R3...) üretir:

def generate_order_group_code(db: Session) -> str:
    # Mevcut kodlardan en yüksek R numarasını al
    result = db.query(func.max(MaterialOrder.order_group_code)).filter(
        MaterialOrder.order_group_code.isnot(None),
        MaterialOrder.order_group_code.like('R%')
    ).scalar()

    if result:
        match = re.search(r'R(\d+)', result)
        if match:
            return f"R{int(match.group(1)) + 1}"
    return "R1"

Aynı sevkiyattan gelen siparişler bir grup kodunu paylaşır. Bu, sistemin arayüzde gruplanmış siparişleri göstermesini ve birden fazla malzeme girişini aynı teslimat olayına bağlamasını sağlar.

4.5 Tarih Değişikliği Takibi

Bir siparişin beklenen tarihi değiştirildiğinde, güncelleme endpoint’i değişikliği otomatik olarak kaydeder:

# Tarih gerçekten değiştiyse ve neden sağlandıysa, kaydet
if old_expected_date != new_expected_date:
    if 'date_change_reason' in data:
        date_change = MaterialOrderDateChange(
            order_id=order.id,
            old_date=old_expected_date,
            new_date=new_expected_date,
            reason_type=data['date_change_reason'],         # supplier | solen | other
            reason_detail=data.get('date_change_detail'),  # serbest metin
            changed_by=current_user.id
        )
        db.add(date_change)

Üç neden kategorisi: supplier (tedarikçi kaynaklı gecikme), solen (Solen dahili kaynaklı gecikme), other (manuel açıklama gerektirir). Bu, tedarik performans analizi için bir hesap verebilirlik izi oluşturur.

4.6 Malzeme Hesaplayıcı Servisi

material_calculator.py (478 satır) veritabanı bağımlılığı olmayan saf bir hesaplama servisidir. Sağladıkları:

Bakır Hesaplama

calculate_copper(wire_groups, length_meters, bunching_stages)
Tel çapı→adet haritası alır (ör. 6mm² için {0.30: 73}), sabitlerden tel başı ağırlık uygular, uzunlukla çarpar ve çok aşamalı büküm için bileşik büküm faktörü uygular. Toplam kg döner.

Kalay Hesaplama

calculate_tin(copper_kg)
Basit yüzde: copper_kg × TIN_COATING_FACTOR (~%0.7). Kalay kaplama 1.8mm tel üzerinde ~4μm kalınlığındadır.

Plastik Hesaplama

calculate_plastic_weight(inner_dia, thickness, density, length, is_first_layer, num_cables)
Silindirik hacim: π × (R² − r²) × uzunluk. Bakır üzerindeki ilk katman pürüzlü yüzey için %14 aşırı dolgu alır. İkiz kablolar num_cables ile çarpılır. Hacim × yoğunluk = ağırlık.

Katman Hesaplama

calculate_layer(...)
Tüm malzeme alternatifleriyle birlikte tam katman. Her alternatif seçim için plastik + katalizör + boya hesaplar. En kötü durum tedarik planlaması için tüm seçenekler arasında maksimum değerleri döner.

4.7 Yetki Sistemi

Modül hibrit bir yetki yaklaşımı kullanır:

4.8 WebSocket Entegrasyonu

Üç varlık türü gerçek zamanlı güncellemeler yayınlar:

# Malzeme oluşturma sonrası
await broadcast_update("materials", "create", {"id": material.id, "qr_code": material.qr_code})

# Malzeme güncelleme sonrası
await broadcast_update("materials", "update", {"id": material.id, "qr_code": material.qr_code})

# Malzeme silme sonrası
await broadcast_update("materials", "delete", {"id": material_id, "qr_code": qr_code})

# Tedarikçiler de yayınlar
await broadcast_update("suppliers", "create", {"id": new_supplier.id, "name": new_supplier.name})

4.9 Yazdırma Kuyruğu Entegrasyonu

Malzeme QR kodu yazdırma engelleyici değildir. POST /materials/print/{material_id} endpoint’i, yazıcıyı beklerken HTTP isteğini engellemek yerine yazdırma kuyruğu sistemine yönlendirir. Sistem GET /materials/print/preview/{material_id} ile önizleme görüntüsü (base64) üretir ve POST /materials/print/update-printer-ip ile yazıcı IP yapılandırmasına izin verir.

5. FRONTEND

Ant Design Pro ile inşa edilmiş 4 React sayfası, toplamda ~5.100 satır TypeScript. Tüm sayfalar koşullu stillendirme ile karanlık mod desteğine sahiptir.

5.1 Sayfa Haritası

RouteBileşenSatırAmaç
/hammadde/hammadde-girisiLab/MaterialEntry1.9308 malzeme türü kartıyla malzeme girişi, fotoğraf yükleme, sipariş bağlama
/hammadde/hammaddeler-listesiHammadde/HammaddelerListesi1.153Lazy fotoğraf önizlemeleriyle ProTable, CRUD, yazdırma, durum yönetimi
/hammadde/hammadde-siparisHammadde/HammaddeSiparis1.237Tarih değişikliği geçmişi, gruplama, puanlama ile sipariş takibi
/hammadde/tedarikci-yonetimiLab/SupplierManagement761İç içe malzeme türleriyle tedarikçi CRUD, arama, gerçek zamanlı güncellemeler

5.2 Temel Frontend Desenleri

Kart Bazlı Malzeme Seçimi

Malzeme Girişi, birincil navigasyon olarak 8 renkli kart kullanır (bakır=turuncu, kalay=camgöbeği, plastik=mor vb.). Her kart türü, türe özgü alanlarla farklı bir modal form açar. Renkler tema duyarlıdır — karanlık modda 0.12 opaklık ile rgba kullanılarak soluklaştırılır.

Lazy Fotoğraf Yükleme

LazyPhotoThumbnail bileşeni fotoğrafları GET /materials/photo/{id} ile tek tek yükler. Tıklandığında, o malzemenin TÜM fotoğraflarını yükler ve gezinmeli galeri görünümü açar. Bu desen, binlerce malzeme olsa bile liste sayfasını hızlı tutar.

Sipariş Bağlama UX

Malzeme girerken, kullanıcı isteğe bağlı olarak bağlanacak bekleyen bir satın alma siparişi seçebilir. Sistem, GET /material-orders/pending-by-type/{type} ile tedarikçi ve beklenen tarihe göre gruplanmış bekleyen siparişleri çeker ve seçilen siparişten tedarikçi bilgisini otomatik doldurur.

Gerçek Zamanlı WebSocket Güncellemeleri

Hem Hammaddeler Listesi hem de Tedarikçi Yönetimi, sırasıyla materials ve suppliers odalarına abone olan useWebSocket hook’unu kullanır. Herhangi bir oluşturma/güncelleme/silme olayında ProTable actionRef.current?.reload() ile otomatik yenilenir.

5.3 Malzeme Türleri ve Renkleri

TürQR Ön EkiRenkGiriş Yöntemi
BakırATuruncuForm + ölçülen ağırlıklarla çoklu palet
KalayBCamgöbeğiTek ağırlık girişi
PlastikCMorLot başına test fotoğraflarıyla lot bazlı
KatalizörDYeşilLot başına test fotoğraflarıyla lot bazlı
BoyaEPembeLot başına test fotoğraflarıyla lot bazlı
AntirodentFDeniz MavisiLot başına test fotoğraflarıyla lot bazlı
PaletIYeşil SarıPalet tipi başına adet
MakaraHAltınMakara tipi başına adet

6. ALT MODÜLLER

Hammadde modülü, her biri ham malzeme yönetiminin farklı bir yönünü ele alan 4 alt modülden oluşur. Aşağıdaki bölümler her birini derinlemesine inceleyecektir.

6.1

Tedarikçi Yönetimi (Supplier Management)

Bire-çok malzeme ilişkileriyle tedarikçi şirket yönetimi. İç içe malzeme listeleriyle tedarikçi oluşturma, her malzeme türü kendi özelliklerini taşır (yoğunluk, boyut, makara tipi). Akıllı yetki kontrolü, gerçek zamanlı WebSocket güncellemeleri, FK bağımlılık korumasıyla kalıcı silme. Başlangıç noktası — kayıtlı tedarikçi olmadan hiçbir şey sipariş edilemez veya girilemez.

761 SATIR 1:N MALZEMELER AKILLI YETKİLER GERÇEK ZAMANLI FK KORUMA
6.2

Hammadde Sipariş (Material Orders)

Sipariş grup kodları (R1, R2...) ile satın alma sipariş takibi, kategorize edilmiş nedenlerle (tedarikçi/solen/diğer) tarih değişikliği geçmişi, teslimat miktarı takibi, teslimat sonrası tedarikçi puanlaması (yarım artışlarla 0.5–5 yıldız) ve durum yaşam döngüsü yönetimi.

1.237 SATIR SİPARİŞ GRUPLARI TARİH TAKİBİ TEDARİKÇİ PUANLAMA 7 ENDPOINT
6.3

Hammadde Girişi (Material Entry)

1.930 satırlık giriş sayfası. 8 malzeme türü kartı, çoklu palet bakır girişi, lot bazlı kimyasal giriş, fotoğraf yüklemeleri (irsaliye + test raporları, her birinden en fazla 3), QR kod oluşturma ve yazdırma, teslimat takibi için sipariş bağlama. Modüldeki en büyük ve en karmaşık sayfa.

1.930 SATIR 14 ENDPOINT 8 MALZEME TÜRÜ QR KODLAR FOTOĞRAF YÜKLEME
6.4

Hammaddeler Listesi (Materials List)

ProTable ile tam envanter görünümü. Lazy-loaded fotoğraf önizlemeleri, malzeme durum yönetimi (received/approved/in_use/consumed/rejected), QR kodu değiştirme ile düzenleme, bağımlılık kontrolüyle kalıcı silme, kalan ağırlık takibi ve QR kod yazdırma kuyruğu entegrasyonu.

1.153 SATIR PROTABLE LAZY FOTOĞRAFLAR GERÇEK ZAMANLI YAZICI KUYRUĞU

6.1 TEDARİKÇİ YÖNETİMİ (SUPPLIER MANAGEMENT)

Tüm Hammadde modülünün başlangıç noktası. Herhangi bir malzeme sipariş edilmeden veya sisteme girilmeden önce bir tedarikçi mevcut olmalıdır. Bu sayfa tedarikçi şirketlerini ve her birinin sağladığı spesifik malzemeleri yönetir.

6.1.1 Ne Yapar

Tedarikçi Yönetimi bire-çok ilişkiyi yönetir: bir tedarikçi şirket birden fazla malzeme türü sağlayabilir. “ORMETSAN” gibi tek bir tedarikçi hem bakır tel çubuğu hem de kalay külçesi sağlayabilirken, “BETEK” 3 farklı plastik bileşeni, 2 katalizör ve bir boya sağlayabilir — hepsi aynı şirket altında ayrı malzeme girişleri olarak kayıtlıdır.

Sayfa şunları sunar:

6.1.2 API Kontratı

MetotYolFonksiyonYetki
POST/api/suppliers/createcreate_supplierAkıllı: lab_user VEYA hammadde.tedarikci-yonetimi.create_supplier
GET/api/suppliers/listget_suppliersHerhangi kimliği doğrulanmış kullanıcı
GET/api/suppliers/by-material/{type}get_suppliers_by_materialHerhangi kimliği doğrulanmış kullanıcı
GET/api/suppliers/materials-listget_supplier_materials_listHerhangi kimliği doğrulanmış kullanıcı
GET/api/suppliers/{id}get_supplierHerhangi kimliği doğrulanmış kullanıcı
PUT/api/suppliers/{id}update_supplierHerhangi kimliği doğrulanmış kullanıcı
PUT/api/suppliers/{id}/toggle-statustoggle_supplier_statusAkıllı: super_admin VEYA deactivate_supplier
DELETE/api/suppliers/{id}/hard-deletehard_delete_supplierAkıllı: super_admin VEYA hard_delete_supplier

6.1.3 CRUD Akışı

Oluşturma:

  1. Araç çubuğundaki “Yeni Tedarikçi” butonuna tıkla
  2. Modal açılır: firma adı + dinamik malzeme bölümü (başlangıçta bir boş malzeme kartı)
  3. Malzeme tipi seç → koşullu alanlar belirir (plastik için yoğunluk, palet için boyut, makara için boyut+reel_type, bakır/kalay için ek alan yok)
  4. Aynı tedarikçiye daha fazla malzeme eklemek için “+” tıkla
  5. Gönderimde: önyüz undefined değerleri temizler → POST /api/suppliers/create
  6. Başarılı: toast “Tedarikçi başarıyla oluşturuldu” → modal kapanır → WebSocket tüm istemcilere yayın yapar → tablo yenilenir

Düzenleme:

  1. Eylemler sütunundaki düzenle ikonuna tıkla
  2. Modal, mevcut firma adı ve tüm malzeme kartlarıyla önceden dolu açılır
  3. Kullanıcı adı değiştirebilir, malzeme ekleyebilir/kaldırabilir/değiştirebilir
  4. Gönderimde: PUT /api/suppliers/{id} → backend malzemeler için sil-ve-yeniden-oluştur stratejisi kullanır (mevcut TÜM supplier_materials silinir, sıfırdan yenileri oluşturulur)
  5. Başarılı: toast “Tedarikçi başarıyla güncellendi” → modal kapanır → WebSocket yayını → tablo yenilenir

Pasif Silme (Devre Dışı Bırakma):

  1. Eylemler sütunundaki durum değiştir ikonuna tıkla
  2. Popconfirm: “Bu tedarikçiyi devre dışı bırakmak istediğinize emin misiniz?”
  3. Onayda: PUT /api/suppliers/{id}/toggle-status
  4. Tedarikçi satırı “inactive” olur — tabloda hala görünür ama grileştirilmiş. Aynı yolla yeniden etkinleştirilebilir.

Kalıcı Silme:

  1. Eylemler sütunundaki sil ikonuna tıkla (hard_delete_supplier yetkisi gerekir)
  2. Güçlü uyarı metinli Popconfirm
  3. Onayda: DELETE /api/suppliers/{id}/hard-delete
  4. Backend bağımlı raw_materials satırlarını kontrol eder — varsa silme engellenir: “Bu tedarikçiye ait {n} hammadde kaydı var. Önce hammaddeleri silin.”
  5. Bağımlılık yoksa: önce supplier_materials silinir (cascade), sonra supplier → WebSocket yayını → tablo yenilenir

6.1.4 Koşullu Form Mantığı

Oluştur/düzenle modalı dinamik bir malzemeler bölümü içerir. Her malzeme kartı seçilen malzeme türüne göre farklı alanlar gösterir:

Malzeme TürüGösterilen AlanlarÖrnek
Bakır, KalayEk alan yok — “Bu malzeme için ek bilgi gerekmez”
Plastik, Katalizör, Boya, Antirodentmaterial_name + density (g/cm³)HF-500, 1.42 g/cm³
Paletmaterial_name + boyut (ölçüler)Euro Palet, 120x80x15 cm
Makaramaterial_name + boyut + reel_type300mm Makara, 300x150 mm, Yazılı

Malzeme türü açılır menüsü değiştiğinde tüm koşullu alanlar temizlenir:

const updateMaterial = (index: number, field: keyof MaterialItem, value: any) => {
    const newMaterials = [...materials];
    newMaterials[index] = { ...newMaterials[index], [field]: value };

    // Tür değiştiğinde koşullu alanları temizle
    if (field === 'material_type') {
        newMaterials[index].material_name = undefined;
        newMaterials[index].density = undefined;
        newMaterials[index].boyut = undefined;
        newMaterials[index].reel_type = undefined;
    }

    setMaterials(newMaterials);
};

Kullanıcılar sınırsız malzeme ekleyebilir (“Malzeme Ekle” kesikli butonu ile) ve sonuncusu hariç herhangi birini kaldırabilir (minimum 1 malzeme gereklidir). Yeni malzemeler ilki için copper, sonrakiler için plastic varsayılanıyla eklenir.

6.1.5 Backend Doğrulama Zinciri

Veri veritabanına ulaşmadan önce üç Pydantic doğrulayıcısı tetiklenir:

İsim Doğrulayıcı

@validator('name')
def validate_name(cls, v):
    if not v or not v.strip():
        raise ValueError('Tedarikçi adı boş olamaz')
    if any(char in v for char in ['@', '#', '$', '%', '^', '&', '*']):
        raise ValueError('Tedarikçi adı özel karakterler içeremez')
    return v.strip().upper()  # Her zaman BÜYÜK HARF olarak saklanır

Telefon Doğrulayıcı

@validator('phone')
def validate_phone(cls, v):
    # TÜM rakam olmayanları sıyır: boşluk, tire, parantez, artı, nokta
    clean = v.replace(' ','').replace('-','').replace('(','').replace(')','').replace('+','').replace('.','')

    # +90 ülke kodunu kaldır → 0xxx
    if clean.startswith('90') and len(clean) > 10:
        clean = '0' + clean[2:]    # +90 212 → 0212

    # Otomatik biçimlendir: "0212 555 1234"
    if len(clean) == 10:
        return f"{clean[:4]} {clean[4:7]} {clean[7:]}"
    elif len(clean) == 11:       # Mobil: 05xx xxx xxxx
        return f"{clean[:4]} {clean[4:7]} {clean[7:]}"

E-posta Doğrulayıcı

Standart regex kontrolü: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

Duplikasyon koruması: Oluşturmadan önce backend Supplier.name == supplier_data.name.upper() kontrolü yapar. İsimler her zaman büyük harf olarak saklandığından, “ormetsan”, “ORMETSAN” ve “Ormetsan” hepsi aynı tedarikçi olarak değerlendirilir. 400 döner: “Bu tedarikçi zaten kayıtlı”.

6.1.6 Güncelleme Stratejisi: Sil-ve-Yeniden Oluştur

Bir tedarikçinin malzemeleri güncellenirken, backend bireysel kayıtları yamamamaz. Bunun yerine TÜM mevcut supplier_materials satırlarını siler ve yenilerini oluşturur:

# Malzemeler sağlandıysa güncelle
if supplier_data.materials is not None:
    # TÜM eski malzemeleri sil
    db.query(SupplierMaterial).filter(
        SupplierMaterial.supplier_id == supplier_id
    ).delete()

    # Sıfırdan yeni malzemeler oluştur
    for material_data in supplier_data.materials:
        supplier_material = SupplierMaterial(
            supplier_id=supplier.id,
            material_type=material_data.material_type.value,
            material_name=material_data.material_name,
            density=material_data.density,
            boyut=material_data.boyut,
            reel_type=material_data.reel_type,
            is_active=True
        )
        db.add(supplier_material)

Neden sil-ve-yeniden oluştur? Bu, mantığı muazzam ölçüde basitleştirir. Alternatif — mevcut kayıtları karşılaştırmak, değişenleri güncellemek, kaldırılanları silmek, yenilerini eklemek — frontend’de malzeme ID’lerini takip etmeyi ve karmaşık birleştirme mantığını yönetmeyi gerektirir. supplier_materials’ın diğer tablolardan gelen yabancı anahtarı olmadığından (material_orders supplier_material_id’ye bağlanır ama siparişler belirli bir malzeme girişine referans verir), bu yaklaşım güvenli ve deterministiktir.

6.1.7 FK Korumasıyla Kalıcı Silme

Bir tedarikçiyi kalıcı olarak silmeden önce, backend bağımlı hammaddeleri kontrol eder:

# Tedarikçinin hammaddeleri var mı kontrol et (FK nedeniyle engellenir)
has_materials = db.query(RawMaterial).filter(
    RawMaterial.supplier_id == supplier_id
).count()

if has_materials > 0:
    raise HTTPException(
        status_code=400,
        detail=f"Bu tedarikçiye ait {has_materials} hammadde kaydı var. Önce hammaddeleri silin."
    )

Kontrol geçerse, silme sırası: önce supplier_materials (cascade), sonra supplier kendisi. Hemen ardından bir WebSocket yayını gelir.

6.1.8 Türkçe Eşleştirmeli İstemci Taraflı Arama

Arama çubuğu, iç içe malzemeler dahil tüm alanlarda Türkçe çevirilerle filtreleme yapar:

const materialTurkish: Record<string, string> = {
    copper: 'bakır',    tin: 'kalay',
    plastic: 'plastik',  catalyst: 'katalizör',
    dye: 'boya',        antirodent: 'antirodent',
    palette: 'palet',    reel: 'makara',
};

// Arama kontrol eder: name, contact_person, phone, email,
// tax_number, address, durum (aktif/pasif), id,
// material_type (EN + TR), material_name

“bakır” yazmak bakır sağlayan tüm tedarikçileri bulur. “HF-500” yazmak o spesifik plastiği sağlayan tedarikçiyi bulur. “pasif” yazmak sadece devre dışı bırakılmış tedarikçileri gösterir.

6.1.9 Malzemeler Kolonu: Gruplama ve İpuçları

Tablonun “Malzemeler” kolonu malzemeleri türe göre gruplar ve sayıları gösterir:

6.1.10 Benzersiz Özellikler Endpoint’i

GET /suppliers/materials-list endpoint’i özel bir amaca hizmet eder: tüm tedarikçiler arasında tekilleştirilmiş malzeme özelliklerini döner. 3 farklı tedarikçi hepsi 1.42 g/cm³ yoğunlukta “HF-500” plastik sağlıyorsa, endpoint bunu bir kez döner. Tekilleştirme anahtarı: material_name|boyut|reel_type. Bu, diğer sayfalar (Malzeme Girişi, Malzeme Siparişleri) tarafından duplikasız açılır menü seçenekleri göstermek için kullanılır.

6.1.11 Yetki Mimarisi

Sayfa 8 kayıtlı butonla hibrit bir yetki modeli kullanır:

// Frontend mevcut TÜM eylemleri kaydeder
registerPageButtons({
    pageId: 'hammadde.tedarikci-yonetimi',
    buttons: [
        { id: 'access_page',          label: 'Sayfaya Erişim' },
        { id: 'view_table',           label: 'Tablo Görüntüle' },
        { id: 'create_supplier',      label: 'Yeni Tedarikçi' },
        { id: 'edit_supplier',        label: 'Düzenle' },
        { id: 'add_material',         label: 'Malzeme Ekle' },
        { id: 'remove_material',      label: 'Malzeme Kaldır' },
        { id: 'deactivate_supplier',  label: 'Pasifleştir' },
        { id: 'hard_delete_supplier', label: 'Kalıcı Sil', critical: true }
    ]
});

Backend, sırasıyla üç katmanı kontrol eden check_permission_smart() kullanır: (1) super_admin her zaman geçer, (2) eski rol bazlı kontrol (user_type gerekli listede), (3) yeni ultra-granüler sayfa.buton yetkisi. Herhangi bir katman geçerse eylem izin verilir. Bu, rol bazlıdan buton düzeyine geçiş sırasında geriye uyumluluğu sağlar.

6.1.12 Gerçek Zamanlı Güncellemeler

Üç tedarikçi işlemi WebSocket olayları yayınlar:

Frontend ['suppliers', 'all'] odalarına abone olur ve herhangi bir olayda tam tablo yenilemesini tetikleyen actionRef.current?.reload() çağırır.

6.1.13 Performans İçin Eager Loading

Liste endpoint’i, tedarikçileri malzemeleriyle birlikte tek bir sorguda çekmek için SQLAlchemy’nin joinedload kullanır:

query = db.query(Supplier).options(
    joinedload(Supplier.materials_provided)
)

Bu olmadan, 50 tedarikçi listelemek her birinin malzemelerini çekmek için 50 ek sorgu tetiklerdi (N+1 problemi). Eager loading ile tek bir JOIN sorgusudur.

6.1.14 Gönderim Öncesi Veri Temizleme

Frontend, Pydantic’in reddedeceği undefined değerleri sıyırarak malzeme dizisini backend’e göndermeden önce temizler:

const cleanedMaterials = materials.map(mat => {
    const cleaned: any = { material_type: mat.material_type };
    if (mat.material_name !== undefined && mat.material_name !== '')
        cleaned.material_name = mat.material_name;
    if (mat.density !== undefined && mat.density !== null)
        cleaned.density = mat.density;
    if (mat.boyut !== undefined && mat.boyut !== '')
        cleaned.boyut = mat.boyut;
    if (mat.reel_type !== undefined && mat.reel_type !== '')
        cleaned.reel_type = mat.reel_type;
    return cleaned;
});

Bu neden önemli: Temizleme olmadan, bir bakır malzemesi {"material_type": "copper", "material_name": undefined, "density": undefined, "boyut": undefined, "reel_type": undefined} olarak gönderilirdi. Pydantic bunları None olarak kabul ederdi, ancak JSON.stringify undefined değerlerini tamamen düşürür. Açık kontrol yalnızca anlamlı verilerin gönderilmesini sağlayarak API yükünü temiz ve öngörülebilir tutar.

6.1.15 Tedarikçi Verisi Sistemde Nasıl Kullanılır

Tedarikçi Yönetimi bağımsız bir sayfa değildir. Oluşturduğu veri, Hammadde’deki diğer tüm alt modüller ve ötesi tarafından tüketilir. Tedarikçi verisinin aktığı yerlerin tam haritası:

Malzeme Girişi (Hammadde Girişi) — Tedarikçi Seçimi

Kullanıcı herhangi bir malzeme kartına (bakır, kalay, plastik vb.) tıkladığında, giriş sayfası GET /suppliers/list?active_only=true çağırır ve her tedarikçinin materials_provided dizisini kontrol ederek yerel olarak filtreler. Yalnızca supplier_materials tablosunda o malzeme türü aktif olan tedarikçiler açılır menüde gösterilir. Bu şu anlama gelir: bir tedarikçiyi sadece “bakır” ve “kalay” ile kaydederseniz, plastik giriş formunda asla görünmezler.

// Malzeme Girişi: tedarikçileri malzeme türüne göre filtrele
const filterSuppliers = (materialType: string) => {
    const filtered = suppliers.filter(supplier => {
        const materials = supplier.materials_provided || [];
        return materials.some(
            (mat: any) => mat.material_type === materialType && mat.is_active
        );
    });
    setFilteredSuppliers(filtered);
};

Malzeme Girişi — Malzeme Adı Çözümleme

Lot bazlı girişlerde (plastik, katalizör, boya, antirodent), bir lot oluşturulduğunda backend spesifik material_name değerini çözümlemek için supplier_material_id arar. Bu ad (ör. “HF-500”, “CAT-203”) doğrudan raw_materials.material_name kolonunda saklanır. Palet ve makaralar için ayrıca boyut ölçüsünü de ekler (ör. “Euro Palet - 120x80x15 cm”).

# Lot girişi: SupplierMaterial'dan malzeme adını çözümle
if material_type_id:
    supplier_material = db.query(SupplierMaterial).filter(
        SupplierMaterial.id == material_type_id
    ).first()
    if supplier_material:
        material_name = supplier_material.material_name
        if supplier_material.boyut:
            material_name = f"{material_name} - {supplier_material.boyut}"

Malzeme Sipariş (Hammadde Sipariş) — Tedarikçi + Malzeme Seçimi

Satın alma siparişi oluştururken, kullanıcı önce bir tedarikçi seçer, sonra yalnızca o tedarikçinin sağladığı malzemeleri görür. Sipariş hem supplier_id (kim) hem de supplier_material_id (tam olarak ne) saklar. Bu bağlantı kritiktir: bir teslimat geldiğinde ve Malzeme Girişi üzerinden girildiğinde, sistem gelen malzemeleri bekleyen siparişleriyle eşleştirmek için supplier_material_id kullanır.

Malzeme Sipariş — Giriş Bağlama İçin Bekleyen Sipariş Grupları

GET /material-orders/pending-by-type/{material_type} endpoint’i bekleyen siparişleri supplier_id + expected_date bazında gruplanmış döner. Malzeme Girişi bunu “Siparişe Bağla” seçeneği göstermek için kullanır. Kullanıcı bir sipariş grubu seçtiğinde, sistem supplier_material_id ile anahtarlanmış bir order_map oluşturur, böylece girişteki her lot otomatik olarak ilgili sipariş satırına bağlanabilir.

Malzeme Hesaplayıcı — Tedarikçi Malzemelerinden Yoğunluk

Plastik, katalizör, boya ve antirodent bileşikleri için supplier_materials tablosunda saklanan density alanı, Malzeme Hesaplayıcı servisi tarafından kullanılır. Sipariş modülü bir sipariş için plastik ağırlığı hesapladığında (hacim × yoğunluk = kg), yoğunluk burada kayıtlı tedarikçi malzeme özelliklerinden gelir.

Açılır Menüler İçin Benzersiz Özellikler

GET /suppliers/materials-list endpoint’i tüm tedarikçiler arasında malzeme özelliklerini tekilleştirir ve benzersiz girişleri döner. Bu, Malzeme Siparişleri ve Malzeme Girişi’ndeki açılır menüleri besler — kullanıcılar ne sipariş edeceklerini veya gireceklerini seçerken aynı “HF-500”’ü üç farklı tedarikçiden üç kez görmezler.

Bağımlılık zinciri: Tedarikçi → supplier_materials (ne satıyorlar) → material_orders (ne sipariş ettik, supplier_material_id referansıyla) → raw_materials (ne geldi, material_order_id ile siparişe bağlı, material_name supplier_materials’dan çözümlenmiş). Bir tedarikçiyi kaldırın, tüm bu zincir kırılır. FK korumasının kalıcı silmede var olmasının ve yumuşak silmenin (aktif/pasif) tercih edilen yaklaşım olmasının nedeni budur.

6.2 — Hammadde Sipariş (Malzeme Siparişleri)

6.2.1 — Amaç ve İş Bağlamı

Bu resmi bir satın alma siparişi sistemi değildir. Solen’in hangi hammaddeleri hangi tedarikçiden sipariş ettiğini, teslimatı ne zaman beklediğini ve gerçekte neyin geldiğini kaydeden bir dahili takip aracıdır. Amacı, satın alma ve depo ekiplerine neyin geleceği, neyin geciktiği ve her tedarikçinin ne kadar iyi performans gösterdiği konusunda net bir tablo sunmaktır.

Modül, Tedarikçi Yönetimi (tedarikçilerin ve ürün kataloglarının tanımlandığı yer) ile Hammadde Girişi (fiziksel teslimatların alındığı yer) arasında konumlanır. Burada oluşturulan siparişler, Hammadde Girişi için “bağlanabilir hedefler” haline gelir — bir kamyon geldiğinde operatör gelen malzemeyi ilgili siparişe bağlayabilir, bu da teslim edilen miktarı otomatik artırır ve tam izlenebilirlik sağlar.

6.2.2 — CRUD Akışı

Oluşturma (Çoklu Öğe):

  1. Araç çubuğundaki “Yeni Sipariş” butonuna tıkla
  2. Modal, kademeli seçimle açılır: Malzeme Tipi → Tedarikçi (tipe göre filtrelenir) → Ürün panelleri
  3. Malzeme tipi seç → tedarikçi dropdown’u sadece o tipi taşıyan tedarikçileri gösterir
  4. Tedarikçi seç → ürün kataloğu katlanabilir paneller olarak belirir. Ürün seç, miktar gir (kg veya adet)
  5. Aynı sevkiyattaki aynı tedarikçiden daha fazla ürün eklemek için “+” tıkla
  6. Sipariş tarihi (varsayılan bugün) ve beklenen teslim tarihi ayarla. İsteğe bağlı notlar ekle
  7. Gönderimde: POST /api/material-orders/create → backend bir grup kodu üretir (R1, R2…) ve öğe başına bir DB satırı oluşturur, hepsi bu kodu paylaşır. Tek işlem — ya hepsi ya hiçbiri
  8. Başarılı: toast onayı → modal kapanır → tablo yeni sipariş grubunu göstererek yenilenir

Düzenleme (Tekli Satır):

  1. Belirli bir sipariş satırında düzenle ikonuna tıkla (grup değil — bireysel satırları düzenlersiniz)
  2. Modal mevcut değerlerle önceden dolu açılır: tedarikçi, malzeme, miktar, tarihler, notlar
  3. Çoklu öğe “+” işlevi düzenleme modunda mevcut değildir
  4. Kritik davranış: beklenen teslim tarihi değiştirilirse, tarih seçici açık kalır ve zorunlu neden gerektiren bir yan panel belirir (Tedarikçi kaynaklı / Solen kaynaklı / Diğer). Bu, material_order_date_changes’da bir denetim kaydı oluşturur
  5. Gönderimde: PUT /api/material-orders/{id} → sipariş güncellenir + varsa tarih değişikliği günlüğe kaydedilir
  6. Başarılı: toast → modal kapanır → tablo yenilenir

Silme:

  1. Belirli bir sipariş satırında sil ikonuna tıkla
  2. Uyarılı Popconfirm
  3. Onayda: DELETE /api/material-orders/{id}
  4. Kademeli: ilişkili material_order_date_changes kayıtları siparişle birlikte silinir
  5. Tablo yenilenir. Bu gruptaki son öğeyse, grup kodu kaybolur

Okuma (Tarih Geçmişi):

  1. Herhangi bir sipariş satırındaki saat ikonuna (Tarih Geçmişi) tıkla
  2. Modal, tüm tarih değişikliklerinin dikey zaman çizelgesini göstererek açılır: eski tarih (üstü çizili) → yeni tarih, renkli neden etiketi, detay metni, kim değiştirdi ve ne zaman
  3. Salt okunur — geçmiş bağımsız olarak düzenlenemez veya silinemez

6.2.3 — Sipariş Yaşam Döngüsü

Her sipariş dört durumlu bir yaşam döngüsü izler:

Beklemede
Sipariş verildi, gönderim bekleniyor
Yolda
Tedarikçi gönderimi onayladı
Teslim Alındı
Malzeme fabrikaya ulaştı
İptal
Sipariş iptal edildi

Durum geçişleri iki şekilde gerçekleşebilir. Birincisi, tablodaki durum sütunu satır içi bir açılır seçicidir — kullanıcı mevcut durum etiketine tıklar ve yenisini seçer. İkincisi ve daha önemlisi, durum, gelen malzemeler bir siparişe bağlandığında Hammadde Girişi modülü tarafından otomatik olarak “Teslim Alındı” yapılır. Hammadde Girişi üzerinden bir teslimat kaydedildiğinde, backend siparişin durumunu otomatik olarak teslim edilmiş yapar, bugünün tarihini teslimat tarihi olarak damgalar ve teslim edilen miktarı artırır. Bu, en yaygın durum geçişinin (beklemede → teslim alındı) bu sayfadaki manuel etkileşimle değil, malzeme alma iş akışının parçası olarak otomatik gerçekleştiği anlamına gelir.

6.2.4 — Sipariş Grup Kodları (Gönderim Gruplama)

Bir tedarikçiden gelen tek bir gönderim genellikle birden fazla farklı malzeme içerir. Örneğin, Tedarikçi X’ten gelen bir kamyon 5 ton HF-500 plastik granül ve 2 ton katalizör taşıyor olabilir. Bunları tamamen ayrı siparişler olarak ele almak yerine, sistem onları paylaşılan bir Sipariş Grup Kodu altında gruplar.

Grup kodları R1, R2, R3, R4… kalıbını izler (“R” öneki ardından sıralı numara). Kullanıcı birden fazla kalem içeren yeni bir sipariş oluşturduğunda, backend tek bir grup kodu üretir ve o partideki her sipariş satırına atar. Tek kalemli siparişler bile tutarlılık için grup kodu alır.

Üretim mantığı veritabanındaki en yüksek R-numarasını bulup bir artırır. Bu basit bir sıralı sayaçtır, UUID değil — kodlar insanlar tarafından okunabilir ve sözlü iletişimde kolay kullanılabilir olacak şekilde tasarlanmıştır (“R47 gönderimi yarın geliyor”).

Tabloda grup kodu ilk sütun olarak (sola sabitlenmiş) görünür ve mavi etiket olarak gösterilir. Görsel gruplama mekanizması olarak hizmet eder — kullanıcılar birden fazla satırda “R12” gördüğünde, bu kalemlerin aynı gönderimden olduğunu hemen anlarlar.

6.2.5 — Sipariş Oluşturma (Çok Adımlı Form Akışı)

Sipariş oluşturma, tedarikçi veri hiyerarşisini yansıtan kademeli bir seçim akışı izler:

  1. Malzeme Tipi Seç — kullanıcı 8 tip arasından seçer (bakır, kalay, plastik, katalizör, boya, antirodent, palet, makara). Bu ilk filtredir.
  2. Tedarikçi Seç — tedarikçi açılır menüsü tam liste değildir. Yalnızca seçilen tipte aktif malzeme sağlayan tedarikçileri gösterir. “Bakır” seçerseniz yalnızca bakır tedarikçilerini görürsünüz. Bu filtreleme istemci tarafında her tedarikçinin materials_provided dizisi kontrol edilerek gerçekleşir.
  3. Ürünler ve Miktarlar Ekle — tedarikçi seçildikten sonra, kullanıcı o malzeme tipi için tedarikçinin özel ürün kataloğunu görür. Her ürün, kullanıcının tam ürünü seçip miktar girdiği açılır/kapanır bir paneldir. Birim otomatik uyarlanır: paletler ve makaralar “adet”, diğer her şey “kg” kullanır.
  4. Birden Fazla Kalem — kullanıcı “+” butonuyla daha fazla ürün paneli ekleyebilir. Her panel ayrı bir sipariş kalemi temsil eder, ancak tüm kalemler kaydedildiğinde aynı grup kodunu paylaşır. “+” butonu tedarikçi seçilene kadar devre dışıdır.
  5. Tarihleri Belirle — iki tarih zorunludur: sipariş tarihi (varsayılan bugün) ve beklenen teslim tarihi.
  6. İsteğe Bağlı Not — ek bağlam için serbest metin alanı.

Kaydetme sırasında frontend tüm kalemleri tek bir API çağrısında gönderir. Backend tek bir grup kodu üretir ve her kalem için o kodu paylaşan bir veritabanı satırı oluşturur. Bu tek bir işlemdir — ya tüm kalemler oluşturulur ya da hiçbiri.

6.2.6 — Sipariş Düzenleme

Düzenleme modu, oluşturmadan farklı çalışır. Düzenlerken kullanıcı bir grup üzerinde değil, tek bir sipariş satırı üzerinde çalışır. Form mevcut değerlerle yüklenir ve kullanıcı tedarikçi, malzeme, miktar, tarih ve notları değiştirebilir. Çoklu kalem “+” işlevselliği düzenleme modunda mevcut değildir — bir seferde bir satır düzenlenir.

Düzenleme modundaki en önemli davranış aşağıda ayrıntılı olarak ele alınan tarih değişikliği takibidir.

6.2.7 — Tarih Değişikliği Takip Sistemi

Bu, modülün en sofistike özelliklerinden biridir. Gerçek dünyada satın alma süreçlerinde beklenen teslim tarihleri sürekli değişir — tedarikçiler gecikir, Solen erteleme talep eder, lojistik sorunlar oluşur. Sistem tarihi sessizce üzerine yazmaz; kullanıcıdan tarihin neden değiştiğini açıklamasını ister ve eksiksiz bir denetim izi saklar.

Nasıl Çalışır

Kullanıcı mevcut bir siparişi düzenlemek için açtığında, sistem orijinal beklenen tarihi kaydeder. Kullanıcı tarih seçicisinde bu tarihi değiştirirse, olağandışı bir şey olur: tarih seçici kapanmaz. Bunun yerine, takvim açılır penceresinin sağ tarafına bir yan panel kayıp girer. Bu panel şunları içerir:

Kullanıcı “Diğer” seçerse, manuel açıklama için bir metin alanı görünür ve bu açıklama da zorunludur. Kullanıcı bu sebep akışını tamamlamadan siparişi kaydedemez.

Kullanıcı fikrini değiştirip orijinal tarihi tekrar seçerse, yan panel kaybolur ve sebep alanları otomatik sıfırlanır.

Backend Depolama

Sipariş değişen tarihle kaydedildiğinde, backend material_order_date_changes tablosunda yeni bir satır oluşturur: eski tarih, yeni tarih, sebep türü, isteğe bağlı açıklama metni, değişikliği yapan kişi ve zaman damgası. Bu tablo CASCADE silme kullanır — ana sipariş silinirse tarih değişikliği geçmişi de silinir.

Geçmişi Görüntüleme

Tablodaki her sipariş satırında bir saat ikonu butonu (Tarih Geçmişi) vardır. Tıklandığında, o siparişte yaşanmış her tarih değişikliğini dikey zaman çizelgesi olarak gösteren bir modal açılır. Her giriş şunları gösterir:

Bu modaldaki zaman damgaları doğru yerel gösterim için Türkiye saat dilimine (Europe/Istanbul) dönüştürülür.

6.2.8 — Teslimat Takibi (Sipariş ve Gelen Miktar)

Her sipariş iki miktar takip eder: sipariş miktarı (talep edilen) ve gelen miktar (gerçekte teslim alınan). Gelen miktar bu sayfadan manuel olarak güncellenmez. Hammadde Girişi modülünde gelen malzemeler bir siparişe bağlandığında otomatik olarak artırılır.

Tabloda her iki miktar yan yana gösterilir. Gelen sütunu durumu bir bakışta iletmek için renk kodlaması kullanır:

6.2.9 — Değerlendirme Sistemi

Bir sipariş “Teslim Alındı” durumuna ulaştığında, işlemler sütununda bir yıldız ikonu görünür. Bu, tedarikçi teslimat değerlendirmesi sistemini etkinleştirir. Kullanıcı teslimatı 0,5–5 yıldız ölçeğinde (yarım yıldız artışlarıyla) puanlayabilir ve isteğe bağlı olarak değerlendirmeyi açıklayan bir not ekleyebilir.

Değerlendirme modalı sipariş bağlamını gösterir (grup kodu, tedarikçi adı, malzeme, teslim edilen miktar) böylece kullanıcı tam olarak neyi değerlendirdiğini bilir. Puan ve not doğrudan sipariş kaydında saklanır.

Bu değerlendirme verileri tedarikçi performans takibine katkıda bulunur — zamanla Solen, hangi tedarikçilerin sürekli zamanında ve iyi durumda teslim ettiğini, hangilerinin tekrarlayan sorunları olduğunu görebilir.

İş mantığı: Değerlendirme butonu yalnızca “teslim alındı” siparişleri için görünür. Bekleyen bir siparişi değerlendiremezsiniz çünkü değerlendirilecek bir şey yoktur. Siparişin zaten bir değerlendirmesi varsa, yıldız ikonu dolu ve sarı görünür ve üzerine gelindiğinde mevcut puanı tooltip olarak gösterir.

6.2.10 — İstemci Tarafı Arama ve Yerelleştirme

Tablo, tüm görünür sütunlar üzerinde istemci tarafı filtreleme kullanarak siparişleri filtreleyen bir arama çubuğu içerir. Bunu önemsiz kılmayan şey, verilerin İngilizce saklanması (örn. “copper”, “pending”) ancak kullanıcıların Türkçe aramasıdır. Arama sistemi iki çeviri haritası tutar:

Kullanıcı “bakır” yazdığında, filtre material_type === 'copper' olan her satırı eşleştirir. Ayrıca tarihleri DD.MM.YYYY formatında arar (ISO değil), dolayısıyla “15.03” araması 15 Mart beklenen siparişleri bulur. Arama şunları kapsar: grup kodu, tedarikçi adı, malzeme adı, malzeme tipi (hem EN hem TR), durum (hem EN hem TR), miktarlar, tarihler (hem ham hem formatlanmış) ve notlar.

6.2.11 — Tablo Düzeni ve Sütunlar

ProTable, kaydırılabilir düzende 11 sütun gösterir:

Sütun Açıklama Davranış
Sipariş NoSipariş grup kodu (R1, R2…)Sola sabit, mavi etiket
MalzemeMalzeme tipiTipe göre renkli etiket
ÜrünTedarikçi kataloğundan ürün adıMavi etiket
TedarikçiTedarikçi adıMavi etiket
Sipariş MiktarıSipariş edilen miktar + birimTürkçe sayı formatı
Gelen MiktarTeslim edilen miktar + birimTamam olunca yeşil, kısmi sarı
Sipariş TarihiSiparişin verildiği tarihGG.AA.YYYY formatı
Beklenen TarihBeklenen teslim tarihiGecikmiş ise kırmızı (bugünden önce)
Geliş TarihiGerçek teslim tarihiYeşil metin, veya teslim edilmediyse “-”
DurumSipariş durumuSatır içi açılır menü — tıklanarak değiştirilebilir
İşlemİşlem butonlarıSağa sabit: geçmiş, değerlendirme, düzenle, sil

Beklenen tarih sütunu özel ilgiyi hak eder: tarihi bugünle karşılaştırır ve geçmişte ise kırmızı olarak gösterir. Bu, herhangi bir manuel işaretleme olmadan gecikmiş siparişler hakkında anında görsel geri bildirim sağlar.

6.2.12 — API Endpoint’leri

Metot Endpoint Amaç
GET/material-orders/listTüm siparişleri getirir, beklenen tarihe göre artan sırayla. Opsiyonel filtreler: durum, malzeme tipi. İlişkili tablolardan çözümlenmiş tedarikçi adı ve malzeme adıyla zenginleştirilmiş veri döner.
GET/material-orders/pending-by-type/{type}Bekleyen siparişleri tedarikçi + beklenen tarih bazında gruplanmış döner. Operatörlerin teslimatları siparişlere bağlaması için Hammadde Girişi tarafından tüketilir. Sipariş sayfasının kendisi tarafından kullanılmaz.
POST/material-orders/createPaylaşılan grup koduyla bir veya daha fazla sipariş satırı oluşturur. items dizisi kabul eder; yeni R-kodu üretir; malzeme tipinden birimi otomatik belirler (kg vs adet).
PUT/material-orders/update/{id}Tek bir siparişi günceller. Durum değişikliklerini (delivered_date otomatik damgalar), denetim izi kaydıyla tarih değişikliklerini ve miktar/not güncellemelerini yönetir.
GET/material-orders/date-changes/{id}Bir sipariş için eksiksiz tarih değişikliği geçmişini getirir. Tüm değişiklikleri en yeniden eskiye sıralı, her değişikliği kimin yaptığı kullanıcı adıyla döner.
PUT/material-orders/rate/{id}0,5–5 yıldız puanı ve opsiyonel not kaydeder. Aralığı backend’de doğrular. Yalnızca teslim alınmış siparişler için anlamlıdır (butonu koşullu göstererek frontend’de zorunlu kılınır).
DELETE/material-orders/delete/{id}Siparişi kalıcı olarak siler. CASCADE ilişkisi, ilişkili tarih değişikliği geçmişi kayıtlarını otomatik kaldırır.

6.2.13 — Veritabanı Şeması

Modül iki tablo kullanır:

material_orders — ana sipariş takip tablosu. Her satır bir satın alma siparişindeki bir malzeme kalemini temsil eder. Önemli alanlar:

material_order_date_changes — beklenen tarih değişikliklerinin denetim izi. Her satır bir değişiklik olayını yakalar:

6.2.14 — Malzeme Siparişlerinin Hammadde Girişiyle Bağlantısı

Bu en kritik alt akış bağlantısıdır. pending-by-type endpoint’i özellikle Hammadde Girişi için mevcuttur. Bir operatör örneğin bakır tel teslimatı girmeye başladığında, Hammadde Girişi sayfası bu endpoint’i material_type=copper ile çağırır. Yanıt, tedarikçi + beklenen tarih bazında organize edilmiş gruplar halinde, her bekleyen sipariş satırının ürün adı ve miktarıyla birlikte döner.

Operatör eşleşen sipariş grubunu seçer ve sistem supplier_material_id ile anahtarlanmış dahili bir order_map oluşturur. Her lot girildiğinde, otomatik olarak ilgili sipariş satırına bağlanır. Bu bağlantı raw_materials.material_order_id alanında saklanır.

Bir malzeme girişi sipariş bağlantısıyla kaydedildiğinde, backend siparişin delivered_quantity değerini artırır. Bu, sipariş rotalarında değil malzeme giriş rotalarında gerçekleşir — sipariş modülü bu açıdan pasiftir. Takip kayıtlarını oluşturur; giriş modülü teslimat sırasında onları günceller.

Varsayılan sıralama bir hikaye anlatır: siparişler expected_date ASC ile sıralanır — en yakın teslimatlar en üstte görünür. Kırmızı gecikme vurgulamasıyla birleşince, tablo doğal olarak en acil kalemleri en üste iter. Depo müdürü bu sayfayı açtığında neyin geciktiğini ve sırada neyin olduğunu anında görür.

6.2.15 — Malzeme Siparişlerinin Stok Projeksiyon Sistemini (Projeksiyon) Beslemesi

Bu, Malzeme Siparişleri verisinin muhtemelen en önemli alt akış tüketicisidir ve sipariş sayfasının kendisinden tamamen farklı bir soyutlama seviyesinde çalışır.

Projeksiyon (Stok Projeksiyon) sistemi, tüm fabrika genelinde hammadde kullanılabilirliğinin haftalık tahminini sağlar. Şu soruyu cevaplar: “Hafta hafta, her malzemeden yeterince olacak mı, yoksa eksik mi kalacağız?” Bunu cevaplamak için iki veri akışına ihtiyacı vardır:

Projeksiyon servisi iptal edilmemiş her malzeme siparişini okur ve kritik bir karara göre doğru haftaya yerleştirir: sipariş teslim edilmişse delivered_date (gerçek varış) kullanır. Hâlâ beklemede veya yoldaysa expected_date (planlanmış varış) kullanır. Benzer şekilde, teslim edilmiş siparişler için delivered_quantity (gerçekte gelen), bekleyen siparişler için quantity (sipariş edilen) kullanır.

Bu, kullanıcının Malzeme Siparişleri sayfasında yaptığı her değişikliğin projeksiyonu doğrudan etkilediği anlamına gelir:

Projeksiyon kod tabanındaki yorumlarda “kalıcı bir plan” olarak tanımlanır, ancak gerçek uygulama daha nüanslı bir hikaye anlatır. Üretim tamamlandığında değişmez (tamamlanmış iş kartları hâlâ planlanan tüketim olarak sayılır). Ancak malzeme teslimatlarına tepki verir: Hammadde Girişi bir siparişi teslim edildi olarak işaretlediğinde, projeksiyon expected_date + quantity (plan) kullanmaktan delivered_date + delivered_quantity (gerçek) kullanmaya geçer. Bu, teslimat beklenenden farklı bir tarihte geldiyse ARTI girişinin farklı bir haftaya kayabileceği ve teslim edilen miktar sipariş edilenden farklıysa miktarın değişebileceği anlamına gelir. Dolayısıyla projeksiyon, planlanan ve gerçek verileri harmanlayan canlı bir görünümdür — bekleyen siparişler neyin gelmesi gerektiğini, teslim edilmiş siparişler neyin gerçekten geldiğini gösterir.

Servis ayrıca her siparişi supplier_material ilişkisi üzerinden spesifik malzeme adına kadar çözümler. Dolayısıyla projeksiyon sadece “Hafta 12’de +500 kg plastik” göstermez — “Hafta 12’de +500 kg HFX-500P” gösterir. Bu malzeme başına granülarite, projeksiyonun yalnızca kategori düzeyinde değil, bireysel malzeme düzeyinde eksiklikleri tespit etmesini sağlar.

Projeksiyon tüm haftalar boyunca kümülatif bakiye hesaplar. Eğer Hafta 10’da +500 kg bakır geliyorsa ama Hafta 11’de üretim için -800 kg gerekiyorsa, kümülatif negatife döner ve eksiklik işaretlenir. Frontend bu eksiklikleri görsel olarak vurgular. Malzeme Siparişleri ARTI tarafını sağlamazsa, tüm projeksiyon yalnızca tüketim gösterir ve gelen yoktur — bu da planlama için kullanışsız hale getirir.

Malzeme Siparişlerinin ikili rolü: Yüzeysel olarak bu modül basit bir takip tablosudur. Ama altında, fabrikanın stok projeksiyon sisteminin iki temel veri kaynağından biridir. Her sipariş, her tarih değişikliği, her miktar güncellemesi haftalık projeksiyona yayılır ve tüm planlama ufku boyunca eksiklik tespitini etkiler. Bu yüzden doğru sipariş girişi ve özenli tarih değişikliği takibi idari yük değil — fabrikanın üretim planlama doğruluğu için kritik girdilerdir.

6.2.16 — Silme Davranışı

Siparişler bir onay diyalogu aracılığıyla kalıcı olarak silinebilir. Yumuşak silme / arşivleme mekanizması yoktur. material_order_date_changes üzerindeki CASCADE ilişkisi, bir siparişin silinmesinin tarih değişikliği geçmişini de kaldırmasını sağlar. Ancak, bir raw_material girişi bu siparişe material_order_id aracılığıyla zaten bağlıysa, bu bağlantı asılı bir referans olur (raw_materials üzerindeki foreign key nullable olduğu için kısıtlama ihlali yaratmaz, ancak izlenebilirlik zinciri kırılır).

6.2.17 — Bu Modülün YAPMADIĞI Şeyler

6.3 — Hammadde Girişi (Malzeme Girişi)

6.3.1 — Amaç ve İş Bağlamı

Fiziksel gerçekliğin dijital sistemle buluştuğu yer burasıdır. Solen fabrikasına hammadde yüklü bir kamyon geldiğinde, depo operatörü neyin geldiğini kaydetmek için bu modülü kullanır. Her kilogram bakır, her varil plastik, her palet — hepsi sisteme bu tek sayfadan girer.

Modül yalnızca envanter kaydetmez; üç başka sistem arasındaki köprüdür. Tedarikçi Yönetimi’nden veri tüketir (kim teslim etti), teslimatları Malzeme Siparişlerine bağlar (ne bekleniyordu), Hammaddeler Listesi’nde görünen QR kodları ve veritabanı kayıtlarını üretir ve sipariş durumunu ve teslim edilen miktarları değiştirerek Projeksiyon’u (stok projeksiyonu) dolaylı olarak günceller.

Sayfa menüde /hammadde/hammadde-girisi altında yer alır, ancak frontend bileşeni aslında Lab/MaterialEntry konumundadır — malzeme girişinin bir laboratuvar/depo operasyonu olduğunu yansıtır.

6.3.2 — CRUD Akışı

Oluşturma (Birincil Operasyon):

  1. Açılış sayfasındaki 8 malzeme tipi kartından birine tıkla (Bakır, Kalay, Plastik, Katalizör, Boya, Antirodent, Palet, Makara)
  2. Adım 1 — Sipariş Seçimi: O malzeme tipi için bekleyen siparişleri gösteren modal belirir, GET /material-orders/pending-by-type/{type} ile getirilir. Kullanıcı bir sipariş grubu seçer (tedarikçi + malzemeleri önceden doldurur) veya “Manuel Giriş”e tıklar (boş form)
  3. Adım 2 — Giriş Formu: Malzeme tipi arketipine göre dinamik form açılır:
    • Bakır: katlanabilir palet panelleri (lot no + form ağırlık + ölçülen ağırlık + durum/palet) → daha fazla palet için “+”
    • Kalay: tekli form (net ağırlık + durum)
    • Lot bazlı: katlanabilir lot panelleri (malzeme tipi dropdown + lot no + ağırlıklar + miktar + fotoğraflar/lot) → daha fazla lot için “+”
    • Sayı bazlı: katlanabilir tip panelleri (tip dropdown + miktar + fotoğraflar/tip) → daha fazla tip için “+”
  4. İrsaliye fotoğrafları ve isteğe bağlı test/hasar fotoğrafları yükle (lot bazlılar için lot başına)
  5. Gönderimde: tipe özel endpoint çağrılır (POST /api/materials/copper-entry, /tin-entry, /lot-entry, /palette-entry veya /reel-entry)
  6. Backend, deterministik QR koduyla (A1, B1, C1…) palet/lot/tip başına bir raw_materials satırı oluşturur. Siparişe bağlıysa: siparişte otomatik olarak delivered_quantity, status=DELIVERED ve delivered_date=bugün günceller
  7. Başarılı: tüm üretilen QR kodlarını gösteren başarı modalı belirir, QR başına “Yazdır” butonu ile. WebSocket materials ve all odalarına yayın yapar

Güncelleme (Sadece Super Admin):

  1. Bu sayfada doğrudan mevcut değil — güncellemeler Hammaddeler Listesi (6.4) düzenleme modalı üzerinden yapılır
  2. Backend endpoint mevcut: PUT /api/materials/{id}, super_admin veya edit_material yetkisi gerektiren check_permission_smart ile

Silme (Sadece Super Admin):

  1. Bu sayfada doğrudan mevcut değil — silme Hammaddeler Listesi (6.4) üzerinden yapılır
  2. Backend endpoint’leri: DELETE /api/materials/{id} (pasif) ve DELETE /api/materials/{id}/hard (kalıcı)
  3. Kalıcı silme ayrıca ilişkili material_photos kayıtlarını da kaldırır

6.3.3 — Açılış Sayfası: Sekiz Malzeme Kartı

Kullanıcı sayfayı açtığında, fabrikanın işlediği her hammadde türü için birer tane olmak üzere 8 tıklanabilir kart görür:

Bakır (A)
Filmaşin — bakır tel çubuk
Kalay (B)
Tekli ağırlık girişi
Plastik (C)
Plastik granül — lot bazlı
Katalizör (D)
Katalizör — lot bazlı
Boya (E)
Boya — lot bazlı
Antirodent (F)
Kemirgen önleyici — lot bazlı
Palet (I)
Ahşap paletler — adet bazlı
Makara (H)
Kablo makaraları — adet bazlı

Her kart, koyu/açık temaya uyum sağlayan benzersiz bir arka plan rengine, büyük bir ikona ve malzeme adına sahiptir. Parantez içindeki harf, o malzeme türünün QR kod önekidir. Herhangi bir karta tıklamak giriş formunu doğrudan açmaz — önce Sipariş Seçimi akışını tetikler.

6.3.4 — İki Adımlı Giriş Akışı

Bu kritik bir tasarım kararıdır. Malzeme girişi iki adımlı bir süreç izler:

  1. Adım 1: Sipariş Seçim Modalı — Kullanıcı bir malzeme kartına tıkladığında, sistem o malzeme türü için bekleyen siparişleri GET /material-orders/pending-by-type/{type} üzerinden anında getirir. Görünen modal:
    • Bekleyen sipariş gruplarının listesi — her biri tedarikçi adı, gönderimdeki malzeme adları, toplam miktar ve beklenen tarihi gösterir
    • Altta “Manuel Giriş” butonu — karşılık gelen siparişi olmayan teslimatlar için
  2. Adım 2: Giriş Formu — Kullanıcı ya bir sipariş grubu seçer (tedarikçi, malzeme tipleri ve miktarları otomatik doldurulur) ya da Manuel Giriş’e tıklar (boş form açılır). Giriş formu, malzeme türüne göre tüm yapısını değiştiren dinamik bir modaldır.

Bu iki adımlı akış kritik bir amaca hizmet eder: operatörleri teslimatları siparişlere bağlamaya teşvik eder, bu da takip zincirini sağlam tutar. Siparişler varsa belirgin şekilde gösterilir. Manuel giriş bir yedek olarak vardır, varsayılan değil.

6.3.5 — Sipariş Ön Doldurma Mantığı

Kullanıcı Adım 1’de bir sipariş grubu seçtiğinde, otomatik olarak şunlar gerçekleşir:

Sipariş grubu ayrıca order_ids dizisini taşır, bu kaydetme sırasında backend’e gönderilir böylece sistem hangi siparişleri teslim edildi olarak işaretleyeceğini bilir.

6.3.6 — Dört Form Arketipi

Giriş formu tek bir form değildir. Seçilen malzeme türüne göre koşullu olarak render edilen dört tamamen farklı form yapısıdır. Hepsi iki ortak alanı (tedarikçi ve teslim alan kişi) ve ortak bir fotoğraf bölümünü paylaşır, ancak aradaki her şey benzersizdir.

Arketip 1: Bakır (Çoklu Palet)

Bakır büyük paletler halinde gelir (Filmaşin — paletler üzerinde tel çubuk bobinleri). Tek bir teslimat birden fazla palet içerebilir, her birinin kendi ağırlığı vardır. Form, dinamik bir açılır/kapanır palet panelleri listesi sunar:

Arketip 2: Kalay (Tekli Giriş)

Kalay en basit giriş türüdür. Tek bir teslimat, tek bir ağırlık ölçümüdür:

Arketip 3: Lot Bazlı (Plastik, Katalizör, Boya, Antirodent)

Bu dört malzeme türü aynı form yapısını paylaşır çünkü hepsi lotlar halinde gelir (tedarikçideki bir üretim serisinden partiler). Form, dinamik bir açılır/kapanır lot panelleri listesi sunar:

Arketip 4: Adet Bazlı (Palet, Makara)

Paletler ve makaralar tartılmaz, sayılır. Form açılır/kapanır tip panelleri sunar:

6.3.7 — Lot Numarası Klavye Geçişi

Küçük ama önemli bir UX özelliğidir. Lot numaraları tamamen sayısal (örn. “24081901”) veya alfanümerik (örn. “LOT-A24-081”) olabilir. Mobil cihazlarda görünen klavye inputMode özelliğine bağlıdır. Sistem varsayılan olarak numeric (sayı tuştakımı) kullanır ancak giriş alanı içinde sayı tuştakımı ile tam klavye arasında geçiş yapan bir buton sağlar. Her lot girişi kendi klavye modunu bağımsız olarak takip eder.

6.3.8 — QR Kod Sistemi

Her malzeme girişi benzersiz, deterministik bir QR kodu üretir. Sistem basit ama etkili bir şema kullanır: malzeme türünü belirleyen bir harf öneki, ardından tür başına artan bir sıra numarası.

Önek Malzeme Örnekler
ABakırA1, A2, A3…
BKalayB1, B2, B3…
CPlastikC1, C2, C3…
DKatalizörD1, D2, D3…
EBoyaE1, E2, E3…
FAntirodentF1, F2, F3…
IPaletI1, I2, I3…
HMakaraH1, H2, H3…

Sıra numarası, o malzeme türü için mevcut en yüksek sequence_number sorgulanarak ve bir artırılarak belirlenir. Her malzeme türünün kendi sayacı vardır — bakır A847’de olabilirken kalay B23’tedir. QR kodu qr_code sütununda benzersiz kısıtlama ile saklanır, çift oluşmamasını garanti eder.

Birden fazla paletli bakır girişlerinde, backend aynı işlem içinde her palet için sırayı artırır (3 paletli bir giriş için A45, A46, A47).

6.3.9 — Fotoğraf Mimarisi

Fotoğraf sistemi iki katmana sahiptir:

Fotoğraflar göndermeden önce frontend’de base64’e dönüştürülür. Backend bunları material_photos tablosunda (malzeme satırında değil) photo_type ayırıcısı (“delivery” veya “test”) ve sequence numarasıyla saklar. Bu ayrı tablo tembel yüklemeyi mümkün kılar — malzemeleri listelerken yalnızca fotoğraf ID’leri döner; gerçek base64 verisi talep üzerine GET /materials/photo/{id} ile getirilir.

6.3.10 — Sipariş Bağlama ve Otomatik Teslimat Güncellemeleri

Malzeme Girişi’nin Malzeme Siparişlerine ve oradan Projeksiyon sistemine geri bağlandığı yer burasıdır.

Bir teslimat siparişlere bağlandığında, backend malzeme satırlarını oluşturduktan sonra şu ek adımları gerçekleştirir:

Bağlanan her sipariş status = delivered, delivered_date = bugün ve delivered_quantity += miktar alır. Bu, Bölüm 6.2’de tartışılan otomatik durum geçişidir.

6.3.11 — Başarı Modalı ve QR Yazdırma

Başarılı bir kaydetmeden sonra sistem formu basitçe kapatmaz. Üretilen QR kodlarını listeleyen (örn. “A45, A46, A47”) bir başarı modalı gösterir:

Yazdır butonu POST /materials/print/{material_id}’yi çağırır ve yazdırma kuyruk sistemine yönlendirir. Birden fazla lotlu lot bazlı girişlerde sistem tüm oluşturulan malzeme ID’lerini dolaşır ve her birini sırayla yazdırır.

Kaydet buton metni bağlamsaldır: palet ve makara girişleri için “Kaydet (QR Yok)” yazar çünkü paletler ve makaralar basılı QR etiketleri yerine fiziksel tanımlama kullanır. Diğer tüm tipler için “Kaydet ve QR Kod Oluştur” yazar.

6.3.12 — Tedarikçi Filtreleme

Bir malzeme kartına tıklanıp giriş formu açıldığında, tedarikçi açılır listesi tüm tedarikçileri göstermez. Seçilen tipte materials_provided kataloğunda aktif malzemeleri olan tedarikçileri gösterecek şekilde filtrelenir. Bu filtreleme istemci tarafında her tedarikçinin malzeme dizisi kontrol edilerek gerçekleşir. Bir malzeme tipi için tedarikçi bulunamazsa, açılır liste yardımcı bir mesaj gösterir: “Bu malzeme için tedarikçi bulunamadı. Önce tedarikçi ekleyin.”

6.3.13 — İzin Sistemi

Malzeme Girişi, ultra-granüler izin sistemiyle 13 sayfa düzeyi butonu kaydeder:

Backend ayrıca rol bazlı erişim zorlar: yalnızca lab_user ve super_admin kullanıcı tipleri malzeme girişi oluşturabilir. Diğer kullanıcı tipleri 403 Forbidden yanıtı alır.

6.3.14 — WebSocket Yayını

Malzeme girişleri oluşturulduktan sonra (bakır/kalay yolu), backend oluşturulan her malzeme için malzeme ID’si, QR kodu ve tipiyle birlikte “materials:create” olay türünde bir WebSocket güncellemesi yayınlar. Bu, başka bir oturumdan yeni malzemeler girildiğinde Hammaddeler Listesi sayfasının manuel yenileme olmadan gerçek zamanlı güncellenmesini sağlar.

Güncelleme ve kalıcı silme işlemleri de sırasıyla “materials:update” ve “materials:delete” olaylarını yayınlar.

6.3.15 — Malzeme Güncelleme (Yalnızca Süper Admin)

Mevcut bir malzeme kaydı PUT /materials/update/{id} üzerinden güncellenebilir, ancak bu yalnızca super_admin ile sınırlıdır. Güncellenebilir alanlar: QR kodu (benzersizlik doğrulamalı), lot numarası, ağırlık, form ağırlığı, kalan ağırlık, adet, durum, notlar ve fotoğraflar. Bu düzeltmeler için kullanılır — bir operatör yanlış ağırlık girdiyse, süper admin düzeltebilir. QR kodu değiştirilebilir ama tüm malzemeler arasında benzersiz kalmalıdır.

6.3.16 — Malzeme Silme

Kalıcı silme DELETE /materials/{id}/hard-delete üzerinden yapılabilir (yalnızca süper admin). Silmeden önce sistem kontrol eder:

Silme sonrası bir WebSocket yayını tüm bağlı istemcileri bilgilendirir.

6.3.17 — Malzeme Durum Yaşam Döngüsü

Her malzeme kaydı, fabrikadaki yolculuğunu takip eden bir duruma sahiptir:

received
Yeni geldi, sisteme girildi
approved
Kalite kontrolden geçti
in_use
Şu an üretimde
consumed
Tamamen tüketildi
rejected
Kalitesiz, iade

Giriş formu yalnızca iki başlangıç durumu sunar: “received” (varsayılan) ve “rejected”. Diğer durumlar (approved, in_use, consumed) alt sistemler tarafından ayarlanır — kalite kontrol ve üretim modülleri. Ayrıca malzemenin is_active bayrağını geçiş yapan bir toggle-status endpoint’i de vardır.

6.3.18 — API Endpoint’leri

Metot Endpoint Amaç
POST/materials/entryBakır (çoklu palet) veya kalay (tekli) girişleri oluşturur. QR kodları üretir, fotoğrafları kaydeder, siparişleri bağlar, WebSocket yayınlar.
POST/materials/lot-entryLot bazlı girişler (plastik, katalizör, boya, antirodent) oluşturur. Lot başına bir satır, malzeme adı SupplierMaterial’dan çözümlenir. Lot başına bağlama için order_map oluşturur.
POST/materials/palette-entryPalet girişleri oluşturur. Palet tipi başına bir satır, I önekli QR kodlarıyla. PALET-{sıra} lot numaralarını otomatik üretir.
POST/materials/reel-entryMakara girişleri oluşturur. Makara tipi başına bir satır, H önekli QR kodlarıyla. Malzeme adı boyut ve reel_type içerir. REEL-{sıra} lot numaraları.
GET/materials/listTüm malzemeleri tedarikçi adları, fotoğraf ID’leri (tembel) ve sipariş grup kodlarıyla döner. Hammaddeler Listesi tarafından kullanılır.
GET/materials/photo/{id}Talep üzerine tekli fotoğraf base64 verisi döner (tembel yükleme).
PUT/materials/update/{id}QR kodu dahil malzeme alanlarını günceller (yalnızca süper admin). Güncellemede tüm fotoğrafları değiştirir.
DELETE/materials/{id}/hard-deleteKalıcı silme (süper admin). in_use ise engeller. Fotoğrafları ve yazdırma işlerini temizler.
PUT/materials/{id}/toggle-statusYumuşak devre dışı/etkin için is_active bayrağını geçiş yapar.
GET/materials/print/preview/{id}Yazdırmadan önce etiket önizleme görüntüsü (base64) üretir.
POST/materials/print/{id}QR etiketini fiziksel yazdırma için yazdırma kuyruğuna gönderir.
POST/materials/print/update-printer-ipYazıcı IP/port günceller (süper admin). Güncellemeden sonra bağlantıyı test eder.
GET/materials/print/test-connectionYazıcı bağlantısını test eder (lab kullanıcı + süper admin).

6.3.19 — Veritabanı Şeması: raw_materials

Tüm 8 malzeme tipi tek bir tabloda saklanır. Önemli alanlar:

6.3.20 — Malzeme Girişinin Her Şeyle Bağlantısı

Bu, Hammadde sistemindeki en çok bağlantılı modüldür. İşte her üst ve alt akış bağlantısı:

Form neden şekil değiştirir: Her malzeme türü temelden farklı fiziksel özelliklere sahiptir. Bakır tek tek tartılması gereken paletlerde gelir. Kalay tek bir bloktur. Plastikler bireysel takip gerektiren numaralı lotlarda gelir. Paletler ve makaralar tartılmaz, sayılır. Tek bir genel form ya çok karmaşık olurdu (alakasız alanlar göstererek) ya da çok basit (gerekli verileri kaçırarak). Dört arketip yaklaşımı, her malzemenin tam olarak ihtiyaç duyduğu alanları almasını sağlar — ne eksik ne fazla.

6.4 — Hammaddeler Listesi

6.4.1 — Amaç ve İş Bağlamı

Bu modül, fabrikaya giren her hammaddenin envanter görünümüdür. Hammadde Girişi teslimatları kaydetmekle ilgiliyken, bu modül envanterin görüntülenmesi, aranması, yönetilmesi ve üzerinde işlem yapılmasıyla ilgilidir. Okuma ağırlıklı bir modüldür — birincil kullanım senaryosu malzemelerin QR koduna göre aranması, kalan ağırlıkların kontrol edilmesi, fotoğrafların görüntülenmesi ve etiket yeniden yazdırılmasıdır. Ancak süper adminler için düzenleme ve silme yetenekleri de sağlar.

Sayfa, Hammadde Girişinin çıktısını tüketir: dört giriş arketipinden herhangi biri aracılığıyla oluşturulan her satır burada görünür. “Hangi hammaddelerimiz var ve ne durumda?” sorusunun tek doğruluk kaynağıdır.

6.4.2 — CRUD Akışı

Okuma (Birincil Operasyon):

  1. Sayfa yüklenir → GET /api/materials/list tüm malzemeleri getirir (sadece fotoğraf ID’leri, base64 verisi değil)
  2. Tablo 14 sütunla render edilir. Küçük resim fotoğrafları GET /api/materials/{id}/photos/first ile tembel yüklenir
  3. Fotoğraf küçük resmine tıkla → önizleme modalı açılır, kalan fotoğraflar GET /api/materials/{id}/photos ile talep üzerine getirilir
  4. Arama çubuğu, QR kod, malzeme tipi, tedarikçi, lot numarası, durum genelinde istemci tarafında filtreler (Türkçe çevirileri dahil)
  5. WebSocket bağlantısı tabloyu senkronize tutar — Hammadde Girişi’nden yeni malzemeler otomatik olarak belirir

Düzenleme (Üç Form Varyantı):

  1. Malzeme satırında düzenle ikonuna tıkla (edit_material yetkisi gerekir)
  2. Düzenleme modalı, malzeme tipine uyarlanmış alanlarla açılır:
    • Bakır/Kalay: QR kod, lot no, form ağırlık, ölçülen ağırlık, kalan ağırlık (düzenlenebilir), durum (received/available/in_use/consumed), fotoğraflar, notlar
    • Lot bazlı: QR kod, lot no, form ağırlık, ölçülen ağırlık, miktar (etiket sayısı), durum (received/rejected), fotoğraflar, notlar
    • Palet/Makara: QR kod, miktar (adet), durum (received/rejected) — en basit varyant
  3. QR kod alanı uyarı gösterir: “Dikkat: QR kodunu değiştirmek sistemdeki kayıtları etkileyebilir”
  4. Mevcut fotoğraflar modala tembel yüklenir; kullanıcı yeni ekleyebilir veya mevcutları kaldırabilir
  5. Gönderimde: PUT /api/materials/{id} → toast “Hammadde başarıyla güncellendi” → modal kapanır → WebSocket yayını → tablo yenilenir

Yazdırma (Etiket Tekrar Yazdırma):

  1. Malzeme satırında yazdır ikonuna tıkla (print_qr yetkisi gerekir; palet/makara için tooltip ile devre dışı)
  2. QR kodu, etiket sayısı ve konumlarıyla aktif yazıcı dropdown’u gösteren yazıcı seçim modalı açılır
  3. Yazıcı seç → POST /print-queue/queue/{material_id}?printer_id={id}
  4. İş, Admin’in yazdırma kuyruğuna QUEUED durumunda girer

Silme:

  1. Sil ikonuna tıkla (delete_material yetkisi gerekir)
  2. Uyarılı Popconfirm
  3. Onayda: DELETE /api/materials/{id} (pasif silme — inactive olarak işaretler)
  4. Kalıcı kaldırma için: DELETE /api/materials/{id}/hard (hard_delete_material yetkisi gerekir, kritik olarak işaretli). İlişkili material_photos kayıtlarını da kaldırır
  5. WebSocket yayını → tablo yenilenir

6.4.3 — WebSocket ile Gerçek Zamanlı Güncellemeler

Hammadde Siparişlerinin aksine (kullanıcı eylemlerinde yenilenen), bu sayfa materials ve all WebSocket odalarına abone olur. Herhangi bir kullanıcı herhangi bir cihaz veya oturumdan bir malzeme oluşturduğunda, güncellediğinde veya sildiğinde tablo otomatik olarak yenilenir. Bu, depodan tablet üzerinden Hammadde Girişi yapan bir operatör olduğunda, masaüstünde listeyi görüntüleyen yöneticinin yeni satırları yenilemek düğmesine basmadan anında görmesi anlamına gelir.

6.4.4 — Tablo: 14 Sütun

ProTable, her malzeme kaydının kapsamlı bir görünümünü sunar:

Sütun Açıklama Davranış
QR KodBenzersiz tanımlayıcı (A1, B5, C23…)Sola sabit, mavi etiket
Sipariş NoBağlı sipariş grup kodu (R1, R2…)Cyan etiket, veya sipariş bağlantısı yoksa “-”
TipMalzeme türüTürkçe adıyla renkli etiket (Bakır, Kalay, Plastik…)
Malzeme AdıSpesifik ürün adıÇözümlenmiş adı gösterir, bakır için “Filmaşin”, kalay için “Kalay Külçe” varsayılan
TedarikçiTedarikçi adıDüz metin
Lot NoLot/parti numarasıPalet/makara için “—” gösterir (uygulanmaz)
Form MiktarTedarikçinin beyan ettiği miktarTüre göre kg veya adet
Ölçülen MiktarFiili ölçülen miktarTüre göre kg veya adet
KalanÜretim sonrası kalan ağırlıkRenk kodlu: orijinalin %95’inden azsa sarı, %20’sinden azsa kırmızı. Palet/makara için “—”.
Giriş TarihiMalzemenin girildiği tarihGG.AA.YYYY Türkçe format
İrsaliyeTeslimat belgesi fotoğraflarıLazy-load küçük resim, birden fazlaysa “+N” rozeti
TestTest/hasar fotoğraflarıLazy-load küçük resim, birden fazlaysa “+N” rozeti
DurumMalzeme durumuRenkli etiket: yeşil=teslim alındı, kırmızı=reddedildi, mavi=mevcut, sarı=kullanımda, gri=tükendi
İşlemlerEylem düğmeleriSağa sabit: yazdır, düzenle, sil

6.4.5 — “Kalan” (Kalan Ağırlık) Sütunu

Bu, operasyonel olarak en önemli sütunlardan biridir. Üretim malzemenin bir kısmını tükettikten sonra orijinal malzemeden ne kadar kaldığını gösterir. Renk kodlaması anlık görsel geri bildirim sağlar:

Palet ve makara malzemeler için bu sütun “—” gösterir çünkü sayılan öğeler kalan ağırlık kavramına sahip değildir — bütün birim olarak ya mevcuttur ya da tükenmiştir.

Eğer remaining_weight ayarlanmamışsa (eski kayıtlar), sistem geriye dönük uyumluluk için orijinal weight değerine döner.

6.4.6 — Lazy Photo Yükleme Sistemi

Fotoğraf sütunları bu sayfanın teknik olarak en ilginç kısmıdır. Potansiyel olarak binlerce malzeme ve her biri için 6’ya kadar fotoğraf (3 irsaliye + 3 test) ile, tüm fotoğraf verilerini tabloyla birlikte yüklemek felaket olurdu. Sistem iki katmanlı lazy loading yaklaşımı kullanır:

  1. Tablo yükleme: /materials/list endpoint’i yalnızca fotoğraf ID’lerini (küçük tamsayılar) döndürür, fotoğraf verisini değil. Bu, API yanıtını hızlı tutar.
  2. Küçük resim yükleme: her fotoğraf hücresi bağımsız olarak GET /materials/photo/{id} üzerinden ilk fotoğrafın base64 verisini getiren bir LazyPhotoThumbnail bileşeni oluşturur. Küçük resim için yalnızca ilk fotoğraf yüklenir.
  3. Önizleme yükleme: kullanıcı önizleme için bir küçük resme tıkladığında, bileşen o gruptaki tüm kalan fotoğrafları getirir. Yani bir malzemenin 3 irsaliye fotoğrafı varsa, başlangıçta yalnızca ilki yüklenir; diğer ikisi tıklama üzerine yüklenir.

Küçük resim 40x40 piksel, yuvarlatilmış köşelerle gösterilir. Birden fazla fotoğraf varsa, sağ altta “+N” gösteren mavi bir rozet belirir (3 fotoğraf için “+2”). Tıklama, sol/sağ gezinme ve sayfa sayıcısıyla tam boyutlu önizlemeyi açar.

6.4.7 — İstemci Tarafı Arama

Arama çubuğu yüklenen tüm verileri istemci tarafında filtreler. Hammadde Siparişleri araması gibi, hem malzeme türleri hem de durumlar için EN→TR çeviri haritalarıyla iki dilli eşleşmeyi destekler. Aranabilir alanlar: QR kod, malzeme adı, malzeme türü (raw_copper→bakır, vb.), tedarikçi adı, lot numarası, sipariş grup kodu, durum (received→teslim alındı, vb.) ve tüm ağırlık/miktar değerleri metin olarak.

Arama, tüm allMaterials dizisine karşı her tuş vurusunda yeniden hesaplanan bir useMemo olarak uygulanmıştır. Tablo filtrelenmiş sonuçları dataSource={filteredData} aracılığıyla gösterir.

6.4.8 — Düzenleme Modalı: Üç Form Varyantı

Düzenleme modalı, düzenlenen malzeme türüne göre alanlarını uyarlar ve üç varyant kullanır:

Her varyant, bir uyarı içeren QR kod alanını içerir: “Dikkat: QR kodunu değiştirmek sistemdeki kayıtları etkileyebilir.”

Düzenleme modalı açılırken fotoğraflar lazy-load edilir: sistem API’den her fotoğrafı ID ile getirir ve upload bileşeni için Ant Design UploadFile nesnelerine dönüştürür. Bu, modalın mevcut fotoğrafları göstermesini ve yenilerinin eklenmesini veya mevcutların kaldırılmasını sağlar.

6.4.9 — Yazıcı Seçimli Yazdırma

İşlemler sütunundaki yazdır düğmesi, yazdırmadan önce bir yazıcı seçim modalı açar. Bu modal şunları gösterir:

Yazdırma işi POST /print-queue/queue/{material_id}?printer_id={id}’ye gönderilir. Yazdır düğmesi palet ve makara malzemeleri için devre dışıdır (çünkü QR etiket kullanmazlar), nedenini açıklayan bir tooltip ile.

6.4.10 — Yetki Sistemi

Sayfa 12 sayfa düzeyi düğmesi kaydeder:

“hard_delete_material” yetkisi critical: true olarak işaretlenmiştir, bu yöneticilere bunun yıkıcı ve geri dönüşü olmayan bir eylem olduğunu bildirir.

6.4.11 — Tablo Yerelleştirmesi

ProTable araç çubuğu düğmeleri (yenile, yoğunluk, sütun ayarları) dahili mesaj ID’lerini Türkçe dizelere eşleyen özel bir ProConfigProvider aracılığıyla Türkçe’ye yerellendirilmiştir. Buna “Yenile”, “Satır Yoğunluğu”, “Tablo Ayarları”, “Sütun Görünümü”, sabitleme yönleri ve daha fazlası dahildir. Ant Design dili de tarih/sayı biçimlendirmesi için trTR olarak ayarlanmıştır.

6.4.12 — Bu Modülün Sisteme Bağlantısı

Tek satırda görünen tam izlenebilirlik zinciri: Bu tablodaki tek bir satır size şunları söyler: ne olduğunu (QR kod + tip + malzeme adı), nereden geldiğini (tedarikçi + sipariş grup kodu), ne kadar olduğunu (form ağırlık vs. ölçülen ağırlık), ne kadar kaldığını (renk kodlu kalan ağırlık), neye benzediğini (irsaliye ve test fotoğrafları) ve şu anki durumunun ne olduğunu (durum). Bu, bir hammaddenin tam yaşam döngüsü görünümüdür — teslimattan tükenmeye kadar — hepsi tek bir satırda.

7. SONUÇ

Hammadde, fiziksel dünyanın dijital sistemle buluştuğu noktadır. Fabrika kapısından giren her gram bakır, her kalay kütük, her plastik parti, her palet ve makara bu modülden geçer. Kimliği atar (QR kod), kanıtı kaydeder (fotoğraflar), miktarları takip eder (ağırlık) ve durumu yönetir (durum yaşam döngüsü). Bu modül olmadan üretim sisteminin tüketeceği malzeme, stok sisteminin raporlayacağı envanter ve projeksiyon sisteminin tahmin için kullanacağı giriş verisi yoktur.

7.1 Bu Dokümanın Kapsamı

Bu derinlemesine analiz, Hammadde modülünü dört alt modül üzerinden inceledi — tedarikçi tanımlarından satın alma takibine, malzeme girişinden envanter görüntülemeye:

BölümAlt ModülDerinlikTemel Öngörü
6.1Tedarikçi YönetimiTamBire-çok tedarikçi→malzeme, malzemeye özel özellikler (yoğunluk, boyut, makara tipi); sil-ve-yeniden-oluştur güncelleme stratejisi; Giriş, Sipariş ve Hesap Makinesi tarafından tüketilir
6.2Hammadde SiparişTamSevkiyat gruplandırması için sipariş grup kodları (R1, R2…); zorunlu nedenlere sahip tarih değişikliği denetim izi; Hammadde Girişi tarafından otomatik durum güncellemesi; Projeksiyon’u “ARTI” tarafı olarak besler
6.3Hammadde GirişiKapsamlıDört dinamik form arketipi (bakır/kalay/lot bazlı/sayı bazlı); deterministik QR kodlar (A–H önekleri); iki katmanlı tembel fotoğraf yükleme; otomatik sipariş teslimat güncellemeleri
6.4Hammaddeler ListesiTamRenk kodlu kalan ağırlıklı 14 sütunlu envanter görünümü; üç düzenleme formu varyantı; tembel fotoğraf küçük resimleri ve önizleme; gerçek zamanlı WebSocket güncellemeleri

7.2 Mimari Prensipler

Fiziksel-Öncelikli Tasarım

Her malzeme türünün temelde farklı fiziksel özellikleri vardır. Tek bir genel form dayatmak yerine, sistem dört farklı arketip kullanır — bakır paletlerin tek tek tartılmasını, kalayın otomatik lot numarası almasını, plastiklerin etiketler için lot sayılarını takip etmesini ve palet/makaraların sadece sayılmasını sağlar. Arayüz malzemeye uyum sağlar, tersi değil.

Tembel Yükleme

Fotoğraflar ayrı depolanarak talep üzerine yüklenir. Malzeme listesi yalnızca fotoğraf kimliklerini döndürür, base64 verisini değil. Küçük resimler birer fotoğraf yükler; önizlemeler geri kalanları tıklandığında getirir. Bu desen, binlerce satırlı ve potansiyel olarak on binlerce fotoğraflı bir tabloyu duyarlı tutar.

Otomatik Kademelendirme

Malzeme teslimatı kaydedildiğinde, bağlantılı satın alma siparişinin teslim_miktarı, durumu ve teslim_tarihi otomatik olarak güncellenir. Bu, Projeksiyon’a da yansır — planlanmış veriden gerçek veriye geçilir. Hammadde Girişi’ndeki tek bir eylem, Siparişler üzerinden projeksiyon sistemine manuel müdahaleye gerek kalmadan yayılır.

Deterministik Kimlik

QR kodlar katı bir önek+sıra deseni izler (A=bakır, B=kalay, C=plastik…). UUID yok, rastgelelik yok. Sıra tipe özeldir ve otomatik artan. Bu, QR kodlarının insan tarafından okunabilir, sıralanabilir ve tahmin edilebilir olmasını sağlar — operatörlerin el tipi cihazlarla etiket taradığı bir fabrika zemininde kritik öneme sahiptir.

7.3 Rakamlarla

4
ALT MODÜL
~30
API ENDPOINT
6
VERİTABANI TABLOSU
~2.200
SATIR BACKEND
~5.100
SATIR FRONTEND
8
MALZEME TİPİ

7.4 Hammadde Fabrikayı Nasıl Besler

Tedarikçi Sipariş Hammadde Girişi Hammaddeler Listesi Üretim

Tedarikçiler hangi malzemelerin mevcut olduğunu ve özelliklerini tanımlar. Siparişler nelerin satın alındığını ve ne zaman geleceğini takip eder. Hammadde Girişi fiziksel varışı kaydeder — tartma, fotoğraflama, QR kodlama ve siparişe bağlama. Hammaddeler Listesi, üretimin tükettiği canlı envanter haline gelir. Üretim malzeme kullandıkça kalan ağırlıklar düşer, durumlar değişir ve malzeme tamamen tükenene kadar döngü devam eder.

Paralel olarak, her sipariş Projeksiyon sistemini planlanmış ve gerçek teslimat verileriyle besleyerek, fabrikanın malzeme mevcudiyetini haftalarca önceden tahmin etmesini sağlar.

7.5 Son Söz

Hammadde modülü, kaotik bir fiziksel süreci — bakır tel, kalay kütük, plastik varil ve tahta palet taşıyan kamyonların gelışıni — yapılandırılmış, izlenebilir, aranabilir dijital kayıtlara dönüştürür. Her malzeme bir kimlik, bir geçmiş ve bir durum kazanır. Bir tedarikçinin tanımlanmasından bakırın son gramının üretimde tüketilmesine kadar, bu modül veri izini sağlar. Dört arketipli form tasarımı, tembel fotoğraf mimarisi, otomatik sipariş kademelendirmesi ve gerçek zamanlı WebSocket güncellemeleri tek bir hedefe hizmet eder: fiziksel gerçeklik ile dijital kayıt arasındaki boşluğu mümkün olduğunca küçük tutmak. Bu doküman, tedarikçi tanımından envanter tükenme noktasına kadar tüm bu zinciri — her API endpoint’i, her veritabanı sütunu, her önyüz etkileşimi ve her modüller arası bağlantıyı — takip etmiştir.