PYBS (Personel Yönetim Bilgi Sistemi) / Ramsa/config/functions.php
functions.php 270 satır • 8.54 KB
<?php
// config/functions.php
// Veritabanı bağlantısını içeri alıyoruz
require_once 'db.php';

// Oturumu başlat (Eğer başlamadıysa)
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

/**
 * 1. GÜVENLİK FONKSİYONU (XSS Temizliği)
 */
function guvenlik($veri) {
    $veri = trim($veri); 
    $veri = stripslashes($veri); 
    $veri = htmlspecialchars($veri); 
    return $veri;
}

/**
 * 2. DETAYLI LOGLAMA FONKSİYONU
 */
function logKaydet($pdo, $kullanici_id, $islem_tipi, $aciklama, $tablo = null, $kayit_id = null, $eski_veri = null, $yeni_veri = null) {
    
    $ip = $_SERVER['REMOTE_ADDR'];
    $cihaz = $_SERVER['HTTP_USER_AGENT'];

    $temiz_islem_tipi = guvenlik($islem_tipi);
    $temiz_aciklama = guvenlik($aciklama);

    $sql = "INSERT INTO sistem_loglari (kullanici_id, islem_tipi, aciklama, tablo_adi, kayit_id, eski_veri, yeni_veri, ip_adresi, cihaz_bilgisi) 
            VALUES (:kid, :tip, :acik, :tablo, :rid, :eski, :yeni, :ip, :cihaz)";
    
    $stmt = $pdo->prepare($sql);
    $stmt->execute([
        ':kid' => $kullanici_id,
        ':tip' => $temiz_islem_tipi,
        ':acik' => $temiz_aciklama,
        ':tablo' => $tablo,
        ':rid' => $kayit_id,
        ':eski' => $eski_veri ? json_encode($eski_veri, JSON_UNESCAPED_UNICODE) : null,
        ':yeni' => $yeni_veri ? json_encode($yeni_veri, JSON_UNESCAPED_UNICODE) : null,
        ':ip' => $ip,
        ':cihaz' => $cihaz
    ]);
}

/**
 * 3. YETKİ KONTROLÜ
 */
function yetkiKontrol($izin_verilen_roller) {
    if (!isset($_SESSION['kullanici_id']) || !isset($_SESSION['rol'])) {
        header("Location: ../index.php?hata=giris_yapilmali");
        exit;
    }

    if (!in_array($_SESSION['rol'], $izin_verilen_roller)) {
        global $pdo; 
        logKaydet($pdo, $_SESSION['kullanici_id'], 'guvenlik_uyarisi', 'Yetkisiz sayfaya erişim denemesi: ' . $_SERVER['PHP_SELF']);
        
        header("Location: ../index.php?hata=yetkisiz_erisim");
        exit;
    }
}

/**
 * 4. CSRF TOKEN OLUŞTURMA
 */
function csrfTokenOlustur() {
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

/**
 * 5. CSRF KONTROL
 */
function csrfKontrol($token) {
    if (!isset($_SESSION['csrf_token']) || $token !== $_SESSION['csrf_token']) {
        die("Güvenlik Uyarısı: CSRF doğrulaması başarısız. Lütfen sayfayı yenileyip tekrar deneyin.");
    }
}

/**
 * 6. HAFTALIK ÇALIŞMA SÜRESİ HESAPLA
 */
function haftalikToplamSureGetir($pdo, $calisan_id, $referans_tarih) {
    $dt = new DateTime($referans_tarih);
    $dt->modify('this week monday'); 
    $baslangic = $dt->format('Y-m-d');
    $dt->modify('this week sunday');
    $bitis = $dt->format('Y-m-d');

    $sql = "SELECT SUM(toplam_saat) as toplam 
            FROM mesai_hareketleri 
            WHERE calisan_id = ? 
            AND tarih BETWEEN ? AND ? 
            AND durum = 'onaylandi'";
            
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$calisan_id, $baslangic, $bitis]);
    return (float)$stmt->fetchColumn(); 
}

/**
 * 7. YILLIK İZİN HAKEDİŞ HESAPLA (OTOMATİK)
 * İşe giriş tarihi ve doğum tarihine göre hak edilen gün sayısını döner.
 */
function yillikIzinHakedisHesapla($pdo, $kullanici_id) {
    $stmt = $pdo->prepare("SELECT ise_giris_tarihi, dogum_tarihi, rol, devreden_izin FROM kullanicilar WHERE id = ?");
    $stmt->execute([$kullanici_id]);
    $u = $stmt->fetch();
    
    if (!$u) return 0;
    if ($u['rol'] == 'stajyer') return 0; // Stajyerin yıllık izni olmaz

    $ise_giris = new DateTime($u['ise_giris_tarihi']);
    $bugun = new DateTime();
    
    // Kıdem Yılı
    $kidem_yil = $ise_giris->diff($bugun)->y;
    
    // Henüz 1 yılı dolmamışsa
    if ($kidem_yil < 1) return (float)$u['devreden_izin'];

    // Baz Hesap (Kıdem Yılına Göre)
    if ($kidem_yil >= 15) {
        $hakedis = 26;
    } elseif ($kidem_yil >= 5) {
        $hakedis = 20;
    } else {
        $hakedis = 14;
    }

    // Yaş Kontrolü (18 yaş altı ve 50 yaş üstü en az 20 gün olmak zorunda - Kanuni Zorunluluk)
    if (!empty($u['dogum_tarihi'])) {
        $dogum = new DateTime($u['dogum_tarihi']);
        $yas = $dogum->diff($bugun)->y;
        
        // GÜNCELLEME: 18 yaş dahil (<=) ve 50 yaş dahil (>=)
        if (($yas <= 18 || $yas >= 50) && $hakedis < 20) {
            $hakedis = 20;
        }
    }

    // Devreden izin varsa ekle
    return $hakedis + (float)$u['devreden_izin'];
}

/**
 * 8. GÜNCEL İZİN BAKİYESİ SORGULA
 * Toplam Hakediş - Kullanılan
 */
function bakiyeSorgula($pdo, $kullanici_id) {
    $toplam_hak = yillikIzinHakedisHesapla($pdo, $kullanici_id);
    
    // Sadece "yillik" izin türü bakiyeden düşer
    $sql_kul = "SELECT SUM(toplam_gun) FROM izin_talepleri 
                WHERE calisan_id = ? 
                AND izin_turu = 'yillik' 
                AND durum = 'onaylandi' 
                AND YEAR(baslangic_tarihi) = YEAR(CURDATE())";
                
    $stmt_kul = $pdo->prepare($sql_kul);
    $stmt_kul->execute([$kullanici_id]);
    $kullanilan = (float)$stmt_kul->fetchColumn();
    
    return [
        'toplam_hak' => $toplam_hak,
        'kullanilan' => $kullanilan,
        'kalan' => $toplam_hak - $kullanilan
    ];
}

/**
 * 9. TELEFON FORMATLAMA
 */
function telefonFormatla($tel) {
    $tel = preg_replace('/[^0-9]/', '', $tel);
    if (empty($tel)) return '';
    if (strlen($tel) == 10) return '+90' . $tel;
    if (strlen($tel) == 11 && substr($tel, 0, 1) == '0') return '+9' . $tel;
    if (strlen($tel) == 12 && substr($tel, 0, 2) == '90') return '+' . $tel;
    return '+' . $tel;
}

/**
 * 10. TÜRKÇE TARİH FORMATLAMA
 */
function tarihTurkce($tarih, $sadece_ay_yil = false) {
    if (!$tarih) return '-';
    $zaman = strtotime($tarih);
    $aylar_en = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
    $aylar_tr = ['Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran', 'Temmuz', 'Ağustos', 'Eylül', 'Ekim', 'Kasım', 'Aralık'];
    $format = $sadece_ay_yil ? 'F Y' : 'd F Y';
    $ingilizce_tarih = date($format, $zaman);
    return str_replace($aylar_en, $aylar_tr, $ingilizce_tarih);
}

/**
 * 11. BİLDİRİM GÖNDER
 */
function bildirimGonder($pdo, $hedef_kullanici_id, $baslik, $mesaj, $link) {
    $sql = "INSERT INTO bildirimler (kullanici_id, baslik, mesaj, link) VALUES (?, ?, ?, ?)";
    $pdo->prepare($sql)->execute([$hedef_kullanici_id, $baslik, $mesaj, $link]);
}

/**
 * 12. GRUP BİLDİRİMİ
 */
function rolBildirimGonder($pdo, $roller_dizisi, $baslik, $mesaj, $link) {
    $in  = str_repeat('?,', count($roller_dizisi) - 1) . '?';
    $sql = "SELECT id FROM kullanicilar WHERE rol IN ($in) AND durum = 1";
    $stmt = $pdo->prepare($sql);
    $stmt->execute($roller_dizisi);
    $kisiler = $stmt->fetchAll(PDO::FETCH_COLUMN);

    foreach($kisiler as $k_id) {
        bildirimGonder($pdo, $k_id, $baslik, $mesaj, $link);
    }
}

/**
 * 13. OKUNMAMIŞ BİLDİRİM SAYISI
 */
function bildirimSayisi($pdo, $uid) {
    $sql = "SELECT COUNT(*) FROM bildirimler WHERE kullanici_id = ? AND okundu = 0";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$uid]); 
    return $stmt->fetchColumn();
}

/**
 * 14. PERSONEL ANLIK DURUM SORGULA
 */
function personelDurumu($pdo, $calisan_id) {
    $bugun = date('Y-m-d');
    $sql = "SELECT COUNT(*) FROM izin_talepleri 
            WHERE calisan_id = ? 
            AND durum = 'onaylandi' 
            AND ? BETWEEN DATE(baslangic_tarihi) AND DATE(bitis_tarihi)";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$calisan_id, $bugun]);
    if ($stmt->fetchColumn() > 0) {
        return '<span class="badge bg-warning text-dark"><i class="fas fa-umbrella-beach"></i> İZİNLİ</span>';
    } else {
        return '<span class="badge bg-success"><i class="fas fa-briefcase"></i> MESAİDE</span>';
    }
}

function maasGetir($pdo, $calisan_id, $yil, $ay) {
    // O ayın son günü itibariyle geçerli olan maaşı baz alıyoruz.
    $hedef_tarih = date("Y-m-t", strtotime("$yil-$ay-01"));
    
    $stmt = $pdo->prepare("SELECT maas_miktari FROM maas_gecmisi WHERE calisan_id = ? AND gecerlilik_baslangic <= ? ORDER BY gecerlilik_baslangic DESC LIMIT 1");
    $stmt->execute([$calisan_id, $hedef_tarih]);
    $maas = $stmt->fetchColumn();
    
    // Eğer geçmişte kayıt yoksa (eski sistemden kalma ise) güncel maaşı döndür
    if (!$maas) {
        $stmt2 = $pdo->prepare("SELECT aylik_net_maas FROM kullanicilar WHERE id = ?");
        $stmt2->execute([$calisan_id]);
        $maas = $stmt2->fetchColumn();
    }
    
    return (float)$maas;
}
?>