From 2c70ed9d7158bb1ab3230662438419641a41d375 Mon Sep 17 00:00:00 2001 From: ht Date: Thu, 3 Sep 2026 22:19:15 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20kismi=20ihalede=20sahte=20kirim=20orani?= =?UTF-8?q?=20=E2=80=94=20maliyet=20tum=20ihale,=20bedel=20kisim=20basina?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sonuc ayristirici yaklasik maliyeti TUM ihale icin okuyor ((? --- src/services/analytics.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/services/analytics.js b/src/services/analytics.js index 898ddff..a383fdb 100644 --- a/src/services/analytics.js +++ b/src/services/analytics.js @@ -29,6 +29,13 @@ export function normProvince(name) { export function firmStats(tenders) { const map = new Map(); let awardCount = 0; + // Kısmi ihale tuzağı: yaklaşık maliyet TÜM ihale için okunuyor, sözleşme + // bedeli ise kısım başına. 11 kısımlık ilaç ihalesinin ilk kısmı 1,6 milyon + // tahmine karşı 25 bine verilmişse bu %98 kırım değil, aritmetik kurgudur. + // Kırım yalnızca tek sonuç satırı olan (kısımsız) ihalelerde hesaplanır; + // yanlış bir oran, hiç oran olmamasından kötüdür. + const iknSatir = new Map(); + for (const t of tenders) if (t.kazananFirma && t.ikn) iknSatir.set(t.ikn, (iknSatir.get(t.ikn) || 0) + 1); for (const t of tenders) { if (!t.kazananFirma) continue; awardCount++; @@ -43,7 +50,8 @@ export function firmStats(tenders) { cur.wins++; if (val != null) cur.total += val; const maliyet = parseTL(t.yaklasikMaliyet); - if (val != null && maliyet > 0 && val <= maliyet * 1.5) { + const kisimsiz = (iknSatir.get(t.ikn) || 1) === 1; + if (kisimsiz && val != null && maliyet > 0 && val <= maliyet * 1.5) { cur.kirimToplam += 1 - val / maliyet; cur.kirimAdet++; }