sys/veri_detay/#008

PYBS (Personel Yönetim Bilgi Sistemi)

Son Senkronizasyon: 16.12.2025
functions.php 329 satır • 11.00 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)
 * Kullanıcıdan gelen her veriyi bu fonksiyonla temizleyeceğiz.
 */
function guvenlik($veri) {
    $veri = trim($veri); // Baştaki sondaki boşlukları sil
    $veri = stripslashes($veri); // Ters eğik çizgileri temizle
    $veri = htmlspecialchars($veri); // HTML etiketlerini etkisiz hale getir (XSS koruması)
    return $veri;
}

/**
 * 2. DETAYLI LOGLAMA FONKSİYONU
 * Sistemdeki her hareketi veritabanına yazar.
 * @param int $kullanici_id İşlemi yapan kişi (Yoksa 0)
 * @param string $islem_tipi giris, ekleme, silme vb.
 * @param string $aciklama Okunabilir detay
 * @param string $tablo Hangi tabloda işlem yapıldı?
 * @param int $kayit_id Hangi kayıt üzerinde işlem yapıldı?
 */
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'];

    // GÜVENLİK GÜNCELLEMESİ: islem_tipi ve aciklama XSS'e karşı temizlenmeli
    $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Ü
 * Sayfanın başında çağrılır. Kullanıcının o sayfaya girme yetkisi var mı bakar.
 * @param array $izin_verilen_roller Bu sayfayı görebilecek rollerin listesi
 */
function yetkiKontrol($izin_verilen_roller) {
    // 1. Giriş yapılmış mı?
    if (!isset($_SESSION['kullanici_id']) || !isset($_SESSION['rol'])) {
        header("Location: ../index.php?hata=giris_yapilmali");
        exit;
    }

    // 2. Rol yetkisi var mı?
    // Eğer kullanıcının rolü, izin verilenler listesinde YOKSA at.
    if (!in_array($_SESSION['rol'], $izin_verilen_roller)) {
        // Log kaydı atalım: Yetkisiz erişim denemesi
        global $pdo; // $pdo nesnesini globalden çek
        logKaydet($pdo, $_SESSION['kullanici_id'], 'guvenlik_uyarisi', 'Yetkisiz sayfaya erişim denemesi: ' . $_SERVER['PHP_SELF']);
        
        // Ana sayfasına yönlendir veya hata göster
        header("Location: ../index.php?hata=yetkisiz_erisim");
        exit;
    }
}

/**
 * 4. CSRF TOKEN OLUŞTURMA (Form Güvenliği)
 * Formlara gizli input olarak ekleyeceğiz.
 */
function csrfTokenOlustur() {
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

/**
 * 5. CSRF KONTROL
 * Form post edildiğinde çağrılır.
 */
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 (Denkleştirme İçin)
 * Bir personelin, verilen tarihteki haftasının toplam onaylı saatini getirir.
 */
function haftalikToplamSureGetir($pdo, $calisan_id, $referans_tarih) {
    // Tarihin olduğu haftanın Pazartesi ve Pazar günlerini bul
    $dt = new DateTime($referans_tarih);
    // ISO-8601'e göre haftanın ilk günü (Pazartesi)
    $dt->modify('this week monday'); 
    $baslangic = $dt->format('Y-m-d');
    $dt->modify('this week sunday');
    $bitis = $dt->format('Y-m-d');

    // O haftaki ONAYLANMIŞ mesaileri topla
    $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(); // Örn: 42.5
}

/**
 * 7. NET İZİN GÜNÜ HESAPLA
 * Pazar günlerini ve Resmi Tatilleri saymaz.
 * @param PDO $pdo Veritabanı bağlantısı
 * @param string $baslangic Y-m-d H:i
 * @param string $bitis Y-m-d H:i
 * @return float Hesaplanan net iş günü
 */
function netIzinGunSayisiHesapla($pdo, $baslangic, $bitis) {
    // Saatleri sıfırla, sadece gün bazlı hesaplayalım
    $start = new DateTime(substr($baslangic, 0, 10));
    $end = new DateTime(substr($bitis, 0, 10));
    // Bitiş günü de dahil edilmeli, o yüzden döngüde <= kullanacağız
    // Ama DateTime loop'unda bitişi dahil etmek için 1 gün ileri alıp < yaparız veya interval kullanırız.
    // En temizi: $end gününü de kontrol etmek.
    
    $toplam_gun = 0;
    
    // Resmi Tatilleri Çek (Performans için bir kere çekip array yapalım)
    // Sadece bu aralıktaki tatilleri çek
    $sql = "SELECT tarih FROM resmi_tatiller WHERE tarih BETWEEN ? AND ?";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$start->format('Y-m-d'), $end->format('Y-m-d')]);
    $tatiller = $stmt->fetchAll(PDO::FETCH_COLUMN); // ['2025-01-01', '2025-04-23'] gibi döner

    // Döngü: Başlangıçtan Bitişe kadar gün gün git
    $current = clone $start;
    while ($current <= $end) {
        $curr_date = $current->format('Y-m-d');
        $haftanin_gunu = $current->format('N'); // 1 (Pzt) - 7 (Paz)
        
        // KURAL 1: Pazar günü mü? (7) -> Sayma
        // KURAL 2: Resmi tatil mi? -> Sayma
        if ($haftanin_gunu != 7 && !in_array($curr_date, $tatiller)) {
            $toplam_gun++;
        }
        
        // Bir sonraki güne geç
        $current->modify('+1 day');
    }
    
    // Eğer başlangıç ve bitiş aynı günse ve o gün tatil değilse 1 saymalı
    if ($start == $end && $toplam_gun == 0) {
        // Ama tatilse 0 kalmalı. Yukarıdaki döngü bunu halleder.
    }
    
    return $toplam_gun;
}

/**
 * 8. TELEFON FORMATLAMA
 * Girdiyi temizler ve +905XXXXXXXXX formatına çevirir.
 */
function telefonFormatla($tel) {
    // Sadece rakamları al
    $tel = preg_replace('/[^0-9]/', '', $tel);
    
    // Boşsa boş dön
    if (empty($tel)) return '';

    // Uzunluğa göre düzenle
    // 532... (10 hane) -> +90532...
    if (strlen($tel) == 10) {
        return '+90' . $tel;
    }
    // 0532... (11 hane) -> +90532...
    if (strlen($tel) == 11 && substr($tel, 0, 1) == '0') {
        return '+9' . $tel;
    }
    // 90532... (12 hane) -> +90532...
    if (strlen($tel) == 12 && substr($tel, 0, 2) == '90') {
        return '+' . $tel;
    }
    
    // Format uymuyorsa olduğu gibi (veya başına + ekleyerek) döndür
    return '+' . $tel;
}
// config/functions.php (En alta ekleyin)

/**
 * 9. HAFTALIK ONAYLI SÜRE HESAPLA
 * Verilen tarihin ait olduğu haftadaki (Pzt-Paz) toplam onaylı saati döndürür.
 */
function haftalikOnayliSureGetir($pdo, $calisan_id, $referans_tarih) {
    $date = new DateTime($referans_tarih);
    // Haftanın günü (1:Pzt ... 7:Paz)
    $gun = $date->format('N');
    
    // Pazartesiye git
    $pazartesi = clone $date;
    $pazartesi->modify('-' . ($gun - 1) . ' days');
    
    // Pazara git
    $pazar = clone $pazartesi;
    $pazar->modify('+6 days');
    
    $bas = $pazartesi->format('Y-m-d');
    $bit = $pazar->format('Y-m-d');

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


/**
 * 10. TÜRKÇE TARİH FORMATLAMA
 * Girdiyi alır, "18 Mayıs 2025" formatına çevirir.
 * @param string $tarih (Y-m-d veya datetime)
 * @param bool $sadece_ay_yil (True ise sadece 'Aralık 2025' döndürür)
 */
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 belirle
    $format = $sadece_ay_yil ? 'F Y' : 'd F Y';
    
    $ingilizce_tarih = date($format, $zaman);
    
    // Değiştir ve döndür
    return str_replace($aylar_en, $aylar_tr, $ingilizce_tarih);
}

/**
 * 11. BİLDİRİM GÖNDER
 * Belirli bir role veya kişiye bildirim atar.
 */
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İ (Rol Bazlı)
 * Örn: Tüm 'muhasebe' ve 'insan_kaynaklari' rollerine gönderir.
 */
function rolBildirimGonder($pdo, $roller_dizisi, $baslik, $mesaj, $link) {
    // Rolleri virgülle ayırıp SQL'e sokalım ('muhasebe','insan_kaynaklari')
    $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
 * GÜVENLİK GÜNCELLEMESİ: SQL Injection'a karşı koruma eklendi
 */
function bildirimSayisi($pdo, $uid) {
    $sql = "SELECT COUNT(*) FROM bildirimler WHERE kullanici_id = ? AND okundu = 0";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$uid]); // Parametre bağlama kullanıldı
    return $stmt->fetchColumn();
}

/**
 * 14. PERSONEL ANLIK DURUM SORGULA
 * Bugünün tarihine göre personelin onaylı bir izni var mı bakar.
 */
function personelDurumu($pdo, $calisan_id) {
    $bugun = date('Y-m-d');
    
    // Bugün tarih aralığında olan ONAYLI izin var mı?
    $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]);
    $izinli_mi = $stmt->fetchColumn();

    if ($izinli_mi > 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>';
    }
}
?>
DATA_PAYLOAD (Açıklama)
Kapak

DEMO SÜRÜMÜDÜR TAM SÜRÜM İÇİN İLETİŞİM KURUN

📖 PYBS (Personel Yönetim Bilgi Sistemi) Kullanım Kılavuzu

🚀 Proje Tanımı

PYBS, personel bilgilerini, izinleri, maaş bordrolarını ve performans değerlendirmelerini merkezi ve dijital bir platformda yönetmek için tasarlanmış kapsamlı bir Personel Yönetim Bilgi Sistemi'dir. Amacımız, İnsan Kaynakları (İK) süreçlerini otomatikleştirerek verimliliği artırmak ve veri tutarlılığını sağlamaktır.

✨ Temel Özellikler

Personel Yönetimi: Çalışanların kişisel, iletişim ve görev bilgilerini kaydetme/güncelleme.

İzin Yönetimi: Çalışanların izin taleplerini oluşturma, onaylama/reddetme ve kalan izin haklarını takip etme.

Performans Değerlendirme: Yöneticilerin ve çalışanların performans hedeflerini belirlemesi ve değerlendirmeleri kaydetmesi.

Bordro Entegrasyonu: Maaş ve avans bilgilerini kaydetme ve bordro çıktılarını oluşturma (Harici sistemlerle entegrasyon potansiyeli).

Raporlama: İK yöneticileri için özet ve detaylı personel, izin ve bordro raporları oluşturma.

💻 Son Kullanıcı Kullanımı🔑 Giriş Yapma

Demo için kullanıcı adı : test.test

Demo için şifre : 123456

Demo hesabında root / yonetici vb yetki yoktur.

Tam sürüm için iletişime geçin.

Sistem "Ramsa Makine" tarafından aktif olarak kullanılmaktadır

Meta Veri (Özet)

İşyeri çalışanlarının maaş, fazla mesai ve puantaj ile bordro takip, kontrol ve raporlama sistemi

9,447
Sinyal (Ağ Hiti)
1.54 MB
Kapasite

Ağda Paylaş