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.
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.
İÇİNDEKİLER
1. HAMMADDE NE YAPAR
Hammadde modülü, fabrikanın tedarik zincirinin bağlı olduğu dört soruyu yanıtlar:
- 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.
- 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.
- 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.
- 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ışı
Sisteme kayıtlı
R1, R2... oluşturulur
Tarih takibi
QR + fotoğraf
Tüketim Akışı
Durum: teslim alındı
Lab onayı
Üretim hattında
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.
| Kolon | Tip | Amaç |
|---|---|---|
| id | INTEGER PK | Otomatik artan birincil anahtar |
| material_type | VARCHAR(50) | raw_copper, raw_tin, raw_plastic, raw_catalyst, raw_dye, raw_antirodent, raw_palette, raw_reel |
| material_name | VARCHAR(200) | Tedarikçi kataloğundan spesifik malzeme adı (ör. HFX500, K388) |
| sequence_number | INTEGER | Tür bazlı sayaç — her material_type için ayrı sıra |
| qr_code | VARCHAR(50) UNIQUE | Oluşturulan kod: ön ek + sıra (A1, B7, C23, I145...) |
| supplier_id | FK → suppliers | Bu malzemeyi hangi tedarikçi sağladı |
| material_order_id | FK → material_orders | Satın alma siparişine bağlantı (teslimat takibi için) |
| lot_number | VARCHAR(100) | Tedarikçinin lot numarası (veya kalay için otomatik: TIN-N) |
| weight | FLOAT | Teslim alındığında ölçülen ağırlık (kg) |
| remaining_weight | FLOAT | Üretim tüketimi sonrası kalan ağırlık (kg) |
| form_weight | FLOAT | Resmi form ağırlığı (bakır paletler için) |
| quantity | INTEGER | Lot bazlı malzemeler için adet (plastik/katalizör/boya/antirodent) |
| status | VARCHAR(50) | received → approved → in_use → consumed | rejected |
| entered_by | FK → users | Malzemeyi sisteme kim girdi |
| notes | TEXT | Serbest notlar |
| received_date | DATETIME | Malzemenin fiziksel olarak teslim alındığı zaman |
| created_at | DATETIME | Kayıt oluşturma zaman damgası |
| updated_at | DATETIME | Son 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.
| Kolon | Tip | Amaç |
|---|---|---|
| id | INTEGER PK | Fotoğraf tanımlayıcısı |
| material_id | FK → raw_materials (CASCADE) | Bu fotoğraf hangi malzemeye ait |
| photo_type | VARCHAR(20) | ‘delivery’ veya ‘test’ |
| sequence | INTEGER | 1, 2 veya 3 (tür başına en fazla 3 fotoğraf) |
| photo_data | TEXT | Base64 kodlanmış görüntü verisi |
| created_at | DATETIME | Yü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.
| Kolon | Tip | Amaç |
|---|---|---|
| id | INTEGER PK | Sipariş tanımlayıcısı |
| order_group_code | VARCHAR(20) | Gruplama kodu (R1, R2...) — aynı sevkiyattan siparişler bunu paylaşır |
| material_type | VARCHAR(50) | Ne sipariş ediliyor (bakır, plastik vb.) |
| supplier_id | FK → suppliers | Siparişi hangi tedarikçi karşılıyor |
| supplier_material_id | FK → supplier_materials | Sipariş edilen spesifik malzeme |
| quantity | FLOAT | Sipariş edilen miktar |
| delivered_quantity | FLOAT | Gerçekte teslim edilen miktar (malzeme girişi bağlandığında güncellenir) |
| unit | VARCHAR(20) | Malzemeler için ‘kg’, palet/makara için ‘adet’ |
| order_date | DATE | Siparişin verildiği tarih |
| expected_date | DATE | Teslimatın beklendiği tarih (değişebilir — takip edilir) |
| delivered_date | DATE | Gerçek teslimat tarihi |
| status | VARCHAR(20) | pending → shipped → delivered | cancelled |
| rating | FLOAT | Teslimat sonrası puan (0.5–5 yıldız, yarım artışlarla) |
| rating_note | TEXT | Puanlama yorumu |
| notes | TEXT | Sipariş notları |
| created_by | FK → users | Bu 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.
| Kolon | Tip | Amaç |
|---|---|---|
| id | INTEGER PK | Değişiklik kaydı tanımlayıcısı |
| order_id | FK → material_orders (CASCADE) | Hangi sipariş değiştirildi |
| old_date | DATE | Önceki beklenen tarih |
| new_date | DATE | Yeni beklenen tarih |
| reason_type | VARCHAR(20) | ‘supplier’ | ‘solen’ | ‘other’ |
| reason_detail | TEXT | Manuel açıklama (‘other’ için zorunlu) |
| changed_by | FK → users | Tarihi kim değiştirdi |
| created_at | DATETIME | Değ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.
| Kolon | Tip | Amaç |
|---|---|---|
| id | INTEGER PK | Tedarikçi tanımlayıcısı |
| name | VARCHAR(200) UNIQUE | Şirket adı (BÜYÜK HARF olarak saklanır) |
| contact_person | VARCHAR(100) | Birincil iletişim kişisi |
| phone | VARCHAR(50) | Otomatik biçimlendirilen Türk telefon numarası |
| VARCHAR(100) | E-posta (regex doğrulamalı) | |
| address | TEXT | Fiziksel adres |
| tax_number | VARCHAR(50) | Vergi sicil numarası |
| is_active | BOOLEAN | Yumuşak silme bayrağı (aktif/pasif geçişi) |
| notes | TEXT | Serbest 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.
| Kolon | Tip | Amaç |
|---|---|---|
| id | INTEGER PK | Tedarikçi-malzeme bağlantı tanımlayıcısı |
| supplier_id | FK → suppliers | Hangi tedarikçi |
| material_type | VARCHAR(50) | copper, tin, plastic, catalyst, dye, antirodent, palette, reel |
| material_name | VARCHAR(100) | Spesifik ürün adı (HF-500, CAT-203 vb.) |
| density | FLOAT | Plastik/katalizör/boya/antirodent için (g/cm³) |
| boyut | VARCHAR(100) | Palet/makara için boyutlar |
| reel_type | VARCHAR(20) | Makaralar için: Yazılı/Yazısız (etiketli/etiketsiz) |
| is_active | BOOLEAN | Bu 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öntemi | Temel Davranış |
|---|---|---|
| Bakır (raw_copper) | POST /materials/entry | Palet 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/entry | Tek satır oluşturur. Tek ağırlık girişi. Lot numarası otomatik: TIN-{sıra}. |
| Plastik, Katalizör, Boya, Antirodent | POST /materials/lot-entry | Lot 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. |
| Palet | POST /materials/palette-entry | Palet tipi başına bir satır oluşturur. QR ön eki I. Lot otomatik: PALET-{sıra}. |
| Makara | POST /materials/reel-entry | Makara 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:
- Rol bazlı: Malzeme girişi
lab_userveyasuper_admingerektirir. Malzeme güncellemelerisuper_admingerektirir. Kalıcı silmelersuper_admingerektirir. - Akıllı yetki kontrolü: Tedarikçi route’ları, hem eski rol bazlı sistem hem de yeni ultra-granüler sayfa-buton yetki sistemiyle aynı anda çalışan
check_permission_smart()kullanır. - Frontend kaydı: Her sayfa butonlarını
registerPageButtons()ile yetki sistemine kaydeder ve hangi eylemlerin var olduğunu tam olarak bildirir (ör.add_copper,add_tin,upload_delivery_photo,print_qr_modal).
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ı
| Route | Bileşen | Satır | Amaç |
|---|---|---|---|
| /hammadde/hammadde-girisi | Lab/MaterialEntry | 1.930 | 8 malzeme türü kartıyla malzeme girişi, fotoğraf yükleme, sipariş bağlama |
| /hammadde/hammaddeler-listesi | Hammadde/HammaddelerListesi | 1.153 | Lazy fotoğraf önizlemeleriyle ProTable, CRUD, yazdırma, durum yönetimi |
| /hammadde/hammadde-siparis | Hammadde/HammaddeSiparis | 1.237 | Tarih değişikliği geçmişi, gruplama, puanlama ile sipariş takibi |
| /hammadde/tedarikci-yonetimi | Lab/SupplierManagement | 761 | İç 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ür | QR Ön Eki | Renk | Giriş Yöntemi |
|---|---|---|---|
| Bakır | A | Turuncu | Form + ölçülen ağırlıklarla çoklu palet |
| Kalay | B | Camgöbeği | Tek ağırlık girişi |
| Plastik | C | Mor | Lot başına test fotoğraflarıyla lot bazlı |
| Katalizör | D | Yeşil | Lot başına test fotoğraflarıyla lot bazlı |
| Boya | E | Pembe | Lot başına test fotoğraflarıyla lot bazlı |
| Antirodent | F | Deniz Mavisi | Lot başına test fotoğraflarıyla lot bazlı |
| Palet | I | Yeşil Sarı | Palet tipi başına adet |
| Makara | H | Altın | Makara 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.
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.
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.
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.
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.
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:
- Tüm alanlarda istemci taraflı arama ile ProTable (Türkçe malzeme türü adları dahil)
- Malzeme türüne göre dinamik koşullu alanlarla Oluştur/Düzenle modalı
- Tabloda sayı rozetleri ve detay ipuçlarıyla malzeme türü gruplandırması
- Yumuşak silme (aktif/pasif geçişi) ve FK bağımlılık korumasıyla kalıcı silme
- Tüm bağlı istemciler arasında gerçek zamanlı WebSocket güncellemeleri
6.1.2 API Kontratı
| Metot | Yol | Fonksiyon | Yetki |
|---|---|---|---|
| POST | /api/suppliers/create | create_supplier | Akıllı: lab_user VEYA hammadde.tedarikci-yonetimi.create_supplier |
| GET | /api/suppliers/list | get_suppliers | Herhangi kimliği doğrulanmış kullanıcı |
| GET | /api/suppliers/by-material/{type} | get_suppliers_by_material | Herhangi kimliği doğrulanmış kullanıcı |
| GET | /api/suppliers/materials-list | get_supplier_materials_list | Herhangi kimliği doğrulanmış kullanıcı |
| GET | /api/suppliers/{id} | get_supplier | Herhangi kimliği doğrulanmış kullanıcı |
| PUT | /api/suppliers/{id} | update_supplier | Herhangi kimliği doğrulanmış kullanıcı |
| PUT | /api/suppliers/{id}/toggle-status | toggle_supplier_status | Akıllı: super_admin VEYA deactivate_supplier |
| DELETE | /api/suppliers/{id}/hard-delete | hard_delete_supplier | Akıllı: super_admin VEYA hard_delete_supplier |
6.1.3 CRUD Akışı
Oluşturma:
- Araç çubuğundaki “Yeni Tedarikçi” butonuna tıkla
- Modal açılır: firma adı + dinamik malzeme bölümü (başlangıçta bir boş malzeme kartı)
- 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)
- Aynı tedarikçiye daha fazla malzeme eklemek için “+” tıkla
- Gönderimde: önyüz
undefineddeğerleri temizler →POST /api/suppliers/create - 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:
- Eylemler sütunundaki düzenle ikonuna tıkla
- Modal, mevcut firma adı ve tüm malzeme kartlarıyla önceden dolu açılır
- Kullanıcı adı değiştirebilir, malzeme ekleyebilir/kaldırabilir/değiştirebilir
- 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) - 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):
- Eylemler sütunundaki durum değiştir ikonuna tıkla
- Popconfirm: “Bu tedarikçiyi devre dışı bırakmak istediğinize emin misiniz?”
- Onayda:
PUT /api/suppliers/{id}/toggle-status - Tedarikçi satırı “inactive” olur — tabloda hala görünür ama grileştirilmiş. Aynı yolla yeniden etkinleştirilebilir.
Kalıcı Silme:
- Eylemler sütunundaki sil ikonuna tıkla (
hard_delete_supplieryetkisi gerekir) - Güçlü uyarı metinli Popconfirm
- Onayda:
DELETE /api/suppliers/{id}/hard-delete - Backend bağımlı
raw_materialssatırlarını kontrol eder — varsa silme engellenir: “Bu tedarikçiye ait {n} hammadde kaydı var. Önce hammaddeleri silin.” - 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, Kalay | Ek alan yok — “Bu malzeme için ek bilgi gerekmez” | — |
| Plastik, Katalizör, Boya, Antirodent | material_name + density (g/cm³) | HF-500, 1.42 g/cm³ |
| Palet | material_name + boyut (ölçüler) | Euro Palet, 120x80x15 cm |
| Makara | material_name + boyut + reel_type | 300mm 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:
- Bir tedarikçi 1 plastik sağlıyorsa →
Plastiketiketi gösterir - Bir tedarikçi 3 plastik sağlıyorsa →
Plastik (3)etiketi gösterir - Herhangi bir etiketin üzerine gelindiğinde tüm malzeme detaylarını gösteren ipucu görünür: ad, yoğunluk, boyutlar
- Her malzeme türü tutarlı bir renk alır: bakır=turuncu, kalay=mavi, plastik=mor, katalizör=yeşil, boya=magenta, antirodent=camgöbeği, palet=yeşil sarı, makara=altın
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:
broadcast_update("suppliers", "create", {id, name})— başarılı oluşturma sonrasıbroadcast_update("suppliers", "update", {id, name})— güncelleme veya durum geçişi sonrasıbroadcast_update("suppliers", "delete", {id, name})— kalıcı silme sonrası
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):
- Araç çubuğundaki “Yeni Sipariş” butonuna tıkla
- Modal, kademeli seçimle açılır: Malzeme Tipi → Tedarikçi (tipe göre filtrelenir) → Ürün panelleri
- Malzeme tipi seç → tedarikçi dropdown’u sadece o tipi taşıyan tedarikçileri gösterir
- Tedarikçi seç → ürün kataloğu katlanabilir paneller olarak belirir. Ürün seç, miktar gir (kg veya adet)
- Aynı sevkiyattaki aynı tedarikçiden daha fazla ürün eklemek için “+” tıkla
- Sipariş tarihi (varsayılan bugün) ve beklenen teslim tarihi ayarla. İsteğe bağlı notlar ekle
- 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 - Başarılı: toast onayı → modal kapanır → tablo yeni sipariş grubunu göstererek yenilenir
Düzenleme (Tekli Satır):
- Belirli bir sipariş satırında düzenle ikonuna tıkla (grup değil — bireysel satırları düzenlersiniz)
- Modal mevcut değerlerle önceden dolu açılır: tedarikçi, malzeme, miktar, tarihler, notlar
- Çoklu öğe “+” işlevi düzenleme modunda mevcut değildir
- 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 - Gönderimde:
PUT /api/material-orders/{id}→ sipariş güncellenir + varsa tarih değişikliği günlüğe kaydedilir - Başarılı: toast → modal kapanır → tablo yenilenir
Silme:
- Belirli bir sipariş satırında sil ikonuna tıkla
- Uyarılı Popconfirm
- Onayda:
DELETE /api/material-orders/{id} - Kademeli: ilişkili
material_order_date_changeskayıtları siparişle birlikte silinir - Tablo yenilenir. Bu gruptaki son öğeyse, grup kodu kaybolur
Okuma (Tarih Geçmişi):
- Herhangi bir sipariş satırındaki saat ikonuna (Tarih Geçmişi) tıkla
- 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
- 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:
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:
- Malzeme Tipi Seç — kullanıcı 8 tip arasından seçer (bakır, kalay, plastik, katalizör, boya, antirodent, palet, makara). Bu ilk filtredir.
- 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_provideddizisi kontrol edilerek gerçekleşir. - Ü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.
- 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.
- Tarihleri Belirle — iki tarih zorunludur: sipariş tarihi (varsayılan bugün) ve beklenen teslim tarihi.
- İ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:
- Seçilen yeni tarih belirgin şekilde gösterilir
- Sebep seçici (zorunlu), üç seçenekli:
- Tedarikçi kaynaklı — tedarikçiden kaynaklanan gecikme
- Solen kaynaklı — Solen’den kaynaklanan gecikme (örn. program nedeniyle erteleme)
- Diğer — başka sebep (serbest metin alanı açar)
- Onayla / İptal butonları — kullanıcı sebep seçtikten sonra tarih değişikliğini açıkça onaylamalıdır
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:
- Eski tarih (üstü çizili) ve yeni tarihe işaret eden ok
- Sebep renkli etiket olarak
- Varsa açıklama metni italik olarak
- Değişikliğin ne zaman yapıldığı ve kim tarafından (sağa hizalı ikincil sütunda)
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:
- Renksiz — henüz hiçbir şey teslim edilmedi (0)
- Sarı/uyarı — kısmen teslim edildi (bir miktar malzeme geldi ama siparişten az)
- Yeşil — tamamen teslim edildi (gelen ≥ sipariş)
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:
- Malzeme tipleri: copper→bakır, tin→kalay, plastic→plastik, catalyst→katalizör, dye→boya, palette→palet, reel→makara
- Durumlar: pending→beklemede, delivered→teslim alındı
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ş No | Sipariş grup kodu (R1, R2…) | Sola sabit, mavi etiket |
| Malzeme | Malzeme tipi | Tipe göre renkli etiket |
| Ürün | Tedarikçi kataloğundan ürün adı | Mavi etiket |
| Tedarikçi | Tedarikçi adı | Mavi etiket |
| Sipariş Miktarı | Sipariş edilen miktar + birim | Türkçe sayı formatı |
| Gelen Miktar | Teslim edilen miktar + birim | Tamam olunca yeşil, kısmi sarı |
| Sipariş Tarihi | Siparişin verildiği tarih | GG.AA.YYYY formatı |
| Beklenen Tarih | Beklenen teslim tarihi | Gecikmiş ise kırmızı (bugünden önce) |
| Geliş Tarihi | Gerçek teslim tarihi | Yeşil metin, veya teslim edilmediyse “-” |
| Durum | Sipariş durumu | Satı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/list | Tü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/create | Paylaşı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:
order_group_code(indeksli) — aynı gönderimden birden fazla kalemi gruplar (R1, R2…)supplier_id→supplierstablosuna FKsupplier_material_id→supplier_materialstablosuna FK — sipariş edilen spesifik ürünquantity/delivered_quantity— sipariş edilen ve gerçekte alınanunit— otomatik belirlenir: palet/makara için “adet”, diğer her şey için “kg”order_date/expected_date/delivered_date— üç tarih kilometre taşıstatus— pending / shipped / delivered / cancelledrating/rating_note— teslimat sonrası değerlendirmecreated_by→userstablosuna FK — siparişi kimin oluşturduğunun denetim izi
material_order_date_changes — beklenen tarih değişikliklerinin denetim izi. Her satır bir değişiklik olayını yakalar:
order_id→material_orderstablosunaCASCADEsilmeli FKold_date/new_date— ne değiştireason_type— supplier, solen veya otherreason_detail— serbest metin (yalnızca “other” tipi için)changed_by→userstablosuna FK
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:
- EKSİ (İhtiyaç) — üretimin her hafta ne kadar malzeme tüketeceği. Bu İş Kartlarından (üretim planlarından) gelir — bakır için KC kartları, kalay için KL kartları, plastik/katalizör/boya/antirodent için EX kartları, makara için Aktarma kartları, palet için Paletleme kartları.
- ARTI (Gelen) — her hafta ne kadar malzemenin geleceği. Bu tamamen Malzeme Siparişlerinden gelir.
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:
- Yeni sipariş oluşturma → beklenen haftaya bir ARTI girişi ekler
- Beklenen tarihi değiştirme → o ARTI’yı bir haftadan diğerine taşır (tarih değişikliği takibinin bu kadar önemli olmasının nedeni budur — projeksiyonu kaydırır)
- Miktarı değiştirme → o haftanın ARTI değerini artırır veya azaltır
- Siparişi iptal etme → ARTI’yı tamamen kaldırır (iptal edilen siparişler hariç tutulur)
- Siparişin teslim edilmesi → ARTI, expected_date/quantity’den delivered_date/delivered_quantity’ye geçer, gerçeği yansıtır
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
- Resmi satın alma siparişleri veya faturalar üretmez
- Fiyatlandırma veya maliyet yönetmez — fiyat alanları yoktur
- Tedarikçilere bildirim veya e-posta göndermez
- WebSocket kullanmaz — tablo açık kullanıcı işlemlerinde yenilenir (kaydetme, silme, durum değişikliği)
- İzin sistemini kullanmaz — kimliği doğrulanmış her kullanıcı tüm özelliklere erişebilir
- Fiyatlandırma, faturalama veya herhangi bir finansal takip yapmaz
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):
- Açılış sayfasındaki 8 malzeme tipi kartından birine tıkla (Bakır, Kalay, Plastik, Katalizör, Boya, Antirodent, Palet, Makara)
- 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) - 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 “+”
- İrsaliye fotoğrafları ve isteğe bağlı test/hasar fotoğrafları yükle (lot bazlılar için lot başına)
- Gönderimde: tipe özel endpoint çağrılır (
POST /api/materials/copper-entry,/tin-entry,/lot-entry,/palette-entryveya/reel-entry) - Backend, deterministik QR koduyla (A1, B1, C1…) palet/lot/tip başına bir
raw_materialssatırı oluşturur. Siparişe bağlıysa: siparişte otomatik olarakdelivered_quantity,status=DELIVERED vedelivered_date=bugün günceller - Başarılı: tüm üretilen QR kodlarını gösteren başarı modalı belirir, QR başına “Yazdır” butonu ile. WebSocket
materialsveallodalarına yayın yapar
Güncelleme (Sadece Super Admin):
- Bu sayfada doğrudan mevcut değil — güncellemeler Hammaddeler Listesi (6.4) düzenleme modalı üzerinden yapılır
- Backend endpoint mevcut:
PUT /api/materials/{id}, super_admin veyaedit_materialyetkisi gerektirencheck_permission_smartile
Silme (Sadece Super Admin):
- Bu sayfada doğrudan mevcut değil — silme Hammaddeler Listesi (6.4) üzerinden yapılır
- Backend endpoint’leri:
DELETE /api/materials/{id}(pasif) veDELETE /api/materials/{id}/hard(kalıcı) - Kalıcı silme ayrıca ilişkili
material_photoskayı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:
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:
- 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
- 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:
- Tedarikçi alanı otomatik doldurulur ve devre dışı bırakılır — bir siparişe karşı giriş yaparken tedarikçiyi değiştiremezsiniz
- Lot bazlı malzemeler (plastik, katalizör, boya, antirodent) için: sistem her sipariş kalemi başına bir lot paneli önceden oluşturur,
material_type_id(spesifik ürün) siparişinsupplier_material_iddeğerinden zaten seçilmiş olarak - Paletler ve makaralar için: sistem her sipariş kalemi başına bir tip paneli önceden oluşturur, palet/makara tipi ve miktar siparişten ön doldurulmuş olarak
- Bakır ve kalay için: tedarikçi ön doldurulur; geri kalanı (palet ağırlıkları, lot numaraları) manuel girilmelidir çünkü siparişler toplam kg takip eder, palet başına detay değil
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:
- Her panel içerir: Lot Numarası (klavye geçişiyle), Form Ağırlığı (tedarikçinin irsaliyesindeki ağırlık), Ölçülen Ağırlık (Solen’de ölçülen gerçek ağırlık) ve Durum (teslim alındı veya reddedildi)
- Kullanıcı “+” butonuyla daha fazla palet ekleyebilir ve sonuncu hariç herhangi bir paneli kaldırabilir
- Form bir boş palet paneliyle başlar
- Kaydetmede backend palet başına bir
raw_materialssatırı oluşturur, her biri kendi QR koduyla (A1, A2, A3…) - Hem form_weight hem measured_weight saklanır — aradaki fark, tedarikçinin iddia ettiği ile gerçekte gelenin tutarsızlıklarını belirlemeye yardımcı olur
remaining_weightbaşlangıçtameasured_weightolarak ayarlanır ve üretim tarafından sonra azaltılır
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:
- Form yalnızca iki alan gösterir: Net Ağırlık (kg) ve Durum
raw_materials’da bir satır, bir QR kodu (B1, B2…)- Lot numarası otomatik olarak
TIN-{sıra}şeklinde üretilir remaining_weightgirilen ağırlığa eşit olarak başlatılı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:
- Her panel içerir: Malzeme Tipi (tedarikçinin kataloğundan spesifik ürünlerin açılır listesi, örn. “HFX-500P”), Lot Numarası (klavye geçişiyle), Form Ağırlığı, Ölçülen Ağırlık, Adet (basılacak etiket sayısı — bu lottaki kaç kap), Durum ve Test/Hasar Fotoğrafları (lot başına, en fazla 3)
- Malzeme Tipi açılır listesi bağlama duyarlıdır: giriş bir siparişe bağlıysa yalnızca o siparişin kalemlerindeki malzemeleri gösterir. Manuelse, tedarikçinin o türdeki tüm malzemelerini gösterir
- Kaydetmede backend lot başına bir satır oluşturur, kendi QR koduyla (C1/D1/E1/F1…)
- Backend spesifik
material_name’iSupplierMaterial’dan çözümler ve varsaboyut’u ekler, “HFX-500P - 2mm” gibi isimler oluşturur
Arketip 4: Adet Bazlı (Palet, Makara)
Paletler ve makaralar tartılmaz, sayılır. Form açılır/kapanır tip panelleri sunar:
- Her panel içerir: Tip (tedarikçi kataloğundan açılır liste, örn. “Euro Palet - 120 cm” veya “500m Makara - 40 cm - Plastik”), Adet (sayı), Durum ve Hasar Fotoğrafları (tip başına, en fazla 3)
- Tip açılır listesi tedarikçinin
materials_providedlistesinden palet veya makara tipine göre filtrelenerek doldurulur - Makaralar için gösterim
material_name - boyut cm - reel_typeşeklinde tam özelliği içerir - Kaydetmede backend tip başına bir satır oluşturur, QR koduyla (I1/H1…). Lot numarası otomatik olarak
PALET-{sıra}veyaREEL-{sıra}şeklinde üretilir weightalanı miktarı (sayıyı) saklamak için kullanılır vequantityde sayıyı saklar — geriye dönük uyumluluk için çift amaçlı alandır
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 |
|---|---|---|
| A | Bakır | A1, A2, A3… |
| B | Kalay | B1, B2, B3… |
| C | Plastik | C1, C2, C3… |
| D | Katalizör | D1, D2, D3… |
| E | Boya | E1, E2, E3… |
| F | Antirodent | F1, F2, F3… |
| I | Palet | I1, I2, I3… |
| H | Makara | H1, 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:
- Ortak teslimat fotoğrafları (İrsaliye) — bunlar teslimat belgesinin (irsaliye) fotoğraflarıdır. Bireysel kalemlere değil, tüm teslimatın geneline uygulanır. En fazla 3 fotoğraf, girişteki tüm malzemeler arasında paylaşılır. Tüm malzeme tipleri için gösterilir.
- Kalem başına fotoğraflar (Test/Hasar) — bireysel kalemler için test raporları veya hasar dokümantasyonu:
- Bakır ve kalay için: teslimat fotoğraflarının yanında ortak bir “Test Raporu Fotoğrafı” bölümü (en fazla 3) görünür
- Lot bazlı malzemeler için: her lot panelinin kendi “Test/Hasar Fotoğrafları” bölümü vardır (lot başına en fazla 3)
- Palet ve makara için: her tip panelinin kendi “Hasar Fotoğrafları” bölümü vardır (tip başına en fazla 3)
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:
- Bakır/kalay için:
material_order_ids’den ilk sipariş ID’si kullanılır. Toplam teslim edilen ağırlık (bakır için tüm palet ağırlıklarının toplamı veya kalay için tekli ağırlık) siparişindelivered_quantitydeğerine eklenir. Sipariş durumu “delivered” yapılır vedelivered_datebugünle damgalanır. - Lot bazlı malzemeler için: sistem
supplier_material_idile anahtarlanmış birorder_mapoluşturur. Her lot için, lotunmaterial_type_iddeğerinin haritada bir anahtarla eşleşip eşleşmediğini kontrol eder ve eşleşirse o lotu ilgili siparişe bağlar. Her siparişindelivered_quantitydeğeri kendi lotlarının ağırlıklarıyla artırılır. - Palet/makara için: aynı order_map mantığı, ama palet/makara tip ID’sini
supplier_material_idile eşleştirmek için kullanılır. Teslim edilen miktar kalem sayısıyla artırılır.
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:
- Üretilen QR kodlarıyla bir onay mesajı
- İki buton: OK (kapat ve dön) ve Yazdır (QR etiket yazdırma akışını tetikler)
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:
access_page— sayfayı görebilme yeteneğiadd_copper,add_tin,add_plastic,add_catalyst,add_dye,add_antirodent,add_palette,add_reel— malzeme kartı başına bir izinsubmit_form— kaydet butonuupload_delivery_photo,upload_test_photo— fotoğraf yükleme yetenekleriprint_qr_modal— başarı modalindeki yazdır butonu
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:
- Malzeme durumu “in_use” ise silme engellenir — üretimde olan malzemeyi kaldıramazsınız
- İlgili yazdırma işleri önce silinir
- İlgili fotoğraflar silinir (CASCADE bunu halledebilir ama kod açıkça yapar)
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:
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/entry | Bakı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-entry | Lot 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-entry | Palet 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-entry | Makara 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/list | Tü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-delete | Kalıcı silme (süper admin). in_use ise engeller. Fotoğrafları ve yazdırma işlerini temizler. |
PUT | /materials/{id}/toggle-status | Yumuş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-ip | Yazıcı IP/port günceller (süper admin). Güncellemeden sonra bağlantıyı test eder. |
GET | /materials/print/test-connection | Yazı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:
material_type— ayırıcı: raw_copper, raw_tin, raw_plastic, raw_catalyst, raw_dye, raw_antirodent, raw_palette, raw_reelmaterial_name— SupplierMaterial’dan çözümlenen spesifik ürün adı (örn. “HFX-500P - 2mm”). Bakır ve kalay için NULL.sequence_number— QR kod üretimi için tür başına artan sayaçqr_code— benzersiz, deterministik tanımlayıcı (A1, B5, C23, vb.)supplier_id→supplierstablosuna FKmaterial_order_id→material_orderstablosuna nullable FK — satın alma siparişine geri izlenebilirlik bağlantısılot_number— bakır/lot bazlı için kullanıcı tarafından girilir, kalay/palet/makara için otomatik üretilirweight— ağırlık bazlı malzemeler için ölçülen ağırlık, paletler/makaralar için sayıremaining_weight— weight olarak başlatılır, üretim tüketimi tarafından azaltılırform_weight— tedarikçinin irsaliyesindeki ağırlık (yalnızca bakır ve lot bazlı)quantity— lot bazlı malzemeler için kap/etiket sayısı, palet/makara için adetstatus— received / approved / in_use / consumed / rejectedentered_by→userstablosuna FK
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ı:
- Tedarikçi Yönetimi (üst akış) — tedarikçi listesini, malzeme kataloglarını ve ürün adlarını sağlar. Giriş formunun açılır listeleri tamamen tedarikçi verisinden doldurulur.
- Malzeme Siparişleri (üst + alt akış) — Adım 1 modalı için bekleyen siparişleri sağlar. Kaydetmede Malzeme Girişi siparişlere geri yazar: durumu teslim edildi yapar, tarihi damgalar, teslim edilen miktarı artırır.
- Projeksiyon (dolaylı alt akış) — sipariş durumunu beklemedenden teslim edildi’ye değiştirerek ve delivered_date/delivered_quantity ayarlayarak, Malzeme Girişi Projeksiyon’u bu siparişler için planlanan veriden gerçek veriye kaydırır.
- Hammaddeler Listesi (alt akış) — burada oluşturulan her satır anında malzeme listesinde görünür. Liste sayfası
/materials/list’i tüketir ve tüm girişleri QR kodları, ağırlıkları, durumları ve fotoğraflarıyla gösterir. - Üretim Sistemi (alt akış) — üretim modülleri malzemeleri QR kodlarına referans vererek tüketir,
remaining_weight’i azaltır ve durumu in_use/consumed olarak değiştirir. - Yazdırma Kuyruğu (alt akış) — başarı modalı yazdırma kuyruk sistemi aracılığıyla etiket yazdırmayı tetikler.
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):
- Sayfa yüklenir →
GET /api/materials/listtüm malzemeleri getirir (sadece fotoğraf ID’leri, base64 verisi değil) - Tablo 14 sütunla render edilir. Küçük resim fotoğrafları
GET /api/materials/{id}/photos/firstile tembel yüklenir - Fotoğraf küçük resmine tıkla → önizleme modalı açılır, kalan fotoğraflar
GET /api/materials/{id}/photosile talep üzerine getirilir - Arama çubuğu, QR kod, malzeme tipi, tedarikçi, lot numarası, durum genelinde istemci tarafında filtreler (Türkçe çevirileri dahil)
- WebSocket bağlantısı tabloyu senkronize tutar — Hammadde Girişi’nden yeni malzemeler otomatik olarak belirir
Düzenleme (Üç Form Varyantı):
- Malzeme satırında düzenle ikonuna tıkla (
edit_materialyetkisi gerekir) - 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
- QR kod alanı uyarı gösterir: “Dikkat: QR kodunu değiştirmek sistemdeki kayıtları etkileyebilir”
- Mevcut fotoğraflar modala tembel yüklenir; kullanıcı yeni ekleyebilir veya mevcutları kaldırabilir
- 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):
- Malzeme satırında yazdır ikonuna tıkla (
print_qryetkisi gerekir; palet/makara için tooltip ile devre dışı) - QR kodu, etiket sayısı ve konumlarıyla aktif yazıcı dropdown’u gösteren yazıcı seçim modalı açılır
- Yazıcı seç →
POST /print-queue/queue/{material_id}?printer_id={id} - İş, Admin’in yazdırma kuyruğuna QUEUED durumunda girer
Silme:
- Sil ikonuna tıkla (
delete_materialyetkisi gerekir) - Uyarılı Popconfirm
- Onayda:
DELETE /api/materials/{id}(pasif silme — inactive olarak işaretler) - Kalıcı kaldırma için:
DELETE /api/materials/{id}/hard(hard_delete_materialyetkisi gerekir, kritik olarak işaretli). İlişkilimaterial_photoskayıtlarını da kaldırır - 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 Kod | Benzersiz tanımlayıcı (A1, B5, C23…) | Sola sabit, mavi etiket |
| Sipariş No | Bağlı sipariş grup kodu (R1, R2…) | Cyan etiket, veya sipariş bağlantısı yoksa “-” |
| Tip | Malzeme 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çi | Tedarikçi adı | Düz metin |
| Lot No | Lot/parti numarası | Palet/makara için “—” gösterir (uygulanmaz) |
| Form Miktar | Tedarikçinin beyan ettiği miktar | Türe göre kg veya adet |
| Ölçülen Miktar | Fiili ölçülen miktar | Türe göre kg veya adet |
| Kalan | Üretim sonrası kalan ağırlık | Renk kodlu: orijinalin %95’inden azsa sarı, %20’sinden azsa kırmızı. Palet/makara için “—”. |
| Giriş Tarihi | Malzemenin girildiği tarih | GG.AA.YYYY Türkçe format |
| İrsaliye | Teslimat belgesi fotoğrafları | Lazy-load küçük resim, birden fazlaysa “+N” rozeti |
| Test | Test/hasar fotoğrafları | Lazy-load küçük resim, birden fazlaysa “+N” rozeti |
| Durum | Malzeme durumu | Renkli etiket: yeşil=teslim alındı, kırmızı=reddedildi, mavi=mevcut, sarı=kullanımda, gri=tükendi |
| İşlemler | Eylem düğmeleri | Sağ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:
- Renk yok — kalan ağırlık orijinale yakın (%5 tolerans içinde)
- Sarı / kalın — malzeme kısmen tüketilmiş (kalan orijinalin %95’inden az)
- Kırmızı / kalın — malzeme neredeyse tükenmiş (kalan orijinalin %20’sinden az)
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:
- Tablo yükleme:
/materials/listendpoint’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. - 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 birLazyPhotoThumbnailbileşeni oluşturur. Küçük resim için yalnızca ilk fotoğraf yüklenir. - Ö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:
- Bakır/Kalay: QR kod, lot numarası, form ağırlık, ölçülen ağırlık, kalan ağırlık (düzeltmeler için düzenlenebilir, amacını açıklayan yardımcı metinle), durum (4 seçenek: teslim alındı, mevcut, kullanımda, tükendi), fotoğraflar, notlar
- Lot bazlı (plastik, katalizör, boya, antirodent): QR kod, lot numarası, form ağırlık, ölçülen ağırlık, adet (etiket sayısı), durum (2 seçenek: teslim alındı, reddedildi), fotoğraflar, notlar
- Palet/Makara: QR kod, miktar (adet), durum (2 seçenek: teslim alındı, reddedildi) — en basit form, ağırlık veya lot numarası yok
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:
- Onay için malzemenin QR kodu
- Etiket sayısı (lot bazlı malzemelerde
quantity > 1ise birden fazla etiket yazdırılır) GET /printers/list?active_only=true’den getirilen aktif yazıcıların bir açılır listesi, her yazıcının adı ve konumuyla
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:
access_page,view_table,view_photos,search_filter— okuma yetenekleriprint_qr— yazdırmaedit_material— düzenleme modalını açmadelete_material,hard_delete_material(kritik işaretli) — silmeupdate_qr_code,update_weight,update_status,update_photos— granüler düzenleme alanı yetkileri
“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ı
- Hammadde Girişi (üst akış) — tek veri kaynağı. Bu tablodaki her satır, dört giriş endpoint’inden biri tarafından oluşturulmuştur.
- Hammadde Siparişleri (dolaylı) — “Sipariş No” sütunu sipariş grup kodunu göstererek, envanterden satın alma siparişine görsel izlenebilirlik sağlar.
- Üretim Sistemi (alt akış) — üretim modülleri bu envanterdeki verileri (
/materials/listveya doğrudan veritabanı sorguları üzerinden) okur, QR koduna göre malzeme seçer ve malzeme tükettikçeremaining_weightvestatus’ü günceller. Bu sayfa bu değişiklikleri WebSocket üzerinden gerçek zamanlı yansıtır. - Yazdırma Kuyruğu (alt akış) — yazdırma eylemi fiziksel etiket çıktısı için yazdırma kuyruğuna iş gönderir.
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üm | Alt Modül | Derinlik | Temel Öngörü |
|---|---|---|---|
| 6.1 | Tedarikçi Yönetimi | Tam | Bire-ç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.2 | Hammadde Sipariş | Tam | Sevkiyat 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.3 | Hammadde Girişi | Kapsamlı | 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.4 | Hammaddeler Listesi | Tam | Renk 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
7.4 Hammadde Fabrikayı Nasıl Besler
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.