Hata mesajı vermeden yanlış sonuç üreten 75 kayıt + 44 formül düzeyi risk; invariant ve salt-okunur doğrulama SQL'leri.
Künye (front-matter) · EKB-SESSIZ · reality [SUPPORT_OBSERVED, SOURCE_IMPLEMENTED, GENERATED_PROPOSAL]
| id | EKB-SESSIZ |
| title | Sessiz Hesaplama Hataları |
| entity_type | ERROR_KB |
| module | MOD-KALITE |
| audience | [SUPPORT, DEVELOPER, QA] |
| confidentiality | AIFASOFT_INTERNAL |
| product_scope | ERPGOLD_CORE |
| customer_scope | ALL |
| reality | [SUPPORT_OBSERVED, SOURCE_IMPLEMENTED, GENERATED_PROPOSAL] |
| lifecycle | ACTIVE |
| confidence | MEDIUM |
| version_from | VERSION_UNKNOWN |
| version_to | - |
| created_at | 2026-09-13 |
| last_verified | 2026-09-13 |
| source_hashes | [] |
| sources | [DOCUMENT:ERPGOLD_ERROR_MASTER.xlsx, DOCUMENT:ERPGOLD_HATA_KOK_NEDEN_BILGI_BANKASI.md, SRC-TKT-ERP, SOURCE_CODE:ERPPRO, DB_CATALOG:INST-ERPGOLDV2] |
| aliases | [Sessiz Hesaplama Hataları] |
| tags | [error-kb] |
| wiki_version | v1.5 |
| source_package | ERPGOLD_HATA_BILGI_BANKASI_v1 / Wiki_23_Hata_Bilgi_Bankasi |
| severity | S1–S4 (kayıt bazında) |
| runtime_status | NOT_REPRODUCED — statik analiz + invariant; Gözlemlendi: HAYIR |
Sessiz mantık / hesaplama hataları (75). Hata mesajı vermeden yanlış sonuç üreten noktalar: yuvarlama/hassasiyet, kur=0, boş Catch blokları, eksik türetilmiş kayıt. Etiket: SESSİZ MANTIK / HESAPLAMA. Doğrulama yöntemi olarak invariant ve salt-okunur SQL verilir; bkz. Health Check.
Özet
| Kayıt | 75 |
| Gözlemlendi: EVET / HAYIR | 38 / 37 |
| Severity | S1 5 · S2 24 · S3 26 · S4 20 |
| Çözümü bilinen | 10 |
| Durum | AÇIK 75 |
Modül dağılımı
| Modül | Kayıt | S1 | S2 | S3 | S4 |
|---|---|---|---|---|---|
| MOD-SISTEM | 18 | 5 | 4 | 4 | 5 |
| MOD-CARI | 18 | 0 | 9 | 9 | 0 |
| MOD-STOK | 12 | 0 | 3 | 5 | 4 |
| MOD-EFATURA | 7 | 0 | 6 | 1 | 0 |
| MOD-VERİTABANI | 6 | 0 | 2 | 4 | 0 |
| MOD-DIGER | 4 | 0 | 0 | 0 | 4 |
| MOD-GENEL | 4 | 0 | 0 | 1 | 3 |
| MOD-RAPOR | 3 | 0 | 0 | 2 | 1 |
| MOD-FINANS | 2 | 0 | 0 | 0 | 2 |
| MOD-URETIM | 1 | 0 | 0 | 0 | 1 |
Hata kategorisi dağılımı
| Kategori | Kayıt |
|---|---|
| E06 — Algoritma Hatası | 25 |
| E07 — Finansal Hesaplama Hatası | 21 |
| E08 — Yuvarlama / Hassasiyet Hatası | 10 |
| E16 — Eksik Türetilmiş Kayıt | 10 |
| E15 — Duplicate / Çift İşlem | 3 |
| E02 — SQL Server Hatası | 2 |
| E05 — Transaction Hatası | 2 |
| E03 — Veri Bütünlüğü Hatası | 1 |
| E17 — Eski Veri / Legacy Problemi | 1 |
Kayıtlar
SESSİZ MANTIK / HESAPLAMA ERR-SIL-001 — IndexOutOfRangeException / InvalidCastException — FrmBlokTakozGirisi.ListRefresh S4 · MOD-STOK · Gözlemlendi: HAYIR · PF-010 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-STOK |
| Alt modül | Kod |
| Problem ailesi | PF-010 Programa giriş yapılamıyor / program açılmıyor (giriş hatası) |
| Kullanıcı belirtisi | Belirti yok; hatalı girişte 'Girilen Bilgilere Göre Takoz Cıkıs İşlemleri Bulunamadı' mesajı. |
| Teknik belirti | TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(0) yok; veya sayısal olmayan parça → Integer'a dönüşüm hatası). |
| Exception türü | IndexOutOfRangeException / InvalidCastException |
| Kod dosyası | ERPPRO/Controls/Islem Ekranı/Ekran/FrmBlokTakozGirisi.vb |
| Class | FrmBlokTakozGirisi |
| Method | ListRefresh |
| Satır / bölge | 17 |
| Tetikleme koşulu | TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(0) yok; veya sayısal olmayan parça → Integer'a dönüşüm hatası). |
| Kök neden | Try/Catch var ama Catch bloğu boş; SubeId/HesapId/FisNo 0 kalır ve sorgu 0 değerleriyle çalışır. Form Load'da (satır 3-4) ListRefresh boş metinle çağrıldığı için istisna HER açılışta oluşur ve yutulur. |
| Neden zinciri | Teknik olay: IndexOutOfRangeException / InvalidCastException ↓ Yakın neden: TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(0) yok; veya sayısal ↓ Kök neden: Try/Catch var ama Catch bloğu boş; SubeId/HesapId/FisNo 0 kalır ve sorgu 0 değerleriyle çalışır. Form Load'da (satır 3-4) ListRefresh boş metinle çağrıldığı içi ↓ Kullanıcı etkisi: Belirti yok; hatalı girişte 'Girilen Bilgilere Göre Takoz Cıkıs İşlemleri Bulunamadı' mesajı. |
| Olasılık / etki / güven | ÇOK YÜKSEK / S4 / 90 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Metni Split edip parça sayısı ve Integer.TryParse ile doğrulamak; geçersizse kullanıcıya uyarı verip Exit Sub. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(0) yok; veya sayısal olmayan parça → Integer'a dönüşüm hatası). |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · FrmBlokTakozGirisi.vb:16-22 `Try SubeId = TxtSubeId.Text.Split(".")(0) ... Catch ex As Exception End Try` |
| İlişkili kayıtlar | ERR-POT-002, ERR-POT-008, ERR-SIL-002, ERR-SIL-003, ERR-SIL-028, ERR-SIL-056, ERR-SIL-059 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-002 — IndexOutOfRangeException / InvalidCastException — FrmBlokTakozGirisi.ListRefresh S4 · MOD-STOK · Gözlemlendi: HAYIR · PF-010 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-STOK |
| Alt modül | Kod |
| Problem ailesi | PF-010 Programa giriş yapılamıyor / program açılmıyor (giriş hatası) |
| Kullanıcı belirtisi | Belirti yok; hatalı girişte 'Girilen Bilgilere Göre Takoz Cıkıs İşlemleri Bulunamadı' mesajı. |
| Teknik belirti | TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(1) yok; veya sayısal olmayan parça → Integer'a dönüşüm hatası). |
| Exception türü | IndexOutOfRangeException / InvalidCastException |
| Kod dosyası | ERPPRO/Controls/Islem Ekranı/Ekran/FrmBlokTakozGirisi.vb |
| Class | FrmBlokTakozGirisi |
| Method | ListRefresh |
| Satır / bölge | 18 |
| Tetikleme koşulu | TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(1) yok; veya sayısal olmayan parça → Integer'a dönüşüm hatası). |
| Kök neden | Try/Catch var ama Catch bloğu boş; SubeId/HesapId/FisNo 0 kalır ve sorgu 0 değerleriyle çalışır. Form Load'da (satır 3-4) ListRefresh boş metinle çağrıldığı için istisna HER açılışta oluşur ve yutulur. |
| Neden zinciri | Teknik olay: IndexOutOfRangeException / InvalidCastException ↓ Yakın neden: TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(1) yok; veya sayısal ↓ Kök neden: Try/Catch var ama Catch bloğu boş; SubeId/HesapId/FisNo 0 kalır ve sorgu 0 değerleriyle çalışır. Form Load'da (satır 3-4) ListRefresh boş metinle çağrıldığı içi ↓ Kullanıcı etkisi: Belirti yok; hatalı girişte 'Girilen Bilgilere Göre Takoz Cıkıs İşlemleri Bulunamadı' mesajı. |
| Olasılık / etki / güven | ÇOK YÜKSEK / S4 / 90 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Metni Split edip parça sayısı ve Integer.TryParse ile doğrulamak; geçersizse kullanıcıya uyarı verip Exit Sub. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(1) yok; veya sayısal olmayan parça → Integer'a dönüşüm hatası). |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · FrmBlokTakozGirisi.vb:16-22 `Try SubeId = TxtSubeId.Text.Split(".")(0) ... Catch ex As Exception End Try` |
| İlişkili kayıtlar | ERR-POT-002, ERR-POT-008, ERR-SIL-001, ERR-SIL-003, ERR-SIL-028, ERR-SIL-056, ERR-SIL-059 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-003 — IndexOutOfRangeException / InvalidCastException — FrmBlokTakozGirisi.ListRefresh S4 · MOD-STOK · Gözlemlendi: HAYIR · PF-010 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-STOK |
| Alt modül | Kod |
| Problem ailesi | PF-010 Programa giriş yapılamıyor / program açılmıyor (giriş hatası) |
| Kullanıcı belirtisi | Belirti yok; hatalı girişte 'Girilen Bilgilere Göre Takoz Cıkıs İşlemleri Bulunamadı' mesajı. |
| Teknik belirti | TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(2) yok; veya sayısal olmayan parça → Integer'a dönüşüm hatası). |
| Exception türü | IndexOutOfRangeException / InvalidCastException |
| Kod dosyası | ERPPRO/Controls/Islem Ekranı/Ekran/FrmBlokTakozGirisi.vb |
| Class | FrmBlokTakozGirisi |
| Method | ListRefresh |
| Satır / bölge | 19 |
| Tetikleme koşulu | TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(2) yok; veya sayısal olmayan parça → Integer'a dönüşüm hatası). |
| Kök neden | Try/Catch var ama Catch bloğu boş; SubeId/HesapId/FisNo 0 kalır ve sorgu 0 değerleriyle çalışır. Form Load'da (satır 3-4) ListRefresh boş metinle çağrıldığı için istisna HER açılışta oluşur ve yutulur. |
| Neden zinciri | Teknik olay: IndexOutOfRangeException / InvalidCastException ↓ Yakın neden: TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(2) yok; veya sayısal ↓ Kök neden: Try/Catch var ama Catch bloğu boş; SubeId/HesapId/FisNo 0 kalır ve sorgu 0 değerleriyle çalışır. Form Load'da (satır 3-4) ListRefresh boş metinle çağrıldığı içi ↓ Kullanıcı etkisi: Belirti yok; hatalı girişte 'Girilen Bilgilere Göre Takoz Cıkıs İşlemleri Bulunamadı' mesajı. |
| Olasılık / etki / güven | ÇOK YÜKSEK / S4 / 90 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Metni Split edip parça sayısı ve Integer.TryParse ile doğrulamak; geçersizse kullanıcıya uyarı verip Exit Sub. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: TxtSubeId.Text 'Sube.Hesap.FisNo' biçiminde değilse (Form Load'da boş metinle çağrılır → Split('.')(2) yok; veya sayısal olmayan parça → Integer'a dönüşüm hatası). |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · FrmBlokTakozGirisi.vb:16-22 `Try SubeId = TxtSubeId.Text.Split(".")(0) ... Catch ex As Exception End Try` |
| İlişkili kayıtlar | ERR-POT-002, ERR-POT-008, ERR-SIL-001, ERR-SIL-002, ERR-SIL-028, ERR-SIL-056, ERR-SIL-059 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-004 — IndexOutOfRangeException — UiForm.LoadDesigner S4 · MOD-SISTEM · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-SISTEM |
| Alt modül | Kod |
| Kullanıcı belirtisi | Tasarımcıda bazı kontroller yüklenmez; hata mesajı yok. |
| Teknik belirti | Designer kodundaki 'Friend WithEvents' satırı beklenen 'Friend WithEvents Ad as New Tip' biçiminde değilse (elle düzenlenmiş, fazladan boşluk → Split(" ") boş token üretir) (5) indeksi bulunamaz. |
| Exception türü | IndexOutOfRangeException |
| Kod dosyası | CodeDesigner/CodeDesigner/Controls/UiFormDesigner/UiForm.vb |
| Class | UiForm |
| Method | LoadDesigner |
| Satır / bölge | 54 |
| Tetikleme koşulu | Designer kodundaki 'Friend WithEvents' satırı beklenen 'Friend WithEvents Ad as New Tip' biçiminde değilse (elle düzenlenmiş, fazladan boşluk → Split(" ") boş token üretir) (5) indeksi bulunamaz. |
| Kök neden | Satır 30 `On Error Resume Next` → istisna yutulur, Dim değişkeni Nothing kalır, `ControlTpye <> ""` False olur ve kontrol sessizce atlanır. Araç tarafından üretilen kod (UiConteiner.vb:332) 6 token üretir, normalde güvenli. |
| Neden zinciri | Teknik olay: IndexOutOfRangeException ↓ Yakın neden: Designer kodundaki 'Friend WithEvents' satırı beklenen 'Friend WithEvents Ad as New Tip' biçiminde değilse (elle düzenle ↓ Kök neden: Satır 30 `On Error Resume Next` → istisna yutulur, Dim değişkeni Nothing kalır, `ControlTpye <> ""` False olur ve kontrol sessizce atlanır. Araç tarafından üret ↓ Kullanıcı etkisi: Tasarımcıda bazı kontroller yüklenmez; hata mesajı yok. |
| Olasılık / etki / güven | DÜŞÜK / S4 / 70 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Split(" "c, StringSplitOptions.RemoveEmptyEntries) + uzunluk kontrolü; On Error Resume Next kaldırılıp Try/Catch ile loglama. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Designer kodundaki 'Friend WithEvents' satırı beklenen 'Friend WithEvents Ad as New Tip' biçiminde değilse (elle düzenlenmiş, fazladan boşluk → Split(" ") boş token üretir) (5) indeksi bulunamaz. |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · UiForm.vb:30 `On Error Resume Next`; :54 `s.Trim.Split(" ")(5).Trim` |
| İlişkili kayıtlar | ERR-SIL-005, ERR-SIL-016 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-005 — IndexOutOfRangeException — UiForm.LoadDesigner S4 · MOD-SISTEM · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-SISTEM |
| Alt modül | Kod |
| Kullanıcı belirtisi | Tasarımcıda bazı kontroller yüklenmez; hata mesajı yok. |
| Teknik belirti | Designer kodundaki 'Friend WithEvents' satırı beklenen 'Friend WithEvents Ad as New Tip' biçiminde değilse (elle düzenlenmiş, fazladan boşluk → Split(" ") boş token üretir) (2) indeksi bulunamaz. |
| Exception türü | IndexOutOfRangeException |
| Kod dosyası | CodeDesigner/CodeDesigner/Controls/UiFormDesigner/UiForm.vb |
| Class | UiForm |
| Method | LoadDesigner |
| Satır / bölge | 55 |
| Tetikleme koşulu | Designer kodundaki 'Friend WithEvents' satırı beklenen 'Friend WithEvents Ad as New Tip' biçiminde değilse (elle düzenlenmiş, fazladan boşluk → Split(" ") boş token üretir) (2) indeksi bulunamaz. |
| Kök neden | Satır 30 `On Error Resume Next` → istisna yutulur, Dim değişkeni Nothing kalır, `ControlTpye <> ""` False olur ve kontrol sessizce atlanır. Araç tarafından üretilen kod (UiConteiner.vb:332) 6 token üretir, normalde güvenli. |
| Neden zinciri | Teknik olay: IndexOutOfRangeException ↓ Yakın neden: Designer kodundaki 'Friend WithEvents' satırı beklenen 'Friend WithEvents Ad as New Tip' biçiminde değilse (elle düzenle ↓ Kök neden: Satır 30 `On Error Resume Next` → istisna yutulur, Dim değişkeni Nothing kalır, `ControlTpye <> ""` False olur ve kontrol sessizce atlanır. Araç tarafından üret ↓ Kullanıcı etkisi: Tasarımcıda bazı kontroller yüklenmez; hata mesajı yok. |
| Olasılık / etki / güven | DÜŞÜK / S4 / 70 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Split(" "c, StringSplitOptions.RemoveEmptyEntries) + uzunluk kontrolü; On Error Resume Next kaldırılıp Try/Catch ile loglama. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Designer kodundaki 'Friend WithEvents' satırı beklenen 'Friend WithEvents Ad as New Tip' biçiminde değilse (elle düzenlenmiş, fazladan boşluk → Split(" ") boş token üretir) (2) indeksi bulunamaz. |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · UiForm.vb:30 `On Error Resume Next`; :55 `s.Trim.Split(" ")(2).Trim` |
| İlişkili kayıtlar | ERR-SIL-004, ERR-SIL-016 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-006 — NullReferenceException — EtiketDesignList.SimpleList1_ButtonClick S4 · MOD-DIGER · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-DIGER |
| Alt modül | DevExpress-GetFocusedRow-Nothing |
| Kullanıcı belirtisi | Butona basınca hiçbir şey olmaz, mesaj yok. |
| Teknik belirti | Liste boşken veya satır seçili değilken Düzenle/Sil butonuna basılırsa GetFocusedRow Nothing döner; `New EtiketDesign(Item)` / `Item.Delete` NRE atar. |
| Exception türü | NullReferenceException |
| Kod dosyası | ERPPRO/Controls/Islem Ekranı/OldFis/EtiketDesignList.vb |
| Class | EtiketDesignList |
| Method | SimpleList1_ButtonClick |
| Satır / bölge | 17 |
| Tetikleme koşulu | Liste boşken veya satır seçili değilken Düzenle/Sil butonuna basılırsa GetFocusedRow Nothing döner; `New EtiketDesign(Item)` / `Item.Delete` NRE atar. |
| Kök neden | Satır 16 `On Error Resume Next` → NRE yutulur, hiçbir şey olmaz. Item Is Nothing kontrolü yok (karşılaştırma: RDPList.vb:13 aynı deseni açıkça kontrol ediyor). |
| Neden zinciri | Teknik olay: NullReferenceException ↓ Yakın neden: Liste boşken veya satır seçili değilken Düzenle/Sil butonuna basılırsa GetFocusedRow Nothing döner; `New EtiketDesign(It ↓ Kök neden: Satır 16 `On Error Resume Next` → NRE yutulur, hiçbir şey olmaz. Item Is Nothing kontrolü yok (karşılaştırma: RDPList.vb:13 aynı deseni açıkça kontrol ediyor). ↓ Kullanıcı etkisi: Butona basınca hiçbir şey olmaz, mesaj yok. |
| Olasılık / etki / güven | ORTA / S4 / 75 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): `If Item Is Nothing Then Message.Show(NotSelectedRecord) : Exit Sub` eklemek; On Error Resume Next kaldırmak. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Liste boşken veya satır seçili değilken Düzenle/Sil butonuna basılırsa GetFocusedRow Nothing döner; `New EtiketDesign(Item)` / `Item.Delete` NRE atar. |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · EtiketDesignList.vb:16-17 `On Error Resume Next` / `Dim Item As AIO.Sistem.Etiket = SimpleList1.GridView.GetFocusedRow()` |
| İlişkili kayıtlar | ERR-SIL-008 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-007 — Tüm istisnalar (maskeleme) — UrunListesi.LoadStok S3 · MOD-CARI · Gözlemlendi: HAYIR · PF-045 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-CARI |
| Alt modül | OnErrorResumeNext-Maskeleme |
| Problem ailesi | PF-045 Kur giriş ekranı / kur listesi boş / kur yanlış geliyor |
| Kullanıcı belirtisi | Seri işlem ekranında ürün listesi eksik görünür; hata mesajı yok. |
| Teknik belirti | DSX.TABLE.ListOfMaden/ListOfEmtia vb. Nothing ise veya öğe eşlemesinde istisna oluşursa |
| Exception türü | Tüm istisnalar (maskeleme) |
| Kod dosyası | ERPPRO/Controls/Islem Ekranı/Ekran/SeriIslemEkrani/UrunListesi.vb |
| Class | UrunListesi |
| Method | LoadStok |
| Satır / bölge | 59 |
| Tetikleme koşulu | DSX.TABLE.ListOfMaden/ListOfEmtia vb. Nothing ise veya öğe eşlemesinde istisna oluşursa |
| Kök neden | On Error Resume Next tüm hataları yutar; liste eksik/boş kalır. Loglama yok. |
| Neden zinciri | Teknik olay: Tüm istisnalar (maskeleme) ↓ Yakın neden: DSX.TABLE.ListOfMaden/ListOfEmtia vb. Nothing ise veya öğe eşlemesinde istisna oluşursa ↓ Kök neden: On Error Resume Next tüm hataları yutar; liste eksik/boş kalır. Loglama yok. ↓ Kullanıcı etkisi: Seri işlem ekranında ürün listesi eksik görünür; hata mesajı yok. |
| Olasılık / etki / güven | DÜŞÜK / S3 / 65 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): On Error Resume Next yerine Try/Catch + kullanıcıya uyarı. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: DSX.TABLE.ListOfMaden/ListOfEmtia vb. Nothing ise veya öğe eşlemesinde istisna oluşursa |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · UrunListesi.vb:59 `On Error Resume Next` |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-008 — Tüm istisnalar (maskeleme) — EtiketDesignList.SimpleList1_ButtonClick S4 · MOD-DIGER · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-DIGER |
| Alt modül | OnErrorResumeNext-Maskeleme |
| Kullanıcı belirtisi | Buton tepkisiz. |
| Teknik belirti | Bkz. satır 17 kaydı |
| Exception türü | Tüm istisnalar (maskeleme) |
| Kod dosyası | ERPPRO/Controls/Islem Ekranı/OldFis/EtiketDesignList.vb |
| Class | EtiketDesignList |
| Method | SimpleList1_ButtonClick |
| Satır / bölge | 16 |
| Tetikleme koşulu | Bkz. satır 17 kaydı |
| Kök neden | On Error Resume Next; NRE ve alt form hataları yutulur. |
| Neden zinciri | Teknik olay: Tüm istisnalar (maskeleme) ↓ Yakın neden: Bkz. satır 17 kaydı ↓ Kök neden: On Error Resume Next; NRE ve alt form hataları yutulur. ↓ Kullanıcı etkisi: Buton tepkisiz. |
| Olasılık / etki / güven | ORTA / S4 / 75 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Try/Catch + Nothing kontrolü. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Bkz. satır 17 kaydı |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · EtiketDesignList.vb:16 |
| İlişkili kayıtlar | ERR-SIL-006 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-009 — TargetInvocationException / InvalidCastException (maskeleme) — EtiketDetay.GetValue S4 · MOD-RAPOR · Gözlemlendi: HAYIR · PF-024 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-RAPOR |
| Alt modül | OnErrorResumeNext-Maskeleme |
| Problem ailesi | PF-024 Etiket tasarımı / etiket yazıcısı çıkmıyor / RFID |
| Kullanıcı belirtisi | Etikette ilgili alan boş basılır. |
| Teknik belirti | Item Nothing ise veya FieldName özelliği okunurken istisna oluşursa (Prop.GetValue), Result boş kalır. |
| Exception türü | TargetInvocationException / InvalidCastException (maskeleme) |
| Kod dosyası | ERPPRO/Controls/Islem Ekranı/OldFis/EtiketDetay.vb |
| Class | EtiketDetay |
| Method | GetValue |
| Satır / bölge | 329 |
| Tetikleme koşulu | Item Nothing ise veya FieldName özelliği okunurken istisna oluşursa (Prop.GetValue), Result boş kalır. |
| Kök neden | On Error Resume Next; Prop IsNot Nothing kontrolü var ancak Item Nothing kontrolü yok. |
| Neden zinciri | Teknik olay: TargetInvocationException / InvalidCastException (maskeleme) ↓ Yakın neden: Item Nothing ise veya FieldName özelliği okunurken istisna oluşursa (Prop.GetValue), Result boş kalır. ↓ Kök neden: On Error Resume Next; Prop IsNot Nothing kontrolü var ancak Item Nothing kontrolü yok. ↓ Kullanıcı etkisi: Etikette ilgili alan boş basılır. |
| Olasılık / etki / güven | DÜŞÜK / S4 / 60 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Try/Catch ile alan bazlı hata metni ('#ERR') basmak. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Item Nothing ise veya FieldName özelliği okunurken istisna oluşursa (Prop.GetValue), Result boş kalır. |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · EtiketDetay.vb:329-337 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-010 — Tüm istisnalar (maskeleme) — DataList.DataBind S4 · MOD-GENEL · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-GENEL |
| Alt modül | OnErrorResumeNext-Maskeleme |
| Kullanıcı belirtisi | Liste boş; ek mesaj yok. |
| Teknik belirti | InternalDb(Query).DataTable Nothing dönerse (SQL hatası) veya DevExpress kolon işlemlerinde istisna olursa |
| Exception türü | Tüm istisnalar (maskeleme) |
| Kod dosyası | ERPPRO/Controls/Grid/DataList.vb |
| Class | DataList |
| Method | DataBind |
| Satır / bölge | 36 |
| Tetikleme koşulu | InternalDb(Query).DataTable Nothing dönerse (SQL hatası) veya DevExpress kolon işlemlerinde istisna olursa |
| Kök neden | On Error Resume Next; SQL hatası InternalDb tarafından MsgBox ile gösterilir, sonrası sessiz. |
| Neden zinciri | Teknik olay: Tüm istisnalar (maskeleme) ↓ Yakın neden: InternalDb(Query).DataTable Nothing dönerse (SQL hatası) veya DevExpress kolon işlemlerinde istisna olursa ↓ Kök neden: On Error Resume Next; SQL hatası InternalDb tarafından MsgBox ile gösterilir, sonrası sessiz. ↓ Kullanıcı etkisi: Liste boş; ek mesaj yok. |
| Olasılık / etki / güven | DÜŞÜK / S4 / 70 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Try/Catch; DataTable Nothing kontrolü. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: InternalDb(Query).DataTable Nothing dönerse (SQL hatası) veya DevExpress kolon işlemlerinde istisna olursa |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · DataList.vb:36,42 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-011 — Tüm istisnalar (maskeleme) — DataListBase.DataBind S4 · MOD-GENEL · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-GENEL |
| Alt modül | OnErrorResumeNext-Maskeleme |
| Kullanıcı belirtisi | Liste/resim yüklenmez, mesaj yok. |
| Teknik belirti | ActiveObject Nothing ise veya görsel/veri bağlama hatası |
| Exception türü | Tüm istisnalar (maskeleme) |
| Kod dosyası | ERPPRO/Controls/Grid/DataListBase.vb |
| Class | DataListBase |
| Method | DataBind |
| Satır / bölge | 54 |
| Tetikleme koşulu | ActiveObject Nothing ise veya görsel/veri bağlama hatası |
| Kök neden | On Error Resume Next. |
| Neden zinciri | Teknik olay: Tüm istisnalar (maskeleme) ↓ Yakın neden: ActiveObject Nothing ise veya görsel/veri bağlama hatası ↓ Kök neden: On Error Resume Next. ↓ Kullanıcı etkisi: Liste/resim yüklenmez, mesaj yok. |
| Olasılık / etki / güven | DÜŞÜK / S4 / 70 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Try/Catch + loglama. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: ActiveObject Nothing ise veya görsel/veri bağlama hatası |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · DataListBase.vb:54 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-012 — Tüm istisnalar (maskeleme) — SimpleList.RetriveData S4 · MOD-GENEL · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-GENEL |
| Alt modül | OnErrorResumeNext-Maskeleme |
| Kullanıcı belirtisi | Liste boş; mesaj yok. |
| Teknik belirti | SQL/DevExpress hataları |
| Exception türü | Tüm istisnalar (maskeleme) |
| Kod dosyası | ERPPRO/Controls/Grid/SimpleList.vb |
| Class | SimpleList |
| Method | RetriveData |
| Satır / bölge | 173 |
| Tetikleme koşulu | SQL/DevExpress hataları |
| Kök neden | On Error Resume Next. |
| Neden zinciri | Teknik olay: Tüm istisnalar (maskeleme) ↓ Yakın neden: SQL/DevExpress hataları ↓ Kök neden: On Error Resume Next. ↓ Kullanıcı etkisi: Liste boş; mesaj yok. |
| Olasılık / etki / güven | DÜŞÜK / S4 / 70 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Try/Catch + loglama. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: SQL/DevExpress hataları |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · SimpleList.vb:173 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-013 — Tüm istisnalar (maskeleme) — Appointment.New(Apt) S4 · MOD-DIGER · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-DIGER |
| Alt modül | OnErrorResumeNext-Maskeleme |
| Kullanıcı belirtisi | Randevu eksik bilgiyle kaydedilir; mesaj yok. |
| Teknik belirti | Apt.ResourceIds / RecurrenceInfo Nothing veya DevExpress persistence helper istisnası |
| Exception türü | Tüm istisnalar (maskeleme) |
| Kod dosyası | ERPPRO/Controls/Takvim/Class/Appointment.vb |
| Class | Appointment |
| Method | New(Apt) |
| Satır / bölge | 28 |
| Tetikleme koşulu | Apt.ResourceIds / RecurrenceInfo Nothing veya DevExpress persistence helper istisnası |
| Kök neden | On Error Resume Next; nesne kısmen dolu olarak devam eder ve kaydedilebilir. |
| Neden zinciri | Teknik olay: Tüm istisnalar (maskeleme) ↓ Yakın neden: Apt.ResourceIds / RecurrenceInfo Nothing veya DevExpress persistence helper istisnası ↓ Kök neden: On Error Resume Next; nesne kısmen dolu olarak devam eder ve kaydedilebilir. ↓ Kullanıcı etkisi: Randevu eksik bilgiyle kaydedilir; mesaj yok. |
| Olasılık / etki / güven | DÜŞÜK / S4 / 60 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Try/Catch, hatalı alan için varsayılan atama ve loglama. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Apt.ResourceIds / RecurrenceInfo Nothing veya DevExpress persistence helper istisnası |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · Appointment.vb:28 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-014 — InvalidCastException (CBool("")) — TicketList.GridView1_CustomDrawCell S4 · MOD-DIGER · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-DIGER |
| Alt modül | OnErrorResumeNext-Maskeleme |
| Kullanıcı belirtisi | Bazı bilet satırları renklendirilmez. |
| Teknik belirti | IsActive veya Status hücresi NULL ise `CBool("" & Nothing)` = CBool("") InvalidCastException atar. |
| Exception türü | InvalidCastException (CBool("")) |
| Kod dosyası | ERPPRO/Controls/Takvim/Class/TicketList.vb |
| Class | TicketList |
| Method | GridView1_CustomDrawCell |
| Satır / bölge | 65 |
| Tetikleme koşulu | IsActive veya Status hücresi NULL ise `CBool("" & Nothing)` = CBool("") InvalidCastException atar. |
| Kök neden | On Error Resume Next; hücre renklendirmesi atlanır. |
| Neden zinciri | Teknik olay: InvalidCastException (CBool("")) ↓ Yakın neden: IsActive veya Status hücresi NULL ise `CBool("" & Nothing)` = CBool("") InvalidCastException atar. ↓ Kök neden: On Error Resume Next; hücre renklendirmesi atlanır. ↓ Kullanıcı etkisi: Bazı bilet satırları renklendirilmez. |
| Olasılık / etki / güven | ORTA / S4 / 75 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Val()/Boolean.TryParse ile güvenli dönüşüm. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: IsActive veya Status hücresi NULL ise `CBool("" & Nothing)` = CBool("") InvalidCastException atar. |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · TicketList.vb:65-68 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-015 — NullReferenceException (hata işleyici içinde) — MyApplication.ShowDebugOutput S1 · MOD-SISTEM · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S1 — KRİTİK |
| Modül | MOD-SISTEM |
| Alt modül | ThreadException-AutoErrorHandle |
| Kullanıcı belirtisi | Uygulama açılışta sessizce kapanır veya hata hiç görünmez; AutoErrorHandle=1 ise hata formu, 'Kapat' → program kapanır. |
| Teknik belirti | 1) Giriş ekranı (FrmLoginForm.New) çalışmadan önce bir istisna oluşursa Program.UserSettings Nothing'dir; satır 15 `Program.UserSettings.AutoErrorHandle` On Error Resume Next'ten ÖNCE çalıştığı için hata işleyicinin kendisi NRE atar (ikincil çökme). 2) AutoErrorHandle <> 1 ise hiçbir şey gösterilmez/loglanmaz. 3) st.GetFrame(0) Nothing ise Show çağrısı tümüyle atlanır. |
| Exception türü | NullReferenceException (hata işleyici içinde) |
| Kod dosyası | ERPPRO/Class/Ext/ApplicationExt.vb |
| Class | MyApplication |
| Method | ShowDebugOutput |
| Satır / bölge | 16 |
| Tetikleme koşulu | 1) Giriş ekranı (FrmLoginForm.New) çalışmadan önce bir istisna oluşursa Program.UserSettings Nothing'dir; satır 15 `Program.UserSettings.AutoErrorHandle` On Error Resume Next'ten ÖNCE çalıştığı için hata işleyicinin kendisi NRE atar (ikincil çökme). 2) AutoErrorHandle <> 1 ise hiçbir şey gösterilmez/loglanmaz. 3) st.GetFrame(0) Nothing ise Show çağrısı tümüyle atlanır. |
| Kök neden | On Error Resume Next yalnızca If içindeki satırları kapsar. Loglama yok. ExeptionForm.BtnKapat → `End` (uygulamayı sonlandırır). |
| Neden zinciri | Teknik olay: NullReferenceException (hata işleyici içinde) ↓ Yakın neden: 1) Giriş ekranı (FrmLoginForm.New) çalışmadan önce bir istisna oluşursa Program.UserSettings Nothing'dir; satır 15 `Prog ↓ Kök neden: On Error Resume Next yalnızca If içindeki satırları kapsar. Loglama yok. ExeptionForm.BtnKapat → `End` (uygulamayı sonlandırır). ↓ Kullanıcı etkisi: Uygulama açılışta sessizce kapanır veya hata hiç görünmez; AutoErrorHandle=1 ise hata formu, 'Kapat' → program kapanır. |
| Etkilenen veri | Belirtilen SQL nesnesi / ekran verisi |
| Olasılık / etki / güven | ORTA / S1 / 80 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): UserSettings Nothing kontrolü; AutoErrorHandle=0 iken de dosyaya loglama; UnhandledException'da e.ExitApplication'ı bilinçli yönetmek. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: 1) Giriş ekranı (FrmLoginForm.New) çalışmadan önce bir istisna oluşursa Program.UserSettings Nothing'dir; satır 15 `Program.UserSettings.AutoErrorHandle` On Error Resume Next'ten ÖNCE çalıştığı için h |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · ApplicationExt.vb:14-21; FrmExeption.vb:16 `Sub FormClose() ... End`; FrmLoginForm.vb:10 `Program.UserSettings = New AIO.Sistem.Clients` |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-016 — Tüm istisnalar (maskeleme) — UiForm.LoadDesigner S4 · MOD-SISTEM · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-SISTEM |
| Alt modül | OnErrorResumeNext-Maskeleme |
| Kullanıcı belirtisi | Form tasarımcısında eksik kontroller. |
| Teknik belirti | Designer kodu ayrıştırılırken herhangi bir istisna (Type.GetType Nothing → Activator NRE, Split indeks vb.) |
| Exception türü | Tüm istisnalar (maskeleme) |
| Kod dosyası | CodeDesigner/CodeDesigner/Controls/UiFormDesigner/UiForm.vb |
| Class | UiForm |
| Method | LoadDesigner |
| Satır / bölge | 30 |
| Tetikleme koşulu | Designer kodu ayrıştırılırken herhangi bir istisna (Type.GetType Nothing → Activator NRE, Split indeks vb.) |
| Kök neden | On Error Resume Next; kontroller sessizce atlanır. |
| Neden zinciri | Teknik olay: Tüm istisnalar (maskeleme) ↓ Yakın neden: Designer kodu ayrıştırılırken herhangi bir istisna (Type.GetType Nothing → Activator NRE, Split indeks vb.) ↓ Kök neden: On Error Resume Next; kontroller sessizce atlanır. ↓ Kullanıcı etkisi: Form tasarımcısında eksik kontroller. |
| Olasılık / etki / güven | DÜŞÜK / S4 / 70 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Try/Catch + hata listesi. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Designer kodu ayrıştırılırken herhangi bir istisna (Type.GetType Nothing → Activator NRE, Split indeks vb.) |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · UiForm.vb:30 |
| İlişkili kayıtlar | ERR-SIL-004, ERR-SIL-005 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-017 — Tüm istisnalar (maskeleme) — Properties.ToString S4 · MOD-SISTEM · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-SISTEM |
| Alt modül | OnErrorResumeNext-Maskeleme |
| Kullanıcı belirtisi | Üretilen designer kodunda eksik özellik satırı. |
| Teknik belirti | Late-bound .FieldName/.Mask erişimi desteklemeyen kontrol tipinde MissingMemberException |
| Exception türü | Tüm istisnalar (maskeleme) |
| Kod dosyası | CodeDesigner/CodeDesigner/Controls/Properties/Properties.vb |
| Class | Properties |
| Method | ToString |
| Satır / bölge | 220 |
| Tetikleme koşulu | Late-bound .FieldName/.Mask erişimi desteklemeyen kontrol tipinde MissingMemberException |
| Kök neden | On Error Resume Next; satır atlanır. |
| Neden zinciri | Teknik olay: Tüm istisnalar (maskeleme) ↓ Yakın neden: Late-bound .FieldName/.Mask erişimi desteklemeyen kontrol tipinde MissingMemberException ↓ Kök neden: On Error Resume Next; satır atlanır. ↓ Kullanıcı etkisi: Üretilen designer kodunda eksik özellik satırı. |
| Olasılık / etki / güven | DÜŞÜK / S4 / 65 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Tip kontrolü (TypeOf) ile üretim. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Late-bound .FieldName/.Mask erişimi desteklemeyen kontrol tipinde MissingMemberException |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · Properties.vb:220-226 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-018 — IndexOutOfRangeException (kolon yok) — DBNull yanlış pozitif — ERPFatura.New(RecordId) S2 · MOD-EFATURA · Gözlemlendi: HAYIR · PF-018 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-EFATURA |
| Alt modül | ERPFatura-KısmiYükleme |
| Problem ailesi | PF-018 e-Belge entegratör güncellemesi / entegratör reddi (Uyumsoft, ICE, Mysoft, QR/dijital fatura) |
| Kullanıcı belirtisi | MADEN faturası eksik tutar/kur ve entegratör bilgisiyle gönderilmeye çalışılır; entegratör reddi veya hatalı belge. |
| Teknik belirti | Convert.ToString(DBNull) "" döndürür, istisna atmaz. Gerçek risk: Muhasebe.GetEFatura sonuç kümesinde 'MADENKODU' kolonu yoksa DR("MADENKODU") IndexOutOfRangeException atar. |
| Exception türü | IndexOutOfRangeException (kolon yok) — DBNull yanlış pozitif |
| Kod dosyası | DijitalFatura/Common/ERPFatura.vb |
| Class | ERPFatura |
| Method | New(RecordId) |
| Satır / bölge | 77 |
| İlgili SQL nesneleri | Muhasebe.GetEFatura |
| Tetikleme koşulu | Convert.ToString(DBNull) "" döndürür, istisna atmaz. Gerçek risk: Muhasebe.GetEFatura sonuç kümesinde 'MADENKODU' kolonu yoksa DR("MADENKODU") IndexOutOfRangeException atar. |
| Kök neden | Satır 48-155 tek bir Try/Catch (boş Catch) içinde: istisna sonrası kalan TÜM alanlar (DovizMiktar, DovizTLKuru, Entegrator bilgileri, limitler) yüklenmez; fHasRecord=True kalır. |
| Neden zinciri | Teknik olay: IndexOutOfRangeException (kolon yok) — DBNull yanlış pozitif ↓ Yakın neden: Convert.ToString(DBNull) "" döndürür, istisna atmaz. Gerçek risk: Muhasebe.GetEFatura sonuç kümesinde 'MADENKODU' kolonu ↓ Kök neden: Satır 48-155 tek bir Try/Catch (boş Catch) içinde: istisna sonrası kalan TÜM alanlar (DovizMiktar, DovizTLKuru, Entegrator bilgileri, limitler) yüklenmez; fHasR ↓ Kullanıcı etkisi: MADEN faturası eksik tutar/kur ve entegratör bilgisiyle gönderilmeye çalışılır; entegratör reddi veya hatalı belge. |
| Etkilenen veri | Belirtilen SQL nesnesi / ekran verisi |
| Olasılık / etki / güven | DÜŞÜK / S2 / 60 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Alan başına ayrı güvenli okuma (HasColumn + TryGet); Catch'te loglama ve HasRecord=False. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Convert.ToString(DBNull) "" döndürür, istisna atmaz. Gerçek risk: Muhasebe.GetEFatura sonuç kümesinde 'MADENKODU' kolonu yoksa DR("MADENKODU") IndexOutOfRangeException atar. |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · ERPFatura.vb:75-81, 152-155 `Catch ex As Exception End Try` |
| İlişkili kayıtlar | ERR-POT-057, ERR-POT-061, ERR-SIL-019, ERR-SIL-020 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-019 — ArgumentOutOfRangeException (Substring) — ERPFatura.New(RecordId) S2 · MOD-EFATURA · Gözlemlendi: HAYIR · PF-018 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-EFATURA |
| Alt modül | ERPFatura-KısmiYükleme |
| Problem ailesi | PF-018 e-Belge entegratör güncellemesi / entegratör reddi (Uyumsoft, ICE, Mysoft, QR/dijital fatura) |
| Kullanıcı belirtisi | E-belge kısmen yüklenmiş nesneyle gönderilir: tutar 0 / entegratör kimlik bilgisi boş → entegratör hatası; kullanıcı nedeni anlayamaz. |
| Teknik belirti | Cari.IslemDetaylari.DovizKodu 3 karakterden kısa ise (boş string '' NULL değildir → DBNull koruması geçer). DovizKodu FrmEFaturaBas.vb:262 `Left(Transaction.Kodu,3)` ile yazılır; Kodu kısa/boş bir stok kodu ise 1-2 karakter kaydedilir. |
| Exception türü | ArgumentOutOfRangeException (Substring) |
| Kod dosyası | DijitalFatura/Common/ERPFatura.vb |
| Class | ERPFatura |
| Method | New(RecordId) |
| Satır / bölge | 79 |
| İlgili SQL nesneleri | Cari.IslemDetaylari |
| Tetikleme koşulu | Cari.IslemDetaylari.DovizKodu 3 karakterden kısa ise (boş string '' NULL değildir → DBNull koruması geçer). DovizKodu FrmEFaturaBas.vb:262 `Left(Transaction.Kodu,3)` ile yazılır; Kodu kısa/boş bir stok kodu ise 1-2 karakter kaydedilir. |
| Kök neden | DBNull kontrolü var, uzunluk kontrolü yok. Dış Try/Catch (boş) istisnayı yutar ve satır 82+ alanları (DovizMiktar, DovizTLKuru, DolarKuru zaten okundu ama EntUserName/EntPassword/EBelgeUsdLimit vb.) atlanır. |
| Neden zinciri | Teknik olay: ArgumentOutOfRangeException (Substring) ↓ Yakın neden: Cari.IslemDetaylari.DovizKodu 3 karakterden kısa ise (boş string '' NULL değildir → DBNull koruması geçer). DovizKodu Fr ↓ Kök neden: DBNull kontrolü var, uzunluk kontrolü yok. Dış Try/Catch (boş) istisnayı yutar ve satır 82+ alanları (DovizMiktar, DovizTLKuru, DolarKuru zaten okundu ama EntUs ↓ Kullanıcı etkisi: E-belge kısmen yüklenmiş nesneyle gönderilir: tutar 0 / entegratör kimlik bilgisi boş → entegratör hatası; kullanıcı ned |
| Etkilenen veri | Belirtilen SQL nesnesi / ekran verisi |
| Olasılık / etki / güven | DÜŞÜK / S2 / 75 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): `If s.Length >= 3 Then s.Substring(0,3) Else s`; Catch'te loglama. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Cari.IslemDetaylari.DovizKodu 3 karakterden kısa ise (boş string '' NULL değildir → DBNull koruması geçer). DovizKodu FrmEFaturaBas.vb:262 `Left(Transaction.Kodu,3)` ile yazılır; Kodu kısa/boş bir sto |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · ERPFatura.vb:79 `DovizKodu = Convert.ToString(DR("DovizKodu")).Substring(0, 3)`; :152-155 boş Catch |
| İlişkili kayıtlar | ERR-POT-057, ERR-POT-061, ERR-SIL-018, ERR-SIL-020 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-020 — ArgumentOutOfRangeException (Substring) [SUBSTRING adayı, aynı satır] — ERPFatura.New(RecordId) S2 · MOD-EFATURA · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-EFATURA |
| Alt modül | ERPFatura-KısmiYükleme |
| Kullanıcı belirtisi | Aynı. |
| Teknik belirti | Bkz. DBNULL_CAST kaydı (aynı satır). |
| Exception türü | ArgumentOutOfRangeException (Substring) [SUBSTRING adayı, aynı satır] |
| Kod dosyası | DijitalFatura/Common/ERPFatura.vb |
| Class | ERPFatura |
| Method | New(RecordId) |
| Satır / bölge | 79 |
| Tetikleme koşulu | Bkz. DBNULL_CAST kaydı (aynı satır). |
| Kök neden | Aynı. |
| Neden zinciri | Teknik olay: ArgumentOutOfRangeException (Substring) [SUBSTRING adayı, aynı satır] ↓ Yakın neden: Bkz. DBNULL_CAST kaydı (aynı satır). ↓ Kök neden: Aynı. ↓ Kullanıcı etkisi: Aynı. |
| Etkilenen veri | Belirtilen SQL nesnesi / ekran verisi |
| Olasılık / etki / güven | DÜŞÜK / S2 / 75 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Aynı. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Bkz. DBNULL_CAST kaydı (aynı satır). |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · ERPFatura.vb:79 |
| İlişkili kayıtlar | ERR-POT-057, ERR-POT-061, ERR-SIL-018, ERR-SIL-019 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-021 — InvalidCastException (CInt(DBNull)) + yutulan SqlException — DBBase.Insert S3 · MOD-GENEL · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-GENEL |
| Alt modül | Kod |
| Kullanıcı belirtisi | Kayıt sessizce kaydedilmez; çağıran yalnızca False alır. |
| Teknik belirti | SCOPE_IDENTITY() NULL dönerse (identity kolonu olmayan tablo) CInt(DBNull) InvalidCastException; ayrıca INSERT'teki her SqlException (kısıt, tip hatası) aynı Catch'e düşer. |
| Exception türü | InvalidCastException (CInt(DBNull)) + yutulan SqlException |
| Kod dosyası | ERPPRO/DataLayout/DBBaseClass.vb |
| Class | DBBase |
| Method | Insert |
| Satır / bölge | 74 |
| Tetikleme koşulu | SCOPE_IDENTITY() NULL dönerse (identity kolonu olmayan tablo) CInt(DBNull) InvalidCastException; ayrıca INSERT'teki her SqlException (kısıt, tip hatası) aynı Catch'e düşer. |
| Kök neden | Try/Catch var; Catch bağlantıyı kapatır, mesaj/log yok → RecId=0 → Insert False döner. Kullanıcıya nedeni gösterilmez. |
| Neden zinciri | Teknik olay: InvalidCastException (CInt(DBNull)) + yutulan SqlException ↓ Yakın neden: SCOPE_IDENTITY() NULL dönerse (identity kolonu olmayan tablo) CInt(DBNull) InvalidCastException; ayrıca INSERT'teki her ↓ Kök neden: Try/Catch var; Catch bağlantıyı kapatır, mesaj/log yok → RecId=0 → Insert False döner. Kullanıcıya nedeni gösterilmez. ↓ Kullanıcı etkisi: Kayıt sessizce kaydedilmez; çağıran yalnızca False alır. |
| Olasılık / etki / güven | DÜŞÜK / S3 / 80 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Catch'te ex.Message'ı göster/logla; ExecuteScalar sonucunu DBNull kontrolüyle oku. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: SCOPE_IDENTITY() NULL dönerse (identity kolonu olmayan tablo) CInt(DBNull) InvalidCastException; ayrıca INSERT'teki her SqlException (kısıt, tip hatası) aynı Catch'e düşer. |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=KISMEN · DBBaseClass.vb:74-78 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-022 — Sessiz (Double Infinity → JSON) — MySoft.Get_eDoviz_Belge S2 · MOD-EFATURA · Gözlemlendi: HAYIR · PF-018 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-EFATURA |
| Alt modül | Kod |
| Problem ailesi | PF-018 e-Belge entegratör güncellemesi / entegratör reddi (Uyumsoft, ICE, Mysoft, QR/dijital fatura) |
| Kullanıcı belirtisi | Entegratör belgeyi reddeder; sebep anlaşılmaz. |
| Teknik belirti | Doviz_TL_Kuru = 0 → 1/0 = Infinity (Double, istisna yok) → CalculationRate (Double) Infinity → JSON'a 'Infinity' yazılır → entegratör reddi. |
| Exception türü | Sessiz (Double Infinity → JSON) |
| Kod dosyası | DijitalFatura/Entegrators/MySoft.vb |
| Class | MySoft |
| Method | Get_eDoviz_Belge |
| Satır / bölge | 586 |
| Tetikleme koşulu | Doviz_TL_Kuru = 0 → 1/0 = Infinity (Double, istisna yok) → CalculationRate (Double) Infinity → JSON'a 'Infinity' yazılır → entegratör reddi. |
| Kök neden | Koruma yok; .NET istisnası oluşmaz. |
| Neden zinciri | Teknik olay: Sessiz (Double Infinity → JSON) ↓ Yakın neden: Doviz_TL_Kuru = 0 → 1/0 = Infinity (Double, istisna yok) → CalculationRate (Double) Infinity → JSON'a 'Infinity' yazılır ↓ Kök neden: Koruma yok; .NET istisnası oluşmaz. ↓ Kullanıcı etkisi: Entegratör belgeyi reddeder; sebep anlaşılmaz. |
| Etkilenen veri | Belirtilen SQL nesnesi / ekran verisi |
| Olasılık / etki / güven | DÜŞÜK / S2 / 70 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Kur > 0 doğrulaması. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Doviz_TL_Kuru = 0 → 1/0 = Infinity (Double, istisna yok) → CalculationRate (Double) Infinity → JSON'a 'Infinity' yazılır → entegratör reddi. |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=HAYIR · MySoft.vb:586; MySoftForeignExchangeModel.vb:259 `Property CalculationRate As Double` |
| İlişkili kayıtlar | ERR-POT-065, ERR-SIL-023 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-023 — Sessiz (Double Infinity) — MySoft.Get_eDoviz_Belge S3 · MOD-EFATURA · Gözlemlendi: HAYIR · PF-018 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-EFATURA |
| Alt modül | Kod |
| Problem ailesi | PF-018 e-Belge entegratör güncellemesi / entegratör reddi (Uyumsoft, ICE, Mysoft, QR/dijital fatura) |
| Kullanıcı belirtisi | Hatalı oran; entegratör reddi. |
| Teknik belirti | VergiHaric_Tutar = 0 → Infinity (Double). |
| Exception türü | Sessiz (Double Infinity) |
| Kod dosyası | DijitalFatura/Entegrators/MySoft.vb |
| Class | MySoft |
| Method | Get_eDoviz_Belge |
| Satır / bölge | 591 |
| Tetikleme koşulu | VergiHaric_Tutar = 0 → Infinity (Double). |
| Kök neden | Koruma yok. |
| Neden zinciri | Teknik olay: Sessiz (Double Infinity) ↓ Yakın neden: VergiHaric_Tutar = 0 → Infinity (Double). ↓ Kök neden: Koruma yok. ↓ Kullanıcı etkisi: Hatalı oran; entegratör reddi. |
| Olasılık / etki / güven | DÜŞÜK / S3 / 65 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Tutar > 0 doğrulaması. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: VergiHaric_Tutar = 0 → Infinity (Double). |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=HAYIR · MySoft.vb:591 |
| İlişkili kayıtlar | ERR-POT-065, ERR-SIL-022 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-024 — Sessiz (Double Infinity → JSON) — Ticari1.Get_eDoviz_Belge S2 · MOD-EFATURA · Gözlemlendi: HAYIR · PF-018 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-EFATURA |
| Alt modül | Kod |
| Problem ailesi | PF-018 e-Belge entegratör güncellemesi / entegratör reddi (Uyumsoft, ICE, Mysoft, QR/dijital fatura) |
| Kullanıcı belirtisi | Entegratör reddi. |
| Teknik belirti | Doviz_TL_Kuru = 0 → 1/0 Infinity (Double özellik). |
| Exception türü | Sessiz (Double Infinity → JSON) |
| Kod dosyası | DijitalFatura/Entegrators/Ticari1.vb |
| Class | Ticari1 |
| Method | Get_eDoviz_Belge |
| Satır / bölge | 347 |
| Tetikleme koşulu | Doviz_TL_Kuru = 0 → 1/0 Infinity (Double özellik). |
| Kök neden | Koruma yok. |
| Neden zinciri | Teknik olay: Sessiz (Double Infinity → JSON) ↓ Yakın neden: Doviz_TL_Kuru = 0 → 1/0 Infinity (Double özellik). ↓ Kök neden: Koruma yok. ↓ Kullanıcı etkisi: Entegratör reddi. |
| Etkilenen veri | Belirtilen SQL nesnesi / ekran verisi |
| Olasılık / etki / güven | DÜŞÜK / S2 / 70 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Kur > 0 doğrulaması. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Doviz_TL_Kuru = 0 → 1/0 Infinity (Double özellik). |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=HAYIR · Ticari1.vb:347; Ticari1_Models.vb:47 `ISLEM_KUR_DEGERI As Double` |
| İlişkili kayıtlar | ERR-SIL-025 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-025 — Sessiz (Double Infinity/NaN → JSON) — Ticari1.Get_eDoviz_Belge S2 · MOD-EFATURA · Gözlemlendi: HAYIR · PF-018 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E06 — Algoritma Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-EFATURA |
| Alt modül | Kod |
| Problem ailesi | PF-018 e-Belge entegratör güncellemesi / entegratör reddi (Uyumsoft, ICE, Mysoft, QR/dijital fatura) |
| Kullanıcı belirtisi | Entegratör reddi. |
| Teknik belirti | Dolar_TL_Kuru = 0 → Infinity/NaN. |
| Exception türü | Sessiz (Double Infinity/NaN → JSON) |
| Kod dosyası | DijitalFatura/Entegrators/Ticari1.vb |
| Class | Ticari1 |
| Method | Get_eDoviz_Belge |
| Satır / bölge | 348 |
| Tetikleme koşulu | Dolar_TL_Kuru = 0 → Infinity/NaN. |
| Kök neden | Koruma yok. |
| Neden zinciri | Teknik olay: Sessiz (Double Infinity/NaN → JSON) ↓ Yakın neden: Dolar_TL_Kuru = 0 → Infinity/NaN. ↓ Kök neden: Koruma yok. ↓ Kullanıcı etkisi: Entegratör reddi. |
| Etkilenen veri | Belirtilen SQL nesnesi / ekran verisi |
| Olasılık / etki / güven | DÜŞÜK / S2 / 70 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Kur > 0 doğrulaması. |
| Önleme | Guard (Nothing/DBNull/sıfır) kontrolü + hata loglama |
| Tespit yöntemi | Statik kod analizi + guard/data-flow doğrulaması |
| Test senaryosu | Koşul: Dolar_TL_Kuru = 0 → Infinity/NaN. |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Kod taraması (scan_exc.py) + doğrulama · Guard=HAYIR · Ticari1.vb:348; Ticari1_Models.vb:48 `KAYNAK_PB_USD_PARITE As Double` |
| İlişkili kayıtlar | ERR-SIL-024 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-026 — SQLR-049 Divide by zero: FN.Bol S2 · MOD-VERİTABANI · Gözlemlendi: HAYIR · PF-004 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-VERİTABANI |
| Alt modül | Divide by zero |
| Problem ailesi | PF-004 Rapor tasarımı / yeni rapor / sütun ekleme / bakiye ekstresi düzenleme (talep) |
| Kullanıcı belirtisi | Hata yok; bakiye/işçilik/ortalama maliyet 0 ya da eksik görünür; raporlarda 0 fiyat. |
| Teknik belirti | FN.Bol(@a,@b): 'IF (@Number1<>0 and @Number2<>0) SET @Number=@Number1/@Number2' — payda 0 ya da NULL ise 0 döner; hata yok. Ortalama fiyat, kur çevrimi, milyem, işçilik hesapları paydası 0 (kur girilmemiş, miktar 0) olduğunda 0 üretir ve bakiye/maliyet satırına yazılır. |
| SQL hata no | 8134 (sessizleştirilmiş → 0) |
| SQL hata mesajı | Divide by zero |
| Ekran | 224 çağrı / 103 modül: Cari.AcceptTransaction (işçilik/altına çevir), Stok.GetMadenMaliyeti, Stok.GetOrtMilyem, FN.GetPariteAVG, Pozisyon.*, Bilanco.*, Report(s).*, Cari.GetNetBakiye, Takoz.*; kod: DataStokList.vb:93, BilancoSimpleView.vb:166, Siparis.ParcaEx.vb:85 |
| Kod dosyası | modules.json (fn.bol regex: 224 eşleşme); ERPPRO/Controls/Grid/DataStokList.vb:93; ERPPRO/Designer/ReportManager/BilancoSimpleView.vb:166 |
| İlgili SQL nesneleri | FN.Bol, Cari.Islemler |
| SQL Object | FN.Bol |
| Tetikleme koşulu | FN.Bol(@a,@b): 'IF (@Number1<>0 and @Number2<>0) SET @Number=@Number1/@Number2' — payda 0 ya da NULL ise 0 döner; hata yok. Ortalama fiyat, kur çevrimi, milyem, işçilik hesapları paydası 0 (kur girilmemiş, miktar 0) olduğunda 0 üretir ve bakiye/maliyet satırına yazılır. |
| Kök neden | modules.json FN.Bol tanımı; AcceptTransaction: '@Iscilik = Fn.Bol((@HasIscilik * @HasIscBirimKur),@IscKur) + …', '@HasBakiye += Fn.Bol(((@Miktar*@AgMilyem)*@GumKur),@HasKur)'; FN.Bol çağıran 103 modül listesi (div.py). |
| Neden zinciri | Teknik olay: SQL 8134 (sessizleştirilmiş → 0) Divide by zero ↓ Yakın neden: FN.Bol(@a,@b): 'IF (@Number1<>0 and @Number2<>0) SET @Number=@Number1/@Number2' — payda 0 ya da NULL ise 0 döner; hata y ↓ Kullanıcı etkisi: Hata yok; bakiye/işçilik/ortalama maliyet 0 ya da eksik görünür; raporlarda 0 fiyat. |
| Etkilenen veri | Cari.BakiyeIslem / Stok.StokHaraketleri (türetilmiş bakiye ve stok kayıtları), Sistem.Kurlar |
| Olasılık / etki / güven | Yüksek (kur/miktar 0 durumları sık) / S2 (finansal — maliyet/bakiye 0 yazılır) / 95 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): FN.Bol'un 0 yerine NULL döndürmesi ya da çağıran yerlerde NULLIF ile açık koruma; 0 dönen durumların loglanması. (Uygulanmadı) |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SQL modül/katalog analizi |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND (ISNULL(HasKur,0)=0 OR ISNULL(IscilikBirimKur,0)=0) AND IslemKodu=0; -- takoz işlemlerinde kur 0 |
| Test senaryosu | Doğrulama SQL'i çalıştır (salt okunur); beklenen: 0 kayıt |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | SQL risk analizi SQLR-049 · DB1=EVET DB2=BİLİNMİYOR (muhtemelen EVET) BASE=EVET (BASE-CORE) · Guard=EVET (ama sessiz 0) · modules.json FN.Bol tanımı; AcceptTransaction: '@Iscilik = Fn.Bol((@HasIscilik * @HasIscBirimKur),@IscKur) + …', '@HasBakiye += Fn.Bol(((@Miktar*@AgMilyem)*@GumKur),@HasKur)'; FN.Bol çağıran 103 modül |
| İlişkili kayıtlar | ERR-OBS-070, ERR-POT-023, ERR-POT-033, ERR-POT-138, ERR-SIL-036, ERR-SIL-041, ERR-SIL-064 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-027 — SQLR-058 Conversion failed: (kod) TCMB.Currency.Save → MERGE Sistem.TCMBDovizKurlari S3 · MOD-VERİTABANI · Gözlemlendi: HAYIR · PF-007 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E02 — SQL Server Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-VERİTABANI |
| Alt modül | Conversion failed |
| Problem ailesi | PF-007 Fatura kesilemiyor / fatura basma / fatura problemi (genel) |
| Kullanıcı belirtisi | TCMB kur arşivi güncellenmez (sessiz); döviz seri fatura ekranında geçmiş tarih kur boş ya da NullReference. |
| Teknik belirti | CheckTable() OBJECT_ID null değilse tablo oluşturmaz; DB1'de ad bir VIEW (tablo NonUsed_TCMBDovizKurlari'na taşınmış). MERGE bir TVF-tabanlı view'a yazamaz → 4406/4405; boş Catch → sessiz. GetUSDCurrency(tarih) view'dan yalnız bugünün kurunu görür → geçmiş tarih için Nothing → Cari.Islem.vb:552 '.Alis' NullReference (uygulama tarafı). |
| SQL hata no | 4406 (View or function is not updatable) |
| SQL hata mesajı | Conversion failed |
| Ekran | Program.vb:225 açılışta arka plan TCMB kur çekme; Cari.Islem.vb:552 GetUSDCurrency |
| Kod dosyası | ERPPRO/Class/Module/TCMB.vb:67,127; ERPPRO/Class/Module/Program.vb:225 |
| İlgili SQL nesneleri | Sistem.TCMBDovizKurlari, Sistem.NonUsed_TCMBDovizKurlari, Sistem.GetKurListesi |
| SQL Object | (kod) TCMB.Currency.Save → MERGE Sistem.TCMBDovizKurlari |
| Tablo | Sistem.TCMBDovizKurlari (DB1'de VIEW: Select … from Sistem.GetKurListesi(getdate())) |
| Tetikleme koşulu | CheckTable() OBJECT_ID null değilse tablo oluşturmaz; DB1'de ad bir VIEW (tablo NonUsed_TCMBDovizKurlari'na taşınmış). MERGE bir TVF-tabanlı view'a yazamaz → 4406/4405; boş Catch → sessiz. GetUSDCurrency(tarih) view'dan yalnız bugünün kurunu görür → geçmiş tarih için Nothing → Cari.Islem.vb:552 '.Alis' NullReference (uygulama tarafı). |
| Kök neden | modules.json 'Create View Sistem.TCMBDovizKurlari as Select Tarih,Birim as Kodu,Alis,Satis from Sistem.GetKurListesi(getdate())'; TCMB.vb:67 CheckTable; :127 MERGE; phase6 KUY_ONLY 'Sistem.TCMBDovizKurlari' tablo. |
| Neden zinciri | Teknik olay: SQL 4406 (View or function is not updatable) Conversion failed ↓ Yakın neden: CheckTable() OBJECT_ID null değilse tablo oluşturmaz; DB1'de ad bir VIEW (tablo NonUsed_TCMBDovizKurlari'na taşınmış). M ↓ Kullanıcı etkisi: TCMB kur arşivi güncellenmez (sessiz); döviz seri fatura ekranında geçmiş tarih kur boş ya da NullReference. |
| Etkilenen veri | Sistem.TCMBDovizKurlari (DB1'de VIEW: Select … from Sistem.GetKurListesi(getdate())) |
| Olasılık / etki / güven | Yüksek (DB1'de her açılışta) / S3 / 85 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): TCMBDovizKurlari'nın tablo mu view mi olacağı kurulum genelinde tek karar; CheckTable'ın view'ı tablo sanmaması. (Uygulanmadı) |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SQL modül/katalog analizi |
| Validation SQL (salt okunur) | SELECT type_desc FROM sys.objects WHERE object_id=OBJECT_ID('Sistem.TCMBDovizKurlari'); SELECT COUNT(*) FROM Sistem.NonUsed_TCMBDovizKurlari; |
| Test senaryosu | [Ekip tarafından doldurulacak] |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | SQL risk analizi SQLR-058 · DB1=EVET (view) / tablo: Sistem.NonUsed_TCMBDovizKurlari (25.212 satır) DB2=EVET (tablo, 34.644 satır) BASE=EVET (view BASE-CORE); NonUsed_ V2_ONLY · Guard=HAYIR · modules.json 'Create View Sistem.TCMBDovizKurlari as Select Tarih,Birim as Kodu,Alis,Satis from Sistem.GetKurListesi(getdate())'; TCMB.vb:67 CheckTable; :127 MERGE; phase6 KUY_ONLY 'Sistem.TCMBDovizKu |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-028 — SQLR-063 Duplicate key: Sistem.Kurlar (BirimId,Tarih); Sistem.Birimler.Kodu; Cari.Hesaplar (VergiNo,SubeId); Cari.Islemler.FisNo; Cari.BakiyeKodlari.Kodu S2 · MOD-VERİTABANI · Gözlemlendi: HAYIR · PF-005 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E15 — Duplicate / Çift İşlem |
| Severity | S2 — YÜKSEK |
| Modül | MOD-VERİTABANI |
| Alt modül | Duplicate key |
| Problem ailesi | PF-005 Bilanço tutmuyor / eksi-zarar yazıyor / yanlış gösteriyor (genel bilanço problemi) |
| Kullanıcı belirtisi | Hata yok; aynı fiş numarası iki işlem, kur listesinde çift satır, bilanço tutarı iki kat. |
| Teknik belirti | DB1'de PK dışı benzersiz indeks yalnız 4 (sysdiagrams, KYC.BelgeTurleri.Kod, POS.Esikler, POS.VergiOranlari). İş anahtarları (Kurlar BirimId+Tarih, Birimler.Kodu, FisNo, RefNo) benzersiz değil → çakışma hata vermez, mükerrer satır oluşur. Sonuç: Sistem.GetKurListesi aynı birim için 2 satır → FN.GetKur TOP 1 (ORDER BY yok) rastgele kur; Bilanco/Pozisyon join'lerinde tutar iki kat; AcceptTransaction '(Select Id From Sistem.Birimler Where Kodu=HasSymbol)' → 512. |
| SQL hata no | 2627 / 2601 (yok — benzersiz indeks yok → sessiz mükerrer) |
| SQL hata mesajı | Duplicate key |
| Ekran | Kur giriş (FrmKurGirisEkrani, Sistem.KurKopyala); Birim tanımı; hesap kartı; fiş numarası (Max+1, TD-02) |
| Kod dosyası | ERPPRO/Class/Ext/Cari.IslemEx.vb:256-267; ERPPRO/Form/Genel/FrmKurGirisEkrani.vb:110 |
| İlgili SQL nesneleri | Sistem.Kurlar, Sistem.Birimler, Cari.Hesaplar, Cari.Islemler, Cari.BakiyeKodlari, KYC.BelgeTurleri, POS.Esikler, POS.VergiOranlari, Sistem.GetKurListesi, FN.GetKur |
| SQL Object | Sistem.Kurlar (BirimId,Tarih); Sistem.Birimler.Kodu; Cari.Hesaplar (VergiNo,SubeId); Cari.Islemler.FisNo; Cari.BakiyeKodlari.Kodu |
| Tablo | Sistem.Kurlar; Sistem.Birimler; Cari.Hesaplar; Cari.Islemler |
| Tetikleme koşulu | DB1'de PK dışı benzersiz indeks yalnız 4 (sysdiagrams, KYC.BelgeTurleri.Kod, POS.Esikler, POS.VergiOranlari). İş anahtarları (Kurlar BirimId+Tarih, Birimler.Kodu, FisNo, RefNo) benzersiz değil → çakışma hata vermez, mükerrer satır oluşur. Sonuç: Sistem.GetKurListesi aynı birim için 2 satır → FN.GetKur TOP 1 (ORDER BY yok) rastgele kur; Bilanco/Pozisyon join'lerinde tutar iki kat; AcceptTransaction '(Select Id From Sistem.Birimler Where Kodu=HasSymbol)' → 512. |
| Kök neden | indexes.json is_unique & not PK: 4 satır; Sistem.Kurlar indeksleri PK_Kurlar(Id), IX_KUR_SORT_TARIH(Tarih)…; FN.GetKur 'Select top 1 Alis … Where BirimId=@BirimId' ORDER BY yok; TD-02. |
| Neden zinciri | Teknik olay: SQL 2627 / 2601 (yok — benzersiz indeks yok → sessiz mükerrer) Duplicate key ↓ Yakın neden: DB1'de PK dışı benzersiz indeks yalnız 4 (sysdiagrams, KYC.BelgeTurleri.Kod, POS.Esikler, POS.VergiOranlari). İş anahtar ↓ Kullanıcı etkisi: Hata yok; aynı fiş numarası iki işlem, kur listesinde çift satır, bilanço tutarı iki kat. |
| Etkilenen veri | Sistem.Kurlar; Sistem.Birimler; Cari.Hesaplar; Cari.Islemler |
| Olasılık / etki / güven | Orta (çok kullanıcılı Max+1 fiş no: yüksek) / S2 (finansal — kur/bakiye çiftlenmesi) / 85 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): İş anahtarlarına benzersiz indeks (Kurlar(BirimId,Tarih), Birimler(Kodu) filtered IsDeleted=0, Hesaplar(SubeId,VergiNo)); fiş no için SEQUENCE. (Uygulanmadı) |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SQL modül/katalog analizi |
| Validation SQL (salt okunur) | SELECT BirimId,Tarih,COUNT(*) FROM Sistem.Kurlar GROUP BY BirimId,Tarih HAVING COUNT(*)>1; SELECT Kodu,COUNT(*) FROM Sistem.Birimler WHERE IsDeleted=0 GROUP BY Kodu HAVING COUNT(*)>1; SELECT FisNo,COUNT(DISTINCT RefNo) FROM Cari.Islemler WHERE IsDeleted=0 GROUP BY FisNo HAVING COUNT(DISTINCT RefNo)>1; |
| Test senaryosu | Doğrulama SQL'i çalıştır (salt okunur); beklenen: 0 kayıt |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | SQL risk analizi SQLR-063 · DB1=EVET DB2=BİLİNMİYOR BASE=EVET · Guard=HAYIR · indexes.json is_unique & not PK: 4 satır; Sistem.Kurlar indeksleri PK_Kurlar(Id), IX_KUR_SORT_TARIH(Tarih)…; FN.GetKur 'Select top 1 Alis … Where BirimId=@BirimId' ORDER BY yok; TD-02. |
| İlişkili kayıtlar | ERR-POT-002, ERR-POT-008, ERR-SIL-001, ERR-SIL-002, ERR-SIL-003, ERR-SIL-056, ERR-SIL-059, ERR-SIL-070 |
| Wiki bağlantıları | TD-02 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-029 — SQLR-066 Identity: Sistem.SirketOlustur; Sistem.Users Id=1 varsayımı S3 · MOD-VERİTABANI · Gözlemlendi: HAYIR · PF-008 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E03 — Veri Bütünlüğü Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-VERİTABANI |
| Alt modül | Identity |
| Problem ailesi | PF-008 ERP kurulumu (yeni kurulum, sıfır kurulum, kurulum sonrası destek) |
| Kullanıcı belirtisi | Yeni şirket kurulumunda ADMIN ile giriş yapılamaz / şube-kasa ataması yok. |
| Teknik belirti | SirketOlustur tüm tabloları TRUNCATE edip ADMIN kullanıcısını ekler ve UserDetails'e UserId=1 yazar; Users kimliği TRUNCATE ile sıfırlandığı için 1 olur — ancak Users tablosu Design/AifaDev dışı olduğu için truncate kapsamında; tohum değiştirilmişse (DBCC CHECKIDENT) ADMIN Id≠1 → UserDetails öksüz, giriş yapılamaz. Kodda Id=1 admin varsayımı. |
| SQL hata no | (sessiz) |
| SQL hata mesajı | Identity |
| Ekran | FrmMainForm.vb:706 (User.Id=1 gizli kısayol); SirketOlustur 'INSERT INTO Sistem.UserDetails(UserId…) Values(1,1,1,1,0)' |
| Kod dosyası | ERPPRO/Form/Genel/FrmMainForm.vb:706 |
| İlgili SQL nesneleri | Sistem.SirketOlustur, Sistem.Users, Sistem.UserDetails |
| SQL Object | Sistem.SirketOlustur; Sistem.Users Id=1 varsayımı |
| Tablo | Sistem.Users; Sistem.UserDetails |
| Kolon | Id / UserId |
| Tetikleme koşulu | SirketOlustur tüm tabloları TRUNCATE edip ADMIN kullanıcısını ekler ve UserDetails'e UserId=1 yazar; Users kimliği TRUNCATE ile sıfırlandığı için 1 olur — ancak Users tablosu Design/AifaDev dışı olduğu için truncate kapsamında; tohum değiştirilmişse (DBCC CHECKIDENT) ADMIN Id≠1 → UserDetails öksüz, giriş yapılamaz. Kodda Id=1 admin varsayımı. |
| Kök neden | modules.json Sistem.SirketOlustur; FrmMainForm.vb:706 'If LoginInformation.User.Id = 1 AndAlso e.Shift…'. |
| Neden zinciri | Teknik olay: SQL (sessiz) Identity ↓ Yakın neden: SirketOlustur tüm tabloları TRUNCATE edip ADMIN kullanıcısını ekler ve UserDetails'e UserId=1 yazar; Users kimliği TRUNC ↓ Kullanıcı etkisi: Yeni şirket kurulumunda ADMIN ile giriş yapılamaz / şube-kasa ataması yok. |
| Etkilenen veri | Sistem.Users; Sistem.UserDetails |
| Olasılık / etki / güven | Düşük / S3 / 70 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): SCOPE_IDENTITY ile UserDetails eklenmesi; Id=1 varsayımının role dayalı yetkiyle değiştirilmesi. (Uygulanmadı) |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SQL modül/katalog analizi |
| Validation SQL (salt okunur) | SELECT Id,UserName FROM Sistem.Users WHERE Id=1; SELECT * FROM Sistem.UserDetails WHERE UserId NOT IN (SELECT Id FROM Sistem.Users); |
| Test senaryosu | [Ekip tarafından doldurulacak] |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | SQL risk analizi SQLR-066 · DB1=EVET DB2=BİLİNMİYOR BASE=SirketOlustur UNKNOWN · Guard=HAYIR · modules.json Sistem.SirketOlustur; FrmMainForm.vb:706 'If LoginInformation.User.Id = 1 AndAlso e.Shift…'. |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-030 — SQLR-070 Subquery returned more than 1 value: Cari.UpdateTransaction; Siparis.Kontrol; MüşteriŞemasıA tetikleyicisi S3 · MOD-VERİTABANI · Gözlemlendi: HAYIR · PF-007 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E02 — SQL Server Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-VERİTABANI |
| Alt modül | Subquery returned more than 1 value |
| Problem ailesi | PF-007 Fatura kesilemiyor / fatura basma / fatura problemi (genel) |
| Kullanıcı belirtisi | Hata yok; iptal edilen fişin bazı satırlarının belge detayı (fatura no/ETTN) silinmez, raporlarda görünür. |
| Teknik belirti | UpdateTransaction 'Select @IsDeleted=I.IsDeleted, @IslemId=D.IslemId, @Ettn=D.ETTN from inserted I Left Join Cari.IslemDetaylari D' → çok satırlı iptalde yalnız SON satırın IslemDetaylari'ı silinir/EIPTAL yapılır; diğer satırların belge detayı kalır (sessiz). Siparis.Kontrol aynı kalıp. |
| SQL hata no | (sessiz — tek satır varsayımı) |
| SQL hata mesajı | Subquery returned more than 1 value |
| Ekran | Fiş iptali: iScreen.vb:723 'Update Cari.Islemler Set IsDeleted=''True'' Where FisNo=… and KasaId=…' (çok satır); Cari.Islem.vb:1058 'Where RefNo=… And IslemKodu=…' |
| Kod dosyası | ERPPRO/Controls/Islem Ekranı/Base Control/iScreen.vb:723; ERPPRO/Class/Dao/Islem/Cari.Islem.vb:1058 |
| İlgili SQL nesneleri | Cari.UpdateTransaction, Siparis.Kontrol, Cari.Islemler, Cari.IslemDetaylari, Siparis.Siparisler |
| SQL Object | Cari.UpdateTransaction; Siparis.Kontrol; MüşteriŞemasıA tetikleyicisi |
| Tablo | Cari.Islemler → Cari.IslemDetaylari; Siparis.Siparisler |
| Kolon | IsDeleted, ETTN, IslemId |
| Tetikleme koşulu | UpdateTransaction 'Select @IsDeleted=I.IsDeleted, @IslemId=D.IslemId, @Ettn=D.ETTN from inserted I Left Join Cari.IslemDetaylari D' → çok satırlı iptalde yalnız SON satırın IslemDetaylari'ı silinir/EIPTAL yapılır; diğer satırların belge detayı kalır (sessiz). Siparis.Kontrol aynı kalıp. |
| Kök neden | modules.json Cari.UpdateTransaction metni; sql_frags çok satırlı UPDATE'ler. |
| Neden zinciri | Teknik olay: SQL (sessiz — tek satır varsayımı) Subquery returned more than 1 value ↓ Yakın neden: UpdateTransaction 'Select @IsDeleted=I.IsDeleted, @IslemId=D.IslemId, @Ettn=D.ETTN from inserted I Left Join Cari.IslemD ↓ Kullanıcı etkisi: Hata yok; iptal edilen fişin bazı satırlarının belge detayı (fatura no/ETTN) silinmez, raporlarda görünür. |
| Etkilenen veri | Cari.Islemler → Cari.IslemDetaylari; Siparis.Siparisler |
| Olasılık / etki / güven | Yüksek (fiş iptali çok satırlı) / S3 / 85 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): Set-tabanlı DELETE/UPDATE (inserted JOIN). (Uygulanmadı) |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SQL modül/katalog analizi |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Cari.IslemDetaylari D JOIN Cari.Islemler I ON I.Id=D.IslemId WHERE I.IsDeleted=1 AND ISNULL(D.ETTN,'')='' ; |
| Test senaryosu | [Ekip tarafından doldurulacak] |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | SQL risk analizi SQLR-070 · DB1=EVET DB2=BİLİNMİYOR BASE=EVET · Guard=HAYIR · modules.json Cari.UpdateTransaction metni; sql_frags çok satırlı UPDATE'ler. |
| İlişkili kayıtlar | ERR-POT-069 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-031 — SQLR-080 Legacy: Pozisyon.GetOldPozisyon; Sistem.NonUsed_TCMBDovizKurlari; Genel.Dosyalar_; Genel.Experler_; Sistem.AyarEvi_ (DB2); LiveUpdate.VersionHistory_; dbo.Temp; dbo.test; Muhasebe.TEst; FN.GetCariLimitOld; FN.GetKurOldKur; FX.StartSyncOld; Report.BakiyeArtisRaporuOld S3 · MOD-VERİTABANI · Gözlemlendi: HAYIR · PF-004 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E17 — Eski Veri / Legacy Problemi |
| Severity | S3 — ORTA |
| Modül | MOD-VERİTABANI |
| Alt modül | Legacy |
| Problem ailesi | PF-004 Rapor tasarımı / yeni rapor / sütun ekleme / bakiye ekstresi düzenleme (talep) |
| Kullanıcı belirtisi | Temizlik sonrası Pozisyon ekranı/raporunda 'Invalid object name Pozisyon.GetOldPozisyon'. |
| Teknik belirti | 'Old' adlı fonksiyon canlı ekran ve rapor tarafından kullanılıyor (BASE-CORE olarak işaretli) — ad yanıltıcı, temizlikte silinirse 208. NonUsed_TCMBDovizKurlari (25.212 satır) hiçbir modül/kod tarafından okunmuyor (TCMB.vb view'ı hedefliyor). Dosyalar_/Experler_ tabloları 0 satır, view'lar tarafından değil kod tarafından da referans edilmiyor. dbo.Temp/test/Muhasebe.TEst referans yok. |
| SQL hata mesajı | Legacy |
| Ekran | FrmPozisyon.vb:8 (ANA MENÜ) → Pozisyon.GetOldPozisyon; AifaDev.Reports #18 'Pozisyon Raporu' → GetOldPozisyon; Pozisyon.GetHacimRaporu → GetOldPozisyon |
| Kod dosyası | ERPPRO/Form/RefreshGrid/FrmPozisyon.vb:8 |
| İlgili SQL nesneleri | Pozisyon.GetOldPozisyon, Sistem.NonUsed_TCMBDovizKurlari, Genel.Dosyalar_, Genel.Experler_, dbo.Temp, dbo.test, Muhasebe.TEst, FN.GetCariLimitOld, FN.GetKurOldKur, FX.StartSyncOld, Report.BakiyeArtisRaporuOld |
| SQL Object | Pozisyon.GetOldPozisyon; Sistem.NonUsed_TCMBDovizKurlari; Genel.Dosyalar_; Genel.Experler_; Sistem.AyarEvi_ (DB2); LiveUpdate.VersionHistory_; dbo.Temp; dbo.test; Muhasebe.TEst; FN.GetCariLimitOld; FN.GetKurOldKur; FX.StartSyncOld; Report.BakiyeArtisRaporuOld |
| Tetikleme koşulu | 'Old' adlı fonksiyon canlı ekran ve rapor tarafından kullanılıyor (BASE-CORE olarak işaretli) — ad yanıltıcı, temizlikte silinirse 208. NonUsed_TCMBDovizKurlari (25.212 satır) hiçbir modül/kod tarafından okunmuyor (TCMB.vb view'ı hedefliyor). Dosyalar_/Experler_ tabloları 0 satır, view'lar tarafından değil kod tarafından da referans edilmiyor. dbo.Temp/test/Muhasebe.TEst referans yok. |
| Kök neden | Legacy referans taraması: code FrmPozisyon.vb:8, dbsql AifaDev.Reports#18, modül Pozisyon.GetHacimRaporu; analysis.json LEGACY 25 nesne. |
| Neden zinciri | Teknik olay: SQL Legacy ↓ Yakın neden: 'Old' adlı fonksiyon canlı ekran ve rapor tarafından kullanılıyor (BASE-CORE olarak işaretli) — ad yanıltıcı, temizlikte ↓ Kullanıcı etkisi: Temizlik sonrası Pozisyon ekranı/raporunda 'Invalid object name Pozisyon.GetOldPozisyon'. |
| Olasılık / etki / güven | Düşük / S3 / 85 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | Öneri (uygulanmadı): GetOldPozisyon'un LEGACY listesine alınmaması (kullanımda); NonUsed_/_ son ekli nesnelerin EXCLUDE_LEGACY olarak kalması. (Uygulanmadı) |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SQL modül/katalog analizi |
| Validation SQL (salt okunur) | SELECT OBJECT_ID('Pozisyon.GetOldPozisyon'); SELECT COUNT(*) FROM Sistem.NonUsed_TCMBDovizKurlari; |
| Test senaryosu | [Ekip tarafından doldurulacak] |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | SQL risk analizi SQLR-080 · DB1=EVET DB2=Sistem.AyarEvi_/TCMBDovizKurlari tablo (KUY_ONLY); NonUsed_ HAYIR BASE=GetOldPozisyon EVET (BASE-CORE); diğerleri HAYIR (LEGACY 25) · Guard=— · Legacy referans taraması: code FrmPozisyon.vb:8, dbsql AifaDev.Reports#18, modül Pozisyon.GetHacimRaporu; analysis.json LEGACY 25 nesne. |
| İlişkili kayıtlar | ERR-POT-101, ERR-POT-102, ERR-POT-138, ERR-POT-139 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-032 — SLR-001 Bakiye satırı hassasiyeti: Has (5 hane) → Cari.BakiyeIslem.Bakiye decimal(18,2) S3 · MOD-CARI · Gözlemlendi: EVET · PF-030 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: CTR-015 (miktar hassasiyeti), H-110/H-125 teması (bakiye küsuratı) – doğrudan ticket yok) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E08 — Yuvarlama / Hassasiyet Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-030 Cari bakiye / ekstre tutmuyor (bakiye yanlış, ters, birden değişti) |
| Kullanıcı belirtisi | Müşteri has bakiyesi ile stok has toplamı (bilanço BAKIYE vs STOK kalemi) arasında açıklanamayan gram farkı; mutabakatta 'küsurat tutmuyor' şikâyeti |
| Teknik belirti | Trigger has'ı 5 haneli hesaplar ancak BakiyeIslem.Bakiye 2 haneli olduğu için her satır ±0,005 has yuvarlanır. Aynı işlem için Stok.StokHaraketleri.Has 5 haneli yazılır; cari has toplamı ile stok has toplamı aynı hareket kümesinde farklılaşır. Binlerce satırda birikimli fark oluşur, hiçbir hata üretmez. |
| Kod dosyası | Cari.AcceptTransaction (dbclean/modules.json def) satır 73, 348-349; kb_src/db/columns.json Cari.BakiyeIslem.Bakiye decimal(18,2); Stok.StokHaraketleri.Has decimal(18,5) |
| İlgili SQL nesneleri | Stok.StokHaraketleri, Cari.Islemler, Cari.BakiyeIslem |
| Tetikleme koşulu | Miktar × AuMilyem üçüncü ondalıkta 5 ve üzeri (ör. 12,34 g × 0,916 = 11,30344 → 11,30); yüksek hacimli hesaplar |
| Kök neden | Trigger has'ı 5 haneli hesaplar ancak BakiyeIslem.Bakiye 2 haneli olduğu için her satır ±0,005 has yuvarlanır. Aynı işlem için Stok.StokHaraketleri.Has 5 haneli yazılır; cari has toplamı ile stok has toplamı aynı hareket kümesinde farklılaşır. Binlerce satırda birikimli fark oluşur, hiçbir hata üretmez. |
| Neden zinciri | Belirti: Müşteri has bakiyesi ile stok has toplamı (bilanço BAKIYE vs STOK kalemi) arasında açıklanamayan gra ↓ Teknik olay: @Has = I.Miktar * Case When AuMilyem=0 Then 1 else AuMilyem end → Insert Into Cari.BakiyeIslem(...,Bakiye) Values(..., ↓ Yakın neden: Miktar × AuMilyem üçüncü ondalıkta 5 ve üzeri (ör. 12,34 g × 0,916 = 11,30344 → 11,30); yüksek hacim ↓ Kök neden: Trigger has'ı 5 haneli hesaplar ancak BakiyeIslem.Bakiye 2 haneli olduğu için her satır ±0,005 has yuvarlanır. Aynı işlem için Stok.StokHara ↓ Etkilenen veri: Bir işlemin has bakiye satırı, |Miktar × AuMilyem| değerine 2 hane yuvarlama toleransı içinde eşit o |
| Etkilenen veri | Bir işlemin has bakiye satırı, |Miktar × AuMilyem| değerine 2 hane yuvarlama toleransı içinde eşit olmalıdır. |
| Etkilenen iş süreci | Bakiye satırı hassasiyeti: Has (5 hane) → Cari.BakiyeIslem.Bakiye decimal(18,2) |
| Olasılık / etki / güven | ÇOK YÜKSEK / S3 / 92 |
| Bilinen ticket | CTR-015 (miktar hassasiyeti), H-110/H-125 teması (bakiye küsuratı) – doğrudan ticket yok |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT I.Id, I.Miktar*I.AuMilyem AS HasHesap, B.Bakiye FROM Cari.Islemler I JOIN Cari.BakiyeIslem B ON B.IslemId=I.Id AND B.BirimId=I.BakiyeId WHERE I.IsDeleted=0 AND I.IslemKodu IN (1,2,9) AND ABS(ABS(B.Bakiye)-ABS(I.Miktar*I.AuMilyem))>0.004; toplam sapma: SELECT SUM(ABS(B.Bakiye)-ABS(I.Miktar*I.AuMilyem)) ... |
| Validation SQL (salt okunur) | SELECT I.Id, I.Miktar*I.AuMilyem AS HasHesap, B.Bakiye FROM Cari.Islemler I JOIN Cari.BakiyeIslem B ON B.IslemId=I.Id AND B.BirimId=I.BakiyeId WHERE I.IsDeleted=0 AND I.IslemKodu IN (1,2,9) AND ABS(ABS(B.Bakiye)-ABS(I.Miktar*I.AuMilyem))>0.004; toplam sapma: SELECT SUM(ABS(B.Bakiye)-ABS(I.Miktar*I.AuMilyem)) ... |
| Test senaryosu | Girdi: Cari.Islemler.Miktar decimal(18,2), AuMilyem decimal(18,5); trigger @Has Decimal(18,5) · Formül: @Has = I.Miktar * Case When AuMilyem=0 Then 1 else AuMilyem end → Insert Into Cari.BakiyeIslem(...,Bakiye) Values(...,@Has) [Bakiye decimal(18,2)] · Sınır: Miktar × AuMilyem üçüncü ondalıkta 5 ve üzeri (ör. 12,34 g × 0,916 = 11,30344 → 11,30); yüksek hacimli hesaplar |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: @Has = I.Miktar * Case When AuMilyem=0 Then 1 else AuMilyem end → Insert Into Cari.BakiyeIslem(...,Bakiye) Values(...,@Has) [Bakiye decimal(18,2)] · Kanıt: Declare @Has as Decimal(18,5) (satır 23) … Values(@InsertDate,…,@BakiyeId,@Has) (satır 349); columns.json: Cari.BakiyeIslem.Bakiye decimal 18,2; Stok.StokHaraketleri.Has decimal 18,5 |
| Wiki bağlantıları | H-110 · H-125 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-033 — SLR-002 Trigger içinde ROLLBACK sonrası RETURN olmayan dallar (evrak eksik, şube/kasa/hesap=0, takoz stok kontrolü) S2 · MOD-CARI · Gözlemlendi: EVET · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: GAP-DB-07 (ROLLBACK sonrası RETURN yok), PRB-BAKIYE-000 / H-104-H-106 teması) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E16 — Eksik Türetilmiş Kayıt |
| Severity | S2 — YÜKSEK |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Cari.Islemler'de IsDeleted=0 kalan işlemin BakiyeIslem satırları silinmiş (bakiye eksik) ya da IsDeleted=1 olması gereken işlem aktif kalırken türetilmiş kayıtları silinmiş; takoz kartı yanlışlıkla silinmiş |
| Teknik belirti | ROLLBACK sonrası trigger yürütmeye devam eder ve sonraki DML'ler autocommit ile kalıcı olur (SQL Server davranışı). Aynı satır için @IsError=1 olduğundan BakiyeIslem'e dokunulmaz; ancak Inserted çok satırlıysa sonraki satırlarda @IsError sıfırlanır: bu satırların BakiyeIslem/StokHaraketleri kayıtları silinip Inserted (yeni) değerlerle yeniden yazılır, oysa Cari.Islemler güncellemesi geri alınmıştır. Ayrıca satır 235 'Update Stok.Takoz Set IsDeleted=True' ve Activity MERGE geri alınmış işlem için kalıcı olur. |
| Kod dosyası | Cari.AcceptTransaction (dbclean/modules.json def) satır 90, 109-123, 180-185, 225-247, 256-260 |
| İlgili SQL nesneleri | Cari.Islemler, Stok.Takoz, Cari.BakiyeIslem |
| Tetikleme koşulu | Tek UPDATE ile birden çok Cari.Islemler satırı değişirken satırlardan birinin hesabında zorunlu evrak eksik/şube pasif/takoz stokta yok olması (virman/parite çift bacağının RefNo ile iptali, İptal-FişNo, hesap birleştirme) |
| Kök neden | ROLLBACK sonrası trigger yürütmeye devam eder ve sonraki DML'ler autocommit ile kalıcı olur (SQL Server davranışı). Aynı satır için @IsError=1 olduğundan BakiyeIslem'e dokunulmaz; ancak Inserted çok satırlıysa sonraki satırlarda @IsError sıfırlanır: bu satırların BakiyeIslem/StokHaraketleri kayıtları silinip Inserted (yeni) değerlerle yeniden yazılır, oysa Cari.Islemler güncellemesi geri alınmıştır. Ayrıca satır 235 'Update Stok.Takoz Set IsDeleted=True' ve Activity MERGE geri alınmış işlem için kalıcı olur. |
| Neden zinciri | Belirti: Cari.Islemler'de IsDeleted=0 kalan işlemin BakiyeIslem satırları silinmiş (bakiye eksik) ya da IsDel ↓ Teknik olay: RAISERROR(...) ; Set @IsError=1 ; ROLLBACK -- RETURN yok (satır 119-123, 180-185, 225-247); döngü başında Set @IsError ↓ Yakın neden: Tek UPDATE ile birden çok Cari.Islemler satırı değişirken satırlardan birinin hesabında zorunlu evra ↓ Kök neden: ROLLBACK sonrası trigger yürütmeye devam eder ve sonraki DML'ler autocommit ile kalıcı olur (SQL Server davranışı). Aynı satır için @IsError ↓ Etkilenen veri: Aktif (IsDeleted=0, tip ∉{1,11,12}) ve tutar/has üreten her işlemin en az bir BakiyeIslem satırı olm |
| Etkilenen veri | Aktif (IsDeleted=0, tip ∉{1,11,12}) ve tutar/has üreten her işlemin en az bir BakiyeIslem satırı olmalı; silinmiş işlemin hiç olmamalı. |
| Etkilenen iş süreci | Trigger içinde ROLLBACK sonrası RETURN olmayan dallar (evrak eksik, şube/kasa/hesap=0, takoz stok kontrolü) |
| Olasılık / etki / güven | ORTA / S2 / 70 |
| Bilinen ticket | GAP-DB-07 (ROLLBACK sonrası RETURN yok), PRB-BAKIYE-000 / H-104-H-106 teması |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT I.Id FROM Cari.Islemler I WHERE I.IsDeleted=0 AND I.IslemTipi NOT IN (1,11,12) AND I.IslemKodu IN (1,2,9,4,5,6) AND (I.Tutar<>0 OR (I.BakiyeId>0 AND I.Miktar<>0)) AND NOT EXISTS (SELECT 1 FROM Cari.BakiyeIslem B WHERE B.IslemId=I.Id); ayrıca sys.triggers sırasını ve SQL error log 3609 kayıtlarını inceleyin |
| Validation SQL (salt okunur) | SELECT I.Id FROM Cari.Islemler I WHERE I.IsDeleted=0 AND I.IslemTipi NOT IN (1,11,12) AND I.IslemKodu IN (1,2,9,4,5,6) AND (I.Tutar<>0 OR (I.BakiyeId>0 AND I.Miktar<>0)) AND NOT EXISTS (SELECT 1 FROM Cari.BakiyeIslem B WHERE B.IslemId=I.Id); ayrıca sys.triggers sırasını ve SQL error log 3609 kayıtlarını inceleyin |
| Test senaryosu | Girdi: Inserted (çok satırlı UPDATE: DeleteAt RefNo, İptal FişNo, FrmHesapTemizle, FrmProvizyonKabul), Cari.GetGerekliEvraklar, Stok.GetTakozAdet · Formül: RAISERROR(...) ; Set @IsError=1 ; ROLLBACK -- RETURN yok (satır 119-123, 180-185, 225-247); döngü başında Set @IsError=0 (satır 90) · Sınır: Tek UPDATE ile birden çok Cari.Islemler satırı değişirken satırlardan birinin hesabında zorunlu evrak eksik/şube pasif/t |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Notlar | Çözüm adayı: kod kanıtı: her ROLLBACK'ten sonra RETURN eklenmesi gerektiği kitapçık 2.7'de not edilmiş; uygulanmamış |
| Kaynak | Sessiz risk analizi · Formül: RAISERROR(...) ; Set @IsError=1 ; ROLLBACK -- RETURN yok (satır 119-123, 180-185, 225-247); döngü başında Set @IsError=0 (satır 90) · Kanıt: satır 119-123: RAISERROR('BU HESABIN ZORUNLU EVRAKLARI EKSIKTIR…') … Set @IsError=1 … ROLLBACK (RETURN yok); satır 92-98'deki şube pasif dalında ise RETURN var — tutarsızlık |
| İlişkili kayıtlar | ERR-POT-003, ERR-POT-004, ERR-POT-134 |
| Wiki bağlantıları | PRB-BAKIYE-000 · H-104 · H-106 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-034 — SLR-003 Limit kontrolü için toplam bakiye (Cari.ToplamBakiye = bugünkü BakiyeIslem + Cari.BakiyeDun) S2 · MOD-CARI · Gözlemlendi: EVET · PF-030 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: GAP-DB-03 (Cari.BakiyeDun boş), CTR-014 (limit kapsamı)) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-030 Cari bakiye / ekstre tutmuyor (bakiye yanlış, ters, birden değişti) |
| Kullanıcı belirtisi | Limit aşan müşteriye satış/çıkış işlemi sessizce kabul edilir ('limit çalışmıyor'); tersine job gün içinde tekrar çalışırsa bugünkü hareketler iki kez sayılıp işlem haksız reddedilir |
| Teknik belirti | Dünkü ve önceki bakiyeler yalnız Cari.BakiyeDun tablosundan gelir; bu tabloyu dolduran prosedürü çağıran bir job kaynakta yok ve örnek DB'de tablo 0 satır. Boşsa kalan limit = Limit + (yalnız bugünkü hareketler) + 3 olur; müşterinin birikmiş borcu yok sayılır. BakiyeIslem.Tarih işlem tarihi olduğundan geçmiş tarihle girilen bugünkü işlemler de ne 'bugün' dilimine ne BakiyeDun'a girer. |
| Kod dosyası | Cari.ToplamBakiye, FN.GetCariLimit, Bakiye.DunkiBakiyeler (modules.json); Cari.Islem.vb:520-528 |
| İlgili SQL nesneleri | Cari.ToplamBakiye, FN.GetCariLimit, Bakiye.DunkiBakiyeler, Cari.BakiyeDun, Cari.BakiyeIslem, Cari.HesapBilgileri |
| SQL Object | Cari.ToplamBakiye, FN.GetCariLimit, Bakiye.DunkiBakiyeler (modules.json); Cari.Islem.vb:520-528 |
| Tetikleme koşulu | Cari.BakiyeDun boş/eski (job çalışmamış); işlem tarihi ≠ bugün; kur listesi HAS satırı 0 |
| Kök neden | Dünkü ve önceki bakiyeler yalnız Cari.BakiyeDun tablosundan gelir; bu tabloyu dolduran prosedürü çağıran bir job kaynakta yok ve örnek DB'de tablo 0 satır. Boşsa kalan limit = Limit + (yalnız bugünkü hareketler) + 3 olur; müşterinin birikmiş borcu yok sayılır. BakiyeIslem.Tarih işlem tarihi olduğundan geçmiş tarihle girilen bugünkü işlemler de ne 'bugün' dilimine ne BakiyeDun'a girer. |
| Neden zinciri | Belirti: Limit aşan müşteriye satış/çıkış işlemi sessizce kabul edilir ('limit çalışmıyor'); tersine job gün ↓ Teknik olay: Cari.ToplamBakiye = Σ_bugün( Convert(dec(18,2), Bol(Bakiye*Carpan*Kur.Alis, KurHAS.Alis)) )*-1 + Σ Cari.BakiyeDun.Bakiye ↓ Yakın neden: Cari.BakiyeDun boş/eski (job çalışmamış); işlem tarihi ≠ bugün; kur listesi HAS satırı 0 ↓ Kök neden: Dünkü ve önceki bakiyeler yalnız Cari.BakiyeDun tablosundan gelir; bu tabloyu dolduran prosedürü çağıran bir job kaynakta yok ve örnek DB'de ↓ Etkilenen veri: Cari.BakiyeDun.Tarih = dün ve limit tanımlı her hesap için satır bulunmalı; ToplamBakiye tüm BakiyeI |
| Etkilenen veri | Cari.BakiyeDun.Tarih = dün ve limit tanımlı her hesap için satır bulunmalı; ToplamBakiye tüm BakiyeIslem toplamına eşit olmalı. |
| Etkilenen iş süreci | Limit kontrolü için toplam bakiye (Cari.ToplamBakiye = bugünkü BakiyeIslem + Cari.BakiyeDun) |
| Olasılık / etki / güven | YÜKSEK / S2 / 85 |
| Bilinen ticket | GAP-DB-03 (Cari.BakiyeDun boş), CTR-014 (limit kapsamı) |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*), MAX(Tarih) FROM Cari.BakiyeDun; karşılaştırma: SELECT H.Id, FN.GetCariLimit(H.Id) AS KalanLimit, H.Limit + (-1)*(SELECT SUM(B.Bakiye*Brm.Carpan*K.Alis/KH.Alis) FROM Cari.BakiyeIslem B …) FROM Cari.HesapBilgileri H WHERE H.Limit<>0 |
| Validation SQL (salt okunur) | SELECT COUNT(*), MAX(Tarih) FROM Cari.BakiyeDun; karşılaştırma: SELECT H.Id, FN.GetCariLimit(H.Id) AS KalanLimit, H.Limit + (-1)*(SELECT SUM(B.Bakiye*Brm.Carpan*K.Alis/KH.Alis) FROM Cari.BakiyeIslem B …) FROM Cari.HesapBilgileri H WHERE H.Limit<>0 |
| Test senaryosu | Girdi: Cari.BakiyeIslem (Tarih = işlem tarihi), Cari.BakiyeDun (Bakiye.DunkiBakiyeler prosedürüyle dolar), Sistem.GetKurListesi(Getdate()) · Formül: Cari.ToplamBakiye = Σ_bugün( Convert(dec(18,2), Bol(Bakiye*Carpan*Kur.Alis, KurHAS.Alis)) )*-1 + Σ Cari.BakiyeDun.Bakiye ; FN.GetCariLimit = IsNull(H · Sınır: Cari.BakiyeDun boş/eski (job çalışmamış); işlem tarihi ≠ bugün; kur listesi HAS satırı 0 |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Cari.ToplamBakiye = Σ_bugün( Convert(dec(18,2), Bol(Bakiye*Carpan*Kur.Alis, KurHAS.Alis)) )*-1 + Σ Cari.BakiyeDun.Bakiye ; FN.GetCariLimit = IsNull(H.Limit,0)+IsNull(ToplamBakiye,0)+3 · Kanıt: Cari.ToplamBakiye: 'Where Convert(date,Tarih)=CONVERT(date,getdate()) … UNION ALL Select Bakiye from Cari.BakiyeDun'; tables.json: Cari.BakiyeDun rows=0 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-035 — SLR-004 Limit kontrolü has karşılığı (Satis ÷ HAS kuru) S2 · MOD-CARI · Gözlemlendi: EVET · PF-030 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: CTR-014, BR-BAKIYE-016) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E16 — Eksik Türetilmiş Kayıt |
| Severity | S2 — YÜKSEK |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-030 Cari bakiye / ekstre tutmuyor (bakiye yanlış, ters, birden değişti) |
| Kullanıcı belirtisi | Limit aşımı sessizce kabul edilir ya da (sembol farkında) her işlem reddedilir |
| Teknik belirti | Divide uzantısı bölen 0 ise 0 döndürür: HAS kuru 0/eksikse Balance=0 ve kontrol daima geçer. GetKur birim listede yoksa 1 döner: HasSymbol 'HAS' dışında tanımlıysa (kod sabit 'HAS' kullanıyor) Balance = Satis (TL) olur ve HAS cinsinden limitle kıyaslanır. Kontrol yalnız IslemKodu 1,2,3 ÇIKIŞ ve tip≠PEŞİN'de çalışır; takoz/vadeli/çevir çıkışları hiç kontrol edilmez; +3 has tolerans sabittir. |
| Kod dosyası | Class/Dao/Islem/Cari.Islem.vb:520-528; Class/Module/Program.vb:260-268; Class/Module/Extention.vb:428-435 |
| İlgili SQL nesneleri | Sistem.Settings, Cari.Islemler, Sistem.GetKurListesi |
| Tetikleme koşulu | Kur listesinde HAS 0 veya yok; Settings.HasSymbol ≠ 'HAS'; IslemKodu ∉ {1,2,3} |
| Kök neden | Divide uzantısı bölen 0 ise 0 döndürür: HAS kuru 0/eksikse Balance=0 ve kontrol daima geçer. GetKur birim listede yoksa 1 döner: HasSymbol 'HAS' dışında tanımlıysa (kod sabit 'HAS' kullanıyor) Balance = Satis (TL) olur ve HAS cinsinden limitle kıyaslanır. Kontrol yalnız IslemKodu 1,2,3 ÇIKIŞ ve tip≠PEŞİN'de çalışır; takoz/vadeli/çevir çıkışları hiç kontrol edilmez; +3 has tolerans sabittir. |
| Neden zinciri | Belirti: Limit aşımı sessizce kabul edilir ya da (sembol farkında) her işlem reddedilir ↓ Teknik olay: Balance = Satis.Divide(Program.GetKur("HAS")) ; AvaibleLimit = Val(FN.GetCariLimit(HesapId)) ; If Balance > AvaibleLimit ↓ Yakın neden: Kur listesinde HAS 0 veya yok; Settings.HasSymbol ≠ 'HAS'; IslemKodu ∉ {1,2,3} ↓ Kök neden: Divide uzantısı bölen 0 ise 0 döndürür: HAS kuru 0/eksikse Balance=0 ve kontrol daima geçer. GetKur birim listede yoksa 1 döner: HasSymbol ' ↓ Etkilenen veri: Aktif işlemde HasKur > 1 ve HasKur ≠ 0 olmalı (has kuru fotoğrafı anlamlı). |
| Etkilenen veri | Aktif işlemde HasKur > 1 ve HasKur ≠ 0 olmalı (has kuru fotoğrafı anlamlı). |
| Etkilenen iş süreci | Limit kontrolü has karşılığı (Satis ÷ HAS kuru) |
| Olasılık / etki / güven | ORTA / S2 / 85 |
| Bilinen ticket | CTR-014, BR-BAKIYE-016 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT HasSymbol FROM Sistem.Settings; SELECT * FROM Sistem.GetKurListesi(GETDATE()) WHERE Birim='HAS' OR Alis=0 OR Alis IS NULL; limit tanımlı hesaplarda çıkış işlemleri: SELECT I.Id,I.Satis,I.HasKur FROM Cari.Islemler I WHERE I.IsDeleted=0 AND I.IslemTuru=1 AND I.IslemTipi<>1 AND I.HasKur IN (0,1) |
| Validation SQL (salt okunur) | SELECT HasSymbol FROM Sistem.Settings; SELECT * FROM Sistem.GetKurListesi(GETDATE()) WHERE Birim='HAS' OR Alis=0 OR Alis IS NULL; limit tanımlı hesaplarda çıkış işlemleri: SELECT I.Id,I.Satis,I.HasKur FROM Cari.Islemler I WHERE I.IsDeleted=0 AND I.IslemTuru=1 AND I.IslemTipi<>1 AND I.HasKur IN (0,1) |
| Test senaryosu | Girdi: Islem.Satis (MaliyetHesapla, Double), Program.GetKur("HAS") (bellek kur listesi Alis), FN.GetCariLimit · Formül: Balance = Satis.Divide(Program.GetKur("HAS")) ; AvaibleLimit = Val(FN.GetCariLimit(HesapId)) ; If Balance > AvaibleLimit Then red · Sınır: Kur listesinde HAS 0 veya yok; Settings.HasSymbol ≠ 'HAS'; IslemKodu ∉ {1,2,3} |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Balance = Satis.Divide(Program.GetKur("HAS")) ; AvaibleLimit = Val(FN.GetCariLimit(HesapId)) ; If Balance > AvaibleLimit Then red · Kanıt: Cari.Islem.vb:521 'Dim Balance As Double = Satis.Divide(Program.GetKur("HAS"))'; Program.vb:264-265 'Else Return 1' |
| İlişkili kayıtlar | ERR-SIL-036, ERR-SIL-057, ERR-SIL-058 |
| Wiki bağlantıları | BR-BAKIYE-016 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-036 — SLR-005 Kur fotoğrafı (HasKur/GumKur/PltKur/PldKur/EurKur) kaydı S2 · MOD-CARI · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | İşlem satırında HasKur=1; takoz/rapor kâr-zarar ve 'işlem günü kur' raporları anlamsız |
| Teknik belirti | Sembol kur listesinde yoksa 1 yazılır; takoz bakiyesinde 'Altına Çevir' Fn.Bol((Miktar*AgMilyem)*GumKur, HasKur) HasKur=1 ile has bakiyeyi TL değerine eşitler. Liste yenileme hatası sessizce yutulur (boş Catch) ve eski kur kullanılmaya devam eder; hesaplanan (IsComputed) birimler için GetLastKur yedeği yoktur (aşağıdaki kayda bakınız). |
| Kod dosyası | Class/Dao/Islem/Cari.Islem.vb:607-612; Class/Module/Program.vb:260-268; Class/Dao/Sistem.KurListesi.vb:60-120 |
| İlgili SQL nesneleri | Cari.Islemler, Sistem.Settings, Sistem.Birimler, FN.Bol |
| Tetikleme koşulu | Settings sembolü Birimler'de yok/silinmiş; kur listesi yenileme başarısız; kur tarihi bugün için girilmemiş |
| Kök neden | Sembol kur listesinde yoksa 1 yazılır; takoz bakiyesinde 'Altına Çevir' Fn.Bol((Miktar*AgMilyem)*GumKur, HasKur) HasKur=1 ile has bakiyeyi TL değerine eşitler. Liste yenileme hatası sessizce yutulur (boş Catch) ve eski kur kullanılmaya devam eder; hesaplanan (IsComputed) birimler için GetLastKur yedeği yoktur (aşağıdaki kayda bakınız). |
| Neden zinciri | Belirti: İşlem satırında HasKur=1; takoz/rapor kâr-zarar ve 'işlem günü kur' raporları anlamsız ↓ Teknik olay: @HasKur = Program.GetKur(GlobalSettings.HasSymbol) → K.Alis ; birim bulunamazsa 1 ↓ Yakın neden: Settings sembolü Birimler'de yok/silinmiş; kur listesi yenileme başarısız; kur tarihi bugün için gir ↓ Kök neden: Sembol kur listesinde yoksa 1 yazılır; takoz bakiyesinde 'Altına Çevir' Fn.Bol((Miktar*AgMilyem)*GumKur, HasKur) HasKur=1 ile has bakiyeyi T ↓ Etkilenen veri: Settings'teki her metal/döviz sembolü Sistem.Birimler'de silinmemiş ve tek satır olarak bulunmalı; a |
| Etkilenen veri | Settings'teki her metal/döviz sembolü Sistem.Birimler'de silinmemiş ve tek satır olarak bulunmalı; aktif işlemde HasKur∉{0,1}. |
| Etkilenen iş süreci | Kur fotoğrafı (HasKur/GumKur/PltKur/PldKur/EurKur) kaydı |
| Olasılık / etki / güven | DÜŞÜK / S2 / 90 |
| Bilinen ticket | HAYIR (BR-KUR-001 kuralı) |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND (HasKur=1 OR GumKur=1 OR PltKur=1 OR PldKur=1 OR EurKur=1); SELECT s.HasSymbol,s.GumSymbol,s.PltSymbol,s.PldSymbol,s.UsdSymbol,s.EurSymbol FROM Sistem.Settings s; her biri için Sistem.Birimler'de IsDeleted=0 tek satır |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND (HasKur=1 OR GumKur=1 OR PltKur=1 OR PldKur=1 OR EurKur=1); SELECT s.HasSymbol,s.GumSymbol,s.PltSymbol,s.PldSymbol,s.UsdSymbol,s.EurSymbol FROM Sistem.Settings s; her biri için Sistem.Birimler'de IsDeleted=0 tek satır |
| Test senaryosu | Girdi: Program.KurListesi (15 sn'de bir arka planda yenilenen liste), GlobalSettings.*Symbol · Formül: @HasKur = Program.GetKur(GlobalSettings.HasSymbol) → K.Alis ; birim bulunamazsa 1 · Sınır: Settings sembolü Birimler'de yok/silinmiş; kur listesi yenileme başarısız; kur tarihi bugün için girilmemiş |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: @HasKur = Program.GetKur(GlobalSettings.HasSymbol) → K.Alis ; birim bulunamazsa 1 · Kanıt: Program.vb:261-266: If K IsNot Nothing Then Return K.Alis Else Return 1 |
| İlişkili kayıtlar | ERR-OBS-070, ERR-POT-023, ERR-POT-033, ERR-POT-138, ERR-SIL-026, ERR-SIL-035, ERR-SIL-041, ERR-SIL-057, ERR-SIL-058, ERR-SIL-064 |
| Wiki bağlantıları | BR-KUR-001 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-037 — SLR-006 Sistem.GetKurListesi – günün kuru yoksa son kur (GetLastKur) yedeği; hesaplanan birimlerde yedek yok S2 · MOD-SISTEM · Gözlemlendi: EVET · PF-023 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-107 (geçmiş tarihli işlem son kurla), H-124, H-125, PRB-KUR-000) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Problem ailesi | PF-023 Birim (para birimi) tanımlama / listede görünmüyor / çarpan / çift birim |
| Kullanıcı belirtisi | Yanlış günün kuruyla TL karşılığı/has karşılığı; türev birimde fiyat 0 (Perakende Fiyat = GetKur × Carpan = 0); TAKOZ satırı yanlış kur |
| Teknik belirti | (a) Günün kuru girilmemişse tüm işlemler sessizce en son (dün, hafta sonu öncesi, hatta ileri tarihli) kurla fiyatlanır; ekranda uyarı yoktur. (b) Hesaplanan birimlerde (ör. ayar/ons türevleri) L join K.BirimId (türev birim Id) üzerinden yapılır; GetLastKur türev birimleri içermediğinden Alis NULL döner; uygulama listesinde KurItem varsayılan 0 ile güncellenir → fiyat 0. (c) TAKOZ (-1) satırı için BirimId 1 sabitlenmiştir (Id=1'in HAS olduğu varsayımı). (d) Kurlar.IsDeleted süzülmez. |
| Kod dosyası | Sistem.GetKurListesi, Sistem.GetLastKur (modules.json); Class/Dao/Sistem.KurListesi.vb:100-108 |
| İlgili SQL nesneleri | Sistem.Birimler, Sistem.Kurlar, Sistem.GetKurListesi |
| Tetikleme koşulu | Gün başında kur girilmeden işlem; hafta sonu/tatil; IsComputed=1 birim; BirimId=1 ≠ HAS olan kurulum |
| Kök neden | (a) Günün kuru girilmemişse tüm işlemler sessizce en son (dün, hafta sonu öncesi, hatta ileri tarihli) kurla fiyatlanır; ekranda uyarı yoktur. (b) Hesaplanan birimlerde (ör. ayar/ons türevleri) L join K.BirimId (türev birim Id) üzerinden yapılır; GetLastKur türev birimleri içermediğinden Alis NULL döner; uygulama listesinde KurItem varsayılan 0 ile güncellenir → fiyat 0. (c) TAKOZ (-1) satırı için BirimId 1 sabitlenmiştir (Id=1'in HAS olduğu varsayımı). (d) Kurlar.IsDeleted süzülmez. |
| Neden zinciri | Belirti: Yanlış günün kuruyla TL karşılığı/has karşılığı; türev birimde fiyat 0 (Perakende Fiyat = GetKur × C ↓ Teknik olay: Alis = IsNull(Convert(dec(18,4), Kur.Alis*Carpan), L.Alis) ; Kur join: (Case When AnaBirimId=-1 Then 1 Else AnaBirimId E ↓ Yakın neden: Gün başında kur girilmeden işlem; hafta sonu/tatil; IsComputed=1 birim; BirimId=1 ≠ HAS olan kurulum ↓ Kök neden: (a) Günün kuru girilmemişse tüm işlemler sessizce en son (dün, hafta sonu öncesi, hatta ileri tarihli) kurla fiyatlanır; ekranda uyarı yoktu ↓ Etkilenen veri: Her aktif, hesaplanmayan birim için bugünün tarihli, silinmemiş tek bir kur satırı bulunmalı; GetKur |
| Etkilenen veri | Her aktif, hesaplanmayan birim için bugünün tarihli, silinmemiş tek bir kur satırı bulunmalı; GetKurListesi hiçbir satırda NULL/0 Alis döndürmemeli. |
| Etkilenen iş süreci | Sistem.GetKurListesi – günün kuru yoksa son kur (GetLastKur) yedeği; hesaplanan birimlerde yedek yok |
| Olasılık / etki / güven | YÜKSEK / S2 / 80 |
| Bilinen ticket | H-107 (geçmiş tarihli işlem son kurla), H-124, H-125, PRB-KUR-000 |
| Ticket sayısı | 0 |
| Bilinen çözüm | Bilinen operasyonel çözüm (wiki H-107/H-124): kur giriş ekranında günün kuru girilir veya KOPYALA; kalıcı kod çözümü [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT B.Kodu FROM Sistem.Birimler B WHERE B.IsDeleted=0 AND B.IsComputed=0 AND NOT EXISTS (SELECT 1 FROM Sistem.Kurlar K WHERE K.BirimId=B.Id AND K.Tarih=CONVERT(date,GETDATE()) AND K.IsDeleted=0); SELECT * FROM Sistem.GetKurListesi(GETDATE()) WHERE Alis IS NULL OR Alis=0; SELECT Id,Kodu FROM Sistem.Birimler WHERE Id=1 |
| Validation SQL (salt okunur) | SELECT B.Kodu FROM Sistem.Birimler B WHERE B.IsDeleted=0 AND B.IsComputed=0 AND NOT EXISTS (SELECT 1 FROM Sistem.Kurlar K WHERE K.BirimId=B.Id AND K.Tarih=CONVERT(date,GETDATE()) AND K.IsDeleted=0); SELECT * FROM Sistem.GetKurListesi(GETDATE()) WHERE Alis IS NULL OR Alis=0; SELECT Id,Kodu FROM Sistem.Birimler WHERE Id=1 |
| Test senaryosu | Girdi: Sistem.Kurlar (Tarih=@Tarih), Cari.BakiyeKodlari (Carpan, AnaBirimId), Sistem.GetLastKur (yalnız IsComputed='False') · Formül: Alis = IsNull(Convert(dec(18,4), Kur.Alis*Carpan), L.Alis) ; Kur join: (Case When AnaBirimId=-1 Then 1 Else AnaBirimId End)=Kur.BirimId And Kur.Tarih= · Sınır: Gün başında kur girilmeden işlem; hafta sonu/tatil; IsComputed=1 birim; BirimId=1 ≠ HAS olan kurulum |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Alis = IsNull(Convert(dec(18,4), Kur.Alis*Carpan), L.Alis) ; Kur join: (Case When AnaBirimId=-1 Then 1 Else AnaBirimId End)=Kur.BirimId And Kur.Tarih=@Tarih ; L join: L.BirimId=K.BirimId · Kanıt: GetKurListesi: 'Left Join Sistem.GetLastKur L on L.BirimId =K.BirimId'; GetLastKur: 'Where K.Id is not null And B.IsComputed ='False''; KurListesi.vb:104-105: DBNull ise Set_Alis çağrılmaz, yeni KurItem 0 ile Add→mevcut kaydı 0'a çeker |
| Wiki bağlantıları | H-107 · H-124 · H-125 · PRB-KUR-000 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-038 — SLR-007 Sistem.Kurlar benzersizlik/tarih kontrolü yok; FN.GetKur TOP 1 sırasız S3 · MOD-SISTEM · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-125, H-131/H-023 teması) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Bakiye/pozisyon/bilanço toplamları çift sayılır; rastgele kur ile dönüşüm |
| Teknik belirti | Aynı birim+tarih için birden çok satır oluşabilir (ekranda Id çözümleme hatası, KOPYALA + elle giriş, dış besleme). GetKurListesi bu durumda birimi iki kez döndürür; FN.GetKur rastgele satırı alır, uygulama listesi son okunanı alır, ToplamBakiye/OzetBilanco Birim koduyla join yaptığından bakiye iki kez toplanır. GetLastKur ileri tarihli (yanlış girilmiş) kuru 'son kur' sayar. |
| Kod dosyası | FN.GetKur, Sistem.GetLastKur, Sistem.GetKurListesi; dbclean/indexes.json (Sistem.Kurlar: yalnız PK_Kurlar ve Tarih indexleri) |
| İlgili SQL nesneleri | FN.GetKur, Sistem.Kurlar, Sistem.GetKurListesi |
| Tetikleme koşulu | Duplicate (BirimId,Tarih); ileri tarihli kur satırı; IsDeleted=1 kur satırı |
| Kök neden | Aynı birim+tarih için birden çok satır oluşabilir (ekranda Id çözümleme hatası, KOPYALA + elle giriş, dış besleme). GetKurListesi bu durumda birimi iki kez döndürür; FN.GetKur rastgele satırı alır, uygulama listesi son okunanı alır, ToplamBakiye/OzetBilanco Birim koduyla join yaptığından bakiye iki kez toplanır. GetLastKur ileri tarihli (yanlış girilmiş) kuru 'son kur' sayar. |
| Neden zinciri | Belirti: Bakiye/pozisyon/bilanço toplamları çift sayılır; rastgele kur ile dönüşüm ↓ Teknik olay: FN.GetKur = Select top 1 Alis From Sistem.GetKurListesi(Getdate()) Where BirimId=@BirimId (ORDER BY yok) ; GetLastKur = ↓ Yakın neden: Duplicate (BirimId,Tarih); ileri tarihli kur satırı; IsDeleted=1 kur satırı ↓ Kök neden: Aynı birim+tarih için birden çok satır oluşabilir (ekranda Id çözümleme hatası, KOPYALA + elle giriş, dış besleme). GetKurListesi bu durumda ↓ Etkilenen veri: Sistem.Kurlar'da (BirimId, Tarih) çifti silinmemiş satırlar için benzersiz olmalı ve Tarih > bugün o |
| Etkilenen veri | Sistem.Kurlar'da (BirimId, Tarih) çifti silinmemiş satırlar için benzersiz olmalı ve Tarih > bugün olmamalı. |
| Etkilenen iş süreci | Sistem.Kurlar benzersizlik/tarih kontrolü yok; FN.GetKur TOP 1 sırasız |
| Olasılık / etki / güven | ORTA / S3 / 85 |
| Bilinen ticket | H-125, H-131/H-023 teması |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT BirimId,Tarih,COUNT(*) FROM Sistem.Kurlar WHERE IsDeleted=0 GROUP BY BirimId,Tarih HAVING COUNT(*)>1; SELECT * FROM Sistem.Kurlar WHERE Tarih>CONVERT(date,GETDATE()); SELECT Birim,COUNT(*) FROM Sistem.GetKurListesi(GETDATE()) GROUP BY Birim HAVING COUNT(*)>1 |
| Validation SQL (salt okunur) | SELECT BirimId,Tarih,COUNT(*) FROM Sistem.Kurlar WHERE IsDeleted=0 GROUP BY BirimId,Tarih HAVING COUNT(*)>1; SELECT * FROM Sistem.Kurlar WHERE Tarih>CONVERT(date,GETDATE()); SELECT Birim,COUNT(*) FROM Sistem.GetKurListesi(GETDATE()) GROUP BY Birim HAVING COUNT(*)>1 |
| Test senaryosu | Girdi: Sistem.Kurlar (BirimId,Tarih) – unique index yok (indexes.json), IsDeleted süzgeci yok · Formül: FN.GetKur = Select top 1 Alis From Sistem.GetKurListesi(Getdate()) Where BirimId=@BirimId (ORDER BY yok) ; GetLastKur = MAX(Tarih) per BirimId (ileri · Sınır: Duplicate (BirimId,Tarih); ileri tarihli kur satırı; IsDeleted=1 kur satırı |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: FN.GetKur = Select top 1 Alis From Sistem.GetKurListesi(Getdate()) Where BirimId=@BirimId (ORDER BY yok) ; GetLastKur = MAX(Tarih) per BirimId (ileri tarih dahil) · Kanıt: indexes.json Sistem.Kurlar: PK_Kurlar(Id), IX_KUR_SORT_TARIH(Tarih), IX_BILANCOARSIV(Tarih) – unique yok; GetLastKur 'Select BirimId,MAX(Tarih) … Group By BirimId' IsDeleted/tarih sınırı yok |
| Wiki bağlantıları | H-125 · H-131 · H-023 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-039 — SLR-008 Kur giriş ekranı: yeni kur satırının Id'si olarak ExecuteNonQuery dönüşü (etkilenen satır sayısı) kullanılıyor S3 · MOD-SISTEM · Gözlemlendi: HAYIR · PF-010 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Problem ailesi | PF-010 Programa giriş yapılamıyor / program açılmıyor (giriş hatası) |
| Kullanıcı belirtisi | Günün kuru yanlış (ilk girilen) kalır; Id=1'li eski kur satırı bozulur → o günkü arşiv raporları/kur farkı hesabı değişir |
| Teknik belirti | ExecuteNonQuery eklenen satır sayısını (1) döndürür, SCOPE_IDENTITY sonucunu değil. Grid'deki Id 1 olur; kullanıcı aynı oturumda (yenilemeden) aynı birimi ikinci kez düzeltirse Kurlar tablosundaki Id=1 olan tarihi kur satırı güncellenir, günün satırı ilk değerde kalır. Hata mesajı çıkmaz. |
| Kod dosyası | Form/Genel/FrmKurGirisEkrani.vb:71-84 |
| İlgili SQL nesneleri | Sistem.Kurlar |
| Tetikleme koşulu | Aynı ekran oturumunda aynı birim için iki kez değer girme (yazım düzeltmesi) |
| Kök neden | ExecuteNonQuery eklenen satır sayısını (1) döndürür, SCOPE_IDENTITY sonucunu değil. Grid'deki Id 1 olur; kullanıcı aynı oturumda (yenilemeden) aynı birimi ikinci kez düzeltirse Kurlar tablosundaki Id=1 olan tarihi kur satırı güncellenir, günün satırı ilk değerde kalır. Hata mesajı çıkmaz. |
| Neden zinciri | Belirti: Günün kuru yanlış (ilk girilen) kalır; Id=1'li eski kur satırı bozulur → o günkü arşiv raporları/kur ↓ Teknik olay: Id = Db.ExecuteNonQuery("Insert Into Sistem.Kurlar(...) Values(...) SELECT SCOPE_IDENTITY()") → 1 ; sonraki düzenleme: ↓ Yakın neden: Aynı ekran oturumunda aynı birim için iki kez değer girme (yazım düzeltmesi) ↓ Kök neden: ExecuteNonQuery eklenen satır sayısını (1) döndürür, SCOPE_IDENTITY sonucunu değil. Grid'deki Id 1 olur; kullanıcı aynı oturumda (yenilemede ↓ Etkilenen veri: Sistem.Kurlar satırında LastModify, Tarih'ten makul süre (≤ birkaç gün) sonra olmalı; Id=1 satırı gü |
| Etkilenen veri | Sistem.Kurlar satırında LastModify, Tarih'ten makul süre (≤ birkaç gün) sonra olmalı; Id=1 satırı güncel tarihli değişiklik taşımamalı. |
| Etkilenen iş süreci | Kur giriş ekranı: yeni kur satırının Id'si olarak ExecuteNonQuery dönüşü (etkilenen satır sayısı) kullanılıyor |
| Olasılık / etki / güven | ORTA / S3 / 85 |
| Bilinen ticket | HAYIR (PRB-KUR-000 teması) |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT Id,Tarih,BirimId,Alis,Satis,LastModify FROM Sistem.Kurlar WHERE Id=1 – LastModify tarihinin Tarih'ten çok sonra olması bulguyu doğrular; SELECT * FROM Sistem.Kurlar WHERE LastModify > DATEADD(day,2,Tarih) |
| Validation SQL (salt okunur) | SELECT Id,Tarih,BirimId,Alis,Satis,LastModify FROM Sistem.Kurlar WHERE Id=1 – LastModify tarihinin Tarih'ten çok sonra olması bulguyu doğrular; SELECT * FROM Sistem.Kurlar WHERE LastModify > DATEADD(day,2,Tarih) |
| Test senaryosu | Girdi: VwKurListesi satırı (Id, BirimId, Alis, Satis), Tarih · Formül: Id = Db.ExecuteNonQuery("Insert Into Sistem.Kurlar(...) Values(...) SELECT SCOPE_IDENTITY()") → 1 ; sonraki düzenleme: Update Sistem.Kurlar Set Alis= · Sınır: Aynı ekran oturumunda aynı birim için iki kez değer girme (yazım düzeltmesi) |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Id = Db.ExecuteNonQuery("Insert Into Sistem.Kurlar(...) Values(...) SELECT SCOPE_IDENTITY()") → 1 ; sonraki düzenleme: Update Sistem.Kurlar Set Alis=…,Satis=… Where Id='1' · Kanıt: FrmKurGirisEkrani.vb:73 'Id = Db.ExecuteNonQuery("Insert Into Sistem.Kurlar(…) … SELECT SCOPE_IDENTITY() ")'; InternalDb.ExecuteNonQuery → SqlCommand.ExecuteNonQuery() (rows affected) |
| Wiki bağlantıları | PRB-KUR-000 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-040 — SLR-009 Sistem.KurKopyala – bugünün kurlarını silip son kurla değiştirir S3 · MOD-SISTEM · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-107/H-124 çözüm adımı olarak öneriliyor (yan etkisi belgelenmemiş)) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Bugünün kurları önceki güne döner; işlemlerde HasKur/BirimKur eski değer |
| Teknik belirti | KOPYALA, bugün elle girilmiş tüm kurları siler ve önceki günün kurlarıyla değiştirir; onay/uyarı yoktur, UserId=0 yazılır. Gün içinde kur güncellendikten sonra basılırsa güncel kurlar kaybolur; işlemler eski kurla devam eder. |
| Kod dosyası | Sistem.KurKopyala (modules.json); FrmKurGirisEkrani.vb:BtnKopyala |
| İlgili SQL nesneleri | Sistem.KurKopyala, Sistem.Kurlar |
| SQL Object | Sistem.KurKopyala (modules.json); FrmKurGirisEkrani.vb:BtnKopyala |
| Tetikleme koşulu | Gün içinde kur girildikten sonra KOPYALA'ya basılması; ileri tarihli kur varsa GetLastKur onu getirir |
| Kök neden | KOPYALA, bugün elle girilmiş tüm kurları siler ve önceki günün kurlarıyla değiştirir; onay/uyarı yoktur, UserId=0 yazılır. Gün içinde kur güncellendikten sonra basılırsa güncel kurlar kaybolur; işlemler eski kurla devam eder. |
| Neden zinciri | Belirti: Bugünün kurları önceki güne döner; işlemlerde HasKur/BirimKur eski değer ↓ Teknik olay: Delete From Sistem.Kurlar Where Tarih=Convert(Date,GETDATE()) ; Insert … Select GETDATE(),BirimId,Alis,Satis,GETDATE(),0 ↓ Yakın neden: Gün içinde kur girildikten sonra KOPYALA'ya basılması; ileri tarihli kur varsa GetLastKur onu getiri ↓ Kök neden: KOPYALA, bugün elle girilmiş tüm kurları siler ve önceki günün kurlarıyla değiştirir; onay/uyarı yoktur, UserId=0 yazılır. Gün içinde kur gü ↓ Etkilenen veri: Günün kur satırları gün içinde sonradan UserId=0 ile yeniden yazılmamalı. |
| Etkilenen veri | Günün kur satırları gün içinde sonradan UserId=0 ile yeniden yazılmamalı. |
| Etkilenen iş süreci | Sistem.KurKopyala – bugünün kurlarını silip son kurla değiştirir |
| Olasılık / etki / güven | ORTA / S3 / 90 |
| Bilinen ticket | H-107/H-124 çözüm adımı olarak öneriliyor (yan etkisi belgelenmemiş) |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT Tarih,BirimId,UserId,LastModify,InsertDate FROM Sistem.Kurlar WHERE Tarih=CONVERT(date,GETDATE()) AND UserId=0 – aynı gün UserId<>0 satırları yoksa ve LastModify öğleden sonra ise kopyalama sonradan yapılmış demektir |
| Validation SQL (salt okunur) | SELECT Tarih,BirimId,UserId,LastModify,InsertDate FROM Sistem.Kurlar WHERE Tarih=CONVERT(date,GETDATE()) AND UserId=0 – aynı gün UserId<>0 satırları yoksa ve LastModify öğleden sonra ise kopyalama sonradan yapılmış demektir |
| Test senaryosu | Girdi: Sistem.Kurlar (Tarih=bugün), Sistem.GetLastKur · Formül: Delete From Sistem.Kurlar Where Tarih=Convert(Date,GETDATE()) ; Insert … Select GETDATE(),BirimId,Alis,Satis,GETDATE(),0 From Sistem.GetLastKur · Sınır: Gün içinde kur girildikten sonra KOPYALA'ya basılması; ileri tarihli kur varsa GetLastKur onu getirir |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Delete From Sistem.Kurlar Where Tarih=Convert(Date,GETDATE()) ; Insert … Select GETDATE(),BirimId,Alis,Satis,GETDATE(),0 From Sistem.GetLastKur · Kanıt: KurKopyala tanımı: 'Delete From Sistem.Kurlar Where Tarih = Convert(Date,GETDATE())' |
| Wiki bağlantıları | H-107 · H-124 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-041 — SLR-010 Kur 0/NULL iken Fn.Bol ve .Divide'ın sessiz 0 üretmesi (NET, limit, bilanço, maliyet) S2 · MOD-SISTEM · Gözlemlendi: EVET · PF-005 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-124 (TOPLAM 0), H-110, H-126 (Divide by zero → Fn.Bol'a çevirme önerisi)) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E16 — Eksik Türetilmiş Kayıt |
| Severity | S2 — YÜKSEK |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Problem ailesi | PF-005 Bilanço tutmuyor / eksi-zarar yazıyor / yanlış gösteriyor (genel bilanço problemi) |
| Kullanıcı belirtisi | Bakiye ekstresi TOPLAM 0; limit kontrolü etkisiz; maliyet 0 |
| Teknik belirti | Sıfıra bölme korunur ancak sonuç 0 olarak akar: kur eksikse NET=0, bilanço kalemi 0, pozisyon 0, limit karşılığı 0 (kontrol geçer), maliyet 0. Kullanıcı 'toplam 0' görür ama işlem/raporda hata yoktur; kararlar 0 üzerinden verilir. |
| Kod dosyası | FN.Bol (modules.json); Class/Module/Extention.vb:428-484; Cari.ToplamBakiye; Bakiye.GetBakiye NET; Stok.GetMadenMaliyeti son satır; Pozisyon.Write |
| İlgili SQL nesneleri | Sistem.Kurlar, Sistem.GetKurListesi |
| Tetikleme koşulu | Kur satırı 0 (ekran engeller ama SQL/KOPYALA/dış kaynak engellemez) veya birim kur listesinde yok |
| Kök neden | Sıfıra bölme korunur ancak sonuç 0 olarak akar: kur eksikse NET=0, bilanço kalemi 0, pozisyon 0, limit karşılığı 0 (kontrol geçer), maliyet 0. Kullanıcı 'toplam 0' görür ama işlem/raporda hata yoktur; kararlar 0 üzerinden verilir. |
| Neden zinciri | Belirti: Bakiye ekstresi TOPLAM 0; limit kontrolü etkisiz; maliyet 0 ↓ Teknik olay: FN.Bol(a,b) = (a<>0 and b<>0) ? a/b : 0 ; Divide(v1,v2) = (v1<>0 And v2<>0) ? v1/v2 : 0 ↓ Yakın neden: Kur satırı 0 (ekran engeller ama SQL/KOPYALA/dış kaynak engellemez) veya birim kur listesinde yok ↓ Kök neden: Sıfıra bölme korunur ancak sonuç 0 olarak akar: kur eksikse NET=0, bilanço kalemi 0, pozisyon 0, limit karşılığı 0 (kontrol geçer), maliyet ↓ Etkilenen veri: Sistem.Kurlar'da silinmemiş hiçbir satırda Alis veya Satis 0/NULL olmamalı. |
| Etkilenen veri | Sistem.Kurlar'da silinmemiş hiçbir satırda Alis veya Satis 0/NULL olmamalı. |
| Etkilenen iş süreci | Kur 0/NULL iken FN.Bol ve .Divide'ın sessiz 0 üretmesi (NET, limit, bilanço, maliyet) |
| Olasılık / etki / güven | ORTA / S2 / 90 |
| Bilinen ticket | H-124 (TOPLAM 0), H-110, H-126 (Divide by zero → FN.Bol'a çevirme önerisi) |
| Ticket sayısı | 0 |
| Bilinen çözüm | Bilinen operasyonel çözüm (H-124): kurları girmek/KOPYALA. Kod tarafında 0 yerine hata/uyarı üretilmesi [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT * FROM Sistem.Kurlar WHERE IsDeleted=0 AND (ISNULL(Alis,0)<=0 OR ISNULL(Satis,0)<=0); SELECT * FROM Sistem.GetKurListesi(GETDATE()) WHERE ISNULL(Alis,0)=0 |
| Validation SQL (salt okunur) | SELECT * FROM Sistem.Kurlar WHERE IsDeleted=0 AND (ISNULL(Alis,0)<=0 OR ISNULL(Satis,0)<=0); SELECT * FROM Sistem.GetKurListesi(GETDATE()) WHERE ISNULL(Alis,0)=0 |
| Test senaryosu | Girdi: Sistem.GetKurListesi Alis/Satis, FN.Bol, Extention.Divide · Formül: FN.Bol(a,b) = (a<>0 and b<>0) ? a/b : 0 ; Divide(v1,v2) = (v1<>0 And v2<>0) ? v1/v2 : 0 · Sınır: Kur satırı 0 (ekran engeller ama SQL/KOPYALA/dış kaynak engellemez) veya birim kur listesinde yok |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: FN.Bol(a,b) = (a<>0 and b<>0) ? a/b : 0 ; Divide(v1,v2) = (v1<>0 And v2<>0) ? v1/v2 : 0 · Kanıt: FN.Bol: 'IF (@Number1 <> 0 and @Number2 <>0) … RETURN (@Number)' (varsayılan 0); BR-MALIYET-004 |
| İlişkili kayıtlar | ERR-OBS-005, ERR-OBS-070, ERR-OBS-076, ERR-POT-023, ERR-POT-033, ERR-POT-138, ERR-SIL-026, ERR-SIL-036, ERR-SIL-045, ERR-SIL-046 |
| Wiki bağlantıları | H-124 · H-110 · H-126 · BR-MALIYET-004 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-042 — SLR-011 Kur hassasiyeti: GetKurListesi Convert(Decimal(18,4)) ile kuru 4 haneye yuvarlar (Kurlar 18,5) S4 · MOD-SISTEM · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E08 — Yuvarlama / Hassasiyet Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | TL karşılıklarında küçük ama sistematik sapma; işlem kur fotoğrafı ile Kurlar tablosu farklı |
| Teknik belirti | Beşinci ondalık atılır; parite tipi küçük kurlarda (ör. 0,00012 gibi TL-dışı çaprazlar) ve Carpan ile türetilen birimlerde bağıl hata büyür. Uygulama, işlem kur fotoğrafı ve tüm SQL NET hesapları bu 4 haneli değeri kullanır. |
| Kod dosyası | Sistem.GetKurListesi (modules.json) |
| İlgili SQL nesneleri | Sistem.GetKurListesi, Sistem.Kurlar |
| SQL Object | Sistem.GetKurListesi (modules.json) |
| Tetikleme koşulu | Kur < 0,01 veya Carpan çarpımı 5. hanede anlamlı; büyük tutarlar |
| Kök neden | Beşinci ondalık atılır; parite tipi küçük kurlarda (ör. 0,00012 gibi TL-dışı çaprazlar) ve Carpan ile türetilen birimlerde bağıl hata büyür. Uygulama, işlem kur fotoğrafı ve tüm SQL NET hesapları bu 4 haneli değeri kullanır. |
| Neden zinciri | Belirti: TL karşılıklarında küçük ama sistematik sapma; işlem kur fotoğrafı ile Kurlar tablosu farklı ↓ Teknik olay: Convert(Decimal(18,4), Kur.Alis * Carpan) as Alis ↓ Yakın neden: Kur < 0,01 veya Carpan çarpımı 5. hanede anlamlı; büyük tutarlar ↓ Kök neden: Beşinci ondalık atılır; parite tipi küçük kurlarda (ör. 0,00012 gibi TL-dışı çaprazlar) ve Carpan ile türetilen birimlerde bağıl hata büyür. ↓ Etkilenen veri: GetKurListesi.Alis ile Kurlar.Alis×Carpan farkı 0,00005'i aşmamalı. |
| Etkilenen veri | GetKurListesi.Alis ile Kurlar.Alis×Carpan farkı 0,00005'i aşmamalı. |
| Etkilenen iş süreci | Kur hassasiyeti: GetKurListesi Convert(Decimal(18,4)) ile kuru 4 haneye yuvarlar (Kurlar 18,5) |
| Olasılık / etki / güven | ORTA / S4 / 80 |
| Bilinen ticket | HAYIR |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT K.BirimId,K.Alis, L.Alis FROM Sistem.Kurlar K JOIN Sistem.GetKurListesi(K.Tarih) L ON L.BirimId=K.BirimId WHERE K.Tarih=CONVERT(date,GETDATE()) AND K.Alis<>L.Alis |
| Validation SQL (salt okunur) | SELECT K.BirimId,K.Alis, L.Alis FROM Sistem.Kurlar K JOIN Sistem.GetKurListesi(K.Tarih) L ON L.BirimId=K.BirimId WHERE K.Tarih=CONVERT(date,GETDATE()) AND K.Alis<>L.Alis |
| Test senaryosu | Girdi: Sistem.Kurlar.Alis/Satis decimal(18,5), Carpan decimal(18,5) · Formül: Convert(Decimal(18,4), Kur.Alis * Carpan) as Alis · Sınır: Kur < 0,01 veya Carpan çarpımı 5. hanede anlamlı; büyük tutarlar |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Convert(Decimal(18,4), Kur.Alis * Carpan) as Alis · Kanıt: 'Convert(Decimal(18,4), Kur.Alis * Carpan) as Alis' ; columns.json Sistem.Kurlar.Alis decimal 18,5 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-043 — SLR-012 IslemTipi 11 (belge takip) ve 12 (MAHSUP) hiç stok/bakiye hareketi üretmez – sayım farkı/açılış girişleri operasyonel stoğa yansımaz S2 · MOD-STOK · Gözlemlendi: EVET · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: CTR-003, CTR-004, CTR-005, BR-TIP-004, H-123 (çözüm adımı MAHSUP), H-142) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-STOK |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Stok sayım düzeltmesi yapılmış sanılır ama stok eski değerde; bilanço farkı; düzeltme ile bakiye kaybı |
| Teknik belirti | Kullanıcı dokümanı (A-Z 1.8/2.4, H-123) sayım farkı ve açılış stoğunun MAHSUP ile girilmesini önerir; tetikleyici MAHSUP için Stok.StokHaraketleri satırı yazmaz. İşlem listede görünür, hata yoktur, ancak stok listesi/bilanço/pozisyon değişmez. Üstelik mevcut NORMAL bir satır Düzelt ile 11/12'ye çevrilirse önce silme (satır 258-259) çalışır ve bakiye/stok kaydı sessizce kaybolur. |
| Kod dosyası | Cari.AcceptTransaction (dbclean/modules.json def) satır 263 |
| İlgili SQL nesneleri | Stok.StokHaraketleri, Cari.Islemler, Cari.History |
| Tetikleme koşulu | IslemTipi ∈ {11,12}; tip değişikliği ile düzeltme |
| Kök neden | Kullanıcı dokümanı (A-Z 1.8/2.4, H-123) sayım farkı ve açılış stoğunun MAHSUP ile girilmesini önerir; tetikleyici MAHSUP için Stok.StokHaraketleri satırı yazmaz. İşlem listede görünür, hata yoktur, ancak stok listesi/bilanço/pozisyon değişmez. Üstelik mevcut NORMAL bir satır Düzelt ile 11/12'ye çevrilirse önce silme (satır 258-259) çalışır ve bakiye/stok kaydı sessizce kaybolur. |
| Neden zinciri | Belirti: Stok sayım düzeltmesi yapılmış sanılır ama stok eski değerde; bilanço farkı; düzeltme ile bakiye kay ↓ Teknik olay: if @IsDeleted='False' And @IsError=0 AND (@IslemTipi <>11 AND @IslemTipi<>12) BEGIN … stok/bakiye üretimi … END ↓ Yakın neden: IslemTipi ∈ {11,12}; tip değişikliği ile düzeltme ↓ Kök neden: Kullanıcı dokümanı (A-Z 1.8/2.4, H-123) sayım farkı ve açılış stoğunun MAHSUP ile girilmesini önerir; tetikleyici MAHSUP için Stok.StokHarak ↓ Etkilenen veri: IslemTipi ∈ {11,12} olan işlemlerin BakiyeIslem/StokHaraketleri(Bolum=0) satırı olmamalı; NORMAL→11/ |
| Etkilenen veri | IslemTipi ∈ {11,12} olan işlemlerin BakiyeIslem/StokHaraketleri(Bolum=0) satırı olmamalı; NORMAL→11/12 tip değişikliği History'de izlenebilir olmalı. |
| Etkilenen iş süreci | IslemTipi 11 (belge takip) ve 12 (MAHSUP) hiç stok/bakiye hareketi üretmez – sayım farkı/açılış girişleri operasyonel stoğa yansımaz |
| Olasılık / etki / güven | YÜKSEK / S2 / 95 |
| Bilinen ticket | CTR-003, CTR-004, CTR-005, BR-TIP-004, H-123 (çözüm adımı MAHSUP), H-142 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*) FROM Cari.Islemler I WHERE I.IsDeleted=0 AND I.IslemTipi=12 AND I.IslemKodu IN (1,2,3); bunların hiçbirinde EXISTS(Stok.StokHaraketleri Bolum=0) olmamalı – varsa trigger sürümü farklıdır; History: SELECT TransactionId FROM Cari.History H WHERE LogType='Düzeltme' AND IslemTipi IN (11,12) AND EXISTS(SELECT 1 FROM Cari.History H0 WHERE H0.TransactionId=H.TransactionId AND H0.IslemTipi NOT IN (11,12)) |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Cari.Islemler I WHERE I.IsDeleted=0 AND I.IslemTipi=12 AND I.IslemKodu IN (1,2,3); bunların hiçbirinde EXISTS(Stok.StokHaraketleri Bolum=0) olmamalı – varsa trigger sürümü farklıdır; History: SELECT TransactionId FROM Cari.History H WHERE LogType='Düzeltme' AND IslemTipi IN (11,12) AND EXISTS(SELECT 1 FROM Cari.History H0 WHERE H0.TransactionId=H.TransactionId AND H0.IslemTipi NOT IN (11,12)) |
| Test senaryosu | Girdi: Cari.Islemler.IslemTipi · Formül: if @IsDeleted='False' And @IsError=0 AND (@IslemTipi <>11 AND @IslemTipi<>12) BEGIN … stok/bakiye üretimi … END · Sınır: IslemTipi ∈ {11,12}; tip değişikliği ile düzeltme |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Notlar | Çözüm adayı: ürün kararı gerektirir: MAHSUP'un operasyonel stok etkisi |
| Kaynak | Sessiz risk analizi · Formül: if @IsDeleted='False' And @IsError=0 AND (@IslemTipi <>11 AND @IslemTipi<>12) BEGIN … stok/bakiye üretimi … END · Kanıt: satır 256-260 önce 'Delete From Cari.BakiyeIslem Where IslemId=@IslemId' çalışır; satır 263 koşulu 11/12'yi yeniden üretimden hariç tutar |
| Wiki bağlantıları | BR-TIP-004 · H-123 · H-142 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-044 — SLR-013 Negatif miktar/adet girişi: bakiye abs() ile yön alır, stok hareketi işaretsiz miktarı taşır S2 · MOD-STOK · Gözlemlendi: HAYIR · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-STOK |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Cari has bakiyesi doğru, stok ters; bilanço BAKIYE≠STOK |
| Teknik belirti | Miktar negatif girilirse bakiye satırı yön kuralına göre düzgün işaret alır ama stok hareketi ters yöne yazılır (giriş stoğu azaltır). Ayrıca tip PEŞİN nakit satırı ve pırlanta maliyeti aynı biçimde ters işaret alır. Uygulama yalnız Miktar=0'ı engeller. |
| Kod dosyası | Cari.AcceptTransaction (dbclean/modules.json def) satır 274, 284, 336-344; Cari.Islem.vb:513 (yalnız Miktar=0 kontrolü) |
| İlgili SQL nesneleri | Cari.Islemler, Stok.StokHaraketleri |
| Tetikleme koşulu | Miktar<0, Adet<0 veya Tutar<0 girilmiş satır |
| Kök neden | Miktar negatif girilirse bakiye satırı yön kuralına göre düzgün işaret alır ama stok hareketi ters yöne yazılır (giriş stoğu azaltır). Ayrıca tip PEŞİN nakit satırı ve pırlanta maliyeti aynı biçimde ters işaret alır. Uygulama yalnız Miktar=0'ı engeller. |
| Neden zinciri | Belirti: Cari has bakiyesi doğru, stok ters; bilanço BAKIYE≠STOK ↓ Teknik olay: Bakiye: Set @Has=0-abs(@Has) / abs(@Has) ; Stok: Miktar = Case When @IslemTuru=0 Then @Miktar When 1 Then 0-@Miktar End ↓ Yakın neden: Miktar<0, Adet<0 veya Tutar<0 girilmiş satır ↓ Kök neden: Miktar negatif girilirse bakiye satırı yön kuralına göre düzgün işaret alır ama stok hareketi ters yöne yazılır (giriş stoğu azaltır). Ayrıc ↓ Etkilenen veri: Aktif işlemde Miktar, Adet ve Tutar negatif olmamalı; stok hareketi işareti IslemTuru ile uyumlu olm |
| Etkilenen veri | Aktif işlemde Miktar, Adet ve Tutar negatif olmamalı; stok hareketi işareti IslemTuru ile uyumlu olmalı. |
| Etkilenen iş süreci | Negatif miktar/adet girişi: bakiye abs() ile yön alır, stok hareketi işaretsiz miktarı taşır |
| Olasılık / etki / güven | DÜŞÜK / S2 / 60 |
| Bilinen ticket | HAYIR (H-123 negatif stok teması) |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT Id,IslemKodu,IslemTuru,Miktar,Adet,Tutar FROM Cari.Islemler WHERE IsDeleted=0 AND (Miktar<0 OR Adet<0 OR Tutar<0); SELECT H.* FROM Stok.StokHaraketleri H JOIN Cari.Islemler I ON I.Id=H.IslemId AND H.Bolum=0 WHERE I.IslemKodu IN (1,2,9) AND H.StokTipi=1 AND SIGN(H.Miktar)<>CASE WHEN I.IslemTuru=0 THEN 1 ELSE -1 END |
| Validation SQL (salt okunur) | SELECT Id,IslemKodu,IslemTuru,Miktar,Adet,Tutar FROM Cari.Islemler WHERE IsDeleted=0 AND (Miktar<0 OR Adet<0 OR Tutar<0); SELECT H.* FROM Stok.StokHaraketleri H JOIN Cari.Islemler I ON I.Id=H.IslemId AND H.Bolum=0 WHERE I.IslemKodu IN (1,2,9) AND H.StokTipi=1 AND SIGN(H.Miktar)<>CASE WHEN I.IslemTuru=0 THEN 1 ELSE -1 END |
| Test senaryosu | Girdi: Cari.Islemler.Miktar/Adet (DevExpress numeric mask; negatif engeli kodda yok), IslemTuru · Formül: Bakiye: Set @Has=0-abs(@Has) / abs(@Has) ; Stok: Miktar = Case When @IslemTuru=0 Then @Miktar When 1 Then 0-@Miktar End (abs yok) · Sınır: Miktar<0, Adet<0 veya Tutar<0 girilmiş satır |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Bakiye: Set @Has=0-abs(@Has) / abs(@Has) ; Stok: Miktar = Case When @IslemTuru=0 Then @Miktar When 1 Then 0-@Miktar End (abs yok) · Kanıt: satır 274: 'Case When @IslemTuru=0 Then @Miktar When @IslemTuru=1 Then 0-@Miktar End' (abs yok); satır 336: 'Set @Has=0-abs(@Has)' |
| Wiki bağlantıları | H-123 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-045 — SLR-014 Stok.GetMadenMaliyeti – son 50 giriş (LIFO), bugünkü kurla bölme, kalan miktara 0 maliyet S3 · MOD-STOK · Gözlemlendi: EVET · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-120, H-121, H-122, H-129, CTR-SEC-MALIYET-01) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E08 — Yuvarlama / Hassasiyet Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-STOK |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Birim maliyet düşük/0; maliyet bir günde sıçrar; kur değişince tarihi maliyet değişir |
| Teknik belirti | Maliyet yalnız girişteki işçilik TL'sidir (metal değeri yoktur); 50 hareket sınırı nedeniyle çok hareketli stokta eski girişler görülmez ve eldeki miktarın karşılanamayan kısmı 0 maliyetle kalır; kur 'en son tarihli' alındığından geçmiş tarihli stok listesi bugünkü kurla değerlenir; Order By IslemId, Bolum=1/2 (üretim/transfer) satırlarının farklı Id ad alanıyla karışmasına açıktır; @Miktar/@Maliyet Decimal(18,2). |
| Kod dosyası | Stok.GetMadenMaliyeti (modules.json) |
| İlgili SQL nesneleri | Stok.GetMadenMaliyeti, Stok.StokHaraketleri, Bilanco.GetKurFarki |
| SQL Object | Stok.GetMadenMaliyeti (modules.json) |
| Tetikleme koşulu | Stok > son 50 girişin toplamı; geçmiş tarihli rapor; maliyet birimi kuru değişimi; transfer ile gelen stok (Maliyet satırı yok) |
| Kök neden | Maliyet yalnız girişteki işçilik TL'sidir (metal değeri yoktur); 50 hareket sınırı nedeniyle çok hareketli stokta eski girişler görülmez ve eldeki miktarın karşılanamayan kısmı 0 maliyetle kalır; kur 'en son tarihli' alındığından geçmiş tarihli stok listesi bugünkü kurla değerlenir; Order By IslemId, Bolum=1/2 (üretim/transfer) satırlarının farklı Id ad alanıyla karışmasına açıktır; @Miktar/@Maliyet Decimal(18,2). |
| Neden zinciri | Belirti: Birim maliyet düşük/0; maliyet bir günde sıçrar; kur değişince tarihi maliyet değişir ↓ Teknik olay: CURSOR top 50 … Order By IslemId Desc ; ToplamMaliyet += Maliyet (veya orantılı) ; RETURN Convert(dec(18,2), Bol(ToplamM ↓ Yakın neden: Stok > son 50 girişin toplamı; geçmiş tarihli rapor; maliyet birimi kuru değişimi; transfer ile gele ↓ Kök neden: Maliyet yalnız girişteki işçilik TL'sidir (metal değeri yoktur); 50 hareket sınırı nedeniyle çok hareketli stokta eski girişler görülmez ve ↓ Etkilenen veri: Eldeki miktar, maliyet hesabına giren giriş hareketleri toplamını aşmamalı (aşarsa maliyet eksik). |
| Etkilenen veri | Eldeki miktar, maliyet hesabına giren giriş hareketleri toplamını aşmamalı (aşarsa maliyet eksik). |
| Etkilenen iş süreci | Stok.GetMadenMaliyeti – son 50 giriş (LIFO), bugünkü kurla bölme, kalan miktara 0 maliyet |
| Olasılık / etki / güven | YÜKSEK / S3 / 90 |
| Bilinen ticket | H-120, H-121, H-122, H-129, CTR-SEC-MALIYET-01 |
| Ticket sayısı | 0 |
| Bilinen çözüm | H-129 teknik çözümü (fonksiyonun ALTER edilip stoğun boş hesaba çıkılıp geri girilmesi) wikide tarif edilmiş; kaynak sürümü doğrulanmadı → [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT StokId,SubeId,KasaId,COUNT(*) FROM Stok.StokHaraketleri WHERE StokTipi=1 AND IslemTuru=0 GROUP BY StokId,SubeId,KasaId HAVING COUNT(*)>50; eldeki miktarı ilk 50 girişin toplamını aşan stoklar: karşılaştırma sorgusu; Bilanco.GetKurFarki çıktısı |
| Validation SQL (salt okunur) | SELECT StokId,SubeId,KasaId,COUNT(*) FROM Stok.StokHaraketleri WHERE StokTipi=1 AND IslemTuru=0 GROUP BY StokId,SubeId,KasaId HAVING COUNT(*)>50; eldeki miktarı ilk 50 girişin toplamını aşan stoklar: karşılaştırma sorgusu; Bilanco.GetKurFarki çıktısı |
| Test senaryosu | Girdi: Stok.StokHaraketleri (IslemTuru=0, StokTipi=1, Bolum süzgeci yok), Stok.Maden.MaliyetBirimId, Sistem.Kurlar (Order By Tarih Desc, IsDeleted yok) · Formül: CURSOR top 50 … Order By IslemId Desc ; ToplamMaliyet += Maliyet (veya orantılı) ; RETURN Convert(dec(18,2), Bol(ToplamMaliyet, (Select top 1 Alis Fro · Sınır: Stok > son 50 girişin toplamı; geçmiş tarihli rapor; maliyet birimi kuru değişimi; transfer ile gelen stok (Maliyet satı |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: CURSOR top 50 … Order By IslemId Desc ; ToplamMaliyet += Maliyet (veya orantılı) ; RETURN Convert(dec(18,2), Bol(ToplamMaliyet, (Select top 1 Alis From Sistem.Kurlar Where BirimId=@BirimId Order By Ta · Kanıt: 'Select top 50 Case When @IscTur =0 Then Adet Else Miktar End as Miktar,Maliyet FRom Stok.StokHaraketleri … Order By IslemId Desc' |
| İlişkili kayıtlar | ERR-OBS-005, ERR-OBS-076, ERR-POT-023, ERR-SIL-041, ERR-SIL-046, ERR-SIL-049 |
| Wiki bağlantıları | H-120 · H-121 · H-122 · H-129 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-046 — SLR-015 Ortalama milyem / maliyet cursor değişkenleri Decimal(18,2) – 5 haneli Has/Miktar kesilir S4 · MOD-STOK · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: CTR-015) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E08 — Yuvarlama / Hassasiyet Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-STOK |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Ortalama milyem ve has stoğu küsuratta yanlış; stok listesi ile hareket dökümü toplamı farklı |
| Teknik belirti | Her hareket 2 haneye yuvarlanarak toplanır; küçük gramajlı çok sayıda hareket (ör. 0,005 g altı has satırları) ortalama milyemi saptırır; stok listesi Miktar/Has 2 haneye yuvarlanır ancak StokHaraketleri toplamı 5 hanelidir → liste toplamı ≠ hareket toplamı. |
| Kod dosyası | Stok.GetOrtMilyem, Stok.GetMadenMaliyeti (modules.json); Stok.GetMadenStok/GetMadenStoklari CONVERT(Decimal(18,2), Miktar) |
| İlgili SQL nesneleri | Stok.StokHaraketleri |
| Tetikleme koşulu | Miktar×Milyem 3. ondalıkta anlamlı; çok sayıda küçük hareket |
| Kök neden | Her hareket 2 haneye yuvarlanarak toplanır; küçük gramajlı çok sayıda hareket (ör. 0,005 g altı has satırları) ortalama milyemi saptırır; stok listesi Miktar/Has 2 haneye yuvarlanır ancak StokHaraketleri toplamı 5 hanelidir → liste toplamı ≠ hareket toplamı. |
| Neden zinciri | Belirti: Ortalama milyem ve has stoğu küsuratta yanlış; stok listesi ile hareket dökümü toplamı farklı ↓ Teknik olay: Declare @Miktar Decimal(18,2), @Has Decimal(18,2), @ToplamHas Decimal(18,2) … RETURN Fn.Bol(@ToplamHas,@ToplamMiktar) ↓ Yakın neden: Miktar×Milyem 3. ondalıkta anlamlı; çok sayıda küçük hareket ↓ Kök neden: Her hareket 2 haneye yuvarlanarak toplanır; küçük gramajlı çok sayıda hareket (ör. 0,005 g altı has satırları) ortalama milyemi saptırır; st ↓ Etkilenen veri: Stok listesi has/miktar değerleri, hareket toplamına 0,01 toleransla eşit olmalı. |
| Etkilenen veri | Stok listesi has/miktar değerleri, hareket toplamına 0,01 toleransla eşit olmalı. |
| Etkilenen iş süreci | Ortalama milyem / maliyet cursor değişkenleri Decimal(18,2) – 5 haneli Has/Miktar kesilir |
| Olasılık / etki / güven | YÜKSEK / S4 / 85 |
| Bilinen ticket | CTR-015 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT StokId,SUM(Miktar) AS M5, SUM(CONVERT(decimal(18,2),Miktar)) AS M2 FROM Stok.StokHaraketleri WHERE StokTipi=1 GROUP BY StokId HAVING SUM(Miktar)<>SUM(CONVERT(decimal(18,2),Miktar)) |
| Validation SQL (salt okunur) | SELECT StokId,SUM(Miktar) AS M5, SUM(CONVERT(decimal(18,2),Miktar)) AS M2 FROM Stok.StokHaraketleri WHERE StokTipi=1 GROUP BY StokId HAVING SUM(Miktar)<>SUM(CONVERT(decimal(18,2),Miktar)) |
| Test senaryosu | Girdi: Stok.StokHaraketleri.Miktar/Has decimal(18,5) · Formül: Declare @Miktar Decimal(18,2), @Has Decimal(18,2), @ToplamHas Decimal(18,2) … RETURN Fn.Bol(@ToplamHas,@ToplamMiktar) · Sınır: Miktar×Milyem 3. ondalıkta anlamlı; çok sayıda küçük hareket |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Declare @Miktar Decimal(18,2), @Has Decimal(18,2), @ToplamHas Decimal(18,2) … RETURN Fn.Bol(@ToplamHas,@ToplamMiktar) · Kanıt: GetOrtMilyem: 'Declare @Miktar Decimal(18,2)=0 ; Declare @Has Decimal(18,2)=0' |
| İlişkili kayıtlar | ERR-OBS-005, ERR-OBS-076, ERR-OBS-086, ERR-POT-003, ERR-POT-023, ERR-POT-030, ERR-POT-116, ERR-POT-134, ERR-POT-135, ERR-SIL-041 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-047 — SLR-016 Stok has değeri kart milyemiyle, cari has bakiyesi işlem milyemiyle – stok ve cari türetilmiş kayıtları farklı milyem kullanır S3 · MOD-STOK · Gözlemlendi: EVET · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-129, H-130, PRB-BILANCO-000, PRB-POZISYON-000) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E16 — Eksik Türetilmiş Kayıt |
| Severity | S3 — ORTA |
| Modül | MOD-STOK |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Pozisyon raporunda has farkı; bilanço kâr/zarar hatalı; 'kur değişince bilanço değişiyor' |
| Teknik belirti | İşçilikli milyem ayrıştırması (BR-HESAP-005) veya elle farklı milyem girilen işlemde bakiyeye Miktar×AuMilyem yazılır; stok ve pozisyon ise kart milyemini kullanır. Pozisyon.Write değişken milyemli (MilyemDurumu=True, hurda) kartlarda da sabit kart milyemini alır. Sonuç: BAKIYE ve STOK kalemleri farklı has üretir; bilanço/pozisyon 'tutmaz'. |
| Kod dosyası | Stok.GetMadenStoklari, Stok.GetMadenStok, Pozisyon.Write (modules.json); iFMaden.vb MilyemDegisti (BR-HESAP-005) |
| İlgili SQL nesneleri | Stok.GetMadenStoklari, Stok.GetMadenStok, Pozisyon.Write, Cari.Islemler, Stok.Maden, Stok.StokHaraketleri |
| SQL Object | Stok.GetMadenStoklari, Stok.GetMadenStok, Pozisyon.Write (modules.json); iFMaden.vb MilyemDegisti (BR-HESAP-005) |
| Tetikleme koşulu | AuMilyem ≠ Maden.Milyem olan işlemler; MilyemDurumu=True kartlar; negatif işçilikli kart (BR-HESAP-011) |
| Kök neden | İşçilikli milyem ayrıştırması (BR-HESAP-005) veya elle farklı milyem girilen işlemde bakiyeye Miktar×AuMilyem yazılır; stok ve pozisyon ise kart milyemini kullanır. Pozisyon.Write değişken milyemli (MilyemDurumu=True, hurda) kartlarda da sabit kart milyemini alır. Sonuç: BAKIYE ve STOK kalemleri farklı has üretir; bilanço/pozisyon 'tutmaz'. |
| Neden zinciri | Belirti: Pozisyon raporunda has farkı; bilanço kâr/zarar hatalı; 'kur değişince bilanço değişiyor' ↓ Teknik olay: Stok listesi: Has = Miktar × (MilyemDurumu='False' ? Maden.Milyem : GetOrtMilyem) ; Pozisyon: Sum(Miktar × StabilMilyem) ↓ Yakın neden: AuMilyem ≠ Maden.Milyem olan işlemler; MilyemDurumu=True kartlar; negatif işçilikli kart (BR-HESAP-0 ↓ Kök neden: İşçilikli milyem ayrıştırması (BR-HESAP-005) veya elle farklı milyem girilen işlemde bakiyeye Miktar×AuMilyem yazılır; stok ve pozisyon ise ↓ Etkilenen veri: Bir stok kodunun StokHaraketleri.Has toplamı, aynı satırların Miktar×Milyem toplamına eşit olmalı; p |
| Etkilenen veri | Bir stok kodunun StokHaraketleri.Has toplamı, aynı satırların Miktar×Milyem toplamına eşit olmalı; pozisyon has'ı hareket has'ı ile aynı temeli kullanmalı. |
| Etkilenen iş süreci | Stok has değeri kart milyemiyle, cari has bakiyesi işlem milyemiyle – stok ve cari türetilmiş kayıtları farklı milyem kullanır |
| Olasılık / etki / güven | ORTA / S3 / 75 |
| Bilinen ticket | H-129, H-130, PRB-BILANCO-000, PRB-POZISYON-000 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT I.Id,I.StokId,I.AuMilyem,M.Milyem,M.MilyemDurumu FROM Cari.Islemler I JOIN Stok.Maden M ON M.Id=I.StokId WHERE I.IsDeleted=0 AND I.IslemKodu IN (1,2) AND I.AuMilyem<>M.Milyem; SELECT StokId,SUM(Has) AS HasHareket, SUM(Miktar)*MAX(Milyem) FROM Stok.StokHaraketleri WHERE StokTipi=1 GROUP BY StokId |
| Validation SQL (salt okunur) | SELECT I.Id,I.StokId,I.AuMilyem,M.Milyem,M.MilyemDurumu FROM Cari.Islemler I JOIN Stok.Maden M ON M.Id=I.StokId WHERE I.IsDeleted=0 AND I.IslemKodu IN (1,2) AND I.AuMilyem<>M.Milyem; SELECT StokId,SUM(Has) AS HasHareket, SUM(Miktar)*MAX(Milyem) FROM Stok.StokHaraketleri WHERE StokTipi=1 GROUP BY StokId |
| Test senaryosu | Girdi: Stok.Maden.Milyem/MilyemDurumu, Cari.Islemler.AuMilyem, Stok.StokHaraketleri.Milyem · Formül: Stok listesi: Has = Miktar × (MilyemDurumu='False' ? Maden.Milyem : GetOrtMilyem) ; Pozisyon: Sum(Miktar × StabilMilyem) (=Maden.Milyem her durumda) ; · Sınır: AuMilyem ≠ Maden.Milyem olan işlemler; MilyemDurumu=True kartlar; negatif işçilikli kart (BR-HESAP-011) |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Stok listesi: Has = Miktar × (MilyemDurumu='False' ? Maden.Milyem : GetOrtMilyem) ; Pozisyon: Sum(Miktar × StabilMilyem) (=Maden.Milyem her durumda) ; Bakiye: Miktar × AuMilyem (işlem) · Kanıt: Pozisyon.Write: 'Sum(Miktar * StabilMilyem) as Has From Stok.GetMadenStoklari' ; GetMadenStoklari: 'M.Milyem as StabilMilyem' |
| Wiki bağlantıları | H-129 · H-130 · PRB-BILANCO-000 · PRB-POZISYON-000 · BR-HESAP-005 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-048 — SLR-017 Transfer kabulünde stok hareketi üretimi (Cari.TransferUpdateSTatus) – eski satırlar silinmiyor S2 · MOD-STOK · Gözlemlendi: EVET · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-114, H-119 teması; BR-TRANSFER-001) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-STOK |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Aynı transfer stoktan iki (n) kez düşer/çıkar; iptal edilen transferin stoğu geri gelmez |
| Teknik belirti | Silme koşulu StokTipi=-2 (var olmayan tip) olduğundan hiçbir zaman eski Bolum=2 satırı silinmez. Transferler.Update() Status kolonunu her zaman yazdığı için UPDATE(status) doğru döner ve Status=1 olan bir transfer her düzenlendiğinde iki stok hareketi daha eklenir. Transferin IsDeleted=1 yapılması veya Status'un 1'den başka değere alınması mevcut hareketleri silmez. |
| Kod dosyası | Cari.TransferUpdateSTatus (modules.json); Class/Dao/Cari.Transferler.vb:222 (Update tüm kolonları, Status dahil yazar), :272-301 (IsDeleted) |
| İlgili SQL nesneleri | Cari.Transferler, Stok.StokHaraketleri |
| Tetikleme koşulu | Kabul edilmiş (Status=1) transferin düzenlenmesi/yeniden kaydı; transferin sonradan iptali |
| Kök neden | Silme koşulu StokTipi=-2 (var olmayan tip) olduğundan hiçbir zaman eski Bolum=2 satırı silinmez. Transferler.Update() Status kolonunu her zaman yazdığı için UPDATE(status) doğru döner ve Status=1 olan bir transfer her düzenlendiğinde iki stok hareketi daha eklenir. Transferin IsDeleted=1 yapılması veya Status'un 1'den başka değere alınması mevcut hareketleri silmez. |
| Neden zinciri | Belirti: Aynı transfer stoktan iki (n) kez düşer/çıkar; iptal edilen transferin stoğu geri gelmez ↓ Teknik olay: if UPDATE(status): Delete From Stok.StokHaraketleri Where StokTipi=-2 AND IslemId in (inserted) ; Insert … Select 2,Id,1 ↓ Yakın neden: Kabul edilmiş (Status=1) transferin düzenlenmesi/yeniden kaydı; transferin sonradan iptali ↓ Kök neden: Silme koşulu StokTipi=-2 (var olmayan tip) olduğundan hiçbir zaman eski Bolum=2 satırı silinmez. Transferler.Update() Status kolonunu her za ↓ Etkilenen veri: Status=1 ve silinmemiş her transfer için tam 2 adet Bolum=2 stok hareketi; diğer durumlarda 0 olmalı |
| Etkilenen veri | Status=1 ve silinmemiş her transfer için tam 2 adet Bolum=2 stok hareketi; diğer durumlarda 0 olmalı. |
| Etkilenen iş süreci | Transfer kabulünde stok hareketi üretimi (Cari.TransferUpdateSTatus) – eski satırlar silinmiyor |
| Olasılık / etki / güven | ORTA / S2 / 80 |
| Bilinen ticket | H-114, H-119 teması; BR-TRANSFER-001 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT T.Id,T.Status,T.IsDeleted,COUNT(H.IslemId) FROM Cari.Transferler T LEFT JOIN Stok.StokHaraketleri H ON H.IslemId=T.Id AND H.Bolum=2 GROUP BY T.Id,T.Status,T.IsDeleted HAVING (T.Status=1 AND T.IsDeleted=0 AND COUNT(H.IslemId)<>2) OR ((T.Status<>1 OR T.IsDeleted=1) AND COUNT(H.IslemId)>0) |
| Validation SQL (salt okunur) | SELECT T.Id,T.Status,T.IsDeleted,COUNT(H.IslemId) FROM Cari.Transferler T LEFT JOIN Stok.StokHaraketleri H ON H.IslemId=T.Id AND H.Bolum=2 GROUP BY T.Id,T.Status,T.IsDeleted HAVING (T.Status=1 AND T.IsDeleted=0 AND COUNT(H.IslemId)<>2) OR ((T.Status<>1 OR T.IsDeleted=1) AND COUNT(H.IslemId)>0) |
| Test senaryosu | Girdi: Cari.Transferler (Status), Stok.StokHaraketleri Bolum=2 · Formül: if UPDATE(status): Delete From Stok.StokHaraketleri Where StokTipi=-2 AND IslemId in (inserted) ; Insert … Select 2,Id,1,…,CikanKasaId,…,Adet*-1,Mikta · Sınır: Kabul edilmiş (Status=1) transferin düzenlenmesi/yeniden kaydı; transferin sonradan iptali |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: if UPDATE(status): Delete From Stok.StokHaraketleri Where StokTipi=-2 AND IslemId in (inserted) ; Insert … Select 2,Id,1,…,CikanKasaId,…,Adet*-1,Miktar*-1 … Where Status=1 ; Insert … GirenKasaId … Whe · Kanıt: 'Delete From Stok.StokHaraketleri Where StokTipi =-2 AND IslemId in (Select Id from inserted)' |
| İlişkili kayıtlar | ERR-POT-136 |
| Wiki bağlantıları | H-114 · H-119 · BR-TRANSFER-001 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-049 — SLR-018 Stok.StokHaraketleri.IslemId ad alanı çakışması (Bolum 0 → Cari.Islemler.Id, Bolum 1 → Uretim, Bolum 2 → Transferler.Id) S3 · MOD-STOK · Gözlemlendi: EVET · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-119 (transfer satırları yanlış tarihte)) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E05 — Transaction Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-STOK |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Stok hareket raporunda transfer satırı yanlış tarih/hesapla; maliyet sırası yanlış |
| Teknik belirti | Transfer/üretim satırlarının IslemId'si Cari.Islemler'deki rastgele bir işlemle çakışır; hareket dökümünde yanlış hesap adı/tarih/tutar görünür; LIFO maliyet sıralaması Id karışımıyla bozulur. AcceptTransaction'daki silme Bolum=0 ile sınırlı olduğundan veri silinmez ama raporlar yanıltır. |
| Kod dosyası | Stok.GetStokHareketleri, Stok.GetTakozAdet, Stok.GetMadenMaliyeti (Order By IslemId) – modules.json; AcceptTransaction satır 259 (Bolum=0 ile sınırlı silme) |
| İlgili SQL nesneleri | Stok.GetStokHareketleri, Stok.GetTakozAdet, Stok.GetMadenMaliyeti, Cari.Islemler, Stok.StokHaraketleri |
| SQL Object | Stok.GetStokHareketleri, Stok.GetTakozAdet, Stok.GetMadenMaliyeti (Order By IslemId) – modules.json; AcceptTransaction satır 259 (Bolum=0 ile sınırlı silme) |
| Tetikleme koşulu | Bolum=2 veya Bolum=1 satırının IslemId'si ile aynı Id'li Cari.Islemler satırı |
| Kök neden | Transfer/üretim satırlarının IslemId'si Cari.Islemler'deki rastgele bir işlemle çakışır; hareket dökümünde yanlış hesap adı/tarih/tutar görünür; LIFO maliyet sıralaması Id karışımıyla bozulur. AcceptTransaction'daki silme Bolum=0 ile sınırlı olduğundan veri silinmez ama raporlar yanıltır. |
| Neden zinciri | Belirti: Stok hareket raporunda transfer satırı yanlış tarih/hesapla; maliyet sırası yanlış ↓ Teknik olay: GetStokHareketleri: Left Join Cari.Islemler I on H.IslemId=I.Id (Bolum süzgeci yok) → HesapAdi/Tarih/Fiyat/Tutar başka i ↓ Yakın neden: Bolum=2 veya Bolum=1 satırının IslemId'si ile aynı Id'li Cari.Islemler satırı ↓ Kök neden: Transfer/üretim satırlarının IslemId'si Cari.Islemler'deki rastgele bir işlemle çakışır; hareket dökümünde yanlış hesap adı/tarih/tutar görü ↓ Etkilenen veri: Bolum≠0 stok hareketleri Cari.Islemler ile Id üzerinden ilişkilendirilmemeli. |
| Etkilenen veri | Bolum≠0 stok hareketleri Cari.Islemler ile Id üzerinden ilişkilendirilmemeli. |
| Etkilenen iş süreci | Stok.StokHaraketleri.IslemId ad alanı çakışması (Bolum 0 → Cari.Islemler.Id, Bolum 1 → Uretim, Bolum 2 → Transferler.Id) |
| Olasılık / etki / güven | YÜKSEK / S3 / 90 |
| Bilinen ticket | H-119 (transfer satırları yanlış tarihte) |
| Ticket sayısı | 0 |
| Bilinen çözüm | H-119 teknik çözümü wikide: GetStokHareketleri'nin IsNull(I.InsertDate,H.Tarih) ve Bolum=2→'TRANSFER' etiketli sürümü; kaynak sürüm doğrulanmadı → [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*) FROM Stok.StokHaraketleri H JOIN Cari.Islemler I ON I.Id=H.IslemId WHERE H.Bolum<>0 |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Stok.StokHaraketleri H JOIN Cari.Islemler I ON I.Id=H.IslemId WHERE H.Bolum<>0 |
| Test senaryosu | Girdi: Stok.StokHaraketleri.IslemId, Bolum · Formül: GetStokHareketleri: Left Join Cari.Islemler I on H.IslemId=I.Id (Bolum süzgeci yok) → HesapAdi/Tarih/Fiyat/Tutar başka işlemden; GetTakozAdet: IslemId · Sınır: Bolum=2 veya Bolum=1 satırının IslemId'si ile aynı Id'li Cari.Islemler satırı |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: GetStokHareketleri: Left Join Cari.Islemler I on H.IslemId=I.Id (Bolum süzgeci yok) → HesapAdi/Tarih/Fiyat/Tutar başka işlemden; GetTakozAdet: IslemId<>@IslemId (Bolum süzgeci yok) · Kanıt: GetStokHareketleri: 'Left Join Cari.Islemler I on H.IslemId =I.Id' (Bolum koşulu yok) |
| İlişkili kayıtlar | ERR-OBS-005, ERR-OBS-076, ERR-POT-023, ERR-SIL-041, ERR-SIL-045, ERR-SIL-046 |
| Wiki bağlantıları | H-119 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-050 — SLR-019 Pırlanta stok maliyeti = Tutar × FN.GetKur(BirimId) S3 · MOD-STOK · Gözlemlendi: EVET · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: CTR-SEC-PIRLANTA-01, BR-STOK-004) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-STOK |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Pırlanta maliyeti NULL/yanlış birim kuruyla; bilanço PIRLANTA kalemi eksik |
| Teknik belirti | GetKur eşleşme bulamazsa NULL döner → Maliyet NULL (bilanço PIRLANTA kalemi Sum ile NULL'u atlar). PEŞİN tipte BirimId nakit stok kimliğidir, birim kimliği değil; yanlış birimin kuru uygulanır. Kur, işlem tarihinin değil bugünün kurudur; düzeltmede de bugünkü kurla yeniden yazılır. Uygulama tarafı (BR-MALIYET-003) farklı formül kullanır (CTR-SEC-PIRLANTA-01). |
| Kod dosyası | Cari.AcceptTransaction (dbclean/modules.json def) satır 291-296; FN.GetKur |
| İlgili SQL nesneleri | Stok.StokHaraketleri, Cari.Islemler |
| Tetikleme koşulu | IslemKodu=8 ve IslemTipi=1; BirimId kur listesinde yok; geçmiş tarihli düzeltme |
| Kök neden | GetKur eşleşme bulamazsa NULL döner → Maliyet NULL (bilanço PIRLANTA kalemi Sum ile NULL'u atlar). PEŞİN tipte BirimId nakit stok kimliğidir, birim kimliği değil; yanlış birimin kuru uygulanır. Kur, işlem tarihinin değil bugünün kurudur; düzeltmede de bugünkü kurla yeniden yazılır. Uygulama tarafı (BR-MALIYET-003) farklı formül kullanır (CTR-SEC-PIRLANTA-01). |
| Neden zinciri | Belirti: Pırlanta maliyeti NULL/yanlış birim kuruyla; bilanço PIRLANTA kalemi eksik ↓ Teknik olay: Declare @Maliyet decimal(18,2) = @Tutar * Fn.GetKur(@BirimId) → StokHaraketleri.Maliyet ↓ Yakın neden: IslemKodu=8 ve IslemTipi=1; BirimId kur listesinde yok; geçmiş tarihli düzeltme ↓ Kök neden: GetKur eşleşme bulamazsa NULL döner → Maliyet NULL (bilanço PIRLANTA kalemi Sum ile NULL'u atlar). PEŞİN tipte BirimId nakit stok kimliğidir ↓ Etkilenen veri: StokTipi=4 hareketlerde Maliyet NULL olmamalı. |
| Etkilenen veri | StokTipi=4 hareketlerde Maliyet NULL olmamalı. |
| Etkilenen iş süreci | Pırlanta stok maliyeti = Tutar × FN.GetKur(BirimId) |
| Olasılık / etki / güven | ORTA / S3 / 75 |
| Bilinen ticket | CTR-SEC-PIRLANTA-01, BR-STOK-004 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT H.* FROM Stok.StokHaraketleri H WHERE H.StokTipi=4 AND (H.Maliyet IS NULL OR H.Maliyet=0); SELECT I.Id,I.IslemTipi,I.BirimId FROM Cari.Islemler I WHERE I.IslemKodu=8 AND I.IslemTipi=1 AND I.IsDeleted=0 |
| Validation SQL (salt okunur) | SELECT H.* FROM Stok.StokHaraketleri H WHERE H.StokTipi=4 AND (H.Maliyet IS NULL OR H.Maliyet=0); SELECT I.Id,I.IslemTipi,I.BirimId FROM Cari.Islemler I WHERE I.IslemKodu=8 AND I.IslemTipi=1 AND I.IsDeleted=0 |
| Test senaryosu | Girdi: @Tutar, @BirimId (PEŞİN'de nakit stok Id'si, diğerlerinde birim Id'si), FN.GetKur (bugünün kur listesi) · Formül: Declare @Maliyet decimal(18,2) = @Tutar * Fn.GetKur(@BirimId) → StokHaraketleri.Maliyet · Sınır: IslemKodu=8 ve IslemTipi=1; BirimId kur listesinde yok; geçmiş tarihli düzeltme |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Declare @Maliyet decimal(18,2) = @Tutar * Fn.GetKur(@BirimId) → StokHaraketleri.Maliyet · Kanıt: 'Declare @Maliyet decimal(18,2) =@Tutar * Fn.GetKur(@BirimId)' |
| Wiki bağlantıları | BR-STOK-004 · BR-MALIYET-003 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-051 — SLR-020 Çeşni ve takoz stok listeleri InsertDate ile, stok hareketleri Tarih ile süzülür S3 · MOD-STOK · Gözlemlendi: EVET · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-108 (devir kesimi), H-130) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E08 — Yuvarlama / Hassasiyet Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-STOK |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Tarihli bilanço/pozisyon farkı; devirde satırın yanlış döneme düşmesi |
| Teknik belirti | Geçmiş tarihe girilen çeşni/takoz işlemi bilançoda kayıt gününe, cari bakiyede işlem gününe düşer; tarihli bilanço iki kalemde farklı kesim kullanır ve tutmaz. Ayrıca trigger değişkeni @InsertDate aslında I.Tarih'i taşır (isim yanıltıcı); devir kesimi bu alana dayanır. |
| Kod dosyası | Stok.GetCesniStoklari, Stok.GetTakozSubeStoklari (modules.json); AcceptTransaction satır 72-75 (@InsertDate = I.Tarih) |
| İlgili SQL nesneleri | Stok.GetCesniStoklari, Stok.GetTakozSubeStoklari, Cari.Islemler |
| SQL Object | Stok.GetCesniStoklari, Stok.GetTakozSubeStoklari (modules.json); AcceptTransaction satır 72-75 (@InsertDate = I.Tarih) |
| Tetikleme koşulu | Geçmiş tarihli takoz/çeşni işlemi; devir kesim tarihine yakın kayıtlar |
| Kök neden | Geçmiş tarihe girilen çeşni/takoz işlemi bilançoda kayıt gününe, cari bakiyede işlem gününe düşer; tarihli bilanço iki kalemde farklı kesim kullanır ve tutmaz. Ayrıca trigger değişkeni @InsertDate aslında I.Tarih'i taşır (isim yanıltıcı); devir kesimi bu alana dayanır. |
| Neden zinciri | Belirti: Tarihli bilanço/pozisyon farkı; devirde satırın yanlış döneme düşmesi ↓ Teknik olay: GetCesniStoklari/GetTakozSubeStoklari: CONVERT(date,InsertDate)<=@Tarih ; StokHaraketleri: Tarih<=@Tarih ; BakiyeIslem.T ↓ Yakın neden: Geçmiş tarihli takoz/çeşni işlemi; devir kesim tarihine yakın kayıtlar ↓ Kök neden: Geçmiş tarihe girilen çeşni/takoz işlemi bilançoda kayıt gününe, cari bakiyede işlem gününe düşer; tarihli bilanço iki kalemde farklı kesim ↓ Etkilenen veri: Stok ve bakiye türetimleri aynı tarih alanını (Tarih) esas almalı. |
| Etkilenen veri | Stok ve bakiye türetimleri aynı tarih alanını (Tarih) esas almalı. |
| Etkilenen iş süreci | Çeşni ve takoz stok listeleri InsertDate ile, stok hareketleri Tarih ile süzülür |
| Olasılık / etki / güven | ORTA / S3 / 85 |
| Bilinen ticket | H-108 (devir kesimi), H-130 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu IN (0,14) AND CONVERT(date,InsertDate)<>Tarih |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu IN (0,14) AND CONVERT(date,InsertDate)<>Tarih |
| Test senaryosu | Girdi: Cari.Islemler.InsertDate vs Tarih; Stok.StokHaraketleri.Tarih · Formül: GetCesniStoklari/GetTakozSubeStoklari: CONVERT(date,InsertDate)<=@Tarih ; StokHaraketleri: Tarih<=@Tarih ; BakiyeIslem.Tarih = I.Tarih · Sınır: Geçmiş tarihli takoz/çeşni işlemi; devir kesim tarihine yakın kayıtlar |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: GetCesniStoklari/GetTakozSubeStoklari: CONVERT(date,InsertDate)<=@Tarih ; StokHaraketleri: Tarih<=@Tarih ; BakiyeIslem.Tarih = I.Tarih · Kanıt: GetCesniStoklari: 'AND CONVERT(date, InsertDate) <= @Tarih' ; GetTakozSubeStoklari: 'Convert(date,I.InsertDate)<=@Tarih' |
| Wiki bağlantıları | H-108 · H-130 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-052 — SLR-021 Nakit tip 10 (PARİTE) satırı doğrudan kaydedilirse ters işaretli bakiye ve BirimId=0 satırı S2 · MOD-CARI · Gözlemlendi: EVET · PF-023 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: CTR-027, BR-YON-004, H-080) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-023 Birim (para birimi) tanımlama / listede görünmüyor / çarpan / çift birim |
| Kullanıcı belirtisi | Müşteri TL bakiyesi ters işaretli; görünmeyen BirimId=0 bakiye satırı |
| Teknik belirti | Ekran PARİTE'yi yeni kayıtta iki NORMAL bacağa çevirir; ancak mevcut kayıt düzenlenirken (RecordId≠0) tip PARİTE seçilirse satır IslemTipi=10 ile kaydedilir. Trigger bu satır için BirimId=0 (Birimler'de yok) bir bakiye satırı ve normal nakit kuralının tersi işaretli tutar satırı yazar. Bakiye kartı BirimId=0 satırını göstermez; ToplamBakiye/bilanço Carpan NULL nedeniyle atlar; tutar satırı ise müşteri bakiyesini ters yöne çevirir. |
| Kod dosyası | Cari.AcceptTransaction (dbclean/modules.json def) satır 318-330, 421-425; Controls/Islem Ekranı/Ekran/iFNakit.vb:91-96, 323-330 |
| İlgili SQL nesneleri | Cari.Islemler, Cari.BakiyeIslem |
| Tetikleme koşulu | IslemTipi=10 olarak kaydedilmiş nakit satırı (düzeltme yolu) |
| Kök neden | Ekran PARİTE'yi yeni kayıtta iki NORMAL bacağa çevirir; ancak mevcut kayıt düzenlenirken (RecordId≠0) tip PARİTE seçilirse satır IslemTipi=10 ile kaydedilir. Trigger bu satır için BirimId=0 (Birimler'de yok) bir bakiye satırı ve normal nakit kuralının tersi işaretli tutar satırı yazar. Bakiye kartı BirimId=0 satırını göstermez; ToplamBakiye/bilanço Carpan NULL nedeniyle atlar; tutar satırı ise müşteri bakiyesini ters yöne çevirir. |
| Neden zinciri | Belirti: Müşteri TL bakiyesi ters işaretli; görünmeyen BirimId=0 bakiye satırı ↓ Teknik olay: satır 318-330: Insert BakiyeIslem(BirimId=@BakiyeId, Bakiye=±@Miktar) ; satır 421-425: Insert BakiyeIslem(BirimId=@Birim ↓ Yakın neden: IslemTipi=10 olarak kaydedilmiş nakit satırı (düzeltme yolu) ↓ Kök neden: Ekran PARİTE'yi yeni kayıtta iki NORMAL bacağa çevirir; ancak mevcut kayıt düzenlenirken (RecordId≠0) tip PARİTE seçilirse satır IslemTipi=1 ↓ Etkilenen veri: Cari.BakiyeIslem.BirimId ∈ Sistem.Birimler.Id ∪ {-1} olmalı; 0/NULL olmamalı. |
| Etkilenen veri | Cari.BakiyeIslem.BirimId ∈ Sistem.Birimler.Id ∪ {-1} olmalı; 0/NULL olmamalı. |
| Etkilenen iş süreci | Nakit tip 10 (PARİTE) satırı doğrudan kaydedilirse ters işaretli bakiye ve BirimId=0 satırı |
| Olasılık / etki / güven | DÜŞÜK / S2 / 65 |
| Bilinen ticket | CTR-027, BR-YON-004, H-080 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=3 AND IslemTipi=10; SELECT * FROM Cari.BakiyeIslem WHERE BirimId=0 OR BirimId IS NULL |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=3 AND IslemTipi=10; SELECT * FROM Cari.BakiyeIslem WHERE BirimId=0 OR BirimId IS NULL |
| Test senaryosu | Girdi: IslemKodu=3, IslemTipi=10, BakiyeId (nakitte daima 0 – Cari.IslemEx.vb:291-303), Tutar · Formül: satır 318-330: Insert BakiyeIslem(BirimId=@BakiyeId, Bakiye=±@Miktar) ; satır 421-425: Insert BakiyeIslem(BirimId=@BirimId, Bakiye=@Tutar*-1) · Sınır: IslemTipi=10 olarak kaydedilmiş nakit satırı (düzeltme yolu) |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: satır 318-330: Insert BakiyeIslem(BirimId=@BakiyeId, Bakiye=±@Miktar) ; satır 421-425: Insert BakiyeIslem(BirimId=@BirimId, Bakiye=@Tutar*-1) · Kanıt: Cari.IslemEx.vb:303 'Case tIslemKodu.NAKIT … Return 0' ; trigger satır 323 'Values(…,@BakiyeId,@Miktar *-1)' |
| Wiki bağlantıları | BR-YON-004 · H-080 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-053 — SLR-022 Çeşni (IslemKodu=14) bakiye satırları yönden bağımsız pozitif yazılır S3 · MOD-CARI · Gözlemlendi: EVET · PF-030 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: BR-BAKIYE-004, BR-HESAP-020, CTR-039) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-030 Cari bakiye / ekstre tutmuyor (bakiye yanlış, ters, birden değişti) |
| Kullanıcı belirtisi | Çeşni girişinde müşteri alacaklanacağına borçlanır |
| Teknik belirti | Ekran her zaman ÇIKIŞ yazdığı için sonuç doğru görünür; ancak satır Düzelt ile tür değiştirilirse ya da seri/sonradan eklenen bir yol GİRİŞ çeşnisi yazarsa bakiye yine borç (+) olarak kalır. Ayrıca çeşni satırı IslemKodu∉{0,1,2,4,5,6,9} olduğu için 'diğer stok işlemi' bloğuna da girer; Tutar≠0 ise ek bir tutar satırı yazılır. |
| Kod dosyası | Cari.AcceptTransaction (dbclean/modules.json def) satır 311-317; Controls/Islem Ekranı/Ekran/iFCesni.vb:60-69 (IslemTuru daima CIKIS) |
| İlgili SQL nesneleri | Cari.Islemler |
| Tetikleme koşulu | IslemKodu=14 ve IslemTuru∈{0,2,4}; Tutar≠0 çeşni satırı |
| Kök neden | Ekran her zaman ÇIKIŞ yazdığı için sonuç doğru görünür; ancak satır Düzelt ile tür değiştirilirse ya da seri/sonradan eklenen bir yol GİRİŞ çeşnisi yazarsa bakiye yine borç (+) olarak kalır. Ayrıca çeşni satırı IslemKodu∉{0,1,2,4,5,6,9} olduğu için 'diğer stok işlemi' bloğuna da girer; Tutar≠0 ise ek bir tutar satırı yazılır. |
| Neden zinciri | Belirti: Çeşni girişinde müşteri alacaklanacağına borçlanır ↓ Teknik olay: Values(…,@HasBirimId,@Miktar * @AuMilyem) ; Values(…,@GumBirimId,@Miktar * @AgMilyem) (IslemTuru'na göre işaret yok) ↓ Yakın neden: IslemKodu=14 ve IslemTuru∈{0,2,4}; Tutar≠0 çeşni satırı ↓ Kök neden: Ekran her zaman ÇIKIŞ yazdığı için sonuç doğru görünür; ancak satır Düzelt ile tür değiştirilirse ya da seri/sonradan eklenen bir yol GİRİŞ ↓ Etkilenen veri: IslemKodu=14 satırlarında IslemTuru=1 ve Tutar=0 olmalı. |
| Etkilenen veri | IslemKodu=14 satırlarında IslemTuru=1 ve Tutar=0 olmalı. |
| Etkilenen iş süreci | Çeşni (IslemKodu=14) bakiye satırları yönden bağımsız pozitif yazılır |
| Olasılık / etki / güven | DÜŞÜK / S3 / 70 |
| Bilinen ticket | BR-BAKIYE-004, BR-HESAP-020, CTR-039 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=14 AND (IslemTuru<>1 OR ISNULL(Tutar,0)<>0) |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=14 AND (IslemTuru<>1 OR ISNULL(Tutar,0)<>0) |
| Test senaryosu | Girdi: IslemKodu=14, Miktar, AuMilyem, AgMilyem, IslemTuru · Formül: Values(…,@HasBirimId,@Miktar * @AuMilyem) ; Values(…,@GumBirimId,@Miktar * @AgMilyem) (IslemTuru'na göre işaret yok) · Sınır: IslemKodu=14 ve IslemTuru∈{0,2,4}; Tutar≠0 çeşni satırı |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Values(…,@HasBirimId,@Miktar * @AuMilyem) ; Values(…,@GumBirimId,@Miktar * @AgMilyem) (IslemTuru'na göre işaret yok) · Kanıt: satır 314: 'Values(@InsertDate,@HesapType,@HesapId,@KasaId,@IslemId,@HasBirimId,@Miktar * @AuMilyem )' |
| Wiki bağlantıları | BR-BAKIYE-004 · BR-HESAP-020 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-054 — SLR-023 Raporsuz takoz bakiyesi: XRF milyemi 0 ise TAKOZ (-1) birimine miktar; değerleme 0,6 varsayımı S3 · MOD-CARI · Gözlemlendi: EVET · PF-004 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: CTR-SYM-TAKOZ-01, BR-BAKIYE-008/009, GAP-TAKOZ-FIRE, H-117, H-130) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-004 Rapor tasarımı / yeni rapor / sütun ekleme / bakiye ekstresi düzenleme (talep) |
| Kullanıcı belirtisi | Pozisyon 0, bilanço 0,6, bakiye kartı miktar bazlı – üç rapor tutmaz |
| Teknik belirti | Aynı raporsuz takoz üç yerde üç farklı has değeriyle değerlenir (0; 0,6; kart Miktar*0,6 vs bakiye Miktar). Rapor geldiğinde işlem düzeltilmezse bakiye TAKOZ satırında kalır; düzeltme (Geri Al/Düzelt) anındaki XRF değerleri orijinal kayıttan farklıysa bakiye yeniden üretimde değişir. |
| Kod dosyası | Cari.AcceptTransaction (dbclean/modules.json def) satır 452-458, 554-558; Cari.BakiyeIslem.NetBakiye computed; Bakiye.GetBakiye; Pozisyon.Write; Bilanco.OzetBilanco |
| İlgili SQL nesneleri | Cari.BakiyeIslem, Stok.Takoz, Cari.Islemler |
| Tetikleme koşulu | IsRapor=0 ve XRF milyemleri 0; rapor sonrası düzeltilmemiş takoz; XRF sonradan güncellenen takoz |
| Kök neden | Aynı raporsuz takoz üç yerde üç farklı has değeriyle değerlenir (0; 0,6; kart Miktar*0,6 vs bakiye Miktar). Rapor geldiğinde işlem düzeltilmezse bakiye TAKOZ satırında kalır; düzeltme (Geri Al/Düzelt) anındaki XRF değerleri orijinal kayıttan farklıysa bakiye yeniden üretimde değişir. |
| Neden zinciri | Belirti: Pozisyon 0, bilanço 0,6, bakiye kartı miktar bazlı – üç rapor tutmaz ↓ Teknik olay: IsRapor=0 ⇒ @AuMilyem=XRFAuMilyem ; (@AuMilyem=0 And @AgMilyem=0) ⇒ Insert BakiyeIslem(BirimId=-1, Bakiye=∓Miktar) ; Net ↓ Yakın neden: IsRapor=0 ve XRF milyemleri 0; rapor sonrası düzeltilmemiş takoz; XRF sonradan güncellenen takoz ↓ Kök neden: Aynı raporsuz takoz üç yerde üç farklı has değeriyle değerlenir (0; 0,6; kart Miktar*0,6 vs bakiye Miktar). Rapor geldiğinde işlem düzeltilm ↓ Etkilenen veri: Raporlu (IsRapor=1) takozun işlemlerinde BirimId=-1 bakiye satırı kalmamalı; raporsuz takoz değerlem |
| Etkilenen veri | Raporlu (IsRapor=1) takozun işlemlerinde BirimId=-1 bakiye satırı kalmamalı; raporsuz takoz değerleme katsayısı tüm raporlarda aynı olmalı. |
| Etkilenen iş süreci | Raporsuz takoz bakiyesi: XRF milyemi 0 ise TAKOZ (-1) birimine miktar; değerleme 0,6 varsayımı |
| Olasılık / etki / güven | ORTA / S3 / 85 |
| Bilinen ticket | CTR-SYM-TAKOZ-01, BR-BAKIYE-008/009, GAP-TAKOZ-FIRE, H-117, H-130 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT HesapId,SUM(Bakiye) FROM Cari.BakiyeIslem WHERE BirimId=-1 GROUP BY HesapId HAVING SUM(Bakiye)<>0; SELECT T.Id FROM Stok.Takoz T WHERE T.IsRapor=1 AND EXISTS(SELECT 1 FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.StokId=T.Id AND I.IslemKodu=0 AND B.BirimId=-1) |
| Validation SQL (salt okunur) | SELECT HesapId,SUM(Bakiye) FROM Cari.BakiyeIslem WHERE BirimId=-1 GROUP BY HesapId HAVING SUM(Bakiye)<>0; SELECT T.Id FROM Stok.Takoz T WHERE T.IsRapor=1 AND EXISTS(SELECT 1 FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.StokId=T.Id AND I.IslemKodu=0 AND B.BirimId=-1) |
| Test senaryosu | Girdi: Stok.Takoz.XRFAuMilyem/XRFAgMilyem, IsRapor, Miktar(+CesniMiktar girişte) · Formül: IsRapor=0 ⇒ @AuMilyem=XRFAuMilyem ; (@AuMilyem=0 And @AgMilyem=0) ⇒ Insert BakiyeIslem(BirimId=-1, Bakiye=∓Miktar) ; NetBakiye = Bakiye*0.6 ; Bakiye.G · Sınır: IsRapor=0 ve XRF milyemleri 0; rapor sonrası düzeltilmemiş takoz; XRF sonradan güncellenen takoz |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Notlar | Çözüm adayı: ürün kararı: raporsuz takoz has varsayımı |
| Kaynak | Sessiz risk analizi · Formül: IsRapor=0 ⇒ @AuMilyem=XRFAuMilyem ; (@AuMilyem=0 And @AgMilyem=0) ⇒ Insert BakiyeIslem(BirimId=-1, Bakiye=∓Miktar) ; NetBakiye = Bakiye*0.6 ; Bakiye.GetBakiye: Case When XRFAuMilyem=0 Then 0.6 ; Pozis · Kanıt: satır 556-557: 'Values(…,-1,Case When @IslemTuru=0 Then 0-@Miktar Else @Miktar End)'; Pozisyon.Write: 'Case When R='False' Then Miktar * 0' |
| Wiki bağlantıları | SYM-TAKOZ · BR-BAKIYE-008 · H-117 · H-130 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-055 — SLR-024 İptalin geri alınması / mutabakat gibi her UPDATE'te bakiye ve stoğun güncel referans verisiyle yeniden üretilmesi S3 · MOD-CARI · Gözlemlendi: EVET · PF-030 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-105 (bakiye birden değişti), BR-BAKIYE-014) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E16 — Eksik Türetilmiş Kayıt |
| Severity | S3 — ORTA |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-030 Cari bakiye / ekstre tutmuyor (bakiye yanlış, ters, birden değişti) |
| Kullanıcı belirtisi | Kimse işlem değiştirmeden bakiye değişir (H-105'in kod bağlantısı) |
| Teknik belirti | Türetilmiş kayıtlar işlem satırındaki kur fotoğrafıyla değil o anki referans verilerle (takoz XRF milyemi, Settings sembolleri, pırlanta için bugünkü kur) yeniden hesaplanır. 'Geri Alındı', mutabakat, hesap birleştirme gibi işlem tutarını değiştirmeyen güncellemelerde bile bakiye satırları değişebilir; Cari.Hesaplar.LastDate güncellenir. Sonuç, tarihi bakiye ekstresinde açıklanamayan değişikliktir (History'de işlem alanları aynı görünür). |
| Kod dosyası | Cari.AcceptTransaction (dbclean/modules.json def) satır 256-260, 293, 452-455; iScreen.vb:1136 (F12 mutabakat UPDATE) |
| İlgili SQL nesneleri | Cari.Hesaplar, Cari.BakiyeIslem, Cari.Islemler |
| Tetikleme koşulu | XRF milyemi/Settings/kur değiştikten sonra eski işlemin herhangi bir nedenle güncellenmesi |
| Kök neden | Türetilmiş kayıtlar işlem satırındaki kur fotoğrafıyla değil o anki referans verilerle (takoz XRF milyemi, Settings sembolleri, pırlanta için bugünkü kur) yeniden hesaplanır. 'Geri Alındı', mutabakat, hesap birleştirme gibi işlem tutarını değiştirmeyen güncellemelerde bile bakiye satırları değişebilir; Cari.Hesaplar.LastDate güncellenir. Sonuç, tarihi bakiye ekstresinde açıklanamayan değişikliktir (History'de işlem alanları aynı görünür). |
| Neden zinciri | Belirti: Kimse işlem değiştirmeden bakiye değişir (H-105'in kod bağlantısı) ↓ Teknik olay: Her UPDATE'te: Delete BakiyeIslem/StokHaraketleri(Bolum=0) → yeniden Insert (XRF milyem, HasBirimId, FN.GetKur bugünkü d ↓ Yakın neden: XRF milyemi/Settings/kur değiştikten sonra eski işlemin herhangi bir nedenle güncellenmesi ↓ Kök neden: Türetilmiş kayıtlar işlem satırındaki kur fotoğrafıyla değil o anki referans verilerle (takoz XRF milyemi, Settings sembolleri, pırlanta içi ↓ Etkilenen veri: Bir işlemin BakiyeIslem toplamı, işlem alanları değişmedikçe (History 'Düzeltme' yoksa) sabit kalmal |
| Etkilenen veri | Bir işlemin BakiyeIslem toplamı, işlem alanları değişmedikçe (History 'Düzeltme' yoksa) sabit kalmalı. |
| Etkilenen iş süreci | İptalin geri alınması / mutabakat gibi her UPDATE'te bakiye ve stoğun güncel referans verisiyle yeniden üretilmesi |
| Olasılık / etki / güven | ORTA / S3 / 75 |
| Bilinen ticket | H-105 (bakiye birden değişti), BR-BAKIYE-014 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT B.IslemId FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.LastModify IS NULL AND I.MTarih IS NOT NULL – mutabakat yapılmış işlemlerde BakiyeIslem toplamı ile History'deki orijinal Miktar×AuMilyem karşılaştırılır |
| Validation SQL (salt okunur) | SELECT B.IslemId FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.LastModify IS NULL AND I.MTarih IS NOT NULL – mutabakat yapılmış işlemlerde BakiyeIslem toplamı ile History'deki orijinal Miktar×AuMilyem karşılaştırılır |
| Test senaryosu | Girdi: Inserted (herhangi bir kolon güncellemesi), Stok.Takoz XRF milyemleri, Sistem.Settings sembolleri, Fn.GetKur(bugün) · Formül: Her UPDATE'te: Delete BakiyeIslem/StokHaraketleri(Bolum=0) → yeniden Insert (XRF milyem, HasBirimId, FN.GetKur bugünkü değerlerle) · Sınır: XRF milyemi/Settings/kur değiştikten sonra eski işlemin herhangi bir nedenle güncellenmesi |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Her UPDATE'te: Delete BakiyeIslem/StokHaraketleri(Bolum=0) → yeniden Insert (XRF milyem, HasBirimId, FN.GetKur bugünkü değerlerle) · Kanıt: satır 258: 'Delete From Cari.BakiyeIslem Where IslemId =@IslemId' her INSERT/UPDATE olayında koşulsuz çalışır |
| Wiki bağlantıları | H-105 · BR-BAKIYE-014 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-056 — SLR-025 Fiş numarası üretimi MAX(FisNo)+1 (silinmemişler) ve fiş bazlı toplu iptal S2 · MOD-CARI · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-102, CTR-012, CTR-016) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Yanlış işlemlerin toplu iptali (bakiye/stok geri alınır); fiş bakiyesi (GetFisBakiye FisNo<=) yanlış |
| Teknik belirti | (a) İki kullanıcı aynı anda aynı fiş numarasını alır (yarış). (b) Son fişin tüm satırları iptal edilince numara yeniden kullanılır; iptal edilen fişle yeni fiş aynı numarayı paylaşır. (c) Fiş-No ile iptal, tarih süzgeci olmadan kasadaki aynı numaralı tüm satırları (farklı günler dahil) sessizce iptal eder; açıklama/onay/karşı bacak kontrolü yapmaz. |
| Kod dosyası | Class/Ext/Cari.IslemEx.vb:256-260; Controls/Islem Ekranı/Base Control/iScreen.vb:720-728 |
| İlgili SQL nesneleri | Cari.Islemler |
| Tetikleme koşulu | Eşzamanlı kayıt; son fişin iptali; aynı FisNo'ya sahip farklı günlerdeki satırlar |
| Kök neden | (a) İki kullanıcı aynı anda aynı fiş numarasını alır (yarış). (b) Son fişin tüm satırları iptal edilince numara yeniden kullanılır; iptal edilen fişle yeni fiş aynı numarayı paylaşır. (c) Fiş-No ile iptal, tarih süzgeci olmadan kasadaki aynı numaralı tüm satırları (farklı günler dahil) sessizce iptal eder; açıklama/onay/karşı bacak kontrolü yapmaz. |
| Neden zinciri | Belirti: Yanlış işlemlerin toplu iptali (bakiye/stok geri alınır); fiş bakiyesi (GetFisBakiye FisNo<=) yanlış ↓ Teknik olay: GetNewFisNo = Val(Select Max(FisNo) From Cari.Islemler Where IsDeleted='False') + 1 ; onIptalFisNoClick: Update Cari.Isl ↓ Yakın neden: Eşzamanlı kayıt; son fişin iptali; aynı FisNo'ya sahip farklı günlerdeki satırlar ↓ Kök neden: (a) İki kullanıcı aynı anda aynı fiş numarasını alır (yarış). (b) Son fişin tüm satırları iptal edilince numara yeniden kullanılır; iptal ed ↓ Etkilenen veri: Aynı kasada aynı FisNo yalnız tek bir güne ve tek bir hesaba ait olmalı. |
| Etkilenen veri | Aynı kasada aynı FisNo yalnız tek bir güne ve tek bir hesaba ait olmalı. |
| Etkilenen iş süreci | Fiş numarası üretimi MAX(FisNo)+1 (silinmemişler) ve fiş bazlı toplu iptal |
| Olasılık / etki / güven | ORTA / S2 / 85 |
| Bilinen ticket | H-102, CTR-012, CTR-016 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT FisNo,KasaId,COUNT(DISTINCT Tarih) FROM Cari.Islemler GROUP BY FisNo,KasaId HAVING COUNT(DISTINCT Tarih)>1; SELECT FisNo,COUNT(DISTINCT HesapId) FROM Cari.Islemler WHERE IsDeleted=0 GROUP BY FisNo HAVING COUNT(DISTINCT HesapId)>1 |
| Validation SQL (salt okunur) | SELECT FisNo,KasaId,COUNT(DISTINCT Tarih) FROM Cari.Islemler GROUP BY FisNo,KasaId HAVING COUNT(DISTINCT Tarih)>1; SELECT FisNo,COUNT(DISTINCT HesapId) FROM Cari.Islemler WHERE IsDeleted=0 GROUP BY FisNo HAVING COUNT(DISTINCT HesapId)>1 |
| Test senaryosu | Girdi: Cari.Islemler.FisNo (unique değil, IX_FisNo), IsDeleted; Program.KasaId · Formül: GetNewFisNo = Val(Select Max(FisNo) From Cari.Islemler Where IsDeleted='False') + 1 ; onIptalFisNoClick: Update Cari.Islemler Set IsDeleted='True' Whe · Sınır: Eşzamanlı kayıt; son fişin iptali; aynı FisNo'ya sahip farklı günlerdeki satırlar |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: GetNewFisNo = Val(Select Max(FisNo) From Cari.Islemler Where IsDeleted='False') + 1 ; onIptalFisNoClick: Update Cari.Islemler Set IsDeleted='True' Where FisNo=@FisNo and KasaId=@KasaId · Kanıt: iScreen.vb:723: "Update Cari.Islemler Set IsDeleted='True' Where FisNo='" & FisNo & "' and KasaId='" & Program.KasaId & "'" |
| İlişkili kayıtlar | ERR-POT-002, ERR-POT-008, ERR-SIL-001, ERR-SIL-002, ERR-SIL-003, ERR-SIL-028, ERR-SIL-059, ERR-SIL-062 |
| Wiki bağlantıları | H-102 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-057 — SLR-026 Çift kayıt (duplicate posting) – zaman aşımı/ağ kopması sonrası tekrar kayıt S2 · MOD-CARI · Gözlemlendi: EVET · PF-071 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: TD-01 teması; PRB-BAGLANTI-000) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E15 — Duplicate / Çift İşlem |
| Severity | S2 — YÜKSEK |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-071 Bakiye ekstresi / bilanço / rapor zaman aşımı (timeout) |
| Kullanıcı belirtisi | Aynı işlem iki kez bakiye ve stoğa yazılır |
| Teknik belirti | Sunucu INSERT'i işledikten sonra yanıt istemciye ulaşmazsa (timeout 30 sn, ağ) uygulama hata gösterir ve kayıt başarısız sanılır; kullanıcı tekrar F2 basar. RefNo her nesnede yeni GUID olduğundan ve FisNo/hesap/tutar için benzersizlik yoktur, ikinci satır sessizce kabul edilir. |
| Kod dosyası | Class/Dao/Islem/Cari.Islem.vb:694-709; Class/Module/InternalDb.vb:69-81; dbclean/indexes.json (Cari.Islemler unique yalnız PK) |
| İlgili SQL nesneleri | Cari.Islemler |
| Tetikleme koşulu | Ağ kesintisi/uzun tetikleyici süresi (AcceptTransaction cursor + GetGerekliEvraklar) sırasında kayıt |
| Kök neden | Sunucu INSERT'i işledikten sonra yanıt istemciye ulaşmazsa (timeout 30 sn, ağ) uygulama hata gösterir ve kayıt başarısız sanılır; kullanıcı tekrar F2 basar. RefNo her nesnede yeni GUID olduğundan ve FisNo/hesap/tutar için benzersizlik yoktur, ikinci satır sessizce kabul edilir. |
| Neden zinciri | Belirti: Aynı işlem iki kez bakiye ve stoğa yazılır ↓ Teknik olay: Try RecId=db.ExecuteScalar() Catch … End Try ; If RecId>0 Then Id=RecId … Else Return False ↓ Yakın neden: Ağ kesintisi/uzun tetikleyici süresi (AcceptTransaction cursor + GetGerekliEvraklar) sırasında kayıt ↓ Kök neden: Sunucu INSERT'i işledikten sonra yanıt istemciye ulaşmazsa (timeout 30 sn, ağ) uygulama hata gösterir ve kayıt başarısız sanılır; kullanıcı ↓ Etkilenen veri: Aynı hesap/tarih/kod/yön/miktar/tutar ile 60 sn içinde ikinci aktif işlem olmamalı. |
| Etkilenen veri | Aynı hesap/tarih/kod/yön/miktar/tutar ile 60 sn içinde ikinci aktif işlem olmamalı. |
| Etkilenen iş süreci | Çift kayıt (duplicate posting) – zaman aşımı/ağ kopması sonrası tekrar kayıt |
| Olasılık / etki / güven | ORTA / S2 / 75 |
| Bilinen ticket | TD-01 teması; PRB-BAGLANTI-000 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT a.Id,b.Id FROM Cari.Islemler a JOIN Cari.Islemler b ON b.Id>a.Id AND b.HesapId=a.HesapId AND b.Tarih=a.Tarih AND b.IslemKodu=a.IslemKodu AND b.IslemTuru=a.IslemTuru AND ISNULL(b.Kodu,'')=ISNULL(a.Kodu,'') AND b.Miktar=a.Miktar AND b.Tutar=a.Tutar AND ABS(DATEDIFF(second,a.InsertDate,b.InsertDate))<=60 WHERE a.IsDeleted=0 AND b.IsDeleted=0 |
| Validation SQL (salt okunur) | SELECT a.Id,b.Id FROM Cari.Islemler a JOIN Cari.Islemler b ON b.Id>a.Id AND b.HesapId=a.HesapId AND b.Tarih=a.Tarih AND b.IslemKodu=a.IslemKodu AND b.IslemTuru=a.IslemTuru AND ISNULL(b.Kodu,'')=ISNULL(a.Kodu,'') AND b.Miktar=a.Miktar AND b.Tutar=a.Tutar AND ABS(DATEDIFF(second,a.InsertDate,b.InsertDate))<=60 WHERE a.IsDeleted=0 AND b.IsDeleted=0 |
| Test senaryosu | Girdi: Insert (InternalDb.ExecuteScalar → hata MsgBox, RecId=0), RefNo (her nesnede yeni GUID), unique index yok · Formül: Try RecId=db.ExecuteScalar() Catch … End Try ; If RecId>0 Then Id=RecId … Else Return False · Sınır: Ağ kesintisi/uzun tetikleyici süresi (AcceptTransaction cursor + GetGerekliEvraklar) sırasında kayıt |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Try RecId=db.ExecuteScalar() Catch … End Try ; If RecId>0 Then Id=RecId … Else Return False · Kanıt: InternalDb.ExecuteScalar: 'Catch ex As Exception MsgBox(ex.Message)' → Result Nothing; Cari.Islem.vb:702 'If RecId > 0' |
| İlişkili kayıtlar | ERR-POT-009, ERR-SIL-035, ERR-SIL-036, ERR-SIL-058, ERR-SIL-059 |
| Wiki bağlantıları | TD-01 · PRB-BAGLANTI-000 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-058 — SLR-027 Çok adımlı kayıt zincirlerinde transaction yokluğu (Insert→RsAktar, Save→SendTo karşı bacak, parite iki bacak, Update→Takoz.RaporYaz) S2 · MOD-CARI · Gözlemlendi: EVET · PF-004 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: TD-01, H-106, H-063, BR-VIRMAN-002) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E16 — Eksik Türetilmiş Kayıt |
| Severity | S2 — YÜKSEK |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-004 Rapor tasarımı / yeni rapor / sütun ekleme / bakiye ekstresi düzenleme (talep) |
| Kullanıcı belirtisi | İki hesabın bakiye toplamı sıfırlanmaz; parite ikinci döviz stoğu değişmez |
| Teknik belirti | İlk bacak yazıldıktan sonra ikinci adım (karşı hesap limiti/evrak/pasif şube nedeniyle trigger reddi, ağ) başarısız olursa uyarı çıkar ama ilk bacak kalır: virman/parite/transfer tek taraflı, RsAktar eksik. İptalde RefNo+IslemKodu ile karşı bacak aranır; farklı IslemKodu'lu eşler (yoksa) bulunmaz. |
| Kod dosyası | Class/Dao/Islem/Cari.Islem.vb:694-700, 987-993; Controls/Islem Ekranı/Ekran/iFormBase.vb:218-264; iFNakit.vb:180-300 |
| İlgili SQL nesneleri | Cari.Islemler |
| Tetikleme koşulu | Karşı hesapta zorunlu evrak eksik, limit aşımı, şube pasif; ağ kesintisi |
| Kök neden | İlk bacak yazıldıktan sonra ikinci adım (karşı hesap limiti/evrak/pasif şube nedeniyle trigger reddi, ağ) başarısız olursa uyarı çıkar ama ilk bacak kalır: virman/parite/transfer tek taraflı, RsAktar eksik. İptalde RefNo+IslemKodu ile karşı bacak aranır; farklı IslemKodu'lu eşler (yoksa) bulunmaz. |
| Neden zinciri | Belirti: İki hesabın bakiye toplamı sıfırlanmaz; parite ikinci döviz stoğu değişmez ↓ Teknik olay: RecId = db.ExecuteScalar() ; If RSAktar … db.ExecuteNonQuery("Cari.RSAktar " & RecId) ; … SendTo: I.Id=0; I.HesapId=karş ↓ Yakın neden: Karşı hesapta zorunlu evrak eksik, limit aşımı, şube pasif; ağ kesintisi ↓ Kök neden: İlk bacak yazıldıktan sonra ikinci adım (karşı hesap limiti/evrak/pasif şube nedeniyle trigger reddi, ağ) başarısız olursa uyarı çıkar ama i ↓ Etkilenen veri: Virman (IslemKodu=11) RefNo'su tam iki aktif satır taşımalı; parite birinci bacağının (VaryantId=-1) |
| Etkilenen veri | Virman (IslemKodu=11) RefNo'su tam iki aktif satır taşımalı; parite birinci bacağının (VaryantId=-1) ikinci bacağı (VaryantId=Id) bulunmalı. |
| Etkilenen iş süreci | Çok adımlı kayıt zincirlerinde transaction yokluğu (Insert→RsAktar, Save→SendTo karşı bacak, parite iki bacak, Update→Takoz.RaporYaz) |
| Olasılık / etki / güven | ORTA / S2 / 90 |
| Bilinen ticket | TD-01, H-106, H-063, BR-VIRMAN-002 |
| Ticket sayısı | 0 |
| Bilinen çözüm | TD-01 önerisi (tek SqlTransaction/TransactionScope) belgelenmiş, uygulanmamış → [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT RefNo,COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=11 GROUP BY RefNo HAVING COUNT(*)<>2; parite: SELECT a.Id FROM Cari.Islemler a WHERE a.IsDeleted=0 AND a.IslemKodu=3 AND a.VaryantId=-1 AND NOT EXISTS(SELECT 1 FROM Cari.Islemler b WHERE b.VaryantId=a.Id AND b.IsDeleted=0) |
| Validation SQL (salt okunur) | SELECT RefNo,COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=11 GROUP BY RefNo HAVING COUNT(*)<>2; parite: SELECT a.Id FROM Cari.Islemler a WHERE a.IsDeleted=0 AND a.IslemKodu=3 AND a.VaryantId=-1 AND NOT EXISTS(SELECT 1 FROM Cari.Islemler b WHERE b.VaryantId=a.Id AND b.IsDeleted=0) |
| Test senaryosu | Girdi: Cari.Islem.Insert/Update, iFormBase.SendTo, iFNakit.SaveCashTransaction · Formül: RecId = db.ExecuteScalar() ; If RSAktar … db.ExecuteNonQuery("Cari.RSAktar " & RecId) ; … SendTo: I.Id=0; I.HesapId=karşı; I.IslemTuru=GetKarsiIslemTu · Sınır: Karşı hesapta zorunlu evrak eksik, limit aşımı, şube pasif; ağ kesintisi |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: RecId = db.ExecuteScalar() ; If RSAktar … db.ExecuteNonQuery("Cari.RSAktar " & RecId) ; … SendTo: I.Id=0; I.HesapId=karşı; I.IslemTuru=GetKarsiIslemTuru; I.Save · Kanıt: Cari.Islem.vb:1055 karşı bacak sorgusu 'RefNo=… And IslemKodu=…'; iFormBase.vb:238 'Karşı Hesaba Transfer Edilemedi. Lütfen İşlemi Manuel Olarak Gerçekleştiriniz.' |
| İlişkili kayıtlar | ERR-SIL-035, ERR-SIL-036, ERR-SIL-057 |
| Wiki bağlantıları | TD-01 · H-106 · H-063 · BR-VIRMAN-002 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-059 — SLR-028 Cari.UpdateTransaction – çok satırlı UPDATE'te tek satır değişkeni; Mutabakat güncellemesi history üretmez S3 · MOD-CARI · Gözlemlendi: HAYIR · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E16 — Eksik Türetilmiş Kayıt |
| Severity | S3 — ORTA |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Belge havuzunda iptal edilmiş işlem 'F' durumunda kalır; history eksik |
| Teknik belirti | RefNo/FisNo ile toplu iptalde yalnız rastgele bir satırın IslemDetaylari kaydı silinir/EIPTAL yapılır; diğer satırların belge detayları aktif kalır (belge havuzu görünümü iptal edilmiş işlemi belgeli sayabilir). Mutabakat ve Mutabakat ile birlikte başka alan değişen güncellemelerde hiç history yazılmaz. |
| Kod dosyası | Cari.UpdateTransaction (modules.json) |
| İlgili SQL nesneleri | Cari.UpdateTransaction, Cari.IslemDetaylari, Cari.Islemler, Cari.History |
| SQL Object | Cari.UpdateTransaction (modules.json) |
| Tetikleme koşulu | Birden çok satırı etkileyen UPDATE; Mutabakat kolonunu içeren UPDATE |
| Kök neden | RefNo/FisNo ile toplu iptalde yalnız rastgele bir satırın IslemDetaylari kaydı silinir/EIPTAL yapılır; diğer satırların belge detayları aktif kalır (belge havuzu görünümü iptal edilmiş işlemi belgeli sayabilir). Mutabakat ve Mutabakat ile birlikte başka alan değişen güncellemelerde hiç history yazılmaz. |
| Neden zinciri | Belirti: Belge havuzunda iptal edilmiş işlem 'F' durumunda kalır; history eksik ↓ Teknik olay: Select @IsDeleted=I.IsDeleted, @IslemId=D.IslemId, @Ettn=D.ETTN from inserted I Left Join IslemDetaylari D … (tek değer) ↓ Yakın neden: Birden çok satırı etkileyen UPDATE; Mutabakat kolonunu içeren UPDATE ↓ Kök neden: RefNo/FisNo ile toplu iptalde yalnız rastgele bir satırın IslemDetaylari kaydı silinir/EIPTAL yapılır; diğer satırların belge detayları akti ↓ Etkilenen veri: İptal edilmiş (IsDeleted=1) ve e-belgesi olmayan işlemin IslemDetaylari satırı kalmamalı; her işlemi |
| Etkilenen veri | İptal edilmiş (IsDeleted=1) ve e-belgesi olmayan işlemin IslemDetaylari satırı kalmamalı; her işlemin en az bir History satırı olmalı. |
| Etkilenen iş süreci | Cari.UpdateTransaction – çok satırlı UPDATE'te tek satır değişkeni; Mutabakat güncellemesi history üretmez |
| Olasılık / etki / güven | ORTA / S3 / 85 |
| Bilinen ticket | HAYIR (H-105 history okuma akışı) |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT D.IslemId FROM Cari.IslemDetaylari D JOIN Cari.Islemler I ON I.Id=D.IslemId WHERE I.IsDeleted=1 AND ISNULL(D.ETTN,'')='' ; SELECT I.Id FROM Cari.Islemler I WHERE NOT EXISTS(SELECT 1 FROM Cari.History H WHERE H.TransactionId=I.Id) |
| Validation SQL (salt okunur) | SELECT D.IslemId FROM Cari.IslemDetaylari D JOIN Cari.Islemler I ON I.Id=D.IslemId WHERE I.IsDeleted=1 AND ISNULL(D.ETTN,'')='' ; SELECT I.Id FROM Cari.Islemler I WHERE NOT EXISTS(SELECT 1 FROM Cari.History H WHERE H.TransactionId=I.Id) |
| Test senaryosu | Girdi: Inserted/Deleted (çok satır), Cari.IslemDetaylari.ETTN · Formül: Select @IsDeleted=I.IsDeleted, @IslemId=D.IslemId, @Ettn=D.ETTN from inserted I Left Join IslemDetaylari D … (tek değer) ; Set @Status=(Select top 1 … · Sınır: Birden çok satırı etkileyen UPDATE; Mutabakat kolonunu içeren UPDATE |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Select @IsDeleted=I.IsDeleted, @IslemId=D.IslemId, @Ettn=D.ETTN from inserted I Left Join IslemDetaylari D … (tek değer) ; Set @Status=(Select top 1 … From Inserted) ; if NOT Update(Mutabakat) … · Kanıt: 'Select @IsDeleted =I.IsDeleted, @IslemId =D.IslemId , @Ettn =D.ETTN from inserted I Left Join Cari.IslemDetaylari D on D.IslemId =I.Id' |
| İlişkili kayıtlar | ERR-POT-002, ERR-POT-008, ERR-POT-009, ERR-SIL-001, ERR-SIL-002, ERR-SIL-003, ERR-SIL-028, ERR-SIL-056, ERR-SIL-057 |
| Wiki bağlantıları | H-105 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-060 — SLR-029 Uygulama yuvarlama yardımcıları: .Round(n) uzantısı keser (truncate) ve hane parametresini yok sayar; Math.Round banker's; ToNumeric/TextN kültür varsayımı S4 · MOD-FINANS · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: CTR-010, BR-BSMV-003/004) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E08 — Yuvarlama / Hassasiyet Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-FINANS |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Vergi tutarı 1 kuruş eksik; ekran ile SQL raporu arasında kuruş farkı; parite TL bacağı ±0,5 TL |
| Teknik belirti | Vadeli ve hızlı satışta BSMV = (Tutar×BSMV/1000).Round(2) her zaman aşağı kesilir (12,999→12,99), hane parametresi 2'ye sabittir, bilimsel gösterim (1E-05) ve kültür ayarı '.' değilse Catch ile yuvarlanmadan döner. Nakit/parite ekranı Math.Round (bankacı yuvarlama) kullanırken SQL Convert(decimal(18,2)) yarım-yukarı yuvarlar → 0,005'lik değerlerde ekran/rapor farkı. Parite tutarları 0 haneye yuvarlanır (Round(...,0)). |
| Kod dosyası | Class/Module/Extention.vb:437-450, 366-368; Controls/Editor/TexBoxEdit.vb:100-105; iFVadeli.vb:755; HizliSatisEkrani.vb:688-737; iFNakit.vb:452,463-471; iFDoviz.vb:95-181 |
| İlgili SQL nesneleri | Sistem.Settings, Cari.Islemler |
| Tetikleme koşulu | BSMV küsuratı 3. hanede ≥5; tutar×fiyat tam yarım kuruş; kültür/ondalık ayarı farklı iş parçacığı |
| Kök neden | Vadeli ve hızlı satışta BSMV = (Tutar×BSMV/1000).Round(2) her zaman aşağı kesilir (12,999→12,99), hane parametresi 2'ye sabittir, bilimsel gösterim (1E-05) ve kültür ayarı '.' değilse Catch ile yuvarlanmadan döner. Nakit/parite ekranı Math.Round (bankacı yuvarlama) kullanırken SQL Convert(decimal(18,2)) yarım-yukarı yuvarlar → 0,005'lik değerlerde ekran/rapor farkı. Parite tutarları 0 haneye yuvarlanır (Round(...,0)). |
| Neden zinciri | Belirti: Vergi tutarı 1 kuruş eksik; ekran ile SQL raporu arasında kuruş farkı; parite TL bacağı ±0,5 TL ↓ Teknik olay: Round(Value,Decimals): Values=Value.ToString.Split(".") ; Result=Values(0)+"."+Left(Values(1),2) ; Val(Result) ; ToNumer ↓ Yakın neden: BSMV küsuratı 3. hanede ≥5; tutar×fiyat tam yarım kuruş; kültür/ondalık ayarı farklı iş parçacığı ↓ Kök neden: Vadeli ve hızlı satışta BSMV = (Tutar×BSMV/1000).Round(2) her zaman aşağı kesilir (12,999→12,99), hane parametresi 2'ye sabittir, bilimsel g ↓ Etkilenen veri: Kayıtlı BSMV, (Tutar−BSMV)×BSMVOran/1000 değerine ±0,01 toleransla eşit olmalı. |
| Etkilenen veri | Kayıtlı BSMV, (Tutar−BSMV)×BSMVOran/1000 değerine ±0,01 toleransla eşit olmalı. |
| Etkilenen iş süreci | Uygulama yuvarlama yardımcıları: .Round(n) uzantısı keser (truncate) ve hane parametresini yok sayar; Math.Round banker's; ToNumeric/TextN kültür varsayımı |
| Olasılık / etki / güven | YÜKSEK / S4 / 90 |
| Bilinen ticket | CTR-010, BR-BSMV-003/004 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT Id,Tutar,BSMV,ROUND((Tutar-BSMV)*(SELECT BSMV FROM Sistem.Settings)/1000,2) AS BSMVHesap FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu IN (3,6) AND BSMV<>0 AND ABS(BSMV-ROUND((Tutar-BSMV)*(SELECT BSMV FROM Sistem.Settings)/1000,2))>0.011 |
| Validation SQL (salt okunur) | SELECT Id,Tutar,BSMV,ROUND((Tutar-BSMV)*(SELECT BSMV FROM Sistem.Settings)/1000,2) AS BSMVHesap FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu IN (3,6) AND BSMV<>0 AND ABS(BSMV-ROUND((Tutar-BSMV)*(SELECT BSMV FROM Sistem.Settings)/1000,2))>0.011 |
| Test senaryosu | Girdi: Double değerler (BSMV, tutar), Utils.Culture (ondalık '.', binlik ',') · Formül: Round(Value,Decimals): Values=Value.ToString.Split(".") ; Result=Values(0)+"."+Left(Values(1),2) ; Val(Result) ; ToNumeric = Val(Replace(Value,",","") · Sınır: BSMV küsuratı 3. hanede ≥5; tutar×fiyat tam yarım kuruş; kültür/ondalık ayarı farklı iş parçacığı |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Round(Value,Decimals): Values=Value.ToString.Split(".") ; Result=Values(0)+"."+Left(Values(1),2) ; Val(Result) ; ToNumeric = Val(Replace(Value,",","")) ; Math.Round(x,2) = MidpointRounding.ToEven · Kanıt: Extention.vb:441 'Dim Result As String = Values(0) + "." + Left(Values(1), 2)' (Decimals kullanılmıyor, kesme) |
| İlişkili kayıtlar | ERR-OBS-057, ERR-SIL-061 |
| Wiki bağlantıları | BR-BSMV-003 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-061 — SLR-030 Nakit BSMV geri hesabı (Tutar'dan fiyat) ileri formülün tersi değil S4 · MOD-FINANS · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: BR-BSMV-003, CTR-010) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-FINANS |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Belge vergi tutarı ile işlem BSMV alanı farklı; tutar 40 kuruş sapar |
| Teknik belirti | Tutar elle girildiğinde net tutar ve fiyat yaklaşık hesaplanır; ardından TutarHesapla yeniden tetiklenirse Tutar ilk girilenden farklı olur (100.000 → 99.999,60). Kayıtlı BSMV ile Tutar arasındaki ilişki işlemden işleme değişir; e-belge vergi matrahı (Calc.BSMV) farklı formülle (BSMVOran) hesaplandığından belge ile işlem satırı uyuşmayabilir. |
| Kod dosyası | Controls/Islem Ekranı/Ekran/iFNakit.vb:440-472; Class/Module/ExtensionEx.vb:16-44 |
| İlgili SQL nesneleri | Cari.Islemler |
| Tetikleme koşulu | IsBsmv ve Tutar elle girilmiş; BSMV ayarı Dahil/Hariç |
| Kök neden | Tutar elle girildiğinde net tutar ve fiyat yaklaşık hesaplanır; ardından TutarHesapla yeniden tetiklenirse Tutar ilk girilenden farklı olur (100.000 → 99.999,60). Kayıtlı BSMV ile Tutar arasındaki ilişki işlemden işleme değişir; e-belge vergi matrahı (Calc.BSMV) farklı formülle (BSMVOran) hesaplandığından belge ile işlem satırı uyuşmayabilir. |
| Neden zinciri | Belirti: Belge vergi tutarı ile işlem BSMV alanı farklı; tutar 40 kuruş sapar ↓ Teknik olay: İleri: BSMV = Net×BSMV/1000 ; TUTAR = Round(Net+BSMV,2) ; Geri (TxtTutar LostFocus): Net ≈ Tutar − Tutar×BSMV/1000 (br ↓ Yakın neden: IsBsmv ve Tutar elle girilmiş; BSMV ayarı Dahil/Hariç ↓ Kök neden: Tutar elle girildiğinde net tutar ve fiyat yaklaşık hesaplanır; ardından TutarHesapla yeniden tetiklenirse Tutar ilk girilenden farklı olur ↓ Etkilenen veri: Nakit satırında Tutar = Miktar×Fiyat + BSMV (±0,01) olmalı. |
| Etkilenen veri | Nakit satırında Tutar = Miktar×Fiyat + BSMV (±0,01) olmalı. |
| Etkilenen iş süreci | Nakit BSMV geri hesabı (Tutar'dan fiyat) ileri formülün tersi değil |
| Olasılık / etki / güven | YÜKSEK / S4 / 85 |
| Bilinen ticket | BR-BSMV-003, CTR-010 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT Id,Tutar,BSMV,Miktar,Fiyat, Miktar*Fiyat AS Net FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=3 AND BSMV<>0 AND ABS((Miktar*Fiyat+BSMV)-Tutar)>0.011 |
| Validation SQL (salt okunur) | SELECT Id,Tutar,BSMV,Miktar,Fiyat, Miktar*Fiyat AS Net FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=3 AND BSMV<>0 AND ABS((Miktar*Fiyat+BSMV)-Tutar)>0.011 |
| Test senaryosu | Girdi: TxtTutar (BSMV dahil), GlobalSettings.BSMV (binde), IsBsmv · Formül: İleri: BSMV = Net×BSMV/1000 ; TUTAR = Round(Net+BSMV,2) ; Geri (TxtTutar LostFocus): Net ≈ Tutar − Tutar×BSMV/1000 (brütten kesinti) · Sınır: IsBsmv ve Tutar elle girilmiş; BSMV ayarı Dahil/Hariç |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: İleri: BSMV = Net×BSMV/1000 ; TUTAR = Round(Net+BSMV,2) ; Geri (TxtTutar LostFocus): Net ≈ Tutar − Tutar×BSMV/1000 (brütten kesinti) · Kanıt: iFNakit.vb:460 'If IsBsmv = True Then Tutar -= (Tutar * Program.GlobalSettings.BSMV).Divide(1000)' |
| İlişkili kayıtlar | ERR-OBS-057, ERR-SIL-060 |
| Wiki bağlantıları | BR-BSMV-003 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-062 — SLR-031 Maliyet/İşçilik hesabı Double ile; negatif işçilik 0'a çekilir; kur 0 ise işçilik 0 S3 · MOD-CARI · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: BR-MALIYET-001, GAP-DOC-05, GAP-SEC-ISCILIK-02) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E08 — Yuvarlama / Hassasiyet Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Kâr raporunda alış iskontosu kaybolur; maliyet 0 |
| Teknik belirti | Müşteriden metal değerinin altında alış (negatif işçilik = iskonto) 0 işçilikle kaydedilir; StokHaraketleri.Maliyet (=Iscilik×Kur) 0 olur, gerçek kazanç maliyet raporunda görünmez. Maliyet birimi kuru 0/eksikse Divide 0 döndürür ve işçilik sessizce 0 yazılır. Tüm hesap Double'dır; decimal(18,2) kolonlara dönüşümde bankacı/yarım-yukarı farkı. |
| Kod dosyası | Class/Ext/Cari.IslemEx.vb:122-146, 185-212 |
| İlgili SQL nesneleri | Cari.Islemler |
| Tetikleme koşulu | TutarMaliyeti < MiktarMaliyeti (iskontolu alış); MaliyetBirim kuru 0; kur listesi eksik |
| Kök neden | Müşteriden metal değerinin altında alış (negatif işçilik = iskonto) 0 işçilikle kaydedilir; StokHaraketleri.Maliyet (=Iscilik×Kur) 0 olur, gerçek kazanç maliyet raporunda görünmez. Maliyet birimi kuru 0/eksikse Divide 0 döndürür ve işçilik sessizce 0 yazılır. Tüm hesap Double'dır; decimal(18,2) kolonlara dönüşümde bankacı/yarım-yukarı farkı. |
| Neden zinciri | Belirti: Kâr raporunda alış iskontosu kaybolur; maliyet 0 ↓ Teknik olay: MiktarMaliyeti=(Miktar×AuMilyem)×AnaBirim.Price ; Giriş: Iscilik=(TutarMaliyeti−MiktarMaliyeti).Divide(MaliyetBirim.Pric ↓ Yakın neden: TutarMaliyeti < MiktarMaliyeti (iskontolu alış); MaliyetBirim kuru 0; kur listesi eksik ↓ Kök neden: Müşteriden metal değerinin altında alış (negatif işçilik = iskonto) 0 işçilikle kaydedilir; StokHaraketleri.Maliyet (=Iscilik×Kur) 0 olur, g ↓ Etkilenen veri: Girişte Iscilik×IscilikBirimKur ≈ Tutar×BirimKur − Miktar×AuMilyem×HasKur (negatif değer 0'a çekilme |
| Etkilenen veri | Girişte Iscilik×IscilikBirimKur ≈ Tutar×BirimKur − Miktar×AuMilyem×HasKur (negatif değer 0'a çekilmemeli). |
| Etkilenen iş süreci | Maliyet/İşçilik hesabı Double ile; negatif işçilik 0'a çekilir; kur 0 ise işçilik 0 |
| Olasılık / etki / güven | ORTA / S3 / 80 |
| Bilinen ticket | BR-MALIYET-001, GAP-DOC-05, GAP-SEC-ISCILIK-02 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT Id,Miktar,AuMilyem,HasKur,Tutar,BirimKur,Iscilik FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu IN (1,9) AND IslemTuru=0 AND IslemTipi NOT IN (1,2,5) AND Iscilik=0 AND (Tutar*BirimKur) < (Miktar*AuMilyem*HasKur) |
| Validation SQL (salt okunur) | SELECT Id,Miktar,AuMilyem,HasKur,Tutar,BirimKur,Iscilik FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu IN (1,9) AND IslemTuru=0 AND IslemTipi NOT IN (1,2,5) AND Iscilik=0 AND (Tutar*BirimKur) < (Miktar*AuMilyem*HasKur) |
| Test senaryosu | Girdi: Miktar, AuMilyem, AnaBirim.Price, TutarBirim.Price, MaliyetBirim.Price (bellek kur listesi Alis) · Formül: MiktarMaliyeti=(Miktar×AuMilyem)×AnaBirim.Price ; Giriş: Iscilik=(TutarMaliyeti−MiktarMaliyeti).Divide(MaliyetBirim.Price) ; If Iscilik<0 Then Iscilik · Sınır: TutarMaliyeti < MiktarMaliyeti (iskontolu alış); MaliyetBirim kuru 0; kur listesi eksik |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: MiktarMaliyeti=(Miktar×AuMilyem)×AnaBirim.Price ; Giriş: Iscilik=(TutarMaliyeti−MiktarMaliyeti).Divide(MaliyetBirim.Price) ; If Iscilik<0 Then Iscilik=0 ; Maliyet=Satis=TutarMaliyeti · Kanıt: Cari.IslemEx.vb:144 'If Iscilik < 0 Then Iscilik = 0'; :135 '.Divide(MaliyetBirim.Price)' |
| İlişkili kayıtlar | ERR-SIL-056 |
| Wiki bağlantıları | BR-MALIYET-001 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-063 — SLR-032 Bilanco.OzetBilanco – kalemler farklı kesim tarihleri ve varsayımlarla toplanır S3 · MOD-RAPOR · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-128, H-129, H-130, CTR-SYM-TAKOZ-01, PRB-BILANCO-000) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E08 — Yuvarlama / Hassasiyet Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-RAPOR |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Bilanço eksi/artı sapar; günlük kâr-zarar yanlış; pozisyon ile bilanço tutmaz |
| Teknik belirti | Geçmiş tarihli bilanço masraf hesaplarının bugüne kadarki tüm bakiyesini içerirken diğer kalemler kesim tarihine kadar alınır; hizmet gelir/gideri yalnız kesim günü toplanır; raporsuz takoz bilançoda 0,6, pozisyonda 0 ile değerlenir; kur listesi eksikse Net 0. Uygulama KÂR/ZARAR = TOPLAM−DEVİR olarak önceki satırla hesaplandığından her hata bir sonraki güne taşınır (SaveAll o günü silip yeniden yazar). |
| Kod dosyası | Bilanco.OzetBilanco, Bilanco.SaveAll, Pozisyon.Write (modules.json); Class/Ext/Sistem.Bilanco.vb:172-211 |
| İlgili SQL nesneleri | Bilanco.OzetBilanco, Bilanco.Bilancolar |
| Tetikleme koşulu | Geçmiş tarih için bilanço; masraf hareketi olan dönem; raporsuz takoz stoğu; kur eksik gün |
| Kök neden | Geçmiş tarihli bilanço masraf hesaplarının bugüne kadarki tüm bakiyesini içerirken diğer kalemler kesim tarihine kadar alınır; hizmet gelir/gideri yalnız kesim günü toplanır; raporsuz takoz bilançoda 0,6, pozisyonda 0 ile değerlenir; kur listesi eksikse Net 0. Uygulama KÂR/ZARAR = TOPLAM−DEVİR olarak önceki satırla hesaplandığından her hata bir sonraki güne taşınır (SaveAll o günü silip yeniden yazar). |
| Neden zinciri | Belirti: Bilanço eksi/artı sapar; günlük kâr-zarar yanlış; pozisyon ile bilanço tutmaz ↓ Teknik olay: BAKIYE: B.Tarih<=@Tarih … GELIR/GIDER(masraf bakiyesi): Where H.HesapTuru=4 (tarih yok) ; GELİR/GİDER(hizmet): Tarih>S.R ↓ Yakın neden: Geçmiş tarih için bilanço; masraf hareketi olan dönem; raporsuz takoz stoğu; kur eksik gün ↓ Kök neden: Geçmiş tarihli bilanço masraf hesaplarının bugüne kadarki tüm bakiyesini içerirken diğer kalemler kesim tarihine kadar alınır; hizmet gelir/ ↓ Etkilenen veri: Aynı kesim tarihi için bilanço yeniden hesaplandığında arşivlenen (Bilancolar) değerle eşit olmalı. |
| Etkilenen veri | Aynı kesim tarihi için bilanço yeniden hesaplandığında arşivlenen (Bilancolar) değerle eşit olmalı. |
| Etkilenen iş süreci | Bilanco.OzetBilanco – kalemler farklı kesim tarihleri ve varsayımlarla toplanır |
| Olasılık / etki / güven | YÜKSEK / S3 / 70 |
| Bilinen ticket | H-128, H-129, H-130, CTR-SYM-TAKOZ-01, PRB-BILANCO-000 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | Aynı @Tarih için Bilanco.OzetBilanco'yu iki farklı günde çalıştırıp Bilanco.Bilancolar arşiviyle karşılaştırın: SELECT Tarih,SubeId,Cinsi,Kodu,Bakiye FROM Bilanco.Bilancolar WHERE Tarih=@T EXCEPT SELECT @T,SubeId,Cinsi,Kodu,Bakiye FROM Bilanco.OzetBilanco(@Sube,@T) |
| Validation SQL (salt okunur) | Aynı @Tarih için Bilanco.OzetBilanco'yu iki farklı günde çalıştırıp Bilanco.Bilancolar arşiviyle karşılaştırın: SELECT Tarih,SubeId,Cinsi,Kodu,Bakiye FROM Bilanco.Bilancolar WHERE Tarih=@T EXCEPT SELECT @T,SubeId,Cinsi,Kodu,Bakiye FROM Bilanco.OzetBilanco(@Sube,@T) |
| Test senaryosu | Girdi: Cari.BakiyeIslem (Tarih<=@Tarih), masraf hesapları (HesapTuru=4, tarih süzgeci yok), IslemKodu=5 GELİR/GİDER (Tarih=@Tarih tek gün), takoz 0,6, GetKur · Formül: BAKIYE: B.Tarih<=@Tarih … GELIR/GIDER(masraf bakiyesi): Where H.HesapTuru=4 (tarih yok) ; GELİR/GİDER(hizmet): Tarih>S.RevCostDate And Tarih=@Tarih ; · Sınır: Geçmiş tarih için bilanço; masraf hareketi olan dönem; raporsuz takoz stoğu; kur eksik gün |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: BAKIYE: B.Tarih<=@Tarih … GELIR/GIDER(masraf bakiyesi): Where H.HesapTuru=4 (tarih yok) ; GELİR/GİDER(hizmet): Tarih>S.RevCostDate And Tarih=@Tarih ; TAKOZ: R='False' ⇒ Miktar*0.6 ; Net = Bol(Bakiye*K · Kanıt: OzetBilanco: 'Where H.HesapTuru =4 group by Br.Kodu ,h.SubeId' (Tarih koşulu yok); '(Tarih>S.RevCostDate And Tarih =@Tarih)' |
| Wiki bağlantıları | H-128 · H-129 · H-130 · SYM-TAKOZ · PRB-BILANCO-000 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-064 — SLR-033 Bilanco.GetIKar – parametre/sabit karışıklığı (KasaId=SubeId, BirimId=1=HAS, Satis kuru, ham bölme) S3 · MOD-RAPOR · Gözlemlendi: HAYIR · PF-023 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | HAYIR · Observed=HAYIR · Potential=EVET · Silent=EVET |
| Runtime durumu | DOĞRULANMADI — statik analiz bulgusu; çalışma zamanında yeniden üretilmedi (Gözlemlendi: HAYIR) |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-RAPOR |
| Alt modül | Hesaplama |
| Problem ailesi | PF-023 Birim (para birimi) tanımlama / listede görünmüyor / çarpan / çift birim |
| Kullanıcı belirtisi | İşlem bazlı kâr raporu boş/yanlış |
| Teknik belirti | Kasa kimliği şube kimliği yerine kullanılır (yalnız Id'ler çakışırsa sonuç döner); HAS için Id=1 varsayımı; bakiye satış kuruyla, stok alış kuruyla değerlenir; FN.Bol yerine ham bölme (kur 0'da hata – sessiz değil ama kur yoksa NULL çarpımı sessiz NULL). |
| Kod dosyası | Bilanco.GetIKar (modules.json) |
| İlgili SQL nesneleri | Bilanco.GetIKar, FN.Bol, Sistem.Kasalar, Sistem.Birimler |
| SQL Object | Bilanco.GetIKar (modules.json) |
| Tetikleme koşulu | KasaId≠SubeId kurulum; BirimId 1 ≠ HAS; kur eksik |
| Kök neden | Kasa kimliği şube kimliği yerine kullanılır (yalnız Id'ler çakışırsa sonuç döner); HAS için Id=1 varsayımı; bakiye satış kuruyla, stok alış kuruyla değerlenir; FN.Bol yerine ham bölme (kur 0'da hata – sessiz değil ama kur yoksa NULL çarpımı sessiz NULL). |
| Neden zinciri | Belirti: İşlem bazlı kâr raporu boş/yanlış ↓ Teknik olay: Where B.KasaId=@SubeId … Bakiye*Kur.Satis / kur1.Alis (Kur1.BirimId=1) ↓ Yakın neden: KasaId≠SubeId kurulum; BirimId 1 ≠ HAS; kur eksik ↓ Kök neden: Kasa kimliği şube kimliği yerine kullanılır (yalnız Id'ler çakışırsa sonuç döner); HAS için Id=1 varsayımı; bakiye satış kuruyla, stok alış ↓ Etkilenen veri: Rapor fonksiyonları HAS birimini Settings.HasSymbol üzerinden çözmeli, sabit Id kullanmamalı. |
| Etkilenen veri | Rapor fonksiyonları HAS birimini Settings.HasSymbol üzerinden çözmeli, sabit Id kullanmamalı. |
| Etkilenen iş süreci | Bilanco.GetIKar – parametre/sabit karışıklığı (KasaId=SubeId, BirimId=1=HAS, Satis kuru, ham bölme) |
| Olasılık / etki / güven | ORTA / S3 / 75 |
| Bilinen ticket | HAYIR (PRB-RAPOR-000) |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*) FROM Sistem.Kasalar K WHERE K.Id<>K.SubeId; SELECT Kodu FROM Sistem.Birimler WHERE Id=1 |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Sistem.Kasalar K WHERE K.Id<>K.SubeId; SELECT Kodu FROM Sistem.Birimler WHERE Id=1 |
| Test senaryosu | Girdi: Cari.BakiyeIslem.KasaId (SubeId parametresiyle karşılaştırılır), GetKurListesi BirimId=1, Kur.Satis · Formül: Where B.KasaId=@SubeId … Bakiye*Kur.Satis / kur1.Alis (Kur1.BirimId=1) · Sınır: KasaId≠SubeId kurulum; BirimId 1 ≠ HAS; kur eksik |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Where B.KasaId=@SubeId … Bakiye*Kur.Satis / kur1.Alis (Kur1.BirimId=1) · Kanıt: 'Where B.KasaId =@SubeId and B.Tarih =@Tarih' ; 'Kur1 on Kur1.BirimId =1' |
| İlişkili kayıtlar | ERR-OBS-070, ERR-POT-023, ERR-POT-033, ERR-POT-138, ERR-SIL-026, ERR-SIL-036, ERR-SIL-041 |
| Wiki bağlantıları | PRB-RAPOR-000 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-065 — SLR-034 Sistem.Devir (SQL) – açılış satırlarında has/milyem sıfır, takoz/pırlanta stokları ve tarihsiz satırlar düşer, 2 hane yuvarlama S2 · MOD-SISTEM · Gözlemlendi: EVET · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-108, H-111, H-130, GAP-DEVIR-SCOPE, CTR-034, PRB-DEVIR-000, H-006) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E08 — Yuvarlama / Hassasiyet Hatası |
| Severity | S2 — YÜKSEK |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Devir sonrası stok has/milyem/maliyet yanlış; takoz çıkışı engellenir veya eksi adet; bakiye eksik |
| Teknik belirti | Devir sonrası maden açılış hareketinin Has=0 ve Milyem=0 olduğu için GetOrtMilyem/GetMadenStok has stoğu ve ortalama milyem sessizce bozulur; takoz (StokTipi 3) ve pırlanta (4) adet stokları sıfırlanır (GetTakozAdet 0 → 'takoz stokta yok'); Tarih NULL satırlar hiçbir dilime girmediği için kaybolur; miktar/has 2 haneye yuvarlanır; maliyet devir günü değil çalıştırma günü kuruyla çevrilir. Tetikleyiciler kapatılıp açılır; arada hata olursa açık kalmayabilir (H-006). |
| Kod dosyası | Sistem.Devir (modules.json) |
| İlgili SQL nesneleri | Sistem.Devir, Stok.StokHaraketleri, Cari.BakiyeIslem |
| SQL Object | Sistem.Devir (modules.json) |
| Tetikleme koşulu | Yıl sonu devri; devir öncesi alınıp sonra çıkılan takoz; Tarih NULL kayıt; devirin kesim tarihinden sonra çalıştırılması |
| Kök neden | Devir sonrası maden açılış hareketinin Has=0 ve Milyem=0 olduğu için GetOrtMilyem/GetMadenStok has stoğu ve ortalama milyem sessizce bozulur; takoz (StokTipi 3) ve pırlanta (4) adet stokları sıfırlanır (GetTakozAdet 0 → 'takoz stokta yok'); Tarih NULL satırlar hiçbir dilime girmediği için kaybolur; miktar/has 2 haneye yuvarlanır; maliyet devir günü değil çalıştırma günü kuruyla çevrilir. Tetikleyiciler kapatılıp açılır; arada hata olursa açık kalmayabilir (H-006). |
| Neden zinciri | Belirti: Devir sonrası stok has/milyem/maliyet yanlış; takoz çıkışı engellenir veya eksi adet; bakiye eksik ↓ Teknik olay: #TBLStokHaraketleri(Miktar dec(18,2), Has dec(18,2)) ; maden açılış: 0 as Milyem, 0 as Has, Maliyet*K.Alis(bugün) ; trun ↓ Yakın neden: Yıl sonu devri; devir öncesi alınıp sonra çıkılan takoz; Tarih NULL kayıt; devirin kesim tarihinden ↓ Kök neden: Devir sonrası maden açılış hareketinin Has=0 ve Milyem=0 olduğu için GetOrtMilyem/GetMadenStok has stoğu ve ortalama milyem sessizce bozulur ↓ Etkilenen veri: Devir açılış satırları (IslemId=-1) StokTipi 1 için Has ve Milyem taşımalı; StokHaraketleri/BakiyeIs |
| Etkilenen veri | Devir açılış satırları (IslemId=-1) StokTipi 1 için Has ve Milyem taşımalı; StokHaraketleri/BakiyeIslem'de Tarih NULL satır olmamalı; devir öncesi/sonrası bakiye toplamları hesap+birim bazında eşit olmalı. |
| Etkilenen iş süreci | Sistem.Devir (SQL) – açılış satırlarında has/milyem sıfır, takoz/pırlanta stokları ve tarihsiz satırlar düşer, 2 hane yuvarlama |
| Olasılık / etki / güven | ORTA / S2 / 85 |
| Bilinen ticket | H-108, H-111, H-130, GAP-DEVIR-SCOPE, CTR-034, PRB-DEVIR-000, H-006 |
| Ticket sayısı | 0 |
| Bilinen çözüm | H-108/H-130 operasyonel çözümleri wikide (arşivle karşılaştırma, takoz çıkışını devir öncesine yapma); kod düzeltmesi [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT * FROM Stok.StokHaraketleri WHERE IslemId=-1 AND StokTipi=1 AND (Has=0 OR Milyem=0) AND Miktar<>0; SELECT COUNT(*) FROM Stok.StokHaraketleri WHERE Tarih IS NULL; SELECT COUNT(*) FROM Cari.BakiyeIslem WHERE Tarih IS NULL; SELECT StokId,SUM(Adet) FROM Stok.StokHaraketleri WHERE StokTipi=3 GROUP BY StokId HAVING SUM(Adet)<0 |
| Validation SQL (salt okunur) | SELECT * FROM Stok.StokHaraketleri WHERE IslemId=-1 AND StokTipi=1 AND (Has=0 OR Milyem=0) AND Miktar<>0; SELECT COUNT(*) FROM Stok.StokHaraketleri WHERE Tarih IS NULL; SELECT COUNT(*) FROM Cari.BakiyeIslem WHERE Tarih IS NULL; SELECT StokId,SUM(Adet) FROM Stok.StokHaraketleri WHERE StokTipi=3 GROUP BY StokId HAVING SUM(Adet)<0 |
| Test senaryosu | Girdi: Stok.GetNakitStoklari/GetMadenStoklari(@Tarih-1), Stok.StokHaraketleri (StokTipi 1,2), Cari.BakiyeIslem (Tarih<@Tarih), GetKurListesi(getdate()) · Formül: #TBLStokHaraketleri(Miktar dec(18,2), Has dec(18,2)) ; maden açılış: 0 as Milyem, 0 as Has, Maliyet*K.Alis(bugün) ; truncate StokHaraketleri/BakiyeIsl · Sınır: Yıl sonu devri; devir öncesi alınıp sonra çıkılan takoz; Tarih NULL kayıt; devirin kesim tarihinden sonra çalıştırılması |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: #TBLStokHaraketleri(Miktar dec(18,2), Has dec(18,2)) ; maden açılış: 0 as Milyem, 0 as Has, Maliyet*K.Alis(bugün) ; truncate StokHaraketleri/BakiyeIslem ; yalnız StokTipi in (1,2) ; Tarih<@Tarih / Tar · Kanıt: 'Select -1 as IslemId,0 as Bolum,…,1 as StokTipi,M.Id as StokId,0 as Adet,Miktar,0 as Milyem,0 as Has,convert( decimal(18,2), Maliyet * K.Alis) as Maliyet … From Stok.GetMadenStoklari (0,0,dateadd(day,-1,@Tarih),0)' |
| Wiki bağlantıları | H-108 · H-111 · H-130 · PRB-DEVIR-000 · H-006 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-066 — SLR-035 Devir.vb (uygulama devri) – Sum(Milyem) ile açılış satırı, tarih=çalıştırma günü, transaction yok S1 · MOD-SISTEM · Gözlemlendi: EVET · PF-036 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: CTR-034, GAP-PROCESS-03, H-108) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E08 — Yuvarlama / Hassasiyet Hatası |
| Severity | S1 — KRİTİK |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Problem ailesi | PF-036 Yıl sonu devir işlemi ve devir sonrası fark |
| Kullanıcı belirtisi | Devir açılış satırında Milyem>1; stok has/maliyet yanlış; tam veri kaybı riski |
| Teknik belirti | Milyem sütunu toplanır (100 satır × 0,916 = 91,6) → NetBakiye hesaplanan sütunu ve GetStokHareketleri'nin Has=Miktar×Milyem gösterimi anlamsız; giriş/çıkış satırları ayrı toplandığı için LIFO maliyet/ortalama milyem yalnız giriş satırlarını görür; takoz/pırlanta yine düşer; Tarih=GETDATE (kesim değil); truncate ile insert arasında transaction yok – hata halinde tablolar boş kalır (yedek dışında geri dönüş yok). |
| Kod dosyası | Class/Module/Devir.vb:36-87, 128 |
| İlgili SQL nesneleri | Stok.StokHaraketleri |
| Tetikleme koşulu | Devir.vb ile devir; hareketli stok kartları; devir sırasında hata |
| Kök neden | Milyem sütunu toplanır (100 satır × 0,916 = 91,6) → NetBakiye hesaplanan sütunu ve GetStokHareketleri'nin Has=Miktar×Milyem gösterimi anlamsız; giriş/çıkış satırları ayrı toplandığı için LIFO maliyet/ortalama milyem yalnız giriş satırlarını görür; takoz/pırlanta yine düşer; Tarih=GETDATE (kesim değil); truncate ile insert arasında transaction yok – hata halinde tablolar boş kalır (yedek dışında geri dönüş yok). |
| Neden zinciri | Belirti: Devir açılış satırında Milyem>1; stok has/maliyet yanlış; tam veri kaybı riski ↓ Teknik olay: INSERT #ERPStok Select -1,0,IslemTuru,Getdate(),SubeId,KasaId,StokTipi,StokId,Sum(Adet),Sum(Miktar),Sum(Milyem),Sum(Has) ↓ Yakın neden: Devir.vb ile devir; hareketli stok kartları; devir sırasında hata ↓ Kök neden: Milyem sütunu toplanır (100 satır × 0,916 = 91,6) → NetBakiye hesaplanan sütunu ve GetStokHareketleri'nin Has=Miktar×Milyem gösterimi anlams ↓ Etkilenen veri: StokHaraketleri.Milyem ≤ 1 olmalı; açılış satırında Has = Miktar×Milyem tutmalı. |
| Etkilenen veri | StokHaraketleri.Milyem ≤ 1 olmalı; açılış satırında Has = Miktar×Milyem tutmalı. |
| Etkilenen iş süreci | Devir.vb (uygulama devri) – Sum(Milyem) ile açılış satırı, tarih=çalıştırma günü, transaction yok |
| Olasılık / etki / güven | ORTA / S1 / 85 |
| Bilinen ticket | CTR-034, GAP-PROCESS-03, H-108 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT * FROM Stok.StokHaraketleri WHERE IslemId=-1 AND Milyem>1; SELECT * FROM Stok.StokHaraketleri WHERE IslemId=-1 AND StokTipi=1 AND ABS(Has - Miktar*Milyem)>0.01 |
| Validation SQL (salt okunur) | SELECT * FROM Stok.StokHaraketleri WHERE IslemId=-1 AND Milyem>1; SELECT * FROM Stok.StokHaraketleri WHERE IslemId=-1 AND StokTipi=1 AND ABS(Has - Miktar*Milyem)>0.01 |
| Test senaryosu | Girdi: Stok.StokHaraketleri (StokTipi 1,2), Cari.BakiyeIslem · Formül: INSERT #ERPStok Select -1,0,IslemTuru,Getdate(),SubeId,KasaId,StokTipi,StokId,Sum(Adet),Sum(Miktar),Sum(Milyem),Sum(Has),Sum(Maliyet),VaryantId … Grou · Sınır: Devir.vb ile devir; hareketli stok kartları; devir sırasında hata |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: INSERT #ERPStok Select -1,0,IslemTuru,Getdate(),SubeId,KasaId,StokTipi,StokId,Sum(Adet),Sum(Miktar),Sum(Milyem),Sum(Has),Sum(Maliyet),VaryantId … Group by IslemTuru,… ; Truncate Cari.Islemler/BakiyeIs · Kanıt: Devir.vb:67 'Sum(Adet),Sum(Miktar),Sum(Milyem),Sum(Has),Sum(Maliyet)' |
| Wiki bağlantıları | H-108 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-067 — SLR-036 Repair.BalanceRepair – güncel tetikleyiciden geride kalmış tam yeniden kurma S1 · MOD-SISTEM · Gözlemlendi: EVET · PF-004 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: TERM-REPAIR-BALANCEREPAIR, KNOWN_GAPS TD-BALANCEREPAIR, SYM-BAKIYE (çalıştırılmaz), proje notu erpgoldv2-balancerepair-riski) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E16 — Eksik Türetilmiş Kayıt |
| Severity | S1 — KRİTİK |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Problem ailesi | PF-004 Rapor tasarımı / yeni rapor / sütun ekleme / bakiye ekstresi düzenleme (talep) |
| Kullanıcı belirtisi | Tüm bakiyeler ve stoklar sistematik olarak farklı kural setiyle yeniden yazılır; devir/transfer verisi kaybı |
| Teknik belirti | Çalıştırılırsa devir (IslemId=-1), transfer (Bolum=2) ve üretim (Bolum=1) satırları kalıcı silinir; tip 11/12 satırları için bakiye/stok üretilir (tetikleyici üretmez); MAHSUP/belge tipleri bakiyeye girer; çeşni, model, pırlanta, hizmet (5), nakit emanet satırları eksik kalır; PEŞİN maden has bakiyesi yazılır. Hata mesajı yok; tablolar dolu görünür. |
| Kod dosyası | Repair.BalanceRepair (modules.json); karşılaştırma: Cari.AcceptTransaction satır 263, 281, 291-302, 311-330, 346, 363, 516 |
| İlgili SQL nesneleri | Repair.BalanceRepair, Cari.AcceptTransaction, Cari.BakiyeIslem, Stok.StokHaraketleri, Cari.Islemler |
| SQL Object | Repair.BalanceRepair (modules.json); karşılaştırma: Cari.AcceptTransaction satır 263, 281, 291-302, 311-330, 346, 363, 516 |
| Tetikleme koşulu | Prosedürün elle çalıştırılması (destek/geliştirici) |
| Kök neden | Çalıştırılırsa devir (IslemId=-1), transfer (Bolum=2) ve üretim (Bolum=1) satırları kalıcı silinir; tip 11/12 satırları için bakiye/stok üretilir (tetikleyici üretmez); MAHSUP/belge tipleri bakiyeye girer; çeşni, model, pırlanta, hizmet (5), nakit emanet satırları eksik kalır; PEŞİN maden has bakiyesi yazılır. Hata mesajı yok; tablolar dolu görünür. |
| Neden zinciri | Belirti: Tüm bakiyeler ve stoklar sistematik olarak farklı kural setiyle yeniden yazılır; devir/transfer veri ↓ Teknik olay: Truncate Cari.BakiyeIslem ; Truncate Stok.StokHaraketleri ; cursor: eski kural seti (tip 11/12 hariç tutma yok; kod 14, ↓ Yakın neden: Prosedürün elle çalıştırılması (destek/geliştirici) ↓ Kök neden: Çalıştırılırsa devir (IslemId=-1), transfer (Bolum=2) ve üretim (Bolum=1) satırları kalıcı silinir; tip 11/12 satırları için bakiye/stok üre ↓ Etkilenen veri: Devir (IslemId=-1) ve Bolum≠0 türetilmiş satırlar hiçbir onarımda silinmemeli; onarım kural seti tet |
| Etkilenen veri | Devir (IslemId=-1) ve Bolum≠0 türetilmiş satırlar hiçbir onarımda silinmemeli; onarım kural seti tetikleyiciyle birebir olmalı. |
| Etkilenen iş süreci | Repair.BalanceRepair – güncel tetikleyiciden geride kalmış tam yeniden kurma |
| Olasılık / etki / güven | DÜŞÜK / S1 / 95 |
| Bilinen ticket | TERM-REPAIR-BALANCEREPAIR, KNOWN_GAPS TD-BALANCEREPAIR, SYM-BAKIYE (çalıştırılmaz), proje notu erpgoldv2-balancerepair-riski |
| Ticket sayısı | 0 |
| Bilinen çözüm | Kanıtlı kural: hiçbir koşulda çalıştırılmaz (SYM-BAKIYE). Güncel tetikleyiciyle eşitlenmiş bir onarım aracı yok → [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | Çalıştırılmış mı: SELECT COUNT(*) FROM Cari.BakiyeIslem WHERE IslemId=-1; SELECT COUNT(*) FROM Stok.StokHaraketleri WHERE Bolum<>0; sıfırsa ve devir/transfer geçmişi varsa çalıştırılmış olabilir; ayrıca tip 11/12 için BakiyeIslem var mı: SELECT COUNT(*) FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.IslemTipi IN (11,12) |
| Validation SQL (salt okunur) | Çalıştırılmış mı: SELECT COUNT(*) FROM Cari.BakiyeIslem WHERE IslemId=-1; SELECT COUNT(*) FROM Stok.StokHaraketleri WHERE Bolum<>0; sıfırsa ve devir/transfer geçmişi varsa çalıştırılmış olabilir; ayrıca tip 11/12 için BakiyeIslem var mı: SELECT COUNT(*) FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.IslemTipi IN (11,12) |
| Test senaryosu | Girdi: Cari.Islemler (IsDeleted=0) – tümü · Formül: Truncate Cari.BakiyeIslem ; Truncate Stok.StokHaraketleri ; cursor: eski kural seti (tip 11/12 hariç tutma yok; kod 14, 9, 8, 3/10, 5 dalları yok; nak · Sınır: Prosedürün elle çalıştırılması (destek/geliştirici) |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Truncate Cari.BakiyeIslem ; Truncate Stok.StokHaraketleri ; cursor: eski kural seti (tip 11/12 hariç tutma yok; kod 14, 9, 8, 3/10, 5 dalları yok; nakit tip 4 istisnası yok; has satırında IslemTipi<>1 · Kanıt: BalanceRepair: 'if @IsDeleted='False' And @IsError=0' (tip 11/12 yok); 'if @IslemKodu=3 ---NAKİT' (tip 4 istisnası yok); 'if @BakiyeId>0 and @Miktar<>0' (tip<>1 yok) |
| İlişkili kayıtlar | ERR-OBS-067, ERR-POT-030, ERR-POT-129 |
| Wiki bağlantıları | TERM-REPAIR-BALANCEREPAIR · SYM-BAKIYE |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-068 — SLR-037 Repair.StokRepair – ikinci FETCH'te değişken sayısı uyumsuz (17 ≠ 18) S1 · MOD-SISTEM · Gözlemlendi: EVET · PF-034 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: TD-BALANCEREPAIR teması) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S1 — KRİTİK |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Problem ailesi | PF-034 Stok tutmuyor / stok düzeltme / eksi stok / stok girişi |
| Kullanıcı belirtisi | Tüm stok hareketleri silinir; stok listeleri boş |
| Teknik belirti | İlk satır işlendikten sonra ikinci FETCH 'number of variables … must match' hatasıyla durur; TRUNCATE zaten autocommit ile kalıcı olduğundan stok hareket tablosu tek satırla kalır. Prosedür hata verir ancak veri kaybı gerçekleşmiştir. |
| Kod dosyası | Repair.StokRepair (modules.json) – son FETCH satırı |
| İlgili SQL nesneleri | Repair.StokRepair, Stok.StokHaraketleri |
| SQL Object | Repair.StokRepair (modules.json) – son FETCH satırı |
| Tetikleme koşulu | Prosedürün çalıştırılması |
| Kök neden | İlk satır işlendikten sonra ikinci FETCH 'number of variables … must match' hatasıyla durur; TRUNCATE zaten autocommit ile kalıcı olduğundan stok hareket tablosu tek satırla kalır. Prosedür hata verir ancak veri kaybı gerçekleşmiştir. |
| Neden zinciri | Belirti: Tüm stok hareketleri silinir; stok listeleri boş ↓ Teknik olay: Truncate Table Stok.StokHaraketleri ; FETCH NEXT … INTO 18 değişken (ilk) ; döngü sonunda FETCH NEXT … INTO 17 değişken ↓ Yakın neden: Prosedürün çalıştırılması ↓ Kök neden: İlk satır işlendikten sonra ikinci FETCH 'number of variables … must match' hatasıyla durur; TRUNCATE zaten autocommit ile kalıcı olduğundan ↓ Etkilenen veri: Onarım prosedürleri TRUNCATE'i yalnız başarılı yeniden kurma ile aynı transaction içinde yapmalı. |
| Etkilenen veri | Onarım prosedürleri TRUNCATE'i yalnız başarılı yeniden kurma ile aynı transaction içinde yapmalı. |
| Etkilenen iş süreci | Repair.StokRepair – ikinci FETCH'te değişken sayısı uyumsuz (17 ≠ 18) |
| Olasılık / etki / güven | DÜŞÜK / S1 / 90 |
| Bilinen ticket | TD-BALANCEREPAIR teması |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | Tanım karşılaştırması: OBJECT_DEFINITION(OBJECT_ID('Repair.StokRepair')) içindeki iki FETCH NEXT satırındaki değişken sayısı; çalıştırılmış mı: SELECT COUNT(*) FROM Stok.StokHaraketleri |
| Validation SQL (salt okunur) | Tanım karşılaştırması: OBJECT_DEFINITION(OBJECT_ID('Repair.StokRepair')) içindeki iki FETCH NEXT satırındaki değişken sayısı; çalıştırılmış mı: SELECT COUNT(*) FROM Stok.StokHaraketleri |
| Test senaryosu | Girdi: Cari.Islemler (IsDeleted=0) · Formül: Truncate Table Stok.StokHaraketleri ; FETCH NEXT … INTO 18 değişken (ilk) ; döngü sonunda FETCH NEXT … INTO 17 değişken (@VaryantId eksik) · Sınır: Prosedürün çalıştırılması |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Notlar | Çözüm adayı: çalıştırılmamalı |
| Kaynak | Sessiz risk analizi · Formül: Truncate Table Stok.StokHaraketleri ; FETCH NEXT … INTO 18 değişken (ilk) ; döngü sonunda FETCH NEXT … INTO 17 değişken (@VaryantId eksik) · Kanıt: İlk FETCH: '…,@StokId,@VaryantId,@Adet,…' ; son FETCH: '…,@StokId,@Adet,@Miktar,…' (@VaryantId yok) |
| İlişkili kayıtlar | ERR-POT-030 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-069 — SLR-038 Sistem.Settings tek satır varsayımı; Save = TRUNCATE + INSERT (transaction yok) S1 · MOD-SISTEM · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: GAP-DB-06) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E05 — Transaction Hatası |
| Severity | S1 — KRİTİK |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | BirimId NULL bakiye satırları; vergi/uyarı kontrolleri kapanır |
| Teknik belirti | INSERT başarısız olursa (tip dönüşümü, kolon uyumsuzluğu) tablo boş kalır: tetikleyici sembolleri NULL alır, takoz/çeşni bakiye satırları BirimId NULL ile yazılır (bakiye kartında görünmez), uygulama varsayılanlarla (BSMV=0, OnsCarpan=31,1035, IslemKurFarki=0) çalışır – kur farkı uyarısı ve BSMV sessizce kapanır. İki satır oluşursa trigger 'subquery returned more than 1 value' ile tüm işlemleri durdurur. Read() 'Do While Dr.Read' ile son satırı alır. |
| Kod dosyası | Form/Settings/Settings.vb:121-138; AcceptTransaction satır 64-67; Uretim.TrBakiyeHesapla |
| İlgili SQL nesneleri | Sistem.Settings, Cari.BakiyeIslem, Sistem.Birimler |
| Tetikleme koşulu | Ayar kaydı sırasında hata; elle satır ekleme; sembolün Birimler'de olmaması |
| Kök neden | INSERT başarısız olursa (tip dönüşümü, kolon uyumsuzluğu) tablo boş kalır: tetikleyici sembolleri NULL alır, takoz/çeşni bakiye satırları BirimId NULL ile yazılır (bakiye kartında görünmez), uygulama varsayılanlarla (BSMV=0, OnsCarpan=31,1035, IslemKurFarki=0) çalışır – kur farkı uyarısı ve BSMV sessizce kapanır. İki satır oluşursa trigger 'subquery returned more than 1 value' ile tüm işlemleri durdurur. Read() 'Do While Dr.Read' ile son satırı alır. |
| Neden zinciri | Belirti: BirimId NULL bakiye satırları; vergi/uyarı kontrolleri kapanır ↓ Teknik olay: GlobalSettings.Save: Truncate Table Sistem.Settings ; Insert Into Sistem.Settings(...) Values('…') ; Trigger: @HasBirimI ↓ Yakın neden: Ayar kaydı sırasında hata; elle satır ekleme; sembolün Birimler'de olmaması ↓ Kök neden: INSERT başarısız olursa (tip dönüşümü, kolon uyumsuzluğu) tablo boş kalır: tetikleyici sembolleri NULL alır, takoz/çeşni bakiye satırları Bi ↓ Etkilenen veri: Sistem.Settings tam 1 satır içermeli; sembol kolonları Birimler'de tekil eşleşmeli. |
| Etkilenen veri | Sistem.Settings tam 1 satır içermeli; sembol kolonları Birimler'de tekil eşleşmeli. |
| Etkilenen iş süreci | Sistem.Settings tek satır varsayımı; Save = TRUNCATE + INSERT (transaction yok) |
| Olasılık / etki / güven | DÜŞÜK / S1 / 80 |
| Bilinen ticket | GAP-DB-06 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*) FROM Sistem.Settings; SELECT COUNT(*) FROM Cari.BakiyeIslem WHERE BirimId IS NULL; SELECT s.HasSymbol FROM Sistem.Settings s WHERE NOT EXISTS(SELECT 1 FROM Sistem.Birimler b WHERE b.Kodu=s.HasSymbol AND b.IsDeleted=0) |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Sistem.Settings; SELECT COUNT(*) FROM Cari.BakiyeIslem WHERE BirimId IS NULL; SELECT s.HasSymbol FROM Sistem.Settings s WHERE NOT EXISTS(SELECT 1 FROM Sistem.Birimler b WHERE b.Kodu=s.HasSymbol AND b.IsDeleted=0) |
| Test senaryosu | Girdi: Sistem.Settings (HasSymbol, GumSymbol, PltSymbol, PldSymbol, BSMV, OnsCarpan, IslemKurFarki…) · Formül: GlobalSettings.Save: Truncate Table Sistem.Settings ; Insert Into Sistem.Settings(...) Values('…') ; Trigger: @HasBirimId=(Select Id From Birimler Whe · Sınır: Ayar kaydı sırasında hata; elle satır ekleme; sembolün Birimler'de olmaması |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: GlobalSettings.Save: Truncate Table Sistem.Settings ; Insert Into Sistem.Settings(...) Values('…') ; Trigger: @HasBirimId=(Select Id From Birimler Where Kodu=(Select HasSymbol From Sistem.Settings)) · Kanıt: Settings.vb:135-136 'Db.ExecuteNonQuery("Truncate Table Sistem.Settings") ; Db.ExecuteNonQuery(Query)' |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-070 — SLR-039 Sistem.Birimler.Kodu benzersiz değil; kur listesi ve bakiye toplamları kod ile birleştirilir S2 · MOD-SISTEM · Gözlemlendi: EVET · PF-023 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-023, H-131) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E15 — Duplicate / Çift İşlem |
| Severity | S2 — YÜKSEK |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Problem ailesi | PF-023 Birim (para birimi) tanımlama / listede görünmüyor / çarpan / çift birim |
| Kullanıcı belirtisi | Limit, bilanço ve pozisyon çift sayım |
| Teknik belirti | Aynı kodlu iki birim (silinip yeniden açılan) kur listesinde iki satır üretir; koda göre join yapan bakiye/limit/bilanço/pozisyon sorguları satırları çiftler (bakiye iki kat). |
| Kod dosyası | Cari.ToplamBakiye, Bilanco.OzetBilanco, Pozisyon.Write, Bakiye.DunkiBakiyeler (modules.json); indexes.json Sistem.Birimler |
| İlgili SQL nesneleri | Cari.ToplamBakiye, Bilanco.OzetBilanco, Pozisyon.Write, Bakiye.DunkiBakiyeler, Sistem.Birimler |
| SQL Object | Cari.ToplamBakiye, Bilanco.OzetBilanco, Pozisyon.Write, Bakiye.DunkiBakiyeler (modules.json); indexes.json Sistem.Birimler |
| Tetikleme koşulu | Birimler'de aynı Kodu ile IsDeleted=0 iki satır |
| Kök neden | Aynı kodlu iki birim (silinip yeniden açılan) kur listesinde iki satır üretir; koda göre join yapan bakiye/limit/bilanço/pozisyon sorguları satırları çiftler (bakiye iki kat). |
| Neden zinciri | Belirti: Limit, bilanço ve pozisyon çift sayım ↓ Teknik olay: Left Join Sistem.GetKurListesi(Getdate()) Kur on Kur.Birim = Bak.Kodu ↓ Yakın neden: Birimler'de aynı Kodu ile IsDeleted=0 iki satır ↓ Kök neden: Aynı kodlu iki birim (silinip yeniden açılan) kur listesinde iki satır üretir; koda göre join yapan bakiye/limit/bilanço/pozisyon sorguları ↓ Etkilenen veri: Sistem.Birimler.Kodu silinmemiş satırlarda benzersiz olmalı. |
| Etkilenen veri | Sistem.Birimler.Kodu silinmemiş satırlarda benzersiz olmalı. |
| Etkilenen iş süreci | Sistem.Birimler.Kodu benzersiz değil; kur listesi ve bakiye toplamları kod ile birleştirilir |
| Olasılık / etki / güven | DÜŞÜK / S2 / 85 |
| Bilinen ticket | H-023, H-131 |
| Ticket sayısı | 0 |
| Bilinen çözüm | H-131 teknik çözümü wikide (tekrarlayan kodun değiştirilmesi) |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT Kodu,COUNT(*) FROM Sistem.Birimler WHERE IsDeleted=0 GROUP BY Kodu HAVING COUNT(*)>1 |
| Validation SQL (salt okunur) | SELECT Kodu,COUNT(*) FROM Sistem.Birimler WHERE IsDeleted=0 GROUP BY Kodu HAVING COUNT(*)>1 |
| Test senaryosu | Girdi: Sistem.Birimler (unique index yalnız PK), ToplamBakiye/OzetBilanco/Pozisyon.Write 'Kur.Birim = Kodu' join'leri · Formül: Left Join Sistem.GetKurListesi(Getdate()) Kur on Kur.Birim = Bak.Kodu · Sınır: Birimler'de aynı Kodu ile IsDeleted=0 iki satır |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Left Join Sistem.GetKurListesi(Getdate()) Kur on Kur.Birim = Bak.Kodu · Kanıt: indexes.json: Sistem.Birimler yalnız PK_Birimler(Id) |
| İlişkili kayıtlar | ERR-SIL-028 |
| Wiki bağlantıları | H-023 · H-131 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-071 — SLR-040 FN.GetKatki daima 0 döndürür; FN.Katsayı tablo dışı milyemde NULL → FN.AyarCevir 0 S3 · MOD-SISTEM · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: GAP-SEC-AYAR-01) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-SISTEM |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Sipariş/üretim miktarı 0 veya katkı 0 |
| Teknik belirti | Katkı hesabı her koşulda 0; ayar çevirici 0,995/0,9166 gibi listede olmayan milyemlerde 0 döndürür (Bol NULL→0). Sipariş girişinde çevrilen miktar sessizce 0 olur. |
| Kod dosyası | FN.GetKatki, FN.Katsayı, FN.AyarCevir (modules.json); Form/Siparis/FrmSiparisGirisi.vb:194 |
| İlgili SQL nesneleri | FN.AyarCevir, FN.GetKatki |
| Tetikleme koşulu | Milyem tam olarak listedeki 7 değerden biri değilse |
| Kök neden | Katkı hesabı her koşulda 0; ayar çevirici 0,995/0,9166 gibi listede olmayan milyemlerde 0 döndürür (Bol NULL→0). Sipariş girişinde çevrilen miktar sessizce 0 olur. |
| Neden zinciri | Belirti: Sipariş/üretim miktarı 0 veya katkı 0 ↓ Teknik olay: GetKatki: … Set @Result=… ; return 0 ; AyarCevir = Bol(@Miktar, Katsayı(@Milyem1)) * Katsayı(@Milyem2) ; Katsayı: CASE ↓ Yakın neden: Milyem tam olarak listedeki 7 değerden biri değilse ↓ Kök neden: Katkı hesabı her koşulda 0; ayar çevirici 0,995/0,9166 gibi listede olmayan milyemlerde 0 döndürür (Bol NULL→0). Sipariş girişinde çevrilen ↓ Etkilenen veri: Ayar çevrimi tanımsız milyemde 0 yerine hata/uyarı üretmeli. |
| Etkilenen veri | Ayar çevrimi tanımsız milyemde 0 yerine hata/uyarı üretmeli. |
| Etkilenen iş süreci | FN.GetKatki daima 0 döndürür; FN.Katsayı tablo dışı milyemde NULL → FN.AyarCevir 0 |
| Olasılık / etki / güven | DÜŞÜK / S3 / 90 |
| Bilinen ticket | GAP-SEC-AYAR-01 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT FN.AyarCevir(10,0.995,0.585), FN.GetKatki(10,0.916,0.585) – beklenen 0 dışı, gelen 0 |
| Validation SQL (salt okunur) | SELECT FN.AyarCevir(10,0.995,0.585), FN.GetKatki(10,0.916,0.585) – beklenen 0 dışı, gelen 0 |
| Test senaryosu | Girdi: Milyem1, Milyem2 (yalnız 0.333/0.375/0.417/0.585/0.750/0.875/0.916 tanımlı) · Formül: GetKatki: … Set @Result=… ; return 0 ; AyarCevir = Bol(@Miktar, Katsayı(@Milyem1)) * Katsayı(@Milyem2) ; Katsayı: CASE … END (ELSE yok → NULL) · Sınır: Milyem tam olarak listedeki 7 değerden biri değilse |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: GetKatki: … Set @Result=… ; return 0 ; AyarCevir = Bol(@Miktar, Katsayı(@Milyem1)) * Katsayı(@Milyem2) ; Katsayı: CASE … END (ELSE yok → NULL) · Kanıt: FN.GetKatki son satır 'return 0'; FN.Katsayı CASE ifadesinde ELSE yok |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-072 — SLR-041 Uretim.TrBakiyeHesapla – kasa seçimi sırasız TOP 1, has = Tutar×Fiyat S4 · MOD-URETIM · Gözlemlendi: EVET · PF-030 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: GAP-SEC-ATOLYE-02) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S4 — DÜŞÜK |
| Modül | MOD-URETIM |
| Alt modül | Hesaplama |
| Problem ailesi | PF-030 Cari bakiye / ekstre tutmuyor (bakiye yanlış, ters, birden değişti) |
| Kullanıcı belirtisi | Üretimden gelen stok yanlış kasada; kasa stok listesi tutmaz |
| Teknik belirti | Şubede birden çok kasa varsa üretim çıktısı rastgele kasaya yazılır (plan değişince kasa değişir); giriş satırında miktar/milyem alanları Tutar/Fiyat ile doldurulduğundan alan anlamı ekrana bağlıdır. |
| Kod dosyası | Uretim.TrBakiyeHesapla (modules.json) |
| İlgili SQL nesneleri | Uretim.TrBakiyeHesapla, Sistem.Kasalar, Stok.StokHaraketleri |
| SQL Object | Uretim.TrBakiyeHesapla (modules.json) |
| Tetikleme koşulu | Şubede >1 kasa; üretim modülü kullanan kurulum |
| Kök neden | Şubede birden çok kasa varsa üretim çıktısı rastgele kasaya yazılır (plan değişince kasa değişir); giriş satırında miktar/milyem alanları Tutar/Fiyat ile doldurulduğundan alan anlamı ekrana bağlıdır. |
| Neden zinciri | Belirti: Üretimden gelen stok yanlış kasada; kasa stok listesi tutmaz ↓ Teknik olay: @KasaId = (Select Top 1 Id From Sistem.Kasalar Where IsDeleted='False' And SubeId=@SubeId) ; URETIMGIRIS: StokHaraketler ↓ Yakın neden: Şubede >1 kasa; üretim modülü kullanan kurulum ↓ Kök neden: Şubede birden çok kasa varsa üretim çıktısı rastgele kasaya yazılır (plan değişince kasa değişir); giriş satırında miktar/milyem alanları Tu ↓ Etkilenen veri: Bolum=1 stok hareketleri deterministik bir kasaya yazılmalı. |
| Etkilenen veri | Bolum=1 stok hareketleri deterministik bir kasaya yazılmalı. |
| Etkilenen iş süreci | Uretim.TrBakiyeHesapla – kasa seçimi sırasız TOP 1, has = Tutar×Fiyat |
| Olasılık / etki / güven | DÜŞÜK / S4 / 60 |
| Bilinen ticket | GAP-SEC-ATOLYE-02 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT SubeId,COUNT(*) FROM Sistem.Kasalar WHERE IsDeleted=0 GROUP BY SubeId HAVING COUNT(*)>1; SELECT KasaId,COUNT(*) FROM Stok.StokHaraketleri WHERE Bolum=1 GROUP BY KasaId |
| Validation SQL (salt okunur) | SELECT SubeId,COUNT(*) FROM Sistem.Kasalar WHERE IsDeleted=0 GROUP BY SubeId HAVING COUNT(*)>1; SELECT KasaId,COUNT(*) FROM Stok.StokHaraketleri WHERE Bolum=1 GROUP BY KasaId |
| Test senaryosu | Girdi: Sistem.Kasalar (SubeId), UretimIslemleri · Formül: @KasaId = (Select Top 1 Id From Sistem.Kasalar Where IsDeleted='False' And SubeId=@SubeId) ; URETIMGIRIS: StokHaraketleri(…, Miktar=@Tutar, Milyem=@Fi · Sınır: Şubede >1 kasa; üretim modülü kullanan kurulum |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: @KasaId = (Select Top 1 Id From Sistem.Kasalar Where IsDeleted='False' And SubeId=@SubeId) ; URETIMGIRIS: StokHaraketleri(…, Miktar=@Tutar, Milyem=@Fiyat, Has=@Tutar*@Fiyat) · Kanıt: 'Declare @KasaId int = (Select Top 1 Id From Sistem.Kasalar Where IsDeleted ='False' And SubeId =@SubeId)' |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-073 — SLR-042 Trigger hata iletimi ve uygulamanın algısı S3 · MOD-CARI · Gözlemlendi: EVET · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: GAP-CODE-05, GAP-CODE-07) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E07 — Finansal Hesaplama Hatası |
| Severity | S3 — ORTA |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Kullanıcı belirtisi | Rs aktarımı eksik işlem; takoz raporu yazılmamış giriş; haksız limit reddi |
| Teknik belirti | Trigger reddi kullanıcıya SQL metniyle gösterilir (sessiz değil). Ancak RAISERROR olmadan hata yutulan yerler vardır: Insert sonrası 'Cari.RSAktar' ve Update sonrası 'Takoz.RaporYaz' hataları MsgBox ile geçilir ve ana kayıt tamam sayılır; GetCariLimit ExecuteScalar hatası Val('')=0 ile 'limit 0' gibi davranır (işlem reddedilir – tersine sessizlik). |
| Kod dosyası | Class/Module/InternalDb.vb:53-81; Cari.Islem.vb:694-709; AcceptTransaction |
| İlgili SQL nesneleri | Cari.RSAktar, Takoz.RaporYaz, Cari.Islemler |
| Tetikleme koşulu | RsAktar/RaporYaz prosedür hatası; FN.GetCariLimit hata |
| Kök neden | Trigger reddi kullanıcıya SQL metniyle gösterilir (sessiz değil). Ancak RAISERROR olmadan hata yutulan yerler vardır: Insert sonrası 'Cari.RSAktar' ve Update sonrası 'Takoz.RaporYaz' hataları MsgBox ile geçilir ve ana kayıt tamam sayılır; GetCariLimit ExecuteScalar hatası Val('')=0 ile 'limit 0' gibi davranır (işlem reddedilir – tersine sessizlik). |
| Neden zinciri | Belirti: Rs aktarımı eksik işlem; takoz raporu yazılmamış giriş; haksız limit reddi ↓ Teknik olay: InternalDb.ExecuteScalar: Catch ex → MsgBox(ex.Message); Result=Nothing ; Insert: RecId=0 → Return False ↓ Yakın neden: RsAktar/RaporYaz prosedür hatası; FN.GetCariLimit hata ↓ Kök neden: Trigger reddi kullanıcıya SQL metniyle gösterilir (sessiz değil). Ancak RAISERROR olmadan hata yutulan yerler vardır: Insert sonrası 'Cari.R ↓ Etkilenen veri: Insert sonrası ikincil adımlar (RsAktar/RaporYaz) başarısızsa ana kayıt işaretlenmeli veya geri alın |
| Etkilenen veri | Insert sonrası ikincil adımlar (RsAktar/RaporYaz) başarısızsa ana kayıt işaretlenmeli veya geri alınmalı. |
| Etkilenen iş süreci | Trigger hata iletimi ve uygulamanın algısı |
| Olasılık / etki / güven | ORTA / S3 / 80 |
| Bilinen ticket | GAP-CODE-05, GAP-CODE-07 |
| Ticket sayısı | 0 |
| Bilinen çözüm | [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND RsAktar=1 AND NOT EXISTS(… Rs hedef tablosu …) [Rs hedefi kaynakta yok – GAP-CODE-05] |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND RsAktar=1 AND NOT EXISTS(… Rs hedef tablosu …) [Rs hedefi kaynakta yok – GAP-CODE-05] |
| Test senaryosu | Girdi: RAISERROR(…,16,1)+ROLLBACK → SqlException 3609; InternalDb MsgBox; Cari.Islem.Insert Catch · Formül: InternalDb.ExecuteScalar: Catch ex → MsgBox(ex.Message); Result=Nothing ; Insert: RecId=0 → Return False · Sınır: RsAktar/RaporYaz prosedür hatası; FN.GetCariLimit hata |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: InternalDb.ExecuteScalar: Catch ex → MsgBox(ex.Message); Result=Nothing ; Insert: RecId=0 → Return False · Kanıt: Cari.Islem.vb:696-697 'If RSAktar = True … db.ExecuteNonQuery("Cari.RSAktar " & RecId) Catch ex As Exception' (boş) |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-074 — SLR-043 Nakit NORMAL girişte yalnız karşılık birimi (TL) bakiyeye yazılır; döviz tarafı yalnız kasa stoğuna S3 · MOD-CARI · Gözlemlendi: EVET · PF-023 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: CTR-025, H-104) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E16 — Eksik Türetilmiş Kayıt |
| Severity | S3 — ORTA |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-023 Birim (para birimi) tanımlama / listede görünmüyor / çarpan / çift birim |
| Kullanıcı belirtisi | Yanlış düzeltme girişleri; çift kayıt |
| Teknik belirti | Kullanıcı dokümanı (A-Z 2.6) EUR+TL iki satır bekler; kod yalnız TL yazar. Personel 'işlem eksik' sanıp ikinci kez döviz satırı girebilir (çift kayıt) ya da müşteri döviz bakiyesini elle takip eder. |
| Kod dosyası | Cari.AcceptTransaction (dbclean/modules.json def) satır 281-285, 401-432; Class/Ext/Cari.IslemEx.vb:291-303 |
| İlgili SQL nesneleri | Cari.BakiyeIslem, Cari.Islemler |
| Tetikleme koşulu | Nakit NORMAL/ EMANET dışı işlem; kullanıcı beklentisi |
| Kök neden | Kullanıcı dokümanı (A-Z 2.6) EUR+TL iki satır bekler; kod yalnız TL yazar. Personel 'işlem eksik' sanıp ikinci kez döviz satırı girebilir (çift kayıt) ya da müşteri döviz bakiyesini elle takip eder. |
| Neden zinciri | Belirti: Yanlış düzeltme girişleri; çift kayıt ↓ Teknik olay: satır 401-432: Tutar satırı (BirimId, ±Tutar) ; has/miktar satırı yok (BakiyeId=0) ; Stok: StokHaraketleri(StokTipi=2, S ↓ Yakın neden: Nakit NORMAL/ EMANET dışı işlem; kullanıcı beklentisi ↓ Kök neden: Kullanıcı dokümanı (A-Z 2.6) EUR+TL iki satır bekler; kod yalnız TL yazar. Personel 'işlem eksik' sanıp ikinci kez döviz satırı girebilir (ç ↓ Etkilenen veri: Nakit işlemi (tip≠10) yalnız BirimId'li tek bakiye satırı üretmeli. |
| Etkilenen veri | Nakit işlemi (tip≠10) yalnız BirimId'li tek bakiye satırı üretmeli. |
| Etkilenen iş süreci | Nakit NORMAL girişte yalnız karşılık birimi (TL) bakiyeye yazılır; döviz tarafı yalnız kasa stoğuna |
| Olasılık / etki / güven | ORTA / S3 / 90 |
| Bilinen ticket | CTR-025, H-104 |
| Ticket sayısı | 0 |
| Bilinen çözüm | Doküman düzeltme önerisi CTR-025'te; kod değişikliği yok |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | SELECT COUNT(*) FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.IslemKodu=3 AND B.BirimId<>I.BirimId AND I.IslemTipi<>10 – 0 beklenir |
| Validation SQL (salt okunur) | SELECT COUNT(*) FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.IslemKodu=3 AND B.BirimId<>I.BirimId AND I.IslemTipi<>10 – 0 beklenir |
| Test senaryosu | Girdi: IslemKodu=3, BakiyeId=0 (Cari.IslemEx.vb:291-303), Tutar/BirimId, Miktar/StokId · Formül: satır 401-432: Tutar satırı (BirimId, ±Tutar) ; has/miktar satırı yok (BakiyeId=0) ; Stok: StokHaraketleri(StokTipi=2, StokId, ±Miktar) · Sınır: Nakit NORMAL/ EMANET dışı işlem; kullanıcı beklentisi |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: satır 401-432: Tutar satırı (BirimId, ±Tutar) ; has/miktar satırı yok (BakiyeId=0) ; Stok: StokHaraketleri(StokTipi=2, StokId, ±Miktar) · Kanıt: Cari.IslemEx.vb:303 'Return 0' (NAKIT BakiyeId) |
| Wiki bağlantıları | H-104 |
SESSİZ MANTIK / HESAPLAMA ERR-SIL-075 — SLR-044 PEŞİN (IslemTipi=1) işlemde bakiye/limit muafiyeti ve %5 karşılık toleransı S2 · MOD-CARI · Gözlemlendi: EVET · PF-007 · AÇIK
| Hata sınıfı | SESSİZ MANTIK / HESAPLAMA SESSİZ MANTIK / HESAPLAMA HATASI |
| Gözlemlendi | EVET · Observed=EVET (wiki/ticket bağı: H-104 (PEŞİN tip bakiye üretmez), BR-DEFTER-URETIMI, BR-BAKIYE-016, BR-FATURA-008) · Potential=EVET · Silent=EVET |
| Runtime durumu | GÖZLEMLENDİ — ticket/wiki kanıtı var |
| Hata kategorisi | E16 — Eksik Türetilmiş Kayıt |
| Severity | S2 — YÜKSEK |
| Modül | MOD-CARI |
| Alt modül | Hesaplama |
| Problem ailesi | PF-007 Fatura kesilemiyor / fatura basma / fatura problemi (genel) |
| Kullanıcı belirtisi | Bakiyesi olmayan ama karşılığı da tam girilmemiş peşin işlem; kasa/stok farkı; limit aşımı |
| Teknik belirti | PEŞİN tip bakiye satırı üretmediği ve limit kontrolünden muaf olduğu için, karşılığı eksik/ yanlış girilmiş peşin fiş sessizce bakiye dışı kalır; %5 tolerans yalnız PesinKontrol açık grupta ve yalnız fiş yazdırırken çalışır (F2 kayıt anında değil). Tolerans içindeki fark (≤%5) hiç uyarı vermez → kasa/stok farkı birikir. |
| Kod dosyası | Cari.GetFisPesinKontrol · basecontrol/Base Control/iScreen.vb:98-101 · Cari.AcceptTransaction (tip 1 bakiye satırı üretmez) |
| İlgili SQL nesneleri | Cari.Islemler |
| Tetikleme koşulu | PesinKontrol kapalı grup; fiş yazdırılmadan kapatılan işlem; %5 altındaki farklar; GIRIS=0 (Bol 0 döner → fark %100 gibi ya da 0) |
| Kök neden | PEŞİN tip bakiye satırı üretmediği ve limit kontrolünden muaf olduğu için, karşılığı eksik/ yanlış girilmiş peşin fiş sessizce bakiye dışı kalır; %5 tolerans yalnız PesinKontrol açık grupta ve yalnız fiş yazdırırken çalışır (F2 kayıt anında değil). Tolerans içindeki fark (≤%5) hiç uyarı vermez → kasa/stok farkı birikir. |
| Neden zinciri | Belirti: Bakiyesi olmayan ama karşılığı da tam girilmemiş peşin işlem; kasa/stok farkı; limit aşımı ↓ Teknik olay: Cari.GetFisPesinKontrol: Tutar = GIRIS>CIKIS ? (1 − Bol(CIKIS,GIRIS)) × 100 : Bol(CIKIS,GIRIS); sonuç > 5 ise 'karşılık ↓ Yakın neden: PesinKontrol kapalı grup; fiş yazdırılmadan kapatılan işlem; %5 altındaki farklar; GIRIS=0 (Bol 0 dö ↓ Kök neden: PEŞİN tip bakiye satırı üretmediği ve limit kontrolünden muaf olduğu için, karşılığı eksik/ yanlış girilmiş peşin fiş sessizce bakiye dışı k ↓ Etkilenen veri: INV-03: IslemTipi=1 işlemin Cari.BakiyeIslem satırı olmamalı; PEŞİN fişte giriş/çıkış karşılığı deng |
| Etkilenen veri | INV-03: IslemTipi=1 işlemin Cari.BakiyeIslem satırı olmamalı; PEŞİN fişte giriş/çıkış karşılığı dengeli olmalı |
| Etkilenen iş süreci | PEŞİN (IslemTipi=1) işlemde bakiye/limit muafiyeti ve %5 karşılık toleransı |
| Olasılık / etki / güven | ORTA / S2 / 75 |
| Bilinen ticket | H-104 (PEŞİN tip bakiye üretmez), BR-DEFTER-URETIMI, BR-BAKIYE-016, BR-FATURA-008 |
| Ticket sayısı | 0 |
| Bilinen çözüm | Bilinen davranış ve kullanıcı bilgilendirmesi: H-104 / BR-TIP-002-003 (PEŞİN tip kasaya yansır, bakiye üretmez). Kod düzeltmesi için: [Ekip tarafından doldurulacak] |
| Geçici çözüm | [Ekip tarafından doldurulacak] |
| Kalıcı çözüm | [Ekip tarafından doldurulacak] |
| Önleme | [Ekip tarafından doldurulacak] |
| Tespit yöntemi | INV-03 (PEŞİN işlemin bakiye satırı olmamalı) + fiş bazında giriş/çıkış TL karşılığı farkı: SELECT FisNo, SUM(CASE WHEN IslemTuru%2=0 THEN Tutar ELSE -Tutar END) FROM Cari.Islemler WHERE IslemTipi=1 AND IsDeleted=0 GROUP BY HesapId,FisNo HAVING ABS(SUM(...))>0 |
| Validation SQL (salt okunur) | INV-03 (PEŞİN işlemin bakiye satırı olmamalı) + fiş bazında giriş/çıkış TL karşılığı farkı: SELECT FisNo, SUM(CASE WHEN IslemTuru%2=0 THEN Tutar ELSE -Tutar END) FROM Cari.Islemler WHERE IslemTipi=1 AND IsDeleted=0 GROUP BY HesapId,FisNo HAVING ABS(SUM(...))>0 |
| Test senaryosu | Girdi: Cari.Islemler.IslemTipi=1; fişteki giriş/çıkış stok hareketleri TL karşılıkları; Sube.IsLimitControl; kullanıcı grubu PesinKontrol · Formül: Cari.GetFisPesinKontrol: Tutar = GIRIS>CIKIS ? (1 − Bol(CIKIS,GIRIS)) × 100 : Bol(CIKIS,GIRIS); sonuç > 5 ise 'karşılık bulunamadı' (yazdırma engellen · Sınır: PesinKontrol kapalı grup; fiş yazdırılmadan kapatılan işlem; %5 altındaki farklar; GIRIS=0 (Bol 0 döner → fark %100 gibi |
| Durum | AÇIK |
| Sorumlu | [Ekip tarafından atanacak] |
| Kaynak | Sessiz risk analizi · Formül: Cari.GetFisPesinKontrol: Tutar = GIRIS>CIKIS ? (1 − Bol(CIKIS,GIRIS)) × 100 : Bol(CIKIS,GIRIS); sonuç > 5 ise 'karşılık bulunamadı' (yazdırma engellenir); limit kontrolü PEŞİN hariç · Kanıt: BR-FATURA-008 (Cari.GetFisPesinKontrol formülü, %5), BR-BAKIYE-016 ('PEŞİN hariç' limit kontrolü), BR-DEFTER-URETIMI, AcceptTransaction tanımı |
| Wiki bağlantıları | H-104 · BR-DEFTER-URETIMI · BR-BAKIYE-016 · BR-FATURA-008 · BR-TIP-002-003 |
Sessiz hesaplama riskleri (44) — formül düzeyi
ERPGOLD_SESSIZ_HESAPLAMA_RISKLERI.xlsx "Sessiz_Riskler" sayfası: hesaplama, girdi, formül, sınır koşulu, olası yanlış sonuç, finansal etki ve doğrulama yöntemi.
| # | Modül | Hesaplama | Girdiler | Formül | Risk | Sınır koşulu | Olası yanlış sonuç | Finansal etki | Olasılık | Güven | Doğrulama | Bilinen ticket | Invariant | Konum |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | MOD-CARI | Bakiye satırı hassasiyeti: Has (5 hane) → Cari.BakiyeIslem.Bakiye decimal(18,2) | Cari.Islemler.Miktar decimal(18,2), AuMilyem decimal(18,5); trigger @Has Decimal(18,5) | @Has = I.Miktar * Case When AuMilyem=0 Then 1 else AuMilyem end → Insert Into Cari.BakiyeIslem(...,Bakiye) Values(...,@Has) [Bakiye decimal(18,2)] | Trigger has'ı 5 haneli hesaplar ancak BakiyeIslem.Bakiye 2 haneli olduğu için her satır ±0,005 has yuvarlanır. Aynı işlem için Stok.StokHaraketleri.Has 5 haneli yazılır; cari has toplamı ile stok has toplamı aynı hareket kümesinde farklılaşır. Binlerce satırda birikimli fark oluşur, hiçbir hata üretmez. | Miktar × AuMilyem üçüncü ondalıkta 5 ve üzeri (ör. 12,34 g × 0,916 = 11,30344 → 11,30); yüksek hacimli hesaplar | Müşteri has bakiyesi ile stok has toplamı (bilanço BAKIYE vs STOK kalemi) arasında açıklanamayan gram farkı; mutabakatta 'küsurat tutmuyor' şikâyeti | S3 – satır başına ≤0,005 has; hacimli hesaplarda birikimli gram farkı, bilanço/pozisyon mutarsızlığı | ÇOK YÜKSEK | 92 | SELECT I.Id, I.Miktar*I.AuMilyem AS HasHesap, B.Bakiye FROM Cari.Islemler I JOIN Cari.BakiyeIslem B ON B.IslemId=I.Id AND B.BirimId=I.BakiyeId WHERE I.IsDeleted=0 AND I.IslemKodu IN (1,2,9) AND ABS(ABS(B.Bakiye)-ABS(I.Miktar*I.AuMilyem))>0.004; toplam sapma: SELECT SUM(ABS(B.Bakiye)-ABS(I.Miktar*I.AuMilyem)) ... | CTR-015 (miktar hassasiyeti), H-110/H-125 teması (bakiye küsuratı) – doğrudan ticket yok | Bir işlemin has bakiye satırı, |Miktar × AuMilyem| değerine 2 hane yuvarlama toleransı içinde eşit olmalıdır. | Cari.AcceptTransaction (dbclean/modules.json def) satır 73, 348-349; kb_src/db/columns.json Cari.BakiyeIslem.Bakiye decimal(18,2); Stok.StokHaraketleri.Has decimal(18,5) |
| 2 | MOD-CARI | Trigger içinde ROLLBACK sonrası RETURN olmayan dallar (evrak eksik, şube/kasa/hesap=0, takoz stok kontrolü) | Inserted (çok satırlı UPDATE: DeleteAt RefNo, İptal FişNo, FrmHesapTemizle, FrmProvizyonKabul), Cari.GetGerekliEvraklar, Stok.GetTakozAdet | RAISERROR(...) ; Set @IsError=1 ; ROLLBACK -- RETURN yok (satır 119-123, 180-185, 225-247); döngü başında Set @IsError=0 (satır 90) | ROLLBACK sonrası trigger yürütmeye devam eder ve sonraki DML'ler autocommit ile kalıcı olur (SQL Server davranışı). Aynı satır için @IsError=1 olduğundan BakiyeIslem'e dokunulmaz; ancak Inserted çok satırlıysa sonraki satırlarda @IsError sıfırlanır: bu satırların BakiyeIslem/StokHaraketleri kayıtları silinip Inserted (yeni) değerlerle yeniden yazılır, oysa Cari.Islemler güncellemesi geri alınmıştır. Ayrıca satır 235 'Update Stok.Takoz Set IsDeleted=True' ve Activity MERGE geri alınmış işlem için kalıcı olur. | Tek UPDATE ile birden çok Cari.Islemler satırı değişirken satırlardan birinin hesabında zorunlu evrak eksik/şube pasif/takoz stokta yok olması (virman/parite çift bacağının RefNo ile iptali, İptal-FişNo, hesap birleştirme) | Cari.Islemler'de IsDeleted=0 kalan işlemin BakiyeIslem satırları silinmiş (bakiye eksik) ya da IsDeleted=1 olması gereken işlem aktif kalırken türetilmiş kayıtları silinmiş; takoz kartı yanlışlıkla silinmiş | S2 – bakiye kartında sessiz eksilme; müşteriye yanlış bakiye bildirimi | ORTA | 70 | SELECT I.Id FROM Cari.Islemler I WHERE I.IsDeleted=0 AND I.IslemTipi NOT IN (1,11,12) AND I.IslemKodu IN (1,2,9,4,5,6) AND (I.Tutar<>0 OR (I.BakiyeId>0 AND I.Miktar<>0)) AND NOT EXISTS (SELECT 1 FROM Cari.BakiyeIslem B WHERE B.IslemId=I.Id); ayrıca sys.triggers sırasını ve SQL error log 3609 kayıtlarını inceleyin | GAP-DB-07 (ROLLBACK sonrası RETURN yok), PRB-BAKIYE-000 / H-104-H-106 teması | Aktif (IsDeleted=0, tip ∉{1,11,12}) ve tutar/has üreten her işlemin en az bir BakiyeIslem satırı olmalı; silinmiş işlemin hiç olmamalı. | Cari.AcceptTransaction (dbclean/modules.json def) satır 90, 109-123, 180-185, 225-247, 256-260 |
| 3 | MOD-CARI | Limit kontrolü için toplam bakiye (Cari.ToplamBakiye = bugünkü BakiyeIslem + Cari.BakiyeDun) | Cari.BakiyeIslem (Tarih = işlem tarihi), Cari.BakiyeDun (Bakiye.DunkiBakiyeler prosedürüyle dolar), Sistem.GetKurListesi(Getdate()) | Cari.ToplamBakiye = Σ_bugün( Convert(dec(18,2), Bol(Bakiye*Carpan*Kur.Alis, KurHAS.Alis)) )*-1 + Σ Cari.BakiyeDun.Bakiye ; FN.GetCariLimit = IsNull(H.Limit,0)+IsNull(ToplamBakiye,0)+3 | Dünkü ve önceki bakiyeler yalnız Cari.BakiyeDun tablosundan gelir; bu tabloyu dolduran prosedürü çağıran bir job kaynakta yok ve örnek DB'de tablo 0 satır. Boşsa kalan limit = Limit + (yalnız bugünkü hareketler) + 3 olur; müşterinin birikmiş borcu yok sayılır. BakiyeIslem.Tarih işlem tarihi olduğundan geçmiş tarihle girilen bugünkü işlemler de ne 'bugün' dilimine ne BakiyeDun'a girer. | Cari.BakiyeDun boş/eski (job çalışmamış); işlem tarihi ≠ bugün; kur listesi HAS satırı 0 | Limit aşan müşteriye satış/çıkış işlemi sessizce kabul edilir ('limit çalışmıyor'); tersine job gün içinde tekrar çalışırsa bugünkü hareketler iki kez sayılıp işlem haksız reddedilir | S2 – kredi limiti kontrolünün devre dışı kalması; tahsilat riski | YÜKSEK | 85 | SELECT COUNT(*), MAX(Tarih) FROM Cari.BakiyeDun; karşılaştırma: SELECT H.Id, FN.GetCariLimit(H.Id) AS KalanLimit, H.Limit + (-1)*(SELECT SUM(B.Bakiye*Brm.Carpan*K.Alis/KH.Alis) FROM Cari.BakiyeIslem B …) FROM Cari.HesapBilgileri H WHERE H.Limit<>0 | GAP-DB-03 (Cari.BakiyeDun boş), CTR-014 (limit kapsamı) | Cari.BakiyeDun.Tarih = dün ve limit tanımlı her hesap için satır bulunmalı; ToplamBakiye tüm BakiyeIslem toplamına eşit olmalı. | Cari.ToplamBakiye, FN.GetCariLimit, Bakiye.DunkiBakiyeler (modules.json); Cari.Islem.vb:520-528 |
| 4 | MOD-CARI | Limit kontrolü has karşılığı (Satis ÷ HAS kuru) | Islem.Satis (MaliyetHesapla, Double), Program.GetKur("HAS") (bellek kur listesi Alis), FN.GetCariLimit | Balance = Satis.Divide(Program.GetKur("HAS")) ; AvaibleLimit = Val(FN.GetCariLimit(HesapId)) ; If Balance > AvaibleLimit Then red | Divide uzantısı bölen 0 ise 0 döndürür: HAS kuru 0/eksikse Balance=0 ve kontrol daima geçer. GetKur birim listede yoksa 1 döner: HasSymbol 'HAS' dışında tanımlıysa (kod sabit 'HAS' kullanıyor) Balance = Satis (TL) olur ve HAS cinsinden limitle kıyaslanır. Kontrol yalnız IslemKodu 1,2,3 ÇIKIŞ ve tip≠PEŞİN'de çalışır; takoz/vadeli/çevir çıkışları hiç kontrol edilmez; +3 has tolerans sabittir. | Kur listesinde HAS 0 veya yok; Settings.HasSymbol ≠ 'HAS'; IslemKodu ∉ {1,2,3} | Limit aşımı sessizce kabul edilir ya da (sembol farkında) her işlem reddedilir | S2 – limit kontrolünün devre dışı kalması | ORTA | 85 | SELECT HasSymbol FROM Sistem.Settings; SELECT * FROM Sistem.GetKurListesi(GETDATE()) WHERE Birim='HAS' OR Alis=0 OR Alis IS NULL; limit tanımlı hesaplarda çıkış işlemleri: SELECT I.Id,I.Satis,I.HasKur FROM Cari.Islemler I WHERE I.IsDeleted=0 AND I.IslemTuru=1 AND I.IslemTipi<>1 AND I.HasKur IN (0,1) | CTR-014, BR-BAKIYE-016 | Aktif işlemde HasKur > 1 ve HasKur ≠ 0 olmalı (has kuru fotoğrafı anlamlı). | Class/Dao/Islem/Cari.Islem.vb:520-528; Class/Module/Program.vb:260-268; Class/Module/Extention.vb:428-435 |
| 5 | MOD-CARI | Kur fotoğrafı (HasKur/GumKur/PltKur/PldKur/EurKur) kaydı | Program.KurListesi (15 sn'de bir arka planda yenilenen liste), GlobalSettings.*Symbol | @HasKur = Program.GetKur(GlobalSettings.HasSymbol) → K.Alis ; birim bulunamazsa 1 | Sembol kur listesinde yoksa 1 yazılır; takoz bakiyesinde 'Altına Çevir' Fn.Bol((Miktar*AgMilyem)*GumKur, HasKur) HasKur=1 ile has bakiyeyi TL değerine eşitler. Liste yenileme hatası sessizce yutulur (boş Catch) ve eski kur kullanılmaya devam eder; hesaplanan (IsComputed) birimler için GetLastKur yedeği yoktur (aşağıdaki kayda bakınız). | Settings sembolü Birimler'de yok/silinmiş; kur listesi yenileme başarısız; kur tarihi bugün için girilmemiş | İşlem satırında HasKur=1; takoz/rapor kâr-zarar ve 'işlem günü kur' raporları anlamsız | S2 – takoz bakiyesinde büyüklük hatası; raporlarda kur farkı hesabı bozulur | DÜŞÜK | 90 | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND (HasKur=1 OR GumKur=1 OR PltKur=1 OR PldKur=1 OR EurKur=1); SELECT s.HasSymbol,s.GumSymbol,s.PltSymbol,s.PldSymbol,s.UsdSymbol,s.EurSymbol FROM Sistem.Settings s; her biri için Sistem.Birimler'de IsDeleted=0 tek satır | HAYIR (BR-KUR-001 kuralı) | Settings'teki her metal/döviz sembolü Sistem.Birimler'de silinmemiş ve tek satır olarak bulunmalı; aktif işlemde HasKur∉{0,1}. | Class/Dao/Islem/Cari.Islem.vb:607-612; Class/Module/Program.vb:260-268; Class/Dao/Sistem.KurListesi.vb:60-120 |
| 6 | MOD-SISTEM | Sistem.GetKurListesi – günün kuru yoksa son kur (GetLastKur) yedeği; hesaplanan birimlerde yedek yok | Sistem.Kurlar (Tarih=@Tarih), Cari.BakiyeKodlari (Carpan, AnaBirimId), Sistem.GetLastKur (yalnız IsComputed='False') | Alis = IsNull(Convert(dec(18,4), Kur.Alis*Carpan), L.Alis) ; Kur join: (Case When AnaBirimId=-1 Then 1 Else AnaBirimId End)=Kur.BirimId And Kur.Tarih=@Tarih ; L join: L.BirimId=K.BirimId | (a) Günün kuru girilmemişse tüm işlemler sessizce en son (dün, hafta sonu öncesi, hatta ileri tarihli) kurla fiyatlanır; ekranda uyarı yoktur. (b) Hesaplanan birimlerde (ör. ayar/ons türevleri) L join K.BirimId (türev birim Id) üzerinden yapılır; GetLastKur türev birimleri içermediğinden Alis NULL döner; uygulama listesinde KurItem varsayılan 0 ile güncellenir → fiyat 0. (c) TAKOZ (-1) satırı için BirimId 1 sabitlenmiştir (Id=1'in HAS olduğu varsayımı). (d) Kurlar.IsDeleted süzülmez. | Gün başında kur girilmeden işlem; hafta sonu/tatil; IsComputed=1 birim; BirimId=1 ≠ HAS olan kurulum | Yanlış günün kuruyla TL karşılığı/has karşılığı; türev birimde fiyat 0 (Perakende Fiyat = GetKur × Carpan = 0); TAKOZ satırı yanlış kur | S2 – işlem fiyatlaması ve bakiye karşılıkları yanlış kurla; S3 türev birim | YÜKSEK | 80 | SELECT B.Kodu FROM Sistem.Birimler B WHERE B.IsDeleted=0 AND B.IsComputed=0 AND NOT EXISTS (SELECT 1 FROM Sistem.Kurlar K WHERE K.BirimId=B.Id AND K.Tarih=CONVERT(date,GETDATE()) AND K.IsDeleted=0); SELECT * FROM Sistem.GetKurListesi(GETDATE()) WHERE Alis IS NULL OR Alis=0; SELECT Id,Kodu FROM Sistem.Birimler WHERE Id=1 | H-107 (geçmiş tarihli işlem son kurla), H-124, H-125, PRB-KUR-000 | Her aktif, hesaplanmayan birim için bugünün tarihli, silinmemiş tek bir kur satırı bulunmalı; GetKurListesi hiçbir satırda NULL/0 Alis döndürmemeli. | Sistem.GetKurListesi, Sistem.GetLastKur (modules.json); Class/Dao/Sistem.KurListesi.vb:100-108 |
| 7 | MOD-SISTEM | Sistem.Kurlar benzersizlik/tarih kontrolü yok; FN.GetKur TOP 1 sırasız | Sistem.Kurlar (BirimId,Tarih) – unique index yok (indexes.json), IsDeleted süzgeci yok | FN.GetKur = Select top 1 Alis From Sistem.GetKurListesi(Getdate()) Where BirimId=@BirimId (ORDER BY yok) ; GetLastKur = MAX(Tarih) per BirimId (ileri tarih dahil) | Aynı birim+tarih için birden çok satır oluşabilir (ekranda Id çözümleme hatası, KOPYALA + elle giriş, dış besleme). GetKurListesi bu durumda birimi iki kez döndürür; FN.GetKur rastgele satırı alır, uygulama listesi son okunanı alır, ToplamBakiye/OzetBilanco Birim koduyla join yaptığından bakiye iki kez toplanır. GetLastKur ileri tarihli (yanlış girilmiş) kuru 'son kur' sayar. | Duplicate (BirimId,Tarih); ileri tarihli kur satırı; IsDeleted=1 kur satırı | Bakiye/pozisyon/bilanço toplamları çift sayılır; rastgele kur ile dönüşüm | S3 – rapor ve karşılık hesaplarında çift sayım | ORTA | 85 | SELECT BirimId,Tarih,COUNT(*) FROM Sistem.Kurlar WHERE IsDeleted=0 GROUP BY BirimId,Tarih HAVING COUNT(*)>1; SELECT * FROM Sistem.Kurlar WHERE Tarih>CONVERT(date,GETDATE()); SELECT Birim,COUNT(*) FROM Sistem.GetKurListesi(GETDATE()) GROUP BY Birim HAVING COUNT(*)>1 | H-125, H-131/H-023 teması | Sistem.Kurlar'da (BirimId, Tarih) çifti silinmemiş satırlar için benzersiz olmalı ve Tarih > bugün olmamalı. | FN.GetKur, Sistem.GetLastKur, Sistem.GetKurListesi; dbclean/indexes.json (Sistem.Kurlar: yalnız PK_Kurlar ve Tarih indexleri) |
| 8 | MOD-SISTEM | Kur giriş ekranı: yeni kur satırının Id'si olarak ExecuteNonQuery dönüşü (etkilenen satır sayısı) kullanılıyor | VwKurListesi satırı (Id, BirimId, Alis, Satis), Tarih | Id = Db.ExecuteNonQuery("Insert Into Sistem.Kurlar(...) Values(...) SELECT SCOPE_IDENTITY()") → 1 ; sonraki düzenleme: Update Sistem.Kurlar Set Alis=…,Satis=… Where Id='1' | ExecuteNonQuery eklenen satır sayısını (1) döndürür, SCOPE_IDENTITY sonucunu değil. Grid'deki Id 1 olur; kullanıcı aynı oturumda (yenilemeden) aynı birimi ikinci kez düzeltirse Kurlar tablosundaki Id=1 olan tarihi kur satırı güncellenir, günün satırı ilk değerde kalır. Hata mesajı çıkmaz. | Aynı ekran oturumunda aynı birim için iki kez değer girme (yazım düzeltmesi) | Günün kuru yanlış (ilk girilen) kalır; Id=1'li eski kur satırı bozulur → o günkü arşiv raporları/kur farkı hesabı değişir | S3 – yanlış kur ile fiyatlama; tarihi kur bozulması | ORTA | 85 | SELECT Id,Tarih,BirimId,Alis,Satis,LastModify FROM Sistem.Kurlar WHERE Id=1 – LastModify tarihinin Tarih'ten çok sonra olması bulguyu doğrular; SELECT * FROM Sistem.Kurlar WHERE LastModify > DATEADD(day,2,Tarih) | HAYIR (PRB-KUR-000 teması) | Sistem.Kurlar satırında LastModify, Tarih'ten makul süre (≤ birkaç gün) sonra olmalı; Id=1 satırı güncel tarihli değişiklik taşımamalı. | Form/Genel/FrmKurGirisEkrani.vb:71-84 |
| 9 | MOD-SISTEM | Sistem.KurKopyala – bugünün kurlarını silip son kurla değiştirir | Sistem.Kurlar (Tarih=bugün), Sistem.GetLastKur | Delete From Sistem.Kurlar Where Tarih=Convert(Date,GETDATE()) ; Insert … Select GETDATE(),BirimId,Alis,Satis,GETDATE(),0 From Sistem.GetLastKur | KOPYALA, bugün elle girilmiş tüm kurları siler ve önceki günün kurlarıyla değiştirir; onay/uyarı yoktur, UserId=0 yazılır. Gün içinde kur güncellendikten sonra basılırsa güncel kurlar kaybolur; işlemler eski kurla devam eder. | Gün içinde kur girildikten sonra KOPYALA'ya basılması; ileri tarihli kur varsa GetLastKur onu getirir | Bugünün kurları önceki güne döner; işlemlerde HasKur/BirimKur eski değer | S3 – yanlış kurla fiyatlama, raporlarda kur farkı | ORTA | 90 | SELECT Tarih,BirimId,UserId,LastModify,InsertDate FROM Sistem.Kurlar WHERE Tarih=CONVERT(date,GETDATE()) AND UserId=0 – aynı gün UserId<>0 satırları yoksa ve LastModify öğleden sonra ise kopyalama sonradan yapılmış demektir | H-107/H-124 çözüm adımı olarak öneriliyor (yan etkisi belgelenmemiş) | Günün kur satırları gün içinde sonradan UserId=0 ile yeniden yazılmamalı. | Sistem.KurKopyala (modules.json); FrmKurGirisEkrani.vb:BtnKopyala |
| 10 | MOD-SISTEM | Kur 0/NULL iken Fn.Bol ve .Divide'ın sessiz 0 üretmesi (NET, limit, bilanço, maliyet) | Sistem.GetKurListesi Alis/Satis, FN.Bol, Extention.Divide | FN.Bol(a,b) = (a<>0 and b<>0) ? a/b : 0 ; Divide(v1,v2) = (v1<>0 And v2<>0) ? v1/v2 : 0 | Sıfıra bölme korunur ancak sonuç 0 olarak akar: kur eksikse NET=0, bilanço kalemi 0, pozisyon 0, limit karşılığı 0 (kontrol geçer), maliyet 0. Kullanıcı 'toplam 0' görür ama işlem/raporda hata yoktur; kararlar 0 üzerinden verilir. | Kur satırı 0 (ekran engeller ama SQL/KOPYALA/dış kaynak engellemez) veya birim kur listesinde yok | Bakiye ekstresi TOPLAM 0; limit kontrolü etkisiz; maliyet 0 | S2 – limit/karar hataları; S3 raporlar | ORTA | 90 | SELECT * FROM Sistem.Kurlar WHERE IsDeleted=0 AND (ISNULL(Alis,0)<=0 OR ISNULL(Satis,0)<=0); SELECT * FROM Sistem.GetKurListesi(GETDATE()) WHERE ISNULL(Alis,0)=0 | H-124 (TOPLAM 0), H-110, H-126 (Divide by zero → FN.Bol'a çevirme önerisi) | Sistem.Kurlar'da silinmemiş hiçbir satırda Alis veya Satis 0/NULL olmamalı. | FN.Bol (modules.json); Class/Module/Extention.vb:428-484; Cari.ToplamBakiye; Bakiye.GetBakiye NET; Stok.GetMadenMaliyeti son satır; Pozisyon.Write |
| 11 | MOD-SISTEM | Kur hassasiyeti: GetKurListesi Convert(Decimal(18,4)) ile kuru 4 haneye yuvarlar (Kurlar 18,5) | Sistem.Kurlar.Alis/Satis decimal(18,5), Carpan decimal(18,5) | Convert(Decimal(18,4), Kur.Alis * Carpan) as Alis | Beşinci ondalık atılır; parite tipi küçük kurlarda (ör. 0,00012 gibi TL-dışı çaprazlar) ve Carpan ile türetilen birimlerde bağıl hata büyür. Uygulama, işlem kur fotoğrafı ve tüm SQL NET hesapları bu 4 haneli değeri kullanır. | Kur < 0,01 veya Carpan çarpımı 5. hanede anlamlı; büyük tutarlar | TL karşılıklarında küçük ama sistematik sapma; işlem kur fotoğrafı ile Kurlar tablosu farklı | S4 – küsurat düzeyinde sistematik sapma | ORTA | 80 | SELECT K.BirimId,K.Alis, L.Alis FROM Sistem.Kurlar K JOIN Sistem.GetKurListesi(K.Tarih) L ON L.BirimId=K.BirimId WHERE K.Tarih=CONVERT(date,GETDATE()) AND K.Alis<>L.Alis | HAYIR | GetKurListesi.Alis ile Kurlar.Alis×Carpan farkı 0,00005'i aşmamalı. | Sistem.GetKurListesi (modules.json) |
| 12 | MOD-STOK | IslemTipi 11 (belge takip) ve 12 (MAHSUP) hiç stok/bakiye hareketi üretmez – sayım farkı/açılış girişleri operasyonel stoğa yansımaz | Cari.Islemler.IslemTipi | if @IsDeleted='False' And @IsError=0 AND (@IslemTipi <>11 AND @IslemTipi<>12) BEGIN … stok/bakiye üretimi … END | Kullanıcı dokümanı (A-Z 1.8/2.4, H-123) sayım farkı ve açılış stoğunun MAHSUP ile girilmesini önerir; tetikleyici MAHSUP için Stok.StokHaraketleri satırı yazmaz. İşlem listede görünür, hata yoktur, ancak stok listesi/bilanço/pozisyon değişmez. Üstelik mevcut NORMAL bir satır Düzelt ile 11/12'ye çevrilirse önce silme (satır 258-259) çalışır ve bakiye/stok kaydı sessizce kaybolur. | IslemTipi ∈ {11,12}; tip değişikliği ile düzeltme | Stok sayım düzeltmesi yapılmış sanılır ama stok eski değerde; bilanço farkı; düzeltme ile bakiye kaybı | S2 – stok ve bilanço farkı; müşteri bakiyesinin sessiz silinmesi | YÜKSEK | 95 | SELECT COUNT(*) FROM Cari.Islemler I WHERE I.IsDeleted=0 AND I.IslemTipi=12 AND I.IslemKodu IN (1,2,3); bunların hiçbirinde EXISTS(Stok.StokHaraketleri Bolum=0) olmamalı – varsa trigger sürümü farklıdır; History: SELECT TransactionId FROM Cari.History H WHERE LogType='Düzeltme' AND IslemTipi IN (11,12) AND EXISTS(SELECT 1 FROM Cari.History H0 WHERE H0.TransactionId=H.TransactionId AND H0.IslemTipi NOT IN (11,12)) | CTR-003, CTR-004, CTR-005, BR-TIP-004, H-123 (çözüm adımı MAHSUP), H-142 | IslemTipi ∈ {11,12} olan işlemlerin BakiyeIslem/StokHaraketleri(Bolum=0) satırı olmamalı; NORMAL→11/12 tip değişikliği History'de izlenebilir olmalı. | Cari.AcceptTransaction (dbclean/modules.json def) satır 263 |
| 13 | MOD-STOK | Negatif miktar/adet girişi: bakiye abs() ile yön alır, stok hareketi işaretsiz miktarı taşır | Cari.Islemler.Miktar/Adet (DevExpress numeric mask; negatif engeli kodda yok), IslemTuru | Bakiye: Set @Has=0-abs(@Has) / abs(@Has) ; Stok: Miktar = Case When @IslemTuru=0 Then @Miktar When 1 Then 0-@Miktar End (abs yok) | Miktar negatif girilirse bakiye satırı yön kuralına göre düzgün işaret alır ama stok hareketi ters yöne yazılır (giriş stoğu azaltır). Ayrıca tip PEŞİN nakit satırı ve pırlanta maliyeti aynı biçimde ters işaret alır. Uygulama yalnız Miktar=0'ı engeller. | Miktar<0, Adet<0 veya Tutar<0 girilmiş satır | Cari has bakiyesi doğru, stok ters; bilanço BAKIYE≠STOK | S2 – stok/bilanço tutarsızlığı | DÜŞÜK | 60 | SELECT Id,IslemKodu,IslemTuru,Miktar,Adet,Tutar FROM Cari.Islemler WHERE IsDeleted=0 AND (Miktar<0 OR Adet<0 OR Tutar<0); SELECT H.* FROM Stok.StokHaraketleri H JOIN Cari.Islemler I ON I.Id=H.IslemId AND H.Bolum=0 WHERE I.IslemKodu IN (1,2,9) AND H.StokTipi=1 AND SIGN(H.Miktar)<>CASE WHEN I.IslemTuru=0 THEN 1 ELSE -1 END | HAYIR (H-123 negatif stok teması) | Aktif işlemde Miktar, Adet ve Tutar negatif olmamalı; stok hareketi işareti IslemTuru ile uyumlu olmalı. | Cari.AcceptTransaction (dbclean/modules.json def) satır 274, 284, 336-344; Cari.Islem.vb:513 (yalnız Miktar=0 kontrolü) |
| 14 | MOD-STOK | Stok.GetMadenMaliyeti – son 50 giriş (LIFO), bugünkü kurla bölme, kalan miktara 0 maliyet | Stok.StokHaraketleri (IslemTuru=0, StokTipi=1, Bolum süzgeci yok), Stok.Maden.MaliyetBirimId, Sistem.Kurlar (Order By Tarih Desc, IsDeleted yok) | CURSOR top 50 … Order By IslemId Desc ; ToplamMaliyet += Maliyet (veya orantılı) ; RETURN Convert(dec(18,2), Bol(ToplamMaliyet, (Select top 1 Alis From Sistem.Kurlar Where BirimId=@BirimId Order By Tarih Desc))) | Maliyet yalnız girişteki işçilik TL'sidir (metal değeri yoktur); 50 hareket sınırı nedeniyle çok hareketli stokta eski girişler görülmez ve eldeki miktarın karşılanamayan kısmı 0 maliyetle kalır; kur 'en son tarihli' alındığından geçmiş tarihli stok listesi bugünkü kurla değerlenir; Order By IslemId, Bolum=1/2 (üretim/transfer) satırlarının farklı Id ad alanıyla karışmasına açıktır; @Miktar/@Maliyet Decimal(18,2). | Stok > son 50 girişin toplamı; geçmiş tarihli rapor; maliyet birimi kuru değişimi; transfer ile gelen stok (Maliyet satırı yok) | Birim maliyet düşük/0; maliyet bir günde sıçrar; kur değişince tarihi maliyet değişir | S3 – kâr/maliyet raporları yanlış; bilanço İŞÇİLİK kalemi | YÜKSEK | 90 | SELECT StokId,SubeId,KasaId,COUNT(*) FROM Stok.StokHaraketleri WHERE StokTipi=1 AND IslemTuru=0 GROUP BY StokId,SubeId,KasaId HAVING COUNT(*)>50; eldeki miktarı ilk 50 girişin toplamını aşan stoklar: karşılaştırma sorgusu; Bilanco.GetKurFarki çıktısı | H-120, H-121, H-122, H-129, CTR-SEC-MALIYET-01 | Eldeki miktar, maliyet hesabına giren giriş hareketleri toplamını aşmamalı (aşarsa maliyet eksik). | Stok.GetMadenMaliyeti (modules.json) |
| 15 | MOD-STOK | Ortalama milyem / maliyet cursor değişkenleri Decimal(18,2) – 5 haneli Has/Miktar kesilir | Stok.StokHaraketleri.Miktar/Has decimal(18,5) | Declare @Miktar Decimal(18,2), @Has Decimal(18,2), @ToplamHas Decimal(18,2) … RETURN Fn.Bol(@ToplamHas,@ToplamMiktar) | Her hareket 2 haneye yuvarlanarak toplanır; küçük gramajlı çok sayıda hareket (ör. 0,005 g altı has satırları) ortalama milyemi saptırır; stok listesi Miktar/Has 2 haneye yuvarlanır ancak StokHaraketleri toplamı 5 hanelidir → liste toplamı ≠ hareket toplamı. | Miktar×Milyem 3. ondalıkta anlamlı; çok sayıda küçük hareket | Ortalama milyem ve has stoğu küsuratta yanlış; stok listesi ile hareket dökümü toplamı farklı | S4 – küsurat sapması; birikimli | YÜKSEK | 85 | SELECT StokId,SUM(Miktar) AS M5, SUM(CONVERT(decimal(18,2),Miktar)) AS M2 FROM Stok.StokHaraketleri WHERE StokTipi=1 GROUP BY StokId HAVING SUM(Miktar)<>SUM(CONVERT(decimal(18,2),Miktar)) | CTR-015 | Stok listesi has/miktar değerleri, hareket toplamına 0,01 toleransla eşit olmalı. | Stok.GetOrtMilyem, Stok.GetMadenMaliyeti (modules.json); Stok.GetMadenStok/GetMadenStoklari CONVERT(Decimal(18,2), Miktar) |
| 16 | MOD-STOK | Stok has değeri kart milyemiyle, cari has bakiyesi işlem milyemiyle – stok ve cari türetilmiş kayıtları farklı milyem kullanır | Stok.Maden.Milyem/MilyemDurumu, Cari.Islemler.AuMilyem, Stok.StokHaraketleri.Milyem | Stok listesi: Has = Miktar × (MilyemDurumu='False' ? Maden.Milyem : GetOrtMilyem) ; Pozisyon: Sum(Miktar × StabilMilyem) (=Maden.Milyem her durumda) ; Bakiye: Miktar × AuMilyem (işlem) | İşçilikli milyem ayrıştırması (BR-HESAP-005) veya elle farklı milyem girilen işlemde bakiyeye Miktar×AuMilyem yazılır; stok ve pozisyon ise kart milyemini kullanır. Pozisyon.Write değişken milyemli (MilyemDurumu=True, hurda) kartlarda da sabit kart milyemini alır. Sonuç: BAKIYE ve STOK kalemleri farklı has üretir; bilanço/pozisyon 'tutmaz'. | AuMilyem ≠ Maden.Milyem olan işlemler; MilyemDurumu=True kartlar; negatif işçilikli kart (BR-HESAP-011) | Pozisyon raporunda has farkı; bilanço kâr/zarar hatalı; 'kur değişince bilanço değişiyor' | S3 – yönetim raporlarında has pozisyonu yanlış | ORTA | 75 | SELECT I.Id,I.StokId,I.AuMilyem,M.Milyem,M.MilyemDurumu FROM Cari.Islemler I JOIN Stok.Maden M ON M.Id=I.StokId WHERE I.IsDeleted=0 AND I.IslemKodu IN (1,2) AND I.AuMilyem<>M.Milyem; SELECT StokId,SUM(Has) AS HasHareket, SUM(Miktar)*MAX(Milyem) FROM Stok.StokHaraketleri WHERE StokTipi=1 GROUP BY StokId | H-129, H-130, PRB-BILANCO-000, PRB-POZISYON-000 | Bir stok kodunun StokHaraketleri.Has toplamı, aynı satırların Miktar×Milyem toplamına eşit olmalı; pozisyon has'ı hareket has'ı ile aynı temeli kullanmalı. | Stok.GetMadenStoklari, Stok.GetMadenStok, Pozisyon.Write (modules.json); iFMaden.vb MilyemDegisti (BR-HESAP-005) |
| 17 | MOD-STOK | Transfer kabulünde stok hareketi üretimi (Cari.TransferUpdateSTatus) – eski satırlar silinmiyor | Cari.Transferler (Status), Stok.StokHaraketleri Bolum=2 | if UPDATE(status): Delete From Stok.StokHaraketleri Where StokTipi=-2 AND IslemId in (inserted) ; Insert … Select 2,Id,1,…,CikanKasaId,…,Adet*-1,Miktar*-1 … Where Status=1 ; Insert … GirenKasaId … Where Status=1 | Silme koşulu StokTipi=-2 (var olmayan tip) olduğundan hiçbir zaman eski Bolum=2 satırı silinmez. Transferler.Update() Status kolonunu her zaman yazdığı için UPDATE(status) doğru döner ve Status=1 olan bir transfer her düzenlendiğinde iki stok hareketi daha eklenir. Transferin IsDeleted=1 yapılması veya Status'un 1'den başka değere alınması mevcut hareketleri silmez. | Kabul edilmiş (Status=1) transferin düzenlenmesi/yeniden kaydı; transferin sonradan iptali | Aynı transfer stoktan iki (n) kez düşer/çıkar; iptal edilen transferin stoğu geri gelmez | S2 – kasa/şube stokları çift sayım | ORTA | 80 | SELECT T.Id,T.Status,T.IsDeleted,COUNT(H.IslemId) FROM Cari.Transferler T LEFT JOIN Stok.StokHaraketleri H ON H.IslemId=T.Id AND H.Bolum=2 GROUP BY T.Id,T.Status,T.IsDeleted HAVING (T.Status=1 AND T.IsDeleted=0 AND COUNT(H.IslemId)<>2) OR ((T.Status<>1 OR T.IsDeleted=1) AND COUNT(H.IslemId)>0) | H-114, H-119 teması; BR-TRANSFER-001 | Status=1 ve silinmemiş her transfer için tam 2 adet Bolum=2 stok hareketi; diğer durumlarda 0 olmalı. | Cari.TransferUpdateSTatus (modules.json); Class/Dao/Cari.Transferler.vb:222 (Update tüm kolonları, Status dahil yazar), :272-301 (IsDeleted) |
| 18 | MOD-STOK | Stok.StokHaraketleri.IslemId ad alanı çakışması (Bolum 0 → Cari.Islemler.Id, Bolum 1 → Uretim, Bolum 2 → Transferler.Id) | Stok.StokHaraketleri.IslemId, Bolum | GetStokHareketleri: Left Join Cari.Islemler I on H.IslemId=I.Id (Bolum süzgeci yok) → HesapAdi/Tarih/Fiyat/Tutar başka işlemden; GetTakozAdet: IslemId<>@IslemId (Bolum süzgeci yok) | Transfer/üretim satırlarının IslemId'si Cari.Islemler'deki rastgele bir işlemle çakışır; hareket dökümünde yanlış hesap adı/tarih/tutar görünür; LIFO maliyet sıralaması Id karışımıyla bozulur. AcceptTransaction'daki silme Bolum=0 ile sınırlı olduğundan veri silinmez ama raporlar yanıltır. | Bolum=2 veya Bolum=1 satırının IslemId'si ile aynı Id'li Cari.Islemler satırı | Stok hareket raporunda transfer satırı yanlış tarih/hesapla; maliyet sırası yanlış | S3 – rapor yanılgısı; maliyet sırası | YÜKSEK | 90 | SELECT COUNT(*) FROM Stok.StokHaraketleri H JOIN Cari.Islemler I ON I.Id=H.IslemId WHERE H.Bolum<>0 | H-119 (transfer satırları yanlış tarihte) | Bolum≠0 stok hareketleri Cari.Islemler ile Id üzerinden ilişkilendirilmemeli. | Stok.GetStokHareketleri, Stok.GetTakozAdet, Stok.GetMadenMaliyeti (Order By IslemId) – modules.json; AcceptTransaction satır 259 (Bolum=0 ile sınırlı silme) |
| 19 | MOD-STOK | Pırlanta stok maliyeti = Tutar × FN.GetKur(BirimId) | @Tutar, @BirimId (PEŞİN'de nakit stok Id'si, diğerlerinde birim Id'si), FN.GetKur (bugünün kur listesi) | Declare @Maliyet decimal(18,2) = @Tutar * Fn.GetKur(@BirimId) → StokHaraketleri.Maliyet | GetKur eşleşme bulamazsa NULL döner → Maliyet NULL (bilanço PIRLANTA kalemi Sum ile NULL'u atlar). PEŞİN tipte BirimId nakit stok kimliğidir, birim kimliği değil; yanlış birimin kuru uygulanır. Kur, işlem tarihinin değil bugünün kurudur; düzeltmede de bugünkü kurla yeniden yazılır. Uygulama tarafı (BR-MALIYET-003) farklı formül kullanır (CTR-SEC-PIRLANTA-01). | IslemKodu=8 ve IslemTipi=1; BirimId kur listesinde yok; geçmiş tarihli düzeltme | Pırlanta maliyeti NULL/yanlış birim kuruyla; bilanço PIRLANTA kalemi eksik | S3 – bilanço kalemi hatası | ORTA | 75 | SELECT H.* FROM Stok.StokHaraketleri H WHERE H.StokTipi=4 AND (H.Maliyet IS NULL OR H.Maliyet=0); SELECT I.Id,I.IslemTipi,I.BirimId FROM Cari.Islemler I WHERE I.IslemKodu=8 AND I.IslemTipi=1 AND I.IsDeleted=0 | CTR-SEC-PIRLANTA-01, BR-STOK-004 | StokTipi=4 hareketlerde Maliyet NULL olmamalı. | Cari.AcceptTransaction (dbclean/modules.json def) satır 291-296; FN.GetKur |
| 20 | MOD-STOK | Çeşni ve takoz stok listeleri InsertDate ile, stok hareketleri Tarih ile süzülür | Cari.Islemler.InsertDate vs Tarih; Stok.StokHaraketleri.Tarih | GetCesniStoklari/GetTakozSubeStoklari: CONVERT(date,InsertDate)<=@Tarih ; StokHaraketleri: Tarih<=@Tarih ; BakiyeIslem.Tarih = I.Tarih | Geçmiş tarihe girilen çeşni/takoz işlemi bilançoda kayıt gününe, cari bakiyede işlem gününe düşer; tarihli bilanço iki kalemde farklı kesim kullanır ve tutmaz. Ayrıca trigger değişkeni @InsertDate aslında I.Tarih'i taşır (isim yanıltıcı); devir kesimi bu alana dayanır. | Geçmiş tarihli takoz/çeşni işlemi; devir kesim tarihine yakın kayıtlar | Tarihli bilanço/pozisyon farkı; devirde satırın yanlış döneme düşmesi | S3 – rapor kesim hatası | ORTA | 85 | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu IN (0,14) AND CONVERT(date,InsertDate)<>Tarih | H-108 (devir kesimi), H-130 | Stok ve bakiye türetimleri aynı tarih alanını (Tarih) esas almalı. | Stok.GetCesniStoklari, Stok.GetTakozSubeStoklari (modules.json); AcceptTransaction satır 72-75 (@InsertDate = I.Tarih) |
| 21 | MOD-CARI | Nakit tip 10 (PARİTE) satırı doğrudan kaydedilirse ters işaretli bakiye ve BirimId=0 satırı | IslemKodu=3, IslemTipi=10, BakiyeId (nakitte daima 0 – Cari.IslemEx.vb:291-303), Tutar | satır 318-330: Insert BakiyeIslem(BirimId=@BakiyeId, Bakiye=±@Miktar) ; satır 421-425: Insert BakiyeIslem(BirimId=@BirimId, Bakiye=@Tutar*-1) | Ekran PARİTE'yi yeni kayıtta iki NORMAL bacağa çevirir; ancak mevcut kayıt düzenlenirken (RecordId≠0) tip PARİTE seçilirse satır IslemTipi=10 ile kaydedilir. Trigger bu satır için BirimId=0 (Birimler'de yok) bir bakiye satırı ve normal nakit kuralının tersi işaretli tutar satırı yazar. Bakiye kartı BirimId=0 satırını göstermez; ToplamBakiye/bilanço Carpan NULL nedeniyle atlar; tutar satırı ise müşteri bakiyesini ters yöne çevirir. | IslemTipi=10 olarak kaydedilmiş nakit satırı (düzeltme yolu) | Müşteri TL bakiyesi ters işaretli; görünmeyen BirimId=0 bakiye satırı | S2 – bakiye yönü hatası | DÜŞÜK | 65 | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=3 AND IslemTipi=10; SELECT * FROM Cari.BakiyeIslem WHERE BirimId=0 OR BirimId IS NULL | CTR-027, BR-YON-004, H-080 | Cari.BakiyeIslem.BirimId ∈ Sistem.Birimler.Id ∪ {-1} olmalı; 0/NULL olmamalı. | Cari.AcceptTransaction (dbclean/modules.json def) satır 318-330, 421-425; Controls/Islem Ekranı/Ekran/iFNakit.vb:91-96, 323-330 |
| 22 | MOD-CARI | Çeşni (IslemKodu=14) bakiye satırları yönden bağımsız pozitif yazılır | IslemKodu=14, Miktar, AuMilyem, AgMilyem, IslemTuru | Values(…,@HasBirimId,@Miktar * @AuMilyem) ; Values(…,@GumBirimId,@Miktar * @AgMilyem) (IslemTuru'na göre işaret yok) | Ekran her zaman ÇIKIŞ yazdığı için sonuç doğru görünür; ancak satır Düzelt ile tür değiştirilirse ya da seri/sonradan eklenen bir yol GİRİŞ çeşnisi yazarsa bakiye yine borç (+) olarak kalır. Ayrıca çeşni satırı IslemKodu∉{0,1,2,4,5,6,9} olduğu için 'diğer stok işlemi' bloğuna da girer; Tutar≠0 ise ek bir tutar satırı yazılır. | IslemKodu=14 ve IslemTuru∈{0,2,4}; Tutar≠0 çeşni satırı | Çeşni girişinde müşteri alacaklanacağına borçlanır | S3 – yön hatası (nadir yol) | DÜŞÜK | 70 | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=14 AND (IslemTuru<>1 OR ISNULL(Tutar,0)<>0) | BR-BAKIYE-004, BR-HESAP-020, CTR-039 | IslemKodu=14 satırlarında IslemTuru=1 ve Tutar=0 olmalı. | Cari.AcceptTransaction (dbclean/modules.json def) satır 311-317; Controls/Islem Ekranı/Ekran/iFCesni.vb:60-69 (IslemTuru daima CIKIS) |
| 23 | MOD-CARI | Raporsuz takoz bakiyesi: XRF milyemi 0 ise TAKOZ (-1) birimine miktar; değerleme 0,6 varsayımı | Stok.Takoz.XRFAuMilyem/XRFAgMilyem, IsRapor, Miktar(+CesniMiktar girişte) | IsRapor=0 ⇒ @AuMilyem=XRFAuMilyem ; (@AuMilyem=0 And @AgMilyem=0) ⇒ Insert BakiyeIslem(BirimId=-1, Bakiye=∓Miktar) ; NetBakiye = Bakiye*0.6 ; Bakiye.GetBakiye: Case When XRFAuMilyem=0 Then 0.6 ; Pozisyon.Write: Miktar*0 ; Bilanço: Miktar*0.6 | Aynı raporsuz takoz üç yerde üç farklı has değeriyle değerlenir (0; 0,6; kart Miktar*0,6 vs bakiye Miktar). Rapor geldiğinde işlem düzeltilmezse bakiye TAKOZ satırında kalır; düzeltme (Geri Al/Düzelt) anındaki XRF değerleri orijinal kayıttan farklıysa bakiye yeniden üretimde değişir. | IsRapor=0 ve XRF milyemleri 0; rapor sonrası düzeltilmemiş takoz; XRF sonradan güncellenen takoz | Pozisyon 0, bilanço 0,6, bakiye kartı miktar bazlı – üç rapor tutmaz | S3 – rafineri/ayar evi kurulumlarında has pozisyonu belirsiz | ORTA | 85 | SELECT HesapId,SUM(Bakiye) FROM Cari.BakiyeIslem WHERE BirimId=-1 GROUP BY HesapId HAVING SUM(Bakiye)<>0; SELECT T.Id FROM Stok.Takoz T WHERE T.IsRapor=1 AND EXISTS(SELECT 1 FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.StokId=T.Id AND I.IslemKodu=0 AND B.BirimId=-1) | CTR-SYM-TAKOZ-01, BR-BAKIYE-008/009, GAP-TAKOZ-FIRE, H-117, H-130 | Raporlu (IsRapor=1) takozun işlemlerinde BirimId=-1 bakiye satırı kalmamalı; raporsuz takoz değerleme katsayısı tüm raporlarda aynı olmalı. | Cari.AcceptTransaction (dbclean/modules.json def) satır 452-458, 554-558; Cari.BakiyeIslem.NetBakiye computed; Bakiye.GetBakiye; Pozisyon.Write; Bilanco.OzetBilanco |
| 24 | MOD-CARI | İptalin geri alınması / mutabakat gibi her UPDATE'te bakiye ve stoğun güncel referans verisiyle yeniden üretilmesi | Inserted (herhangi bir kolon güncellemesi), Stok.Takoz XRF milyemleri, Sistem.Settings sembolleri, Fn.GetKur(bugün) | Her UPDATE'te: Delete BakiyeIslem/StokHaraketleri(Bolum=0) → yeniden Insert (XRF milyem, HasBirimId, Fn.GetKur bugünkü değerlerle) | Türetilmiş kayıtlar işlem satırındaki kur fotoğrafıyla değil o anki referans verilerle (takoz XRF milyemi, Settings sembolleri, pırlanta için bugünkü kur) yeniden hesaplanır. 'Geri Alındı', mutabakat, hesap birleştirme gibi işlem tutarını değiştirmeyen güncellemelerde bile bakiye satırları değişebilir; Cari.Hesaplar.LastDate güncellenir. Sonuç, tarihi bakiye ekstresinde açıklanamayan değişikliktir (History'de işlem alanları aynı görünür). | XRF milyemi/Settings/kur değiştikten sonra eski işlemin herhangi bir nedenle güncellenmesi | Kimse işlem değiştirmeden bakiye değişir (H-105'in kod bağlantısı) | S3 – bakiye değişimi izlenemez | ORTA | 75 | SELECT B.IslemId FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.LastModify IS NULL AND I.MTarih IS NOT NULL – mutabakat yapılmış işlemlerde BakiyeIslem toplamı ile History'deki orijinal Miktar×AuMilyem karşılaştırılır | H-105 (bakiye birden değişti), BR-BAKIYE-014 | Bir işlemin BakiyeIslem toplamı, işlem alanları değişmedikçe (History 'Düzeltme' yoksa) sabit kalmalı. | Cari.AcceptTransaction (dbclean/modules.json def) satır 256-260, 293, 452-455; iScreen.vb:1136 (F12 mutabakat UPDATE) |
| 25 | MOD-CARI | Fiş numarası üretimi MAX(FisNo)+1 (silinmemişler) ve fiş bazlı toplu iptal | Cari.Islemler.FisNo (unique değil, IX_FisNo), IsDeleted; Program.KasaId | GetNewFisNo = Val(Select Max(FisNo) From Cari.Islemler Where IsDeleted='False') + 1 ; onIptalFisNoClick: Update Cari.Islemler Set IsDeleted='True' Where FisNo=@FisNo and KasaId=@KasaId | (a) İki kullanıcı aynı anda aynı fiş numarasını alır (yarış). (b) Son fişin tüm satırları iptal edilince numara yeniden kullanılır; iptal edilen fişle yeni fiş aynı numarayı paylaşır. (c) Fiş-No ile iptal, tarih süzgeci olmadan kasadaki aynı numaralı tüm satırları (farklı günler dahil) sessizce iptal eder; açıklama/onay/karşı bacak kontrolü yapmaz. | Eşzamanlı kayıt; son fişin iptali; aynı FisNo'ya sahip farklı günlerdeki satırlar | Yanlış işlemlerin toplu iptali (bakiye/stok geri alınır); fiş bakiyesi (GetFisBakiye FisNo<=) yanlış | S2 – yanlış işlemlerin iptali | ORTA | 85 | SELECT FisNo,KasaId,COUNT(DISTINCT Tarih) FROM Cari.Islemler GROUP BY FisNo,KasaId HAVING COUNT(DISTINCT Tarih)>1; SELECT FisNo,COUNT(DISTINCT HesapId) FROM Cari.Islemler WHERE IsDeleted=0 GROUP BY FisNo HAVING COUNT(DISTINCT HesapId)>1 | H-102, CTR-012, CTR-016 | Aynı kasada aynı FisNo yalnız tek bir güne ve tek bir hesaba ait olmalı. | Class/Ext/Cari.IslemEx.vb:256-260; Controls/Islem Ekranı/Base Control/iScreen.vb:720-728 |
| 26 | MOD-CARI | Çift kayıt (duplicate posting) – zaman aşımı/ağ kopması sonrası tekrar kayıt | Insert (InternalDb.ExecuteScalar → hata MsgBox, RecId=0), RefNo (her nesnede yeni GUID), unique index yok | Try RecId=db.ExecuteScalar() Catch … End Try ; If RecId>0 Then Id=RecId … Else Return False | Sunucu INSERT'i işledikten sonra yanıt istemciye ulaşmazsa (timeout 30 sn, ağ) uygulama hata gösterir ve kayıt başarısız sanılır; kullanıcı tekrar F2 basar. RefNo her nesnede yeni GUID olduğundan ve FisNo/hesap/tutar için benzersizlik yoktur, ikinci satır sessizce kabul edilir. | Ağ kesintisi/uzun tetikleyici süresi (AcceptTransaction cursor + GetGerekliEvraklar) sırasında kayıt | Aynı işlem iki kez bakiye ve stoğa yazılır | S2 – çift bakiye/stok | ORTA | 75 | SELECT a.Id,b.Id FROM Cari.Islemler a JOIN Cari.Islemler b ON b.Id>a.Id AND b.HesapId=a.HesapId AND b.Tarih=a.Tarih AND b.IslemKodu=a.IslemKodu AND b.IslemTuru=a.IslemTuru AND ISNULL(b.Kodu,'')=ISNULL(a.Kodu,'') AND b.Miktar=a.Miktar AND b.Tutar=a.Tutar AND ABS(DATEDIFF(second,a.InsertDate,b.InsertDate))<=60 WHERE a.IsDeleted=0 AND b.IsDeleted=0 | TD-01 teması; PRB-BAGLANTI-000 | Aynı hesap/tarih/kod/yön/miktar/tutar ile 60 sn içinde ikinci aktif işlem olmamalı. | Class/Dao/Islem/Cari.Islem.vb:694-709; Class/Module/InternalDb.vb:69-81; dbclean/indexes.json (Cari.Islemler unique yalnız PK) |
| 27 | MOD-CARI | Çok adımlı kayıt zincirlerinde transaction yokluğu (Insert→RsAktar, Save→SendTo karşı bacak, parite iki bacak, Update→Takoz.RaporYaz) | Cari.Islem.Insert/Update, iFormBase.SendTo, iFNakit.SaveCashTransaction | RecId = db.ExecuteScalar() ; If RSAktar … db.ExecuteNonQuery("Cari.RsAktar " & RecId) ; … SendTo: I.Id=0; I.HesapId=karşı; I.IslemTuru=GetKarsiIslemTuru; I.Save | İlk bacak yazıldıktan sonra ikinci adım (karşı hesap limiti/evrak/pasif şube nedeniyle trigger reddi, ağ) başarısız olursa uyarı çıkar ama ilk bacak kalır: virman/parite/transfer tek taraflı, RsAktar eksik. İptalde RefNo+IslemKodu ile karşı bacak aranır; farklı IslemKodu'lu eşler (yoksa) bulunmaz. | Karşı hesapta zorunlu evrak eksik, limit aşımı, şube pasif; ağ kesintisi | İki hesabın bakiye toplamı sıfırlanmaz; parite ikinci döviz stoğu değişmez | S2 – tek taraflı bakiye/stok | ORTA | 90 | SELECT RefNo,COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=11 GROUP BY RefNo HAVING COUNT(*)<>2; parite: SELECT a.Id FROM Cari.Islemler a WHERE a.IsDeleted=0 AND a.IslemKodu=3 AND a.VaryantId=-1 AND NOT EXISTS(SELECT 1 FROM Cari.Islemler b WHERE b.VaryantId=a.Id AND b.IsDeleted=0) | TD-01, H-106, H-063, BR-VIRMAN-002 | Virman (IslemKodu=11) RefNo'su tam iki aktif satır taşımalı; parite birinci bacağının (VaryantId=-1) ikinci bacağı (VaryantId=Id) bulunmalı. | Class/Dao/Islem/Cari.Islem.vb:694-700, 987-993; Controls/Islem Ekranı/Ekran/iFormBase.vb:218-264; iFNakit.vb:180-300 |
| 28 | MOD-CARI | Cari.UpdateTransaction – çok satırlı UPDATE'te tek satır değişkeni; Mutabakat güncellemesi history üretmez | Inserted/Deleted (çok satır), Cari.IslemDetaylari.ETTN | Select @IsDeleted=I.IsDeleted, @IslemId=D.IslemId, @Ettn=D.ETTN from inserted I Left Join IslemDetaylari D … (tek değer) ; Set @Status=(Select top 1 … From Inserted) ; if NOT Update(Mutabakat) … | RefNo/FisNo ile toplu iptalde yalnız rastgele bir satırın IslemDetaylari kaydı silinir/EIPTAL yapılır; diğer satırların belge detayları aktif kalır (belge havuzu görünümü iptal edilmiş işlemi belgeli sayabilir). Mutabakat ve Mutabakat ile birlikte başka alan değişen güncellemelerde hiç history yazılmaz. | Birden çok satırı etkileyen UPDATE; Mutabakat kolonunu içeren UPDATE | Belge havuzunda iptal edilmiş işlem 'F' durumunda kalır; history eksik | S3 – belge/kontrol görünümü tutarsızlığı | ORTA | 85 | SELECT D.IslemId FROM Cari.IslemDetaylari D JOIN Cari.Islemler I ON I.Id=D.IslemId WHERE I.IsDeleted=1 AND ISNULL(D.ETTN,'')='' ; SELECT I.Id FROM Cari.Islemler I WHERE NOT EXISTS(SELECT 1 FROM Cari.History H WHERE H.TransactionId=I.Id) | HAYIR (H-105 history okuma akışı) | İptal edilmiş (IsDeleted=1) ve e-belgesi olmayan işlemin IslemDetaylari satırı kalmamalı; her işlemin en az bir History satırı olmalı. | Cari.UpdateTransaction (modules.json) |
| 29 | MOD-FINANS | Uygulama yuvarlama yardımcıları: .Round(n) uzantısı keser (truncate) ve hane parametresini yok sayar; Math.Round banker's; ToNumeric/TextN kültür varsayımı | Double değerler (BSMV, tutar), Utils.Culture (ondalık '.', binlik ',') | Round(Value,Decimals): Values=Value.ToString.Split(".") ; Result=Values(0)+"."+Left(Values(1),2) ; Val(Result) ; ToNumeric = Val(Replace(Value,",","")) ; Math.Round(x,2) = MidpointRounding.ToEven | Vadeli ve hızlı satışta BSMV = (Tutar×BSMV/1000).Round(2) her zaman aşağı kesilir (12,999→12,99), hane parametresi 2'ye sabittir, bilimsel gösterim (1E-05) ve kültür ayarı '.' değilse Catch ile yuvarlanmadan döner. Nakit/parite ekranı Math.Round (bankacı yuvarlama) kullanırken SQL Convert(decimal(18,2)) yarım-yukarı yuvarlar → 0,005'lik değerlerde ekran/rapor farkı. Parite tutarları 0 haneye yuvarlanır (Round(...,0)). | BSMV küsuratı 3. hanede ≥5; tutar×fiyat tam yarım kuruş; kültür/ondalık ayarı farklı iş parçacığı | Vergi tutarı 1 kuruş eksik; ekran ile SQL raporu arasında kuruş farkı; parite TL bacağı ±0,5 TL | S4 – kuruş düzeyinde sistematik sapma (vergi tarafında birikimli) | YÜKSEK | 90 | SELECT Id,Tutar,BSMV,ROUND((Tutar-BSMV)*(SELECT BSMV FROM Sistem.Settings)/1000,2) AS BSMVHesap FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu IN (3,6) AND BSMV<>0 AND ABS(BSMV-ROUND((Tutar-BSMV)*(SELECT BSMV FROM Sistem.Settings)/1000,2))>0.011 | CTR-010, BR-BSMV-003/004 | Kayıtlı BSMV, (Tutar−BSMV)×BSMVOran/1000 değerine ±0,01 toleransla eşit olmalı. | Class/Module/Extention.vb:437-450, 366-368; Controls/Editor/TexBoxEdit.vb:100-105; iFVadeli.vb:755; HizliSatisEkrani.vb:688-737; iFNakit.vb:452,463-471; iFDoviz.vb:95-181 |
| 30 | MOD-FINANS | Nakit BSMV geri hesabı (Tutar'dan fiyat) ileri formülün tersi değil | TxtTutar (BSMV dahil), GlobalSettings.BSMV (binde), IsBsmv | İleri: BSMV = Net×BSMV/1000 ; TUTAR = Round(Net+BSMV,2) ; Geri (TxtTutar LostFocus): Net ≈ Tutar − Tutar×BSMV/1000 (brütten kesinti) | Tutar elle girildiğinde net tutar ve fiyat yaklaşık hesaplanır; ardından TutarHesapla yeniden tetiklenirse Tutar ilk girilenden farklı olur (100.000 → 99.999,60). Kayıtlı BSMV ile Tutar arasındaki ilişki işlemden işleme değişir; e-belge vergi matrahı (Calc.BSMV) farklı formülle (BSMVOran) hesaplandığından belge ile işlem satırı uyuşmayabilir. | IsBsmv ve Tutar elle girilmiş; BSMV ayarı Dahil/Hariç | Belge vergi tutarı ile işlem BSMV alanı farklı; tutar 40 kuruş sapar | S4 – kuruş/TL düzeyinde vergi farkı; mutabakat sorusu | YÜKSEK | 85 | SELECT Id,Tutar,BSMV,Miktar,Fiyat, Miktar*Fiyat AS Net FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu=3 AND BSMV<>0 AND ABS((Miktar*Fiyat+BSMV)-Tutar)>0.011 | BR-BSMV-003, CTR-010 | Nakit satırında Tutar = Miktar×Fiyat + BSMV (±0,01) olmalı. | Controls/Islem Ekranı/Ekran/iFNakit.vb:440-472; Class/Module/ExtensionEx.vb:16-44 |
| 31 | MOD-CARI | Maliyet/İşçilik hesabı Double ile; negatif işçilik 0'a çekilir; kur 0 ise işçilik 0 | Miktar, AuMilyem, AnaBirim.Price, TutarBirim.Price, MaliyetBirim.Price (bellek kur listesi Alis) | MiktarMaliyeti=(Miktar×AuMilyem)×AnaBirim.Price ; Giriş: Iscilik=(TutarMaliyeti−MiktarMaliyeti).Divide(MaliyetBirim.Price) ; If Iscilik<0 Then Iscilik=0 ; Maliyet=Satis=TutarMaliyeti | Müşteriden metal değerinin altında alış (negatif işçilik = iskonto) 0 işçilikle kaydedilir; StokHaraketleri.Maliyet (=Iscilik×Kur) 0 olur, gerçek kazanç maliyet raporunda görünmez. Maliyet birimi kuru 0/eksikse Divide 0 döndürür ve işçilik sessizce 0 yazılır. Tüm hesap Double'dır; decimal(18,2) kolonlara dönüşümde bankacı/yarım-yukarı farkı. | TutarMaliyeti < MiktarMaliyeti (iskontolu alış); MaliyetBirim kuru 0; kur listesi eksik | Kâr raporunda alış iskontosu kaybolur; maliyet 0 | S3 – kâr/maliyet raporu | ORTA | 80 | SELECT Id,Miktar,AuMilyem,HasKur,Tutar,BirimKur,Iscilik FROM Cari.Islemler WHERE IsDeleted=0 AND IslemKodu IN (1,9) AND IslemTuru=0 AND IslemTipi NOT IN (1,2,5) AND Iscilik=0 AND (Tutar*BirimKur) < (Miktar*AuMilyem*HasKur) | BR-MALIYET-001, GAP-DOC-05, GAP-SEC-ISCILIK-02 | Girişte Iscilik×IscilikBirimKur ≈ Tutar×BirimKur − Miktar×AuMilyem×HasKur (negatif değer 0'a çekilmemeli). | Class/Ext/Cari.IslemEx.vb:122-146, 185-212 |
| 32 | MOD-RAPOR | Bilanco.OzetBilanco – kalemler farklı kesim tarihleri ve varsayımlarla toplanır | Cari.BakiyeIslem (Tarih<=@Tarih), masraf hesapları (HesapTuru=4, tarih süzgeci yok), IslemKodu=5 GELİR/GİDER (Tarih=@Tarih tek gün), takoz 0,6, GetKurListesi(@Tarih) | BAKIYE: B.Tarih<=@Tarih … GELIR/GIDER(masraf bakiyesi): Where H.HesapTuru=4 (tarih yok) ; GELİR/GİDER(hizmet): Tarih>S.RevCostDate And Tarih=@Tarih ; TAKOZ: R='False' ⇒ Miktar*0.6 ; Net = Bol(Bakiye*K1.Alis, K2.Alis) | Geçmiş tarihli bilanço masraf hesaplarının bugüne kadarki tüm bakiyesini içerirken diğer kalemler kesim tarihine kadar alınır; hizmet gelir/gideri yalnız kesim günü toplanır; raporsuz takoz bilançoda 0,6, pozisyonda 0 ile değerlenir; kur listesi eksikse Net 0. Uygulama KÂR/ZARAR = TOPLAM−DEVİR olarak önceki satırla hesaplandığından her hata bir sonraki güne taşınır (SaveAll o günü silip yeniden yazar). | Geçmiş tarih için bilanço; masraf hareketi olan dönem; raporsuz takoz stoğu; kur eksik gün | Bilanço eksi/artı sapar; günlük kâr-zarar yanlış; pozisyon ile bilanço tutmaz | S3 – yönetim raporu yanlış (karar riski) | YÜKSEK | 70 | Aynı @Tarih için Bilanco.OzetBilanco'yu iki farklı günde çalıştırıp Bilanco.Bilancolar arşiviyle karşılaştırın: SELECT Tarih,SubeId,Cinsi,Kodu,Bakiye FROM Bilanco.Bilancolar WHERE Tarih=@T EXCEPT SELECT @T,SubeId,Cinsi,Kodu,Bakiye FROM Bilanco.OzetBilanco(@Sube,@T) | H-128, H-129, H-130, CTR-SYM-TAKOZ-01, PRB-BILANCO-000 | Aynı kesim tarihi için bilanço yeniden hesaplandığında arşivlenen (Bilancolar) değerle eşit olmalı. | Bilanco.OzetBilanco, Bilanco.SaveAll, Pozisyon.Write (modules.json); Class/Ext/Sistem.Bilanco.vb:172-211 |
| 33 | MOD-RAPOR | Bilanco.GetIKar – parametre/sabit karışıklığı (KasaId=SubeId, BirimId=1=HAS, Satis kuru, ham bölme) | Cari.BakiyeIslem.KasaId (SubeId parametresiyle karşılaştırılır), GetKurListesi BirimId=1, Kur.Satis | Where B.KasaId=@SubeId … Bakiye*Kur.Satis / kur1.Alis (Kur1.BirimId=1) | Kasa kimliği şube kimliği yerine kullanılır (yalnız Id'ler çakışırsa sonuç döner); HAS için Id=1 varsayımı; bakiye satış kuruyla, stok alış kuruyla değerlenir; Fn.Bol yerine ham bölme (kur 0'da hata – sessiz değil ama kur yoksa NULL çarpımı sessiz NULL). | KasaId≠SubeId kurulum; BirimId 1 ≠ HAS; kur eksik | İşlem bazlı kâr raporu boş/yanlış | S3 – rapor | ORTA | 75 | SELECT COUNT(*) FROM Sistem.Kasalar K WHERE K.Id<>K.SubeId; SELECT Kodu FROM Sistem.Birimler WHERE Id=1 | HAYIR (PRB-RAPOR-000) | Rapor fonksiyonları HAS birimini Settings.HasSymbol üzerinden çözmeli, sabit Id kullanmamalı. | Bilanco.GetIKar (modules.json) |
| 34 | MOD-SISTEM | Sistem.Devir (SQL) – açılış satırlarında has/milyem sıfır, takoz/pırlanta stokları ve tarihsiz satırlar düşer, 2 hane yuvarlama | Stok.GetNakitStoklari/GetMadenStoklari(@Tarih-1), Stok.StokHaraketleri (StokTipi 1,2), Cari.BakiyeIslem (Tarih<@Tarih), GetKurListesi(getdate()) | #TBLStokHaraketleri(Miktar dec(18,2), Has dec(18,2)) ; maden açılış: 0 as Milyem, 0 as Has, Maliyet*K.Alis(bugün) ; truncate StokHaraketleri/BakiyeIslem ; yalnız StokTipi in (1,2) ; Tarih<@Tarih / Tarih>=@Tarih (NULL düşer) | Devir sonrası maden açılış hareketinin Has=0 ve Milyem=0 olduğu için GetOrtMilyem/GetMadenStok has stoğu ve ortalama milyem sessizce bozulur; takoz (StokTipi 3) ve pırlanta (4) adet stokları sıfırlanır (GetTakozAdet 0 → 'takoz stokta yok'); Tarih NULL satırlar hiçbir dilime girmediği için kaybolur; miktar/has 2 haneye yuvarlanır; maliyet devir günü değil çalıştırma günü kuruyla çevrilir. Tetikleyiciler kapatılıp açılır; arada hata olursa açık kalmayabilir (H-006). | Yıl sonu devri; devir öncesi alınıp sonra çıkılan takoz; Tarih NULL kayıt; devirin kesim tarihinden sonra çalıştırılması | Devir sonrası stok has/milyem/maliyet yanlış; takoz çıkışı engellenir veya eksi adet; bakiye eksik | S2 – devir sonrası stok ve bakiye tutarsızlığı | ORTA | 85 | SELECT * FROM Stok.StokHaraketleri WHERE IslemId=-1 AND StokTipi=1 AND (Has=0 OR Milyem=0) AND Miktar<>0; SELECT COUNT(*) FROM Stok.StokHaraketleri WHERE Tarih IS NULL; SELECT COUNT(*) FROM Cari.BakiyeIslem WHERE Tarih IS NULL; SELECT StokId,SUM(Adet) FROM Stok.StokHaraketleri WHERE StokTipi=3 GROUP BY StokId HAVING SUM(Adet)<0 | H-108, H-111, H-130, GAP-DEVIR-SCOPE, CTR-034, PRB-DEVIR-000, H-006 | Devir açılış satırları (IslemId=-1) StokTipi 1 için Has ve Milyem taşımalı; StokHaraketleri/BakiyeIslem'de Tarih NULL satır olmamalı; devir öncesi/sonrası bakiye toplamları hesap+birim bazında eşit olmalı. | Sistem.Devir (modules.json) |
| 35 | MOD-SISTEM | Devir.vb (uygulama devri) – Sum(Milyem) ile açılış satırı, tarih=çalıştırma günü, transaction yok | Stok.StokHaraketleri (StokTipi 1,2), Cari.BakiyeIslem | INSERT #ERPStok Select -1,0,IslemTuru,Getdate(),SubeId,KasaId,StokTipi,StokId,Sum(Adet),Sum(Miktar),Sum(Milyem),Sum(Has),Sum(Maliyet),VaryantId … Group by IslemTuru,… ; Truncate Cari.Islemler/BakiyeIslem/History/StokHaraketleri/IslemDetaylari ; Insert … | Milyem sütunu toplanır (100 satır × 0,916 = 91,6) → NetBakiye hesaplanan sütunu ve GetStokHareketleri'nin Has=Miktar×Milyem gösterimi anlamsız; giriş/çıkış satırları ayrı toplandığı için LIFO maliyet/ortalama milyem yalnız giriş satırlarını görür; takoz/pırlanta yine düşer; Tarih=GETDATE (kesim değil); truncate ile insert arasında transaction yok – hata halinde tablolar boş kalır (yedek dışında geri dönüş yok). | Devir.vb ile devir; hareketli stok kartları; devir sırasında hata | Devir açılış satırında Milyem>1; stok has/maliyet yanlış; tam veri kaybı riski | S2 – devir sonrası stok bozulması; S1 hata halinde | ORTA | 85 | SELECT * FROM Stok.StokHaraketleri WHERE IslemId=-1 AND Milyem>1; SELECT * FROM Stok.StokHaraketleri WHERE IslemId=-1 AND StokTipi=1 AND ABS(Has - Miktar*Milyem)>0.01 | CTR-034, GAP-PROCESS-03, H-108 | StokHaraketleri.Milyem ≤ 1 olmalı; açılış satırında Has = Miktar×Milyem tutmalı. | Class/Module/Devir.vb:36-87, 128 |
| 36 | MOD-SISTEM | Repair.BalanceRepair – güncel tetikleyiciden geride kalmış tam yeniden kurma | Cari.Islemler (IsDeleted=0) – tümü | Truncate Cari.BakiyeIslem ; Truncate Stok.StokHaraketleri ; cursor: eski kural seti (tip 11/12 hariç tutma yok; kod 14, 9, 8, 3/10, 5 dalları yok; nakit tip 4 istisnası yok; has satırında IslemTipi<>1 yok; IsRapor=0+XRF dalı yok; Bolum/VaryantId yazılmaz) | Çalıştırılırsa devir (IslemId=-1), transfer (Bolum=2) ve üretim (Bolum=1) satırları kalıcı silinir; tip 11/12 satırları için bakiye/stok üretilir (tetikleyici üretmez); MAHSUP/belge tipleri bakiyeye girer; çeşni, model, pırlanta, hizmet (5), nakit emanet satırları eksik kalır; PEŞİN maden has bakiyesi yazılır. Hata mesajı yok; tablolar dolu görünür. | Prosedürün elle çalıştırılması (destek/geliştirici) | Tüm bakiyeler ve stoklar sistematik olarak farklı kural setiyle yeniden yazılır; devir/transfer verisi kaybı | S1 – kurulum genelinde veri kaybı | DÜŞÜK | 95 | Çalıştırılmış mı: SELECT COUNT(*) FROM Cari.BakiyeIslem WHERE IslemId=-1; SELECT COUNT(*) FROM Stok.StokHaraketleri WHERE Bolum<>0; sıfırsa ve devir/transfer geçmişi varsa çalıştırılmış olabilir; ayrıca tip 11/12 için BakiyeIslem var mı: SELECT COUNT(*) FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.IslemTipi IN (11,12) | TERM-REPAIR-BALANCEREPAIR, KNOWN_GAPS TD-BALANCEREPAIR, SYM-BAKIYE (çalıştırılmaz), proje notu erpgoldv2-balancerepair-riski | Devir (IslemId=-1) ve Bolum≠0 türetilmiş satırlar hiçbir onarımda silinmemeli; onarım kural seti tetikleyiciyle birebir olmalı. | Repair.BalanceRepair (modules.json); karşılaştırma: Cari.AcceptTransaction satır 263, 281, 291-302, 311-330, 346, 363, 516 |
| 37 | MOD-SISTEM | Repair.StokRepair – ikinci FETCH'te değişken sayısı uyumsuz (17 ≠ 18) | Cari.Islemler (IsDeleted=0) | Truncate Table Stok.StokHaraketleri ; FETCH NEXT … INTO 18 değişken (ilk) ; döngü sonunda FETCH NEXT … INTO 17 değişken (@VaryantId eksik) | İlk satır işlendikten sonra ikinci FETCH 'number of variables … must match' hatasıyla durur; TRUNCATE zaten autocommit ile kalıcı olduğundan stok hareket tablosu tek satırla kalır. Prosedür hata verir ancak veri kaybı gerçekleşmiştir. | Prosedürün çalıştırılması | Tüm stok hareketleri silinir; stok listeleri boş | S1 – stok verisi kaybı | DÜŞÜK | 90 | Tanım karşılaştırması: OBJECT_DEFINITION(OBJECT_ID('Repair.StokRepair')) içindeki iki FETCH NEXT satırındaki değişken sayısı; çalıştırılmış mı: SELECT COUNT(*) FROM Stok.StokHaraketleri | TD-BALANCEREPAIR teması | Onarım prosedürleri TRUNCATE'i yalnız başarılı yeniden kurma ile aynı transaction içinde yapmalı. | Repair.StokRepair (modules.json) – son FETCH satırı |
| 38 | MOD-SISTEM | Sistem.Settings tek satır varsayımı; Save = TRUNCATE + INSERT (transaction yok) | Sistem.Settings (HasSymbol, GumSymbol, PltSymbol, PldSymbol, BSMV, OnsCarpan, IslemKurFarki…) | GlobalSettings.Save: Truncate Table Sistem.Settings ; Insert Into Sistem.Settings(...) Values('…') ; Trigger: @HasBirimId=(Select Id From Birimler Where Kodu=(Select HasSymbol From Sistem.Settings)) | INSERT başarısız olursa (tip dönüşümü, kolon uyumsuzluğu) tablo boş kalır: tetikleyici sembolleri NULL alır, takoz/çeşni bakiye satırları BirimId NULL ile yazılır (bakiye kartında görünmez), uygulama varsayılanlarla (BSMV=0, OnsCarpan=31,1035, IslemKurFarki=0) çalışır – kur farkı uyarısı ve BSMV sessizce kapanır. İki satır oluşursa trigger 'subquery returned more than 1 value' ile tüm işlemleri durdurur. Read() 'Do While Dr.Read' ile son satırı alır. | Ayar kaydı sırasında hata; elle satır ekleme; sembolün Birimler'de olmaması | BirimId NULL bakiye satırları; vergi/uyarı kontrolleri kapanır | S1 – kurulum genelinde bakiye/vergi hesabı bozulur (düşük olasılık) | DÜŞÜK | 80 | SELECT COUNT(*) FROM Sistem.Settings; SELECT COUNT(*) FROM Cari.BakiyeIslem WHERE BirimId IS NULL; SELECT s.HasSymbol FROM Sistem.Settings s WHERE NOT EXISTS(SELECT 1 FROM Sistem.Birimler b WHERE b.Kodu=s.HasSymbol AND b.IsDeleted=0) | GAP-DB-06 | Sistem.Settings tam 1 satır içermeli; sembol kolonları Birimler'de tekil eşleşmeli. | Form/Settings/Settings.vb:121-138; AcceptTransaction satır 64-67; Uretim.TrBakiyeHesapla |
| 39 | MOD-SISTEM | Sistem.Birimler.Kodu benzersiz değil; kur listesi ve bakiye toplamları kod ile birleştirilir | Sistem.Birimler (unique index yalnız PK), ToplamBakiye/OzetBilanco/Pozisyon.Write 'Kur.Birim = Kodu' join'leri | Left Join Sistem.GetKurListesi(Getdate()) Kur on Kur.Birim = Bak.Kodu | Aynı kodlu iki birim (silinip yeniden açılan) kur listesinde iki satır üretir; koda göre join yapan bakiye/limit/bilanço/pozisyon sorguları satırları çiftler (bakiye iki kat). | Birimler'de aynı Kodu ile IsDeleted=0 iki satır | Limit, bilanço ve pozisyon çift sayım | S2 – limit/pozisyon çift sayım | DÜŞÜK | 85 | SELECT Kodu,COUNT(*) FROM Sistem.Birimler WHERE IsDeleted=0 GROUP BY Kodu HAVING COUNT(*)>1 | H-023, H-131 | Sistem.Birimler.Kodu silinmemiş satırlarda benzersiz olmalı. | Cari.ToplamBakiye, Bilanco.OzetBilanco, Pozisyon.Write, Bakiye.DunkiBakiyeler (modules.json); indexes.json Sistem.Birimler |
| 40 | MOD-SISTEM | FN.GetKatki daima 0 döndürür; FN.Katsayı tablo dışı milyemde NULL → FN.AyarCevir 0 | Milyem1, Milyem2 (yalnız 0.333/0.375/0.417/0.585/0.750/0.875/0.916 tanımlı) | GetKatki: … Set @Result=… ; return 0 ; AyarCevir = Bol(@Miktar, Katsayı(@Milyem1)) * Katsayı(@Milyem2) ; Katsayı: CASE … END (ELSE yok → NULL) | Katkı hesabı her koşulda 0; ayar çevirici 0,995/0,9166 gibi listede olmayan milyemlerde 0 döndürür (Bol NULL→0). Sipariş girişinde çevrilen miktar sessizce 0 olur. | Milyem tam olarak listedeki 7 değerden biri değilse | Sipariş/üretim miktarı 0 veya katkı 0 | S3 – üretim/sipariş miktarı | DÜŞÜK | 90 | SELECT FN.AyarCevir(10,0.995,0.585), FN.GetKatki(10,0.916,0.585) – beklenen 0 dışı, gelen 0 | GAP-SEC-AYAR-01 | Ayar çevrimi tanımsız milyemde 0 yerine hata/uyarı üretmeli. | FN.GetKatki, FN.Katsayı, FN.AyarCevir (modules.json); Form/Siparis/FrmSiparisGirisi.vb:194 |
| 41 | MOD-URETIM | Uretim.TrBakiyeHesapla – kasa seçimi sırasız TOP 1, has = Tutar×Fiyat | Sistem.Kasalar (SubeId), UretimIslemleri | @KasaId = (Select Top 1 Id From Sistem.Kasalar Where IsDeleted='False' And SubeId=@SubeId) ; URETIMGIRIS: StokHaraketleri(…, Miktar=@Tutar, Milyem=@Fiyat, Has=@Tutar*@Fiyat) | Şubede birden çok kasa varsa üretim çıktısı rastgele kasaya yazılır (plan değişince kasa değişir); giriş satırında miktar/milyem alanları Tutar/Fiyat ile doldurulduğundan alan anlamı ekrana bağlıdır. | Şubede >1 kasa; üretim modülü kullanan kurulum | Üretimden gelen stok yanlış kasada; kasa stok listesi tutmaz | S4 – kuyumcu üretim kurulumlarında kasa bazlı stok | DÜŞÜK | 60 | SELECT SubeId,COUNT(*) FROM Sistem.Kasalar WHERE IsDeleted=0 GROUP BY SubeId HAVING COUNT(*)>1; SELECT KasaId,COUNT(*) FROM Stok.StokHaraketleri WHERE Bolum=1 GROUP BY KasaId | GAP-SEC-ATOLYE-02 | Bolum=1 stok hareketleri deterministik bir kasaya yazılmalı. | Uretim.TrBakiyeHesapla (modules.json) |
| 42 | MOD-CARI | Trigger hata iletimi ve uygulamanın algısı | RAISERROR(…,16,1)+ROLLBACK → SqlException 3609; InternalDb MsgBox; Cari.Islem.Insert Catch | InternalDb.ExecuteScalar: Catch ex → MsgBox(ex.Message); Result=Nothing ; Insert: RecId=0 → Return False | Trigger reddi kullanıcıya SQL metniyle gösterilir (sessiz değil). Ancak RAISERROR olmadan hata yutulan yerler vardır: Insert sonrası 'Cari.RsAktar' ve Update sonrası 'Takoz.RaporYaz' hataları MsgBox ile geçilir ve ana kayıt tamam sayılır; GetCariLimit ExecuteScalar hatası Val('')=0 ile 'limit 0' gibi davranır (işlem reddedilir – tersine sessizlik). | RsAktar/RaporYaz prosedür hatası; FN.GetCariLimit hata | Rs aktarımı eksik işlem; takoz raporu yazılmamış giriş; haksız limit reddi | S3 | ORTA | 80 | SELECT COUNT(*) FROM Cari.Islemler WHERE IsDeleted=0 AND RsAktar=1 AND NOT EXISTS(… Rs hedef tablosu …) [Rs hedefi kaynakta yok – GAP-CODE-05] | GAP-CODE-05, GAP-CODE-07 | Insert sonrası ikincil adımlar (RsAktar/RaporYaz) başarısızsa ana kayıt işaretlenmeli veya geri alınmalı. | Class/Module/InternalDb.vb:53-81; Cari.Islem.vb:694-709; AcceptTransaction |
| 43 | MOD-CARI | Nakit NORMAL girişte yalnız karşılık birimi (TL) bakiyeye yazılır; döviz tarafı yalnız kasa stoğuna | IslemKodu=3, BakiyeId=0 (Cari.IslemEx.vb:291-303), Tutar/BirimId, Miktar/StokId | satır 401-432: Tutar satırı (BirimId, ±Tutar) ; has/miktar satırı yok (BakiyeId=0) ; Stok: StokHaraketleri(StokTipi=2, StokId, ±Miktar) | Kullanıcı dokümanı (A-Z 2.6) EUR+TL iki satır bekler; kod yalnız TL yazar. Personel 'işlem eksik' sanıp ikinci kez döviz satırı girebilir (çift kayıt) ya da müşteri döviz bakiyesini elle takip eder. | Nakit NORMAL/ EMANET dışı işlem; kullanıcı beklentisi | Yanlış düzeltme girişleri; çift kayıt | S3 – operasyon hatasına zemin | ORTA | 90 | SELECT COUNT(*) FROM Cari.BakiyeIslem B JOIN Cari.Islemler I ON I.Id=B.IslemId WHERE I.IslemKodu=3 AND B.BirimId<>I.BirimId AND I.IslemTipi<>10 – 0 beklenir | CTR-025, H-104 | Nakit işlemi (tip≠10) yalnız BirimId'li tek bakiye satırı üretmeli. | Cari.AcceptTransaction (dbclean/modules.json def) satır 281-285, 401-432; Class/Ext/Cari.IslemEx.vb:291-303 |
| 44 | MOD-CARI | PEŞİN (IslemTipi=1) işlemde bakiye/limit muafiyeti ve %5 karşılık toleransı | Cari.Islemler.IslemTipi=1; fişteki giriş/çıkış stok hareketleri TL karşılıkları; Sube.IsLimitControl; kullanıcı grubu PesinKontrol | Cari.GetFisPesinKontrol: Tutar = GIRIS>CIKIS ? (1 − Bol(CIKIS,GIRIS)) × 100 : Bol(CIKIS,GIRIS); sonuç > 5 ise 'karşılık bulunamadı' (yazdırma engellenir); limit kontrolü PEŞİN hariç | PEŞİN tip bakiye satırı üretmediği ve limit kontrolünden muaf olduğu için, karşılığı eksik/ yanlış girilmiş peşin fiş sessizce bakiye dışı kalır; %5 tolerans yalnız PesinKontrol açık grupta ve yalnız fiş yazdırırken çalışır (F2 kayıt anında değil). Tolerans içindeki fark (≤%5) hiç uyarı vermez → kasa/stok farkı birikir. | PesinKontrol kapalı grup; fiş yazdırılmadan kapatılan işlem; %5 altındaki farklar; GIRIS=0 (Bol 0 döner → fark %100 gibi ya da 0) | Bakiyesi olmayan ama karşılığı da tam girilmemiş peşin işlem; kasa/stok farkı; limit aşımı | S2 — kasa/stok farkı birikir, limit korumasız | ORTA | 75 | INV-03 (PEŞİN işlemin bakiye satırı olmamalı) + fiş bazında giriş/çıkış TL karşılığı farkı: SELECT FisNo, SUM(CASE WHEN IslemTuru%2=0 THEN Tutar ELSE -Tutar END) FROM Cari.Islemler WHERE IslemTipi=1 AND IsDeleted=0 GROUP BY HesapId,FisNo HAVING ABS(SUM(...))>0 | H-104 (PEŞİN tip bakiye üretmez), BR-DEFTER-URETIMI, BR-BAKIYE-016, BR-FATURA-008 | INV-03: IslemTipi=1 işlemin Cari.BakiyeIslem satırı olmamalı; PEŞİN fişte giriş/çıkış karşılığı dengeli olmalı | Cari.GetFisPesinKontrol · basecontrol/Base Control/iScreen.vb:98-101 · Cari.AcceptTransaction (tip 1 bakiye satırı üretmez) |
