sys/veri_detay/#008

PYBS (Personel Yönetim Bilgi Sistemi)

Son Senkronizasyon: 16.12.2025
izin-talep.php 625 satır • 30.84 KB
<?php
// modules/izin-talep.php (Personel Kişisel İzin Talep Sayfası)
session_start();
require_once '../config/db.php';
require_once '../config/functions.php';

// Yetki kontrolü: Oturum açan herkes bu sayfaya erişebilir.
yetkiKontrol(['root', 'yonetici', 'mudur', 'vardiya_amiri', 'calisan', 'stajyer', 'muhasebe', 'insan_kaynaklari']);

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

$mesaj = '';
$kullanici_id = $_SESSION['kullanici_id'];
$rol = $_SESSION['rol'];
$ad_soyad = $_SESSION['ad_soyad']; // Bildirim metni için

// --- SAAT SEÇENEKLERİ (SADECE TAM VE BUÇUK SAATLER) ---
$zaman_secenekleri = "";
for ($saat = 0; $saat < 24; $saat++) {
    foreach (['00', '30'] as $dakika) {
        $deger = sprintf('%02d:%s', $saat, $dakika); 
        $zaman_secenekleri .= "<option value='$deger'>$deger</option>";
    }
}

// --- RESMİ TATİLLERİ ÇEK ---
$tatiller_db = $pdo->query("SELECT tarih FROM resmi_tatiller")->fetchAll(PDO::FETCH_COLUMN);
$tatiller_json = json_encode($tatiller_db);

// --- BAKİYE HESAPLAMA ---
$stmt_u = $pdo->prepare("SELECT ise_giris_tarihi, devreden_izin FROM kullanicilar WHERE id = ?");
$stmt_u->execute([$kullanici_id]);
$user_data = $stmt_u->fetch();

$ise_giris = new DateTime($user_data['ise_giris_tarihi']);
$bugun = new DateTime();
$kidem_yil = $ise_giris->diff($bugun)->y;

// Yasal Hakediş Hesaplama
$yasal_hak = ($kidem_yil >= 15) ? 26 : (($kidem_yil >= 5) ? 20 : 14);
if ($rol == 'stajyer') $yasal_hak = 0;
$toplam_hak = $yasal_hak + (float)$user_data['devreden_izin'];

// Kullanılan Yıllık İzin (Bu yıl)
$sql_kul = "SELECT SUM(toplam_gun) FROM izin_talepleri WHERE calisan_id = ? AND izin_turu IN ('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();
$kalan_bakiye = $toplam_hak - $kullanilan;

// --- KAYIT İŞLEMİ ---
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    csrfKontrol($_POST['csrf_token']);

    $hedef_yonetici = $_POST['hedef_yonetici_id'];
    $izin_secimi = $_POST['izin_turu'];
    $izin_turu = ($izin_secimi == 'saatlik') ? 'saatlik' : $izin_secimi;
    $aciklama = guvenlik($_POST['aciklama']);

    $hata = false; $toplam_gun = 0; $saatlik_sure = 0; $baslangic = ""; $bitis = "";
    $kontrol_bas = "";
    $kontrol_bit = "";

    // 1. SAATLİK İZİN HESAPLAMA
    if ($izin_turu == 'saatlik') {
        $tarih = $_POST['saatlik_tarih'];
        $bas_saat = $_POST['saatlik_bas']; 
        $bit_saat = $_POST['saatlik_bit']; 
        $baslangic = "$tarih $bas_saat:00";
        $bitis = "$tarih $bit_saat:00";
        $kontrol_bas = $tarih;
        $kontrol_bit = $tarih;

        if (empty($tarih) || empty($bas_saat) || empty($bit_saat)) {
             $mesaj = '<div class="alert alert-danger">Hata: Saatlik izin için Tarih ve saatler zorunludur.</div>';
             $hata = true;
             goto end_of_post_logic;
        }

        if (strtotime($bitis) <= strtotime($baslangic)) {
            $mesaj = '<div class="alert alert-danger">Bitiş saati başlangıçtan sonra olmalı.</div>';
            $hata = true;
        } else {
            $diff = strtotime($bitis) - strtotime($baslangic);
            $saatlik_sure = round($diff / 3600, 2); 
            $toplam_gun = 0; 
        }
    } 
    // 2. GÜNLÜK İZİN HESAPLAMA
    else {
        $gelen_tarih = $_POST['baslangic_tarihi_gun']; 
        $gun_sayisi = (float)$_POST['gun_sayisi'];
        
        if (empty($gelen_tarih) || $gun_sayisi <= 0) {
             $mesaj = '<div class="alert alert-danger">Hata: Başlangıç tarihi ve gün sayısı zorunludur.</div>';
             $hata = true;
             goto end_of_post_logic;
        }
        
        $baslangic_tarihi = $gelen_tarih . ' 08:00:00'; 
        
        // Bakiye Kontrolü (Sadece Yıllık İzin)
        if ($izin_turu === 'yillik' && $gun_sayisi > $kalan_bakiye) {
            $mesaj = '<div class="alert alert-danger">Yetersiz bakiye! Talep edilen süre kalan hakkınızdan fazla.</div>';
            $hata = true;
        } else {
            // Bitiş Tarihini Hesapla (İşe Başlama Tarihi)
            $temp_date = new DateTime($gelen_tarih);
            $sayilan_gun = 0;
            $tatil_atla = in_array($izin_turu, ['yillik']); 

            $i=0;
            while ($sayilan_gun < floor($gun_sayisi)) {
                $ymd = $temp_date->format('Y-m-d');
                $h_gun = $temp_date->format('N');
                
                $gun_gecerli = true;
                if ($tatil_atla) {
                    if ($h_gun == 7 || in_array($ymd, $tatiller_db)) { $gun_gecerli = false; }
                }
                
                if ($gun_gecerli) { $sayilan_gun++; }

                if ($sayilan_gun < floor($gun_sayisi)) { $temp_date->modify('+1 day'); }
                $i++; if($i>90) break;
            }
            
            $baslangic = $baslangic_tarihi;
            $bitis = $temp_date->format('Y-m-d 18:00:00');
            $toplam_gun = $gun_sayisi;
            $kontrol_bas = date('Y-m-d', strtotime($baslangic));
            $kontrol_bit = date('Y-m-d', strtotime($bitis));
        }
    }

    // =========================================================
    // !!! ÇAKIŞMA KONTROLÜ (Mevcut İzin/Mesai Var mı?) !!!
    // =========================================================
    if (!$hata) {
        $hata_mesaji_detay = "Seçilen tarihler arasında zaten **onaylanmış veya beklemede olan** başka bir izin/mesai kaydınız bulunmaktadır. Bu tarihlere yeni bir talep giremezsiniz. Hata varsa lütfen **İnsan Kaynakları ya da Yönetim** birimine başvurunuz.";
        
        // 1. İzin Çakışması
        $sql_izin_cakisma = "
            SELECT COUNT(*) 
            FROM izin_talepleri 
            WHERE calisan_id = ? 
            AND durum IN ('beklemede', 'onaylandi') 
            AND (
                (? BETWEEN DATE(baslangic_tarihi) AND DATE(bitis_tarihi)) OR
                (? BETWEEN DATE(baslangic_tarihi) AND DATE(bitis_tarihi))
            )";
        $stmt_izin_cakisma = $pdo->prepare($sql_izin_cakisma);
        $stmt_izin_cakisma->execute([$kullanici_id, $kontrol_bas, $kontrol_bit]);
        
        if ($stmt_izin_cakisma->fetchColumn() > 0) {
            $mesaj = "<div class='alert alert-danger shadow-sm border-start border-danger border-5'>
                        <h5 class='alert-heading h6 fw-bold'><i class='fas fa-exclamation-triangle me-2'></i> KAYIT HATA!</h5> $hata_mesaji_detay
                      </div>";
            $hata = true;
        }
    }
    
    // 2. Mesai Çakışması
    if (!$hata) {
        $sql_mesai_cakisma = "
            SELECT COUNT(*) FROM mesai_hareketleri 
            WHERE calisan_id = ? 
            AND durum IN ('beklemede', 'onaylandi') 
            AND tarih BETWEEN ? AND ?";
        $stmt_mesai_cakisma = $pdo->prepare($sql_mesai_cakisma);
        $stmt_mesai_cakisma->execute([$kullanici_id, $kontrol_bas, $kontrol_bit]);

        if ($stmt_mesai_cakisma->fetchColumn() > 0) {
            $mesaj = "<div class='alert alert-danger shadow-sm border-start border-danger border-5'>
                        <h5 class='alert-heading h6 fw-bold'><i class='fas fa-exclamation-triangle me-2'></i> KAYIT HATA!</h5> $hata_mesaji_detay
                      </div>";
            $hata = true;
        }
    }
    // =========================================================

    if (!$hata) {
        $sql = "INSERT INTO izin_talepleri (calisan_id, hedef_yonetici_id, izin_turu, baslangic_tarihi, bitis_tarihi, toplam_gun, saatlik_sure, aciklama, durum) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'beklemede')";
        try {
            // Kendi ID'mizi kullandığımız için calisan_id otomatik olarak session'dan gelir.
            $pdo->prepare($sql)->execute([$kullanici_id, $hedef_yonetici, $izin_turu, $baslangic, $bitis, $toplam_gun, $saatlik_sure, $aciklama]);
            
            // Log
            $log_txt = ($izin_turu == 'saatlik') ? "Saatlik İzin ($saatlik_sure S)" : "$gun_sayisi Gün İzin ($izin_turu)";
            logKaydet($pdo, $kullanici_id, 'ekleme', $log_txt, 'izin_talepleri', $pdo->lastInsertId());
            
            // --- BİLDİRİMLER ---
            // 1. Yöneticiye
            bildirimGonder($pdo, $hedef_yonetici, "Yeni İzin Talebi", "$ad_soyad sizden izin onayı bekliyor.", "../modules/tum-izinler.php");
            
            // 2. İK ve Muhasebeye (Bilgi)
            rolBildirimGonder($pdo, ['insan_kaynaklari', 'muhasebe'], "Yeni İzin Talebi", "$ad_soyad bir izin talebi oluşturdu.", "../modules/tum-izinler.php");

            $mesaj = '<div class="alert alert-success shadow-sm border-start border-success border-5"><i class="fas fa-check-circle me-2"></i> İzin talebiniz başarıyla iletildi ve bildirim gönderildi.</div>';
        } catch (PDOException $e) {
            $mesaj = '<div class="alert alert-danger">Hata: ' . $e->getMessage() . '</div>';
        }
    }
}
end_of_post_logic:


// Personel, talebini yöneticisine veya müdürüne gönderebilir.
$yoneticiler = $pdo->query("SELECT id, ad, soyad, rol FROM kullanicilar WHERE rol IN ('yonetici', 'mudur') AND durum=1 AND id != $kullanici_id")->fetchAll();
$izinler = $pdo->prepare("SELECT * FROM izin_talepleri WHERE calisan_id = ? ORDER BY olusturulma_tarihi DESC");
$izinler->execute([$kullanici_id]);
$kayitlar = $izinler->fetchAll();
?>

<div class="container-fluid">
    <div class="row g-4 mb-4">
        <div class="col-12 col-md-4">
            <div class="card border-0 shadow-sm h-100" style="background: linear-gradient(135deg, #2A7BB8 0%, #1e5c8a 100%); color: white;">
                <div class="card-body text-center p-4">
                    <div class="mb-2 text-white-50 text-uppercase fw-bold small">Kalan Yıllık İzin Bakiyesi</div>
                    <h1 class="display-3 fw-bold mb-0"><?php echo $kalan_bakiye; ?></h1>
                    <span class="badge bg-white text-primary rounded-pill px-3 mt-2">GÜN</span>
                </div>
            </div>
        </div>
        
        <div class="col-12 col-md-8">
            <div class="card border-0 shadow-sm h-100 border-start border-5 border-warning">
                <div class="card-body p-4">
                    <h6 class="text-muted text-uppercase mb-3 fw-bold"><i class="fas fa-balance-scale text-warning me-2"></i> İzin Kuralları</h6>
                    <div class="row small text-muted">
                        <div class="col-md-6">
                            <ul class="list-unstyled mb-0">
                                <li class="mb-2"><strong class="text-dark">Yıllık İzin:</strong> Pazar ve Resmi Tatiller izin süresinden <u>sayılmaz</u>. Bakiyeden düşer.</li>
                                <li class="mb-2"><strong class="text-dark">Saatlik İzin:</strong> Ücretsiz izin olarak kabul edilir, maaştan kesinti yapılır.</li>
                            </ul>
                        </div>
                        <div class="col-md-6">
                            <ul class="list-unstyled mb-0">
                                <li class="mb-2"><strong class="text-dark">Evlilik/Ölüm:</strong> Takvim Günü Sayılır. Bakiye düşmez.</li>
                                <li><strong class="text-dark">Babalık:</strong> Takvim Günü Sayılır. Bakiye düşmez.</li>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="row g-4">
        <div class="col-12 col-lg-8 mx-auto">
            <div class="card border-0 shadow-sm">
                <div class="card-header bg-white py-3 border-bottom">
                    <h5 class="mb-0 fw-bold text-dark"><i class="fas fa-file-signature text-primary me-2"></i> İzin Talebi Oluştur</h5>
                </div>
                <div class="card-body p-4">
                    <?php echo $mesaj; ?>
                    <form method="POST" id="izinFormu">
                        <input type="hidden" name="csrf_token" value="<?php echo csrfTokenOlustur(); ?>">
                        
                        <div class="row g-3 mb-4">
                            <div class="col-md-6">
                                <label class="form-label fw-bold small text-muted">ONAYLAYACAK YÖNETİCİ</label>
                                <select name="hedef_yonetici_id" id="yoneticiSecim" class="form-select py-2 bg-light" required>
                                    <option value="">Seçiniz...</option>
                                    <?php foreach($yoneticiler as $y): ?>
                                        <option value="<?php echo $y['id']; ?>"><?php echo $y['ad'].' '.$y['soyad']; ?> (<?php echo strtoupper($y['rol']); ?>)</option>
                                    <?php endforeach; ?>
                                </select>
                            </div>
                            <div class="col-md-6">
                                <label class="form-label fw-bold small text-muted">İZİN TÜRÜ</label>
                                <select name="izin_turu" id="izinTuruSecimi" class="form-select py-2 border-primary fw-bold" required onchange="turDegisti()">
                                    <optgroup label="Bakiyeden Düşenler">
                                        <?php if($rol != 'stajyer'): ?>
                                            <option value="yillik">📅 Yıllık İzin (Tatiller Sayılmaz)</option>
                                        <?php endif; ?>
                                    </optgroup>
                                    <optgroup label="Ücretli Yasal İzinler (Bakiye Düşmez)">
                                        <?php if($rol != 'stajyer'): ?>
                                            <option value="evlilik" data-sure="7">💍 Evlilik İzni (7 Gün)</option>
                                            <option value="babalik" data-sure="5">👶 Babalık İzni (5 Gün)</option>
                                            <option value="olum" data-sure="3">⚰️ Ölüm İzni (3 Gün)</option>
                                        <?php endif; ?>
                                        <option value="hastalik">🚑 Hastalık / Rapor</option>
                                        <option value="diger">❓ Diğer Ücretli İzin</option>
                                    </optgroup>
                                    <optgroup label="Ücretsiz İzinler (Maaş Kesintisi)">
                                        <option value="saatlik">🕒 Saatlik İzin (Maaş Kesintisi)</option>
                                    </optgroup>
                                </select>
                            </div>
                        </div>

                        <div id="yasalBilgiKutusu" class="alert alert-info d-none small shadow-sm"></div>
                        <hr class="my-4" style="opacity: 0.1">

                        <div id="alan_gunluk" class="bg-light p-3 rounded border mb-3">
                            <div class="row g-3">
                                <div class="col-12 col-md-4">
                                    <label class="form-label fw-bold small text-muted">BAŞLANGIÇ TARİHİ</label>
                                    <input type="date" name="baslangic_tarihi_gun" id="inpTarih" class="form-control py-2" value="<?php echo date('Y-m-d'); ?>" onchange="hesaplaBitis()">
                                    <div class="form-text small">Seçilen tarih 1. gün sayılır.</div>
                                </div>
                                <div class="col-12 col-md-4">
                                    <label class="form-label fw-bold small text-muted text-primary">GÜN SAYISI</label>
                                    <div class="input-group">
                                        <input type="number" name="gun_sayisi" id="inpGun" class="form-control py-2" step="0.5" min="0.5" placeholder="Gün" onchange="hesaplaBitis()">
                                        <span class="input-group-text">Gün</span>
                                    </div>
                                    <input type="hidden" id="kalanBakiye" value="<?php echo $kalan_bakiye; ?>">
                                </div>
                                <div class="col-12 col-md-4">
                                    <label class="form-label fw-bold small text-muted text-success">İŞE BAŞLAMA TARİHİ</label>
                                    <input type="text" id="outBitis" class="form-control py-2 bg-white text-success fw-bold" readonly value="-">
                                </div>
                            </div>
                            <div id="bakiyeUyari" class="alert alert-danger mt-2 d-none small"><i class="fas fa-exclamation-circle"></i> Talep edilen gün sayısı bakiyenizden fazla!</div>
                        </div>

                        <div id="alan_saatlik" class="bg-warning bg-opacity-10 p-3 rounded border border-warning mb-3" style="display:none;">
                            <div class="row g-3">
                                <div class="col-12 col-md-6">
                                    <label class="form-label fw-bold small text-muted">BAŞLANGIÇ TARİHİ <span class="text-danger">*</span></label>
                                    <input type="date" name="saatlik_tarih" id="inpSaatTarih" class="form-control py-2" value="<?php echo date('Y-m-d'); ?>">
                                </div>
                                <div class="col-6 col-md-3">
                                    <label class="form-label fw-bold small text-muted">BAŞLANGIÇ SAATİ</label>
                                    <select name="saatlik_bas" class="form-select">
                                        <option value="">Seçiniz</option>
                                        <?php echo $zaman_secenekleri; ?>
                                    </select>
                                </div>
                                <div class="col-6 col-md-3">
                                    <label class="form-label fw-bold small text-muted">BİTİŞ SAATİ</label>
                                    <select name="saatlik_bit" class="form-select">
                                        <option value="">Seçiniz</option>
                                        <?php echo $zaman_secenekleri; ?>
                                    </select>
                                </div>
                            </div>
                        </div>

                        <div class="mb-4">
                            <label class="form-label fw-bold small text-muted">AÇIKLAMA / MAZERET</label>
                            <textarea name="aciklama" id="inpAciklama" class="form-control" rows="2" required placeholder="İzin nedeninizi belirtiniz..."></textarea>
                        </div>

                        <div class="d-grid">
                            <button type="button" class="btn btn-primary btn-lg fw-bold shadow-sm" onclick="onayIste()">
                                <i class="fas fa-paper-plane me-2"></i> İzin Talebini Gönder
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>

    <div class="card border-0 shadow-sm mt-4">
        <div class="card-header bg-white py-3 border-bottom">
            <h5 class="mb-0 fw-bold text-dark"><i class="fas fa-history me-2"></i> İzin Geçmişim</h5>
        </div>
        <div class="table-responsive">
            <table class="table table-hover align-middle mb-0">
                <thead class="table-light small text-muted">
                    <tr><th>Tür</th><th>Başlangıç</th><th>Süre</th><th>Durum</th><th>Kayıt</th></tr>
                </thead>
                <tbody>
                    <?php foreach($kayitlar as $k): ?>
                        <tr>
                            <td class="ps-4">
                                <?php if($k['izin_turu'] == 'saatlik'): ?>
                                    <span class="badge bg-warning text-dark">SAATLİK</span>
                                <?php else: ?>
                                    <span class="badge bg-secondary"><?php echo strtoupper($k['izin_turu']); ?></span>
                                <?php endif; ?>
                            </td>
                            <td>
                                <span class="fw-bold text-dark"><?php echo tarihTurkce(date('Y-m-d', strtotime($k['baslangic_tarihi']))); ?></span>
                                <br>
                                <?php if($k['izin_turu'] == 'saatlik'): ?>
                                    <small class="text-muted"><?php echo date('H:i', strtotime($k['baslangic_tarihi'])) . ' - ' . date('H:i', strtotime($k['bitis_tarihi'])); ?></small>
                                <?php endif; ?>
                            </td>
                            <td>
                                <?php echo ($k['izin_turu'] == 'saatlik') ? $k['saatlik_sure'].' Saat' : floatval($k['toplam_gun']).' Gün'; ?>
                            </td>
                            <td>
                                <?php if($k['durum']=='onaylandi'): ?><span class="badge bg-success bg-opacity-10 text-success">Onaylı</span>
                                <?php elseif($k['durum']=='reddedildi'): ?><span class="badge bg-danger bg-opacity-10 text-danger">Red</span>
                                <?php else: ?><span class="badge bg-warning bg-opacity-10 text-warning">Bekliyor</span><?php endif; ?>
                            </td>
                            <td class="text-muted small">
                                <?php echo date('d.m.Y', strtotime($k['olusturulma_tarihi'])); ?>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
        </div>
    </div>
</div>

<div class="modal fade" id="onayModal" tabindex="-1">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content border-0 shadow">
            <div class="modal-header bg-primary text-white">
                <h5 class="modal-title"><i class="fas fa-question-circle me-2"></i> Onaylıyor musunuz?</h5>
                <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body p-4">
                <p class="mb-3 text-center">Aşağıdaki izin talebiniz yöneticiye iletilecektir:</p>
                <div class="alert alert-light border small">
                    <div><strong class="text-dark">Yönetici:</strong> <span id="modalYonetici" class="text-primary"></span></div>
                    <div><strong class="text-dark">Tarih / Süre:</strong> <span id="modalTarih" class="text-primary"></span></div>
                    <div><strong class="text-dark">Konu:</strong> <span id="modalKonu" class="text-primary"></span></div>
                    <div id="modalIseBaslama" class="mt-2 text-success fw-bold border-top pt-2"></div>
                </div>
                <div class="text-center small text-muted">Göndermek istediğinize emin misiniz?</div>
            </div>
            <div class="modal-footer justify-content-center border-0 bg-light">
                <button type="button" class="btn btn-secondary px-4" data-bs-dismiss="modal">İptal</button>
                <button type="button" class="btn btn-primary px-4 fw-bold" onclick="formuGonder()">Evet, Gönder</button>
            </div>
        </div>
    </div>
</div>

<script>
const resmiTatiller = <?php echo $tatiller_json; ?>;

function turDegisti() {
    const select = document.getElementById('izinTuruSecimi');
    const selectedOption = select.options[select.selectedIndex];
    const tur = select.value;
    const inpGun = document.getElementById('inpGun');
    const bilgiKutusu = document.getElementById('yasalBilgiKutusu');
    
    let msg = "";
    if (tur === 'evlilik') msg = "<strong>Evlilik İzni:</strong> 7 Gün (Takvim günü). Bakiye düşmez.";
    else if (tur === 'babalik') msg = "<strong>Babalık İzni:</strong> 5 Gün (Takvim günü). Bakiye düşmez.";
    else if (tur === 'olum') msg = "<strong>Ölüm İzni:</strong> 3 Gün (Takvim günü). Bakiye düşmez.";
    else if (tur === 'yillik') msg = "<strong>Yıllık İzin:</strong> Pazar ve Tatiller sayılmaz. Bakiyeden düşer.";
    
    if(msg) { bilgiKutusu.innerHTML = "<i class='fas fa-info-circle'></i> " + msg; bilgiKutusu.classList.remove('d-none'); } 
    else { bilgiKutusu.classList.add('d-none'); }

    const divGunluk = document.getElementById('alan_gunluk');
    const divSaatlik = document.getElementById('alan_saatlik');
    
    const inpGunlukBas = document.getElementById('inpTarih');
    const inpSaatlikBas = document.querySelector('#alan_saatlik select[name="saatlik_bas"]');
    const inpSaatlikBit = document.querySelector('#alan_saatlik select[name="saatlik_bit"]');
    const inpSaatlikTarih = document.querySelector('input[name="saatlik_tarih"]');

    // Zorunluluk/Görünürlük Ayarı
    const resetFields = (bas, bit, tarih = null, required = false) => {
        if (required) {
            bas.setAttribute('required', 'required');
            if (bit) bit.setAttribute('required', 'required');
            if (tarih) tarih.setAttribute('required', 'required');
        } else {
            bas.removeAttribute('required');
            if (bit) bit.removeAttribute('required');
            if (tarih) tarih.removeAttribute('required');
        }
    };

    if (tur === 'saatlik') {
        divGunluk.style.display = 'none'; 
        divSaatlik.style.display = 'block';
        
        resetFields(inpSaatlikBas, inpSaatlikBit, inpSaatlikTarih, true);
        resetFields(inpGunlukBas, inpGun); // Günlük alanların required'ını kaldır

    } else {
        divGunluk.style.display = 'block'; 
        divSaatlik.style.display = 'none';

        resetFields(inpGunlukBas, inpGun, null, true);
        resetFields(inpSaatlikBas, inpSaatlikBit, inpSaatlikTarih); // Saatlik alanların required'ını kaldır

        const yasalSure = selectedOption.getAttribute('data-sure');
        if (yasalSure) { inpGun.value = yasalSure; inpGun.setAttribute('readonly', true); }
        else { if(inpGun.hasAttribute('readonly')) { inpGun.value = ''; inpGun.removeAttribute('readonly'); } }
        hesaplaBitis();
    }
}

function hesaplaBitis() {
    const basTarihStr = document.getElementById('inpTarih').value;
    const gunSayisi = parseFloat(document.getElementById('inpGun').value);
    const tur = document.getElementById('izinTuruSecimi').value;
    const outBitis = document.getElementById('outBitis');
    const kalanBakiye = parseFloat(document.getElementById('kalanBakiye').value);
    const uyari = document.getElementById('bakiyeUyari');

    if (tur === 'yillik' && gunSayisi > kalanBakiye) {
        uyari.classList.remove('d-none');
        outBitis.value = "Limit Aşıldı";
        return;
    } else {
        uyari.classList.add('d-none');
    }

    if (!basTarihStr || !gunSayisi || gunSayisi <= 0) { outBitis.value = "-"; return; }

    let currentDate = new Date(basTarihStr + 'T00:00:00'); // Saat hatasını önlemek için T00:00:00 eklendi
    let sayilanGun = 0;
    const tatilAtla = (tur === 'yillik'); 

    while (sayilanGun < Math.floor(gunSayisi)) {
        let ymd = currentDate.toISOString().split('T')[0];
        let dayOfWeek = currentDate.getDay(); 

        let gunGecerli = true;
        if (tatilAtla) {
            // Pazar (0) veya Resmi Tatil
            if (dayOfWeek === 0 || resmiTatiller.includes(ymd)) { 
                gunGecerli = false; 
            }
        }
        
        if (gunGecerli) { sayilanGun++; }

        if (sayilanGun < Math.floor(gunSayisi)) {
            currentDate.setDate(currentDate.getDate() + 1);
        }
    }
    
    // İş Başı (Bitiş tarihi + 1 gün)
    currentDate.setDate(currentDate.getDate() + 1);
    
    // İş Başı, Pazar veya Resmi Tatil gününe denk geliyorsa atla
    let checkLoop = 0;
    while(checkLoop < 10) {
        let ymdCheck = currentDate.toISOString().split('T')[0];
        let dayCheck = currentDate.getDay();
        
        // Pazar (0) veya Resmi Tatil ise atla
        if(dayCheck === 0 || resmiTatiller.includes(ymdCheck)) {
            currentDate.setDate(currentDate.getDate() + 1);
        } else {
            break;
        }
        checkLoop++;
    }
    
    const options = { day: 'numeric', month: 'long', year: 'numeric' };
    outBitis.value = currentDate.toLocaleDateString('tr-TR', options);
}

function calculateHours(start, end) {
    const [h1, m1] = start.split(':').map(Number);
    const [h2, m2] = end.split(':').map(Number);
    
    let totalMinutes1 = h1 * 60 + m1;
    let totalMinutes2 = h2 * 60 + m2;
    
    // Gece geçişi
    if (totalMinutes2 < totalMinutes1) {
        totalMinutes2 += 24 * 60;
    }
    
    const diffMinutes = totalMinutes2 - totalMinutes1;
    return diffMinutes / 60;
}

function onayIste() {
    const form = document.getElementById('izinFormu');
    if (!form.checkValidity()) { form.reportValidity(); return; }

    const yonetici = document.getElementById('yoneticiSecim');
    const yoneticiText = yonetici.options[yonetici.selectedIndex].text;
    const konu = document.getElementById('inpAciklama').value;
    const tur = document.getElementById('izinTuruSecimi').value;
    
    let tarihBilgi = "";
    let iseBaslama = "";

    if (tur === 'saatlik') {
        const tarih = document.querySelector('input[name="saatlik_tarih"]').value;
        const bas_saat = document.querySelector('select[name="saatlik_bas"]').value;
        const bit_saat = document.querySelector('select[name="saatlik_bit"]').value;
        const saatFarki = calculateHours(bas_saat, bit_saat);

        tarihBilgi = `${tarih} ${bas_saat} - ${bit_saat} (Saatlik)`;
        iseBaslama = "Süre: " + saatFarki + " Saat";

        if(saatFarki <= 0) {
            alert("Bitiş saati başlangıç saatinden sonra olmalıdır."); return;
        }

    } else {
        const trh = new Date(document.getElementById('inpTarih').value + 'T00:00:00');
        const gun = document.getElementById('inpGun').value;
        const baslama = document.getElementById('outBitis').value;
        if(baslama === "Limit Aşıldı") { alert("Yıllık izin bakiyesi yetersiz!"); return; }
        
        const tarihOptions = { year: 'numeric', month: 'long', day: 'numeric' };
        tarihBilgi = trh.toLocaleDateString('tr-TR', tarihOptions) + " (" + gun + " Gün)";
        iseBaslama = "İşe Başlama: " + baslama;
    }

    document.getElementById('modalYonetici').textContent = yoneticiText;
    document.getElementById('modalTarih').textContent = tarihBilgi;
    document.getElementById('modalKonu').textContent = konu.substring(0, 40) + (konu.length > 40 ? "..." : "");
    document.getElementById('modalIseBaslama').textContent = iseBaslama;

    new bootstrap.Modal(document.getElementById('onayModal')).show();
}

function formuGonder() {
    document.getElementById('izinFormu').submit();
}

document.addEventListener('DOMContentLoaded', function() {
    turDegisti(); 
});
</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,471
Sinyal (Ağ Hiti)
1.54 MB
Kapasite

Ağda Paylaş