sys/veri_detay/#008

PYBS (Personel Yönetim Bilgi Sistemi)

Son Senkronizasyon: 16.12.2025
puantaj-cetveli-haftalik.php 377 satır • 17.46 KB
<?php
// modules/puantaj-cetveli-haftali.php
session_start();
require_once '../config/db.php';
require_once '../config/functions.php';

// Yetkiler: Root, Yönetici, Muhasebe, İK
yetkiKontrol(['root', 'yonetici', 'muhasebe', 'insan_kaynaklari']);

include '../includes/header.php';
include '../includes/menu.php';

// --- FİLTRELER ---
$yil = guvenlik($_GET['yil'] ?? date('Y'));
$ay = guvenlik($_GET['ay'] ?? date('m'));
$hafta = guvenlik($_GET['hafta'] ?? 'tumu');
$rol_filtre = guvenlik($_GET['rol'] ?? 'tumu');
$personel_id_filtre = guvenlik($_GET['personel_id'] ?? 'tumu');

// Standart Haftalık Çalışma Saati (45 Saat)
$haftalik_calisma_std = 45.0; 

// Standart Günlük Mesai (Ayarlardan) - 45/5 = 9 Saat
$gunluk_saat_std = (float)($pdo->query("SELECT ayar_degeri FROM site_ayarlari WHERE ayar_anahtari = 'gunluk_mesai_saati'")->fetchColumn() ?: 9);

// --- YARDIMCI FONKSİYONLAR ---
function gunIsmi($tarih) {
    $gunler = ['Mon'=>'Pzt', 'Tue'=>'Sal', 'Wed'=>'Çar', 'Thu'=>'Per', 'Fri'=>'Cum', 'Sat'=>'Cts', 'Sun'=>'Pzr'];
    return $gunler[date('D', strtotime($tarih))];
}

function ayAdi($ay, $kisa = false) {
    $aylar = ['01'=>'Ocak','02'=>'Şubat','03'=>'Mart','04'=>'Nisan','05'=>'Mayıs','06'=>'Haziran','07'=>'Temmuz','08'=>'Ağustos','09'=>'Eylül','10'=>'Ekim','11'=>'Kasım','12'=>'Aralık'];
    return $aylar[ltrim($ay, '0')] ?? '';
}

// İzin Renkleri ve Etiketleri (Önceki dosyadan alındı)
function izinStili($tur) {
    $stiller = [
        'yillik'   => ['bg'=>'bg-info text-white', 't'=>'Y.İZ'],
        'mazeret'  => ['bg'=>'bg-warning text-dark', 't'=>'MAZ'],
        'hastalik' => ['bg'=>'bg-danger text-white', 't'=>'RAPOR'],
        'evlilik'  => ['bg'=>'bg-primary text-white', 't'=>'EVL'],
        'babalik'  => ['bg'=>'bg-primary text-white', 't'=>'BAB'],
        'olum'     => ['bg'=>'bg-dark text-white', 't'=>'ÖLM'],
        'saatlik'  => ['bg'=>'bg-warning bg-opacity-25 text-dark', 't'=>'S.İZ'],
        'diger'    => ['bg'=>'bg-danger bg-opacity-50 text-white', 't'=>'ÜCR.İZ']
    ];
    return $stiller[$tur] ?? ['bg'=>'bg-secondary text-white', 't'=>strtoupper($tur)];
}

// --- HAFTA HESAPLAMA ---
$tarih_start = "$yil-$ay-01";
$tarih_end = "$yil-$ay-" . cal_days_in_month(CAL_GREGORIAN, $ay, $yil);

$haftalar = [];
$gecerli_tarih = strtotime($tarih_start);
$hafta_sayac = 1;

while ($gecerli_tarih <= strtotime($tarih_end)) {
    // Haftanın Pazartesi gününü bul
    $pazartesi = date('N', $gecerli_tarih) == 1 ? $gecerli_tarih : strtotime('last monday', $gecerli_tarih);
    
    // Pazar gününü bul
    $pazar = strtotime('+6 days', $pazartesi);
    
    // Ay sınırlarını kontrol et
    $hafta_baslangic = max($pazartesi, strtotime($tarih_start));
    $hafta_bitis = min($pazar, strtotime($tarih_end));
    
    // TÜRKÇE HAFTA ETİKETİ
    $bas_gun = date('d', $hafta_baslangic);
    $bit_gun = date('d', $hafta_bitis);
    $bas_ay = ayAdi(date('m', $hafta_baslangic));
    $bit_ay = ayAdi(date('m', $hafta_bitis));

    $etiket = "Hafta {$hafta_sayac}: {$bas_gun} {$bas_ay} - {$bit_gun} {$bit_ay}";

    $haftalar[$hafta_sayac] = [
        'baslangic' => date('Y-m-d', $hafta_baslangic),
        'bitis' => date('Y-m-d', $hafta_bitis),
        'etiket' => $etiket,
        'baslangic_timestamp' => $hafta_baslangic,
        'bitis_timestamp' => $hafta_bitis
    ];
    
    // Bir sonraki Pazartesiye geç
    $gecerli_tarih = strtotime('+7 days', $pazartesi);
    $hafta_sayac++;

    // Bitiş tarihi Ay sonundan büyükse döngüyü kır
    if ($hafta_baslangic > strtotime($tarih_end) && $hafta_bitis > strtotime($tarih_end)) break;
}

// Eğer filtrelenecek hafta seçildiyse, tarih aralığını belirle
$secilen_hafta_bilgi = $haftalar[(int)$hafta] ?? null;
$baslangic_tarih = $secilen_hafta_bilgi['baslangic'] ?? $tarih_start;
$bitis_tarih = $secilen_hafta_bilgi['bitis'] ?? $tarih_end;

// --- PERSONEL LİSTESİ ---
$sql_per = "SELECT id, ad, soyad FROM kullanicilar WHERE durum=1";
if ($rol_filtre != 'tumu') $sql_per .= " AND rol = '$rol_filtre'";
if ($personel_id_filtre != 'tumu') $sql_per .= " AND id = " . (int)$personel_id_filtre;
$sql_per .= " ORDER BY ad ASC";
$personeller = $pdo->query($sql_per)->fetchAll();

// 1. Resmi Tatiller
$tatiller = $pdo->query("SELECT tarih FROM resmi_tatiller")->fetchAll(PDO::FETCH_COLUMN);

// 2. Tüm personeller (Filtre kutusu için)
$tum_personeller_query = $pdo->query("SELECT id, ad, soyad FROM kullanicilar WHERE durum=1 ORDER BY ad ASC")->fetchAll();

// --- HAFTALIK PUANTAJ VERİ TOPLAMA ---
$haftalik_puantaj_ozet = []; 

foreach($personeller as $per) {
    $personel_id = $per['id'];
    
    $toplam_calisma = 0.0;
    $toplam_izin_saat = 0.0;
    $toplam_mesai_saat = 0.0;
    $toplam_izin_gun = 0.0;
    
    $tarih_simdiki = strtotime($baslangic_tarih);
    $tarih_bitis = strtotime($bitis_tarih);

    while ($tarih_simdiki <= $tarih_bitis) {
        $g_tarih = date('Y-m-d', $tarih_simdiki);
        $haftanin_gunu = date('N', $tarih_simdiki); // 1 (Pzt) - 7 (Pzr)
        $is_haftaici = $haftanin_gunu <= 5;
        $is_tatil_gunu = in_array($g_tarih, $tatiller);
        
        // --- İZİN HESAPLAMA ---
        $stmt_izin = $pdo->prepare("SELECT * FROM izin_talepleri WHERE calisan_id=? AND durum='onaylandi' AND ? BETWEEN DATE(baslangic_tarihi) AND DATE(bitis_tarihi)");
        $stmt_izin->execute([$personel_id, $g_tarih]);
        $izin = $stmt_izin->fetch();

        $gunluk_normal_calisma = $is_haftaici && !$is_tatil_gunu ? $gunluk_saat_std : 0.0;
        $izin_kesinti_saati = 0.0;
        $gunluk_net_calisma = $gunluk_normal_calisma;

        if ($izin) {
            $izin_turu = $izin['izin_turu'];
            
            if ($izin_turu == 'saatlik') {
                $izin_saat = (float)$izin['saatlik_sure'];
                
                // Mola kuralı kontrolü (Sadece hafta içi 9 saatlik günlerde uygulanır varsayılır)
                if ($is_haftaici && $gunluk_saat_std == 9.0) {
                     $bas_saat_str = date('H:i', strtotime($izin['baslangic_tarihi']));
                     $bit_saat_str = date('H:i', strtotime($izin['bitis_tarihi']));

                    if ($bas_saat_str === '08:00' && $bit_saat_str === '12:00') {
                        $izin_kesinti_saati = 4.0; 
                    } elseif ($bas_saat_str === '13:00' && $bit_saat_str === '18:00') {
                        $izin_kesinti_saati = 5.0;
                    } else {
                        $izin_kesinti_saati = $izin_saat;
                    }
                } else {
                    $izin_kesinti_saati = $izin_saat;
                }
                
                $gunluk_net_calisma = max(0, $gunluk_normal_calisma - $izin_kesinti_saati);
                $toplam_izin_saat += $izin_kesinti_saati;
                
            } elseif ($izin_turu == 'diger') {
                // Ücretsiz izin (Tam gün kesinti)
                $izin_kesinti_saati = $gunluk_normal_calisma;
                $gunluk_net_calisma = 0.0;
                $toplam_izin_saat += $izin_kesinti_saati;
                $toplam_izin_gun += 1.0; 

            } elseif ($is_haftaici && $gunluk_normal_calisma > 0) {
                // Tam Gün Ücretli İzin (Yıllık, Mazeret vb.) - Kesinti 0, ancak normal çalışma saati düşer
                $gunluk_net_calisma = 0.0; 
                $toplam_izin_gun += 1.0; 
            }
        }
        
        // --- MESAİ HESAPLAMA ---
        $stmt_mesai = $pdo->prepare("SELECT SUM(toplam_saat) FROM mesai_hareketleri WHERE calisan_id=? AND durum='onaylandi' AND tarih=? AND mesai_turu IN ('fazla_mesai', 'hafta_tatili', 'resmi_tatil_mesaisi')");
        $stmt_mesai->execute([$personel_id, $g_tarih]);
        $mesai_saat = $stmt_mesai->fetchColumn() ?: 0.0;
        
        $toplam_calisma += $gunluk_net_calisma;
        $toplam_mesai_saat += $mesai_saat;

        $tarih_simdiki = strtotime('+1 day', $tarih_simdiki);
    }
    
    // --- HAFTALIK ÖZET HESAPLAMA ---
    $toplam_saat_haftaici = $toplam_calisma; // Normal hafta içi çalışma (izinler düşülmüş)
    $haftalik_fazla_mesai_ici = 0.0;
    
    // Hafta içi fazla mesaiyi belirle
    if ($toplam_saat_haftaici > $haftalik_calisma_std) {
        $haftalik_fazla_mesai_ici = $toplam_saat_haftaici - $haftalik_calisma_std;
        $toplam_saat_haftaici = $haftalik_calisma_std; // Tavanı 45 saat yap
    }

    // Toplam Haftalık Normal Çalışma (Fazla mesai düşülmüş)
    $haftalik_normal_calisma = $toplam_saat_haftaici; 

    // Genel Fazla Mesai (Hafta içi fazla mesaisi + Hafta sonu/Tatil mesaisi)
    $genel_fazla_mesai = $haftalik_fazla_mesai_ici + $toplam_mesai_saat;

    $haftalik_puantaj_ozet[$personel_id] = [
        'ad_soyad' => $per['ad'] . ' ' . $per['soyad'],
        'normal_saat' => (float)number_format($haftalik_normal_calisma, 2),
        'izin_saat' => (float)number_format($toplam_izin_saat, 2),
        'izin_gun' => (float)number_format($toplam_izin_gun, 1),
        // Fazla mesai kaldırıldı, ancak hesaplamayı verinin içinde tuttuk
        'fazla_mesai' => (float)number_format($genel_fazla_mesai, 2), 
    ];
}
?>

<div class="container-fluid">
    <div class="d-flex justify-content-between align-items-center mb-3">
        <h3><i class="fas fa-calendar-alt text-success"></i> Haftalık Puantaj Özeti</h3>
    </div>
    
    <div class="card-box p-3 mb-3 border-top border-success border-3">
        <form method="GET" id="puantajForm" class="row g-2 align-items-end">
            <div class="col-md-2">
                <label class="fw-bold small">Yıl</label>
                <select name="yil" class="form-select form-select-sm">
                    <?php for($y=2024; $y<=2030; $y++): ?>
                        <option value='<?php echo $y; ?>' <?php echo ($y == $yil) ? 'selected' : ''; ?>>
                            <?php echo $y; ?>
                        </option>
                    <?php endfor; ?>
                </select>
            </div>
            <div class="col-md-2">
                <label class="fw-bold small">Ay</label>
                <select name="ay" class="form-select form-select-sm">
                    <?php 
                    $aylar = ['01'=>'Ocak','02'=>'Şubat','03'=>'Mart','04'=>'Nisan','05'=>'Mayıs','06'=>'Haziran','07'=>'Temmuz','08'=>'Ağustos','09'=>'Eylül','10'=>'Ekim','11'=>'Kasım','12'=>'Aralık'];
                    foreach($aylar as $k=>$v): 
                    ?>
                        <option value='<?php echo $k; ?>' <?php echo ($k == $ay) ? 'selected' : ''; ?>>
                            <?php echo $v; ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>
             <div class="col-md-2">
                <label class="fw-bold small">Hafta Aralığı</label>
                <select name="hafta" class="form-select form-select-sm" required>
                    <option value="tumu" <?php echo ('tumu' == $hafta) ? 'selected' : ''; ?>>Tüm Ay</option>
                    <?php foreach($haftalar as $k => $h): ?>
                        <option value='<?php echo $k; ?>' <?php echo ($k == $hafta) ? 'selected' : ''; ?>>
                            <?php echo $h['etiket']; ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div class="col-md-2">
                <label class="fw-bold small">Departman</label>
                <select name="rol" class="form-select form-select-sm">
                    <option value="tumu" <?php echo ('tumu' == $rol_filtre) ? 'selected' : ''; ?>>Tümü</option>
                    <option value="calisan" <?php echo ('calisan' == $rol_filtre) ? 'selected' : ''; ?>>Personel</option>
                    <option value="vardiya_amiri" <?php echo ('vardiya_amiri' == $rol_filtre) ? 'selected' : ''; ?>>Vardiya Amiri</option>
                    <option value="mudur" <?php echo ('mudur' == $rol_filtre) ? 'selected' : ''; ?>>Müdür</option>
                    </select>
            </div>
            <div class="col-md-2">
                <label class="fw-bold small">Personel</label>
                <select name="personel_id" class="form-select form-select-sm">
                    <option value="tumu" <?php echo ('tumu' == $personel_id_filtre) ? 'selected' : ''; ?>>Herkes</option>
                    <?php foreach($tum_personeller_query as $p): ?>
                        <option value='<?php echo $p['id']; ?>' <?php echo ($p['id'] == $personel_id_filtre) ? 'selected' : ''; ?>>
                            <?php echo $p['ad'] . ' ' . $p['soyad']; ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>
            
            <div class="col-md-2 d-flex gap-1">
                <button type="button" onclick="submitForm('')" class="btn btn-success btn-sm flex-grow-1"><i class="fas fa-search"></i> Listele</button>
                <div class="btn-group">
                    <button type="button" onclick="submitForm('excel')" class="btn btn-primary btn-sm" title="Excel İndir"><i class="fas fa-file-excel"></i></button>
                    <button type="button" onclick="submitForm('pdf')" class="btn btn-dark btn-sm" title="PDF İndir"><i class="fas fa-file-pdf"></i></button>
                </div>
            </div>
            <input type="hidden" name="format" id="exportFormat" value="">
        </form>
        <?php if ($secilen_hafta_bilgi): ?>
            <div class="alert alert-info small mt-3 mb-0 py-2">
                Gösterilen Tarih Aralığı: **<?php echo $secilen_hafta_bilgi['etiket']; ?>** (<?php echo $baslangic_tarih; ?> - <?php echo $bitis_tarih; ?>)
            </div>
        <?php endif; ?>
    </div>

    <div class="card border-0 shadow-sm overflow-auto">
        <table class="table table-bordered table-sm text-center mb-0 align-middle" style="font-size: 0.8rem;">
            <thead class="table-success text-white">
                <tr>
                    <th class="align-middle text-start ps-3" style="min-width: 180px; position: sticky; left: 0; z-index: 10;">Personel Adı</th>
                    <th style="min-width: 120px;">Haftalık Normal Çalışma (Saat)</th>
                    <th style="min-width: 120px;">İzin/Kesinti Süresi (Saat)</th>
                    <th style="min-width: 100px;">Toplam İzin Günü (Tam Gün)</th>
                    <th style="min-width: 180px;">Açıklama</th>
                </tr>
            </thead>
            <tbody>
                <?php if (empty($haftalik_puantaj_ozet)): ?>
                    <tr><td colspan="5" class="text-center text-muted p-4">Seçilen tarihlerde puantaj verisi bulunmamaktadır veya filtre uygulanmamıştır.</td></tr>
                <?php else: ?>
                    <?php foreach($haftalik_puantaj_ozet as $ozet): ?>
                    <tr>
                        <td class="text-start ps-3 fw-bold bg-light" style="position: sticky; left: 0; z-index: 5;">
                            <?php echo htmlspecialchars($ozet['ad_soyad']); ?>
                        </td>
                        <td class="fw-bold <?php echo ($ozet['normal_saat'] >= $haftalik_calisma_std) ? 'text-primary' : 'text-danger'; ?>">
                            <?php echo $ozet['normal_saat']; ?> / 45.00
                        </td>
                        <td class="fw-bold text-warning">
                            - <?php echo $ozet['izin_saat']; ?>
                        </td>
                        <td>
                            <?php echo $ozet['izin_gun']; ?>
                        </td>
                        <td class="small text-muted text-start">
                            <?php 
                                $aciklama = '';
                                if ($ozet['normal_saat'] < $haftalik_calisma_std) {
                                    $aciklama = "Haftalık hedef çalışma saati ($haftalik_calisma_std s.) aşılamadı.";
                                } else {
                                    $aciklama = "Haftalık hedef tamamlandı. ";
                                }
                                
                                if ($ozet['fazla_mesai'] > 0) {
                                    $aciklama .= "Toplam Fazla Mesai: " . $ozet['fazla_mesai'] . " saat.";
                                }

                                echo $aciklama;
                            ?>
                        </td>
                    </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>
    </div>
    
    <div class="mt-3 small text-muted border-top pt-2">
        **Hesaplama Notları:** Normal Çalışma, İzinler düşüldükten sonra 45 saat ile sınırlandırılmıştır. İzin/Kesinti Süresi, saatlik veya ücretsiz izin nedeniyle yapılan kesintilerdir.
    </div>
</div>

<script>
// -----------------------------------------------------------
function submitForm(type) {
    const form = document.getElementById('puantajForm');
    const hiddenInput = document.getElementById('exportFormat');
    
    hiddenInput.value = type;
    
    // Filtreleme yapılıyorsa (type boşsa), formu normal olarak gönderir
    if (type === 'excel' || type === 'pdf') {
        // Raporlama için yeni bir PHP dosyasına yönlendirilir (puantaj-rapor-haftalik.php)
        form.action = 'puantaj-rapor-haftalik.php'; 
        form.target = '_blank';
    } else {
        // Filtreleme için (Listele butonu)
        form.action = 'puantaj-cetveli-haftali.php'; // Sayfanın kendisine gönderir
        form.target = '_self';
    }
    form.submit();
}
// -----------------------------------------------------------
</script>

<?php include '../includes/footer.php'; ?>
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,262
Sinyal (Ağ Hiti)
1.54 MB
Kapasite

Ağda Paylaş