sys/veri_detay/#008

PYBS (Personel Yönetim Bilgi Sistemi)

Son Senkronizasyon: 16.12.2025
izin-gir.php 545 satır • 26.60 KB
<?php
// modules/izin-gir.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']);

// --- GELİŞMİŞ KIDEM VE İZİN HESAPLAMA MOTORU ---
if (!function_exists('yillikIzinHesapla')) {
    function yillikIzinHesapla($pdo, $calisan_id) {
        $stmt = $pdo->prepare("SELECT * FROM calisma_donemleri WHERE calisan_id = ? ORDER BY ise_giris ASC");
        $stmt->execute([$calisan_id]);
        $donemler = $stmt->fetchAll();
        
        // Kullanıcı bilgisini al
        $u_bilgi = $pdo->query("SELECT ise_giris_tarihi, devreden_izin, dogum_tarihi FROM kullanicilar WHERE id = $calisan_id")->fetch();

        // Eski veri fallback
        if (empty($donemler)) {
            if (!$u_bilgi) return ['toplam_hak'=>0, 'kullanilan'=>0, 'kalan'=>0, 'calisma_yili'=>0, 'ise_giris'=>date('Y-m-d')];
            $donemler = [['ise_giris' => $u_bilgi['ise_giris_tarihi'], 'isten_cikis' => null]];
        }

        $toplam_gun = 0;
        foreach ($donemler as $d) {
            $giris = new DateTime($d['ise_giris']);
            $cikis = $d['isten_cikis'] ? new DateTime($d['isten_cikis']) : new DateTime(); 
            if ($cikis >= $giris) {
                $fark = $giris->diff($cikis);
                $toplam_gun += $fark->days;
            }
        }

        $calisma_yili = floor($toplam_gun / 365);
        $toplam_hak = floatval($u_bilgi['devreden_izin'] ?? 0);
        
        // Yaş Hesabı
        $yas = 0;
        if (!empty($u_bilgi['dogum_tarihi'])) {
            $dt_dogum = new DateTime($u_bilgi['dogum_tarihi']);
            $dt_bugun = new DateTime();
            $yas = $dt_bugun->diff($dt_dogum)->y;
        }
        
        for ($i = 1; $i <= $calisma_yili; $i++) {
            $hak = 14;
            if ($i > 5 && $i < 15) $hak = 20; elseif ($i >= 15) $hak = 26;
            
            // 50 yaş üstü ve 18 yaş altı kontrolü (Min 20 Gün)
            if (($yas <= 18 || $yas >= 50) && $hak < 20) {
                $hak = 20;
            }
            
            $toplam_hak += $hak;
        }

        $stmt_used = $pdo->prepare("SELECT SUM(toplam_gun) FROM izin_talepleri WHERE calisan_id = ? AND izin_turu = 'yillik' AND durum != 'reddedildi'");
        $stmt_used->execute([$calisan_id]);
        $kullanilan = floatval($stmt_used->fetchColumn());

        return [
            'toplam_hak' => $toplam_hak,
            'kullanilan' => $kullanilan,
            'kalan' => $toplam_hak - $kullanilan,
            'calisma_yili' => $calisma_yili,
            'ise_giris' => $u_bilgi['ise_giris_tarihi']
        ];
    }
}

// --- ÇAKIŞMA KONTROL FONKSİYONU ---
function cakismaVarMi($pdo, $calisan_id, $bas, $bit) {
    // Reddedilenler hariç, tarih aralığı çakışan kayıt var mı?
    // Mantık: (TalepBas < MevcutBit) AND (TalepBit > MevcutBas)
    $sql = "SELECT count(*) FROM izin_talepleri 
            WHERE calisan_id = ? 
            AND durum != 'reddedildi' 
            AND (baslangic_tarihi < ? AND bitis_tarihi > ?)";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$calisan_id, $bit, $bas]);
    return $stmt->fetchColumn() > 0;
}

// --- AJAX İŞLEMİ ---
if (isset($_GET['action']) && $_GET['action'] == 'get_bakiye') {
    $pid = (int)$_GET['personel_id'];
    $b = yillikIzinHesapla($pdo, $pid);
    header('Content-Type: application/json');
    echo json_encode($b);
    exit;
}

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

$mesaj = '';
$kullanici_id = $_SESSION['kullanici_id'];
$tum_calisanlar = $pdo->query("SELECT id, ad, soyad, rol, cinsiyet FROM kullanicilar WHERE durum=1 AND rol != 'root' ORDER BY ad ASC")->fetchAll();

// --- GÜNCELLENMİŞ İZİN AYARLARI ---
$izin_ayarlari = [
    'yillik' => ['label' => 'Yıllık İzin', 'gun' => 0, 'ucret' => 'Ücretli', 'kural' => 'yillik'],
    'babalik' => ['label' => 'Babalık İzni', 'gun' => 5, 'ucret' => 'Ücretli', 'kural' => 'takvim'],
    'olum' => ['label' => 'Ölüm İzni', 'gun' => 3, 'ucret' => 'Ücretli', 'kural' => 'takvim'],
    'evlilik' => ['label' => 'Evlilik İzni', 'gun' => 3, 'ucret' => 'Ücretli', 'kural' => 'takvim'],
    'diger' => ['label' => 'Diğer İzin', 'gun' => 0, 'ucret' => 'Ücretli', 'kural' => 'takvim'], 
    'sut_izni' => ['label' => 'Süt İzni', 'type' => 'saat', 'ucret' => 'Ücretli', 'kural' => 'saat'],
    'hastalik' => ['label' => 'Hastalık / Rapor', 'gun' => 0, 'ucret' => 'Ücretsiz (SGK)', 'kural' => 'takvim'],
    'saatlik' => ['label' => 'Saatlik İzin', 'type' => 'saat', 'ucret' => 'Ücretsiz', 'kural' => 'saat'],
    'ucretsiz' => ['label' => 'Ücretsiz İzin', 'gun' => 0, 'ucret' => 'Ücretsiz', 'kural' => 'takvim'],
    'mesaiye_gelmedi' => ['label' => 'Devamsızlık', 'gun' => 0, 'ucret' => 'Ücretsiz', 'kural' => 'takvim']
];

$resmi_tatiller = $pdo->query("SELECT tarih FROM resmi_tatiller")->fetchAll(PDO::FETCH_COLUMN);
$tatiller_json = json_encode($resmi_tatiller);
$izin_ayarlari_json = json_encode($izin_ayarlari);

$zaman_secenekleri = ""; 
for($s=0;$s<24;$s++) foreach(['00','30'] as $d) $zaman_secenekleri .= "<option>".sprintf('%02d:%s',$s,$d)."</option>";

// POST İŞLEMİ
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    csrfKontrol($_POST['csrf_token']);
    $calisan_id = (int)$_POST['calisan_id'];
    $izin_turu = $_POST['izin_turu'];
    $aciklama = guvenlik($_POST['aciklama']);
    $hata = false;

    // Süt İzni Cinsiyet Kontrolü
    if ($izin_turu == 'sut_izni') {
        $cinsiyet = $pdo->query("SELECT cinsiyet FROM kullanicilar WHERE id = $calisan_id")->fetchColumn();
        if ($cinsiyet !== 'Kadın') { 
            $mesaj = '<div class="alert alert-danger">Hata: Süt izni sadece kadın personel içindir.</div>'; 
            $hata = true; 
        }
    }

    // Yıllık İzin Kontrolü
    if (!$hata && $izin_turu == 'yillik') {
        $bakiye = yillikIzinHesapla($pdo, $calisan_id);
        $talep_gun = (float)$_POST['gun_sayisi'];
        
        $baslangic = $_POST['baslangic_gunluk'];
        $ise_giris_obj = new DateTime($bakiye['ise_giris']);
        $izin_bas_obj = new DateTime($baslangic);
        $birinci_yil_dolus = clone $ise_giris_obj;
        $birinci_yil_dolus->modify('+1 year');

        if ($izin_bas_obj < $birinci_yil_dolus) {
            $mesaj = '<div class="alert alert-danger fw-bold"><i class="fas fa-ban"></i> HATA: Personel 1 yıllık kıdem süresini ('.$birinci_yil_dolus->format('d.m.Y').') doldurmadan yıllık izin kullanamaz.</div>';
            $hata = true;
        } elseif ($talep_gun > $bakiye['kalan']) {
            $mesaj = '<div class="alert alert-danger fw-bold"><i class="fas fa-exclamation-triangle"></i> Yetersiz Bakiye! (Kalan: '.$bakiye['kalan'].')</div>';
            $hata = true;
        }
    }

    if (!$hata) {
        $ayar = $izin_ayarlari[$izin_turu];
        
        // --- SAATLİK ve SÜT İZNİ ---
        if (isset($ayar['type']) && $ayar['type'] == 'saat') {
            if ($izin_turu == 'sut_izni') {
                $bas_t = $_POST['sut_bas_tarih']; $bit_t = $_POST['sut_bit_tarih'];
                $sut_bas = $_POST['sut_bas_saat']; $sut_bit = $_POST['sut_bit_saat'];
                $t1 = strtotime($sut_bas); $t2 = strtotime($sut_bit);
                $fark = round(($t2 - $t1) / 3600, 2);
                
                if($fark > 1.5) {
                    $mesaj = '<div class="alert alert-danger fw-bold"><i class="fas fa-ban"></i> HATA: Süt izni günlük 1.5 saati geçemez!</div>';
                } else {
                    $current = new DateTime($bas_t); $end = new DateTime($bit_t);
                    $stmt = $pdo->prepare("INSERT INTO izin_talepleri (calisan_id, hedef_yonetici_id, onaylayan_id, izin_turu, baslangic_tarihi, bitis_tarihi, toplam_gun, saatlik_sure, aciklama, durum, onaylanma_tarihi) VALUES (?, ?, ?, 'sut_izni', ?, ?, 0, ?, ?, 'onaylandi', NOW())");
                    
                    // Transaction Başlat
                    $pdo->beginTransaction();
                    try {
                        while ($current <= $end) {
                            $ymd = $current->format('Y-m-d'); $gun_no = $current->format('N');
                            if ($gun_no < 6 && !in_array($ymd, $resmi_tatiller)) {
                                $db_bas = "$ymd $sut_bas:00"; 
                                $db_bit = "$ymd $sut_bit:00";
                                
                                // Çakışma Kontrolü
                                if (cakismaVarMi($pdo, $calisan_id, $db_bas, $db_bit)) {
                                    throw new Exception("Seçilen tarihlerin bazılarında ($ymd) zaten kayıtlı bir izin mevcut.");
                                }

                                $stmt->execute([$calisan_id, $kullanici_id, $kullanici_id, $db_bas, $db_bit, $fark, $aciklama]);
                            }
                            $current->modify('+1 day');
                        }
                        $pdo->commit();
                        $mesaj = '<div class="alert alert-success">Süt izni kaydedildi.</div>';
                    } catch (Exception $e) {
                        $pdo->rollBack();
                        $mesaj = '<div class="alert alert-danger"><i class="fas fa-exclamation-circle"></i> '.$e->getMessage().'</div>';
                    }
                }

            } else {
                // Saatlik İzin
                $tarih = $_POST['saatlik_tarih'];
                $bas = $_POST['saatlik_bas']; $bit = $_POST['saatlik_bit'];
                $t1 = strtotime("$tarih $bas:00"); $t2 = strtotime("$tarih $bit:00");
                $mola_bas = strtotime("$tarih 12:00:00"); $mola_bit = strtotime("$tarih 13:00:00");
                $overlap = max(0, min($t2, $mola_bit) - max($t1, $mola_bas));
                $diff = (($t2 - $t1) - $overlap) / 3600; 
                
                $db_bas = "$tarih $bas:00"; 
                $db_bit = "$tarih $bit:00";
                
                if ($diff <= 0) { 
                    $mesaj = '<div class="alert alert-danger">Hata: Geçersiz süre.</div>'; 
                } elseif (cakismaVarMi($pdo, $calisan_id, $db_bas, $db_bit)) {
                    $mesaj = '<div class="alert alert-danger"><i class="fas fa-exclamation-circle"></i> HATA: Bu tarih ve saat aralığında personelin zaten bir izni var.</div>';
                } else {
                    $pdo->prepare("INSERT INTO izin_talepleri (calisan_id, hedef_yonetici_id, onaylayan_id, izin_turu, baslangic_tarihi, bitis_tarihi, toplam_gun, saatlik_sure, aciklama, durum, onaylanma_tarihi) VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?, 'onaylandi', NOW())")
                        ->execute([$calisan_id, $kullanici_id, $kullanici_id, $izin_turu, $db_bas, $db_bit, $diff, $aciklama]);
                    $mesaj = "<div class='alert alert-success'>Saatlik izin kaydedildi. ($diff Saat)</div>";
                }
            }
        } 
        // --- GÜNLÜK İZİN ---
        else {
            $bas = $_POST['baslangic_gunluk'];
            $gun = (float)$_POST['gun_sayisi'];
            $kural = $ayar['kural'];

            $current = new DateTime($bas);
            $sayilan = 0;
            
            while ($sayilan < $gun) {
                $ymd = $current->format('Y-m-d');
                $day = $current->format('N'); // 1:Pzt ... 7:Paz
                
                $gecerli = true;
                if ($kural == 'yillik') { 
                    // Yıllık: Cumartesi DAHİL, Pazar ve Tatil HARİÇ
                    if ($day == 7 || in_array($ymd, $resmi_tatiller)) $gecerli = false;
                }
                
                if ($gecerli) $sayilan++;
                if ($sayilan >= $gun) break;
                
                $current->modify('+1 day');
            }
            
            $db_bas = $bas . ' 08:00:00';
            $db_bit = $current->format('Y-m-d') . ' 18:00:00';
            
            if (cakismaVarMi($pdo, $calisan_id, $db_bas, $db_bit)) {
                $mesaj = '<div class="alert alert-danger"><i class="fas fa-exclamation-circle"></i> HATA: Seçilen tarih aralığında personelin zaten kayıtlı bir izni bulunuyor. Lütfen tarihleri kontrol edin.</div>';
            } else {
                $pdo->prepare("INSERT INTO izin_talepleri (calisan_id, hedef_yonetici_id, onaylayan_id, izin_turu, baslangic_tarihi, bitis_tarihi, toplam_gun, aciklama, durum, onaylanma_tarihi) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'onaylandi', NOW())")
                    ->execute([$calisan_id, $kullanici_id, $kullanici_id, $izin_turu, $db_bas, $db_bit, $gun, $aciklama]);
                $mesaj = '<div class="alert alert-success">İzin başarıyla kaydedildi.</div>';
            }
        }
    }
}
?>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<style>
    .flatpickr-day.resmi-tatil { background: #ffebee !important; border-color: #ffcdd2 !important; color: #c62828 !important; font-weight: bold; }
    .flatpickr-day.pazar-gunu { background: #fff3e0 !important; border-color: #ffe0b2 !important; color: #ef6c00 !important; font-weight: bold; }
    .flatpickr-input[readonly] { background-color: #fff !important; cursor: pointer; }
</style>

<div class="container-fluid">
    <div class="row justify-content-center">
        <div class="col-md-10">
            <div class="card p-4 shadow-sm">
                <h4 class="mb-3 border-bottom pb-2 text-primary"><i class="fas fa-user-clock me-2"></i> Personel İzin Girişi</h4>
                <?php echo $mesaj; ?>
                
                <form method="POST" id="izinForm">
                    <input type="hidden" name="csrf_token" value="<?php echo csrfTokenOlustur(); ?>">

                    <div class="row mb-3">
                        <div class="col-md-6">
                            <label class="fw-bold">Personel</label>
                            <select name="calisan_id" id="calisanId" class="form-select" required onchange="personelDegisti()">
                                <option value="">Seçiniz...</option>
                                <?php foreach($tum_calisanlar as $c) echo "<option value='{$c['id']}'>{$c['ad']} {$c['soyad']}</option>"; ?>
                            </select>
                        </div>
                        <div class="col-md-6">
                            <label class="fw-bold">İzin Türü</label>
                            <select name="izin_turu" id="izinTuru" class="form-select" required onchange="turDegisti()">
                                <option value="">Seçiniz...</option>
                                <?php foreach($izin_ayarlari as $k=>$v): 
                                    $label = $v['label'];
                                    if(isset($v['gun']) && $v['gun'] > 0) $label .= ' (' . $v['gun'] . ' Gün)';
                                    $label .= ' - ' . $v['ucret'];
                                ?>
                                    <option value="<?php echo $k; ?>"><?php echo $label; ?></option>
                                <?php endforeach; ?>
                            </select>
                            <div id="izinBilgiNotu" class="small mt-1 text-primary fw-bold"></div>
                            
                            <div id="bakiyeAlani" class="alert alert-info py-2 px-3 mt-2 d-none shadow-sm">
                                <i class="fas fa-info-circle"></i> <span id="bakiyeMetin">...</span>
                            </div>
                        </div>
                    </div>

                    <div id="gunlukAlan">
                        <div class="row g-2 mb-3 bg-light p-3 rounded border">
                            <div class="col-md-3"><label class="small fw-bold">Başlangıç</label><input type="text" name="baslangic_gunluk" id="basTarih" class="form-control bg-white" required></div>
                            <div class="col-md-2"><label class="small fw-bold">Gün Sayısı</label><input type="number" name="gun_sayisi" id="gunSayisi" class="form-control" step="0.5" min="0.5" onkeyup="hesapla()" onchange="hesapla()"></div>
                            <div class="col-md-3"><label class="small fw-bold">Bitiş (Dahil)</label><input type="text" id="bitTarih" class="form-control bg-white" readonly></div>
                            <div class="col-md-4"><label class="small fw-bold text-success">İşe Başlama</label><input type="text" id="iseBaslama" class="form-control bg-white fw-bold text-success" readonly value="-"></div>
                        </div>
                        <small class="text-muted mt-2 d-block" id="hesapAciklama"></small>
                    </div>

                    <div id="ozelAlan" class="d-none">
                        <div id="saatlikInputs" class="row g-2 mb-3 bg-warning bg-opacity-10 p-3 rounded d-none">
                            <div class="col-12"><label class="small fw-bold">Tarih</label><input type="text" name="saatlik_tarih" id="saatlikTarih" class="form-control bg-white"></div>
                            <div class="col-4"><label class="small fw-bold">Başlangıç</label><select name="saatlik_bas" id="saatBas" class="form-select bg-white" onchange="saatHesapla()"><?php echo $zaman_secenekleri; ?></select></div>
                            <div class="col-4"><label class="small fw-bold">Bitiş</label><select name="saatlik_bit" id="saatBit" class="form-select bg-white" onchange="saatHesapla()"><?php echo $zaman_secenekleri; ?></select></div>
                            <div class="col-4"><label class="small fw-bold">Süre</label><input type="text" id="saatSonuc" class="form-control fw-bold bg-white" readonly value="0 Saat"></div>
                            <div class="col-12"><small class="text-danger fst-italic">* 12:00 - 13:00 arası öğle molası süreden otomatik düşülür.</small></div>
                        </div>
                        
                        <div id="sutInputs" class="row g-2 mb-3 bg-danger bg-opacity-10 p-3 rounded d-none">
                            <div class="col-6"><label class="small fw-bold">Başlangıç Tarihi</label><input type="text" name="sut_bas_tarih" id="sutBasTarih" class="form-control bg-white"></div>
                            <div class="col-6"><label class="small fw-bold">Bitiş Tarihi</label><input type="text" name="sut_bit_tarih" id="sutBitTarih" class="form-control bg-white"></div>
                            <div class="col-6"><label class="small fw-bold">Çıkış Saati</label><select name="sut_bas_saat" id="sutBas" class="form-select bg-white" onchange="sutHesapla()"><?php echo $zaman_secenekleri; ?></select></div>
                            <div class="col-6"><label class="small fw-bold">Dönüş Saati</label><select name="sut_bit_saat" id="sutBit" class="form-select bg-white" onchange="sutHesapla()"><?php echo $zaman_secenekleri; ?></select></div>
                            <div class="col-12" id="sutUyari"></div>
                        </div>
                    </div>

                    <div class="mb-3">
                        <label class="fw-bold small">Açıklama</label>
                        <textarea name="aciklama" class="form-control" rows="2"></textarea>
                    </div>

                    <button type="submit" id="submitBtn" class="btn btn-primary fw-bold w-100 py-2">KAYDET</button>
                </form>
            </div>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/tr.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>

<script>
const tatiller = <?php echo $tatiller_json; ?>;
const izinAyarlari = <?php echo $izin_ayarlari_json; ?>;
let currentBakiye = 0;
let calismaYili = 0;
let iseGirisTarihi = null;

const fpConfig = {
    locale: "tr", 
    dateFormat: "Y-m-d", 
    altInput: true, 
    altFormat: "d F Y", 
    disableMobile: true,
    onDayCreate: function(dObj, dStr, fp, dayElem){
        let d = fp.formatDate(dayElem.dateObj, "Y-m-d");
        if(tatiller.includes(d)) dayElem.className += " bg-danger text-white";
        else if(dayElem.dateObj.getDay()===0) dayElem.className += " bg-warning";
    }
};

document.addEventListener('DOMContentLoaded', function() {
    flatpickr("#basTarih", { ...fpConfig, defaultDate: "today", onChange: hesapla });
    flatpickr("#saatlikTarih", { ...fpConfig, defaultDate: "today" });
    flatpickr("#sutBasTarih", { ...fpConfig, defaultDate: "today" });
    flatpickr("#sutBitTarih", { ...fpConfig });
});

function personelDegisti() {
    const pid = document.getElementById('calisanId').value;
    if(pid) {
        fetch(`izin-gir.php?action=get_bakiye&personel_id=${pid}`)
            .then(r => r.json())
            .then(d => {
                currentBakiye = parseFloat(d.kalan);
                calismaYili = parseInt(d.calisma_yili);
                iseGirisTarihi = new Date(d.ise_giris);
                
                let txt = `Kıdem: ${d.calisma_yili} Yıl | Kalan Hak: ${d.kalan} Gün`;
                if(d.calisma_yili < 1) txt += " (1 Yıl dolmadı!)";
                
                document.getElementById('bakiyeMetin').innerText = txt;
                turDegisti();
            });
    }
}

function turDegisti() {
    const tur = document.getElementById('izinTuru').value;
    const ayar = izinAyarlari[tur];
    const bakiyeDiv = document.getElementById('bakiyeAlani');
    const bilgiDiv = document.getElementById('izinBilgiNotu');
    
    document.getElementById('gunSayisi').readOnly = false;
    document.getElementById('gunSayisi').value = '';
    
    if (!ayar) return;

    let bilgiTxt = `Durum: ${ayar.ucret}`;
    if (ayar.gun > 0) {
        document.getElementById('gunSayisi').value = ayar.gun;
        document.getElementById('gunSayisi').readOnly = true;
        bilgiTxt += ` | Süre: ${ayar.gun} Gün (Otomatik)`;
    }
    bilgiDiv.innerText = bilgiTxt;

    if (tur === 'yillik') {
        bakiyeDiv.classList.remove('d-none');
        if (calismaYili < 1) bakiyeDiv.className = "alert alert-danger py-2 px-3 mt-2 shadow-sm";
        else bakiyeDiv.className = "alert alert-info py-2 px-3 mt-2 shadow-sm";
    } else {
        bakiyeDiv.classList.add('d-none');
    }

    const gunluk = document.getElementById('gunlukAlan');
    const ozel = document.getElementById('ozelAlan');
    document.getElementById('saatlikInputs').classList.add('d-none');
    document.getElementById('sutInputs').classList.add('d-none');
    gunluk.classList.add('d-none');
    ozel.classList.add('d-none');
    document.getElementById('sutUyari').innerHTML = '';

    if (ayar.type === 'saat') {
        ozel.classList.remove('d-none');
        if (tur === 'saatlik') document.getElementById('saatlikInputs').classList.remove('d-none');
        if (tur === 'sut_izni') document.getElementById('sutInputs').classList.remove('d-none');
    } else {
        gunluk.classList.remove('d-none');
        hesapla();
    }
}

function saatHesapla() {
    let bas = document.getElementById('saatBas').value;
    let bit = document.getElementById('saatBit').value;
    if (!bas || !bit) return;

    let t1 = parseInt(bas.split(':')[0]) * 60 + parseInt(bas.split(':')[1]);
    let t2 = parseInt(bit.split(':')[0]) * 60 + parseInt(bit.split(':')[1]);
    if (t2 <= t1) { document.getElementById('saatSonuc').value = "Hata!"; return; }

    let diffMin = t2 - t1;
    let molaBas = 720; let molaBit = 780; 
    let overlap = Math.max(0, Math.min(t2, molaBit) - Math.max(t1, molaBas));

    diffMin -= overlap;
    document.getElementById('saatSonuc').value = (diffMin / 60).toFixed(2) + " Saat";
}

// Süt İzni 1.5 Saat Kontrolü
function sutHesapla() {
    let bas = document.getElementById('sutBas').value;
    let bit = document.getElementById('sutBit').value;
    const btn = document.getElementById('submitBtn');
    const uyari = document.getElementById('sutUyari');
    
    uyari.innerHTML = '';
    btn.disabled = false;

    if (!bas || !bit) return;
    
    let t1 = parseInt(bas.split(':')[0])*60 + parseInt(bas.split(':')[1]);
    let t2 = parseInt(bit.split(':')[0])*60 + parseInt(bit.split(':')[1]);
    
    if (t2 <= t1) { 
        uyari.innerHTML = '<span class="text-danger fw-bold small">Hata: Bitiş saati başlangıçtan büyük olmalıdır.</span>';
        btn.disabled = true;
        return; 
    }
    
    let diff = (t2 - t1) / 60; // Saat cinsinden fark
    
    if (diff > 1.5) {
        uyari.innerHTML = `<span class="text-danger fw-bold small"><i class="fas fa-exclamation-triangle"></i> Uyarı: Seçilen süre ${diff.toFixed(2)} saat. Süt izni günlük 1.5 saati geçemez!</span>`;
        btn.disabled = true;
    } else {
        uyari.innerHTML = `<span class="text-success fw-bold small"><i class="fas fa-check-circle"></i> Süre uygun: ${diff.toFixed(2)} Saat</span>`;
        btn.disabled = false;
    }
}

function hesapla() {
    const basStr = document.getElementById('basTarih').value; 
    const gunInput = document.getElementById('gunSayisi');
    let gun = parseFloat(gunInput.value);
    const tur = document.getElementById('izinTuru').value;
    const ayar = izinAyarlari[tur];
    const btn = document.getElementById('submitBtn');
    
    if (!tur || !ayar) return;
    
    if (tur === 'yillik') {
        if (gun > currentBakiye) gunInput.classList.add('is-invalid'); 
        else { gunInput.classList.remove('is-invalid'); btn.disabled = false; }
    }

    if(!basStr || gun <= 0) return;
    
    let parts = basStr.split('-');
    let current = new Date(parts[0], parts[1]-1, parts[2]); 
    let sayilan = 0;

    while (sayilan < gun) {
        let z = new Date(current.getTime() - (current.getTimezoneOffset() * 60000)).toISOString().split('T')[0];
        let day = current.getDay();
        let gecerli = true;

        if (ayar.kural === 'yillik') {
            if (day === 0 || tatiller.includes(z)) gecerli = false;
        } 
        if (gecerli) sayilan++;
        if (sayilan >= gun) break;
        current.setDate(current.getDate() + 1);
    }
    
    document.getElementById('bitTarih').value = current.toLocaleDateString('tr-TR', { day: 'numeric', month: 'long', year: 'numeric' });

    let isBasi = new Date(current);
    isBasi.setDate(isBasi.getDate() + 1);
    while (true) {
        let z = new Date(isBasi.getTime() - (isBasi.getTimezoneOffset() * 60000)).toISOString().split('T')[0];
        let day = isBasi.getDay();
        if (day === 0 || tatiller.includes(z)) isBasi.setDate(isBasi.getDate() + 1);
        else break; 
    }
    document.getElementById('iseBaslama').value = isBasi.toLocaleDateString('tr-TR', {weekday:'long', year:'numeric', month:'long', day:'numeric'});
    
    let kuralAciklama = (ayar.kural === 'yillik') ? "Kural: Pazar ve Tatiller süreden düşülmez (süreyi uzatır)." : "Kural: Takvim günü bazlıdır.";
    document.getElementById('hesapAciklama').innerHTML = kuralAciklama;
}
</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,332
Sinyal (Ağ Hiti)
1.54 MB
Kapasite

Ağda Paylaş