Neden: ERP_WeighBridgeEngine.getWeighBridge() metodunda throw error() kullanımı
Etki: Kantar bağlantısı kesildiğinde tüm AX session çöküyor, kullanıcı sistemden atılıyor
Neden: ERP_Utility.printReport() metodunda try-catch yok
Etki: Yazıcı hatası veya iptal = Session çökme
Neden: N+1 sorgu problemi, sleep(600), tekrarlanan sorgular
Etki: Sistem 3-5 kat yavaş çalışıyor
Durum: ERP_Barcode, ERP_BarcodeReaded, ERP_WeighBridge tabloları projede export edilmemiş
Etki: Tam analiz yapılamıyor
| Bağlantı | Protokol | Port | Risk Seviyesi | Sorun |
|---|---|---|---|---|
| Terminal → Kantar | TCP/IP | 1001 | Yüksek | Timeout yönetimi yok, throw error() kullanımı |
| Terminal → Yazıcı | Windows Print | - | Yüksek | Exception handling yok |
| El Terminali → Terminal Server | RDP | 3389 | Orta | Session timeout ayarları |
| AX Client → AOS | AX Protocol | 2712 | Düşük | Standart AX bağlantısı |
Dosya: ERP_WeighBridgeEngine sınıfı
Metod: getWeighBridge()
static Real getWeighBridge(ERP_WeighBridge _weighBridge)
{
...
weighBridgeResponse = engine.getValue(_weighBridge.IP, _weighBridge.Port);
success = weighBridgeResponse.get_success();
if(success == false)
{
throw error(response); // 💀 SESSION ÇÖKER!
}
...
}
static Real getWeighBridge(ERP_WeighBridge _weighBridge)
{
...
try
{
weighBridgeResponse = engine.getValue(_weighBridge.IP, _weighBridge.Port);
success = weighBridgeResponse.get_success();
if(success == false)
{
if(_weighBridge.AllowManualEntry)
{
warning(strFmt("Kantar hatası: %1", response));
return -1; // Manuel giriş sinyali
}
warning(strFmt("Kantar hatası: %1", response));
return 0;
}
}
catch (Exception::CLRError)
{
warning("Kantar DLL hatası!");
return _weighBridge.AllowManualEntry ? -1 : 0;
}
...
}
Dosya: ERP_Utility sınıfı
Metod: printReport()
static client void printReport(str _reportName, Common _record,
str _printerName, int _copies)
{
reportRun reportRun;
PrintJobSettings printJobSettings;
reportRun = new ReportRun(...);
reportRun.init();
reportRun.run(); // 💀 TRY-CATCH YOK!
}
static client void printReport(str _reportName, Common _record,
str _printerName, int _copies)
{
reportRun reportRun;
PrintJobSettings printJobSettings;
try
{
reportRun = new ReportRun(...);
reportRun.init();
reportRun.run();
info("Etiket başarıyla yazdırıldı.");
}
catch (Exception::Error)
{
warning("Yazdırma hatası! Lütfen yazıcıyı kontrol edin.");
}
catch (Exception::CLRError)
{
warning("Yazıcı bağlantı hatası!");
}
catch (Exception::Break)
{
info("Yazdırma iptal edildi.");
}
}
Kullanıcı ürünü tarar
ERP_WeighBridgeEngine::getWeighBridge() çağrılır
Ağ sorunu, timeout veya kantar kapalı
Yakalanmayan exception fırlatılır
Kullanıcı sistemden atılır, veri kaybı riski
Lokasyon: createPickingList() metodu (Satır 35040-35111)
// Her döngü adımında veritabanına gidiliyor! while select forUpdate thisProdBom where thisProdBom.ProdId == prodTable.ProdId { inventTable = thisProdBom.inventTable(); // Sorgu 1 while select forUpdate barcodeReaded where barcodeReaded.ProdBomRecId == thisProdBom.RecId { barcode = ERP_Barcode::find(barcodeReaded.BarcodeId); // Sorgu 2 inventDim = thisProdBom.inventDim(); // Sorgu 3 inventDim = inventDim::findOrCreate(inventDim); // Sorgu 4 prodPool = ProdPool::find(prodTable.ProdPoolId); // Sorgu 5 (aynı değer!) select inventTransOrigin join forUpdate inventTrans ... // Sorgu 6 } } // 10 ProdBOM x 5 Barkod = 300+ veritabanı sorgusu! 💀
// Döngü dışında bir kez oku, cache'le ProdPool prodPool = ProdPool::find(prodTable.ProdPoolId); // 1 kez // Map ile cache oluştur Map inventTableCache = new Map(Types::String, Types::Record); while select inventTable exists join thisProdBom where thisProdBom.ProdId == prodTable.ProdId && thisProdBom.ItemId == inventTable.ItemId { inventTableCache.insert(inventTable.ItemId, inventTable); } // Döngüde cache'den oku while select thisProdBom ... { if(inventTableCache.exists(thisProdBom.ItemId)) inventTable = inventTableCache.lookup(thisProdBom.ItemId); }
Lokasyon: ERP_WeighBridgeEngine (Satır 405, 458)
tcpClient = new System.Net.Sockets.TcpClient(ipAddress, port);
stream = tcpClient.GetStream();
sleep(600); // 600ms tüm thread'i bloklar!
tcpClient = new System.Net.Sockets.TcpClient(); tcpClient.set_ReceiveTimeout(2000); // Timeout kullan tcpClient.set_SendTimeout(1000); tcpClient.Connect(ipAddress, port); stream = tcpClient.GetStream(); // sleep() KALDIRILDI!
Lokasyon: updateAutoConsumption() (Satır 35339-35345)
// Aynı metod 3 kez çağrılıyor! if(localBarcode.availPhysicalByLocation(inventLocationId) <= 0) continue; if(localBarcode.availPhysicalByLocation(inventLocationId) >= bomQty) miktar = bomQty - toplamMiktar; else miktar = localBarcode.availPhysicalByLocation(inventLocationId); // 100 barkod = 300 ekstra sorgu!
// Bir kez hesapla, değişkene ata Qty availQty = localBarcode.availPhysicalByLocation(inventLocationId); if(availQty <= 0) continue; if(availQty >= bomQty - toplamMiktar) miktar = bomQty - toplamMiktar; else miktar = availQty;
| Sorun | Mevcut Durum | Düzeltme Sonrası | Kazanç |
|---|---|---|---|
| N+1 Sorgu (createPickingList) | 300+ sorgu | ~20 sorgu | %90 azalma |
| sleep(600) | 600ms/okuma | 0ms | 600ms kazanç |
| availPhysicalByLocation 3x | 300 sorgu | 100 sorgu | %66 azalma |
| ProdPool::find tekrarı | 50+ sorgu | 1 sorgu | %98 azalma |
| Tablo Adı | Açıklama | Index | Durum |
|---|---|---|---|
| ERP_HandTerminalParameters | El terminali parametreleri | ✅ | OK |
| ERP_HeadpanTable | Kap/konteyner takibi | ❌ Eksik | Index gerekli |
| ERP_PalletTable | Palet başlık | ✅ PalletIdx | OK |
| ERP_PackingTable | Paketleme başlık | ✅ PackingIdx | OK |
| ERP_PackingLine | Paketleme satır | ? | İncelenmeli |
| ERP_ProductionStockTransferTemp | Üretim transfer (InMemory) | - | TempDB önerilir |
Kullanım: Tüm barkod işlemleri
Referans: ERP_Barcode::find(), availPhysicalByLocation()
Önem: Kritik - Sistem çalışmaz
Kullanım: Üretim malzeme tüketimi
Referans: createPickingList(), insertBarcodeReaded()
Önem: Kritik - Üretim çalışmaz
Kullanım: Kantar parametreleri
Referans: IP, Port, Kalibrasyon değerleri
Önem: Kritik - Kantar çalışmaz
Kullanım: Palet satırları
Referans: ERP_PalletTable cascade delete
Önem: Orta
Kullanım: Sevkiyat başlık
Referans: Form datasource
Önem: Orta
Kullanım: Sevkiyat satır
Referans: Form datasource
Önem: Orta
Kod analizine göre bu tablonun şu alanlara sahip olması gerekiyor:
| Alan Adı | Tip | Açıklama | Index |
|---|---|---|---|
| BarcodeId | String (PK) | Barkod numarası | ✅ Unique |
| ItemId | String | Madde kodu | ✅ Composite |
| ItemName | String | Madde adı | |
| InventConfigId | String | Konfigürasyon | ✅ Composite |
| InventColorId | String | Renk | |
| InventSizeId | String | Boyut | |
| InventBatchId | String | Parti numarası | ✅ Composite |
| InventSerialId | String | Seri numarası | |
| InventLocationId | String | Ambar | ✅ Composite |
| OrderNo | String | Üretim emri (ProdId) | ✅ |
| Qty | Real | Miktar | |
| HeadpanId | String | Kap referansı |
4 yerde hata mesajları siliniyor (Satır 35292, 35296, 41334, 41339)
Sorun: Debug imkansız, kullanıcı hatayı görmüyor
Çözüm: Kaldırın veya sadece başarılı işlemden sonra kullanın
Barkod tarama mantığı 5 formda tekrarlanıyor
Formlar: PressStockTransfer, MontageStockTransfer, DoughStockTransfer, WeavingStockTransfer, InjectionStockTransfer
Çözüm: ERP_StockTransferHelper sınıfı oluşturun
Gereksiz yere tüm kayıtlar kilitleniyor
Sorun: Database lock contention
Çözüm: Sadece güncellenecek kayıtları kilitleyin
getWeighBridge_old, getWeighBridge_old2, getWeighBridge_old3 metodları mevcut
Öneri: Kullanılmıyorsa silin
| Havuz | Tip | Form | Özel Mantık |
|---|---|---|---|
| PRES | Press | ERP_PressProduction | Kantar + Barkod okuma |
| MONTAJ | Montage | ERP_MontageProduction | Çoklu barkod birleştirme |
| DOKUMA | Weaving | ERP_WeavingProduction | Farklı miktar hesaplama |
| ENJEKSİYON | Injection | ERP_InjectionProduction | Otomatik tüketim |
| HAMUR | Dough | ERP_DoughProduction | Hammadde karışım |
| Durum | Açıklama | İzin Verilen İşlemler |
|---|---|---|
| Created | Oluşturuldu | Düzenleme, Silme, Sevke Gönder |
| Read | Okundu (Barkod tarandı) | Sevkiyat Oluştur |
| Discharged | Yüklendi | Manuel Kantar, Düzenleme |
| Shipped | Sevk Edildi | İrsaliye Kes |
| Cancelled | İptal | - |
Gerçek zamanlı üretim durumu, kantar okumaları, sevkiyat durumu için dashboard ekleyin.
El terminalinde offline çalışma ve sonra senkronizasyon desteği.
Stok düşük, kantar bağlantısı yok, yazıcı hatası gibi durumlar için bildirim sistemi.
Üretim verimliliği, barkod okuma istatistikleri, hata raporları.
| Özellik | Açıklama | Fayda | Zorluk |
|---|---|---|---|
| Barkod Doğrulama | Okutmadan önce format ve geçerlilik kontrolü | Hata azaltma | Kolay |
| Çift Okutma Engelleme | Aynı barkodun tekrar okutulmasını engelle | Veri doğruluğu | Kolay |
| Otomatik Yedekleme | Session çökmelerinde veri kurtarma | Veri güvenliği | Orta |
| Mobil Onay | Kritik işlemler için mobil bildirim/onay | Kontrol artışı | Zor |