<?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']);
include '../includes/header.php';
include '../includes/menu.php';
$mesaj = '';
$kullanici_id = $_SESSION['kullanici_id'];
$rol = $_SESSION['rol'];
// Tüm aktif çalışanlar
$tum_calisanlar = $pdo->query("SELECT id, ad, soyad, rol FROM kullanicilar WHERE durum=1 AND rol != 'root' ORDER BY ad ASC")->fetchAll();
// İzin türleri
$izin_turleri = [
'yillik' => 'Yıllık İzin (Hakedişe Göre)',
'hastalik' => 'Hastalık/Rapor İzni',
'evlilik' => 'Evlilik İzni (7 Gün)',
'babalik' => 'Babalık İzni (5 Gün)',
'olum' => 'Ölüm İzni (3 Gün)',
'saatlik' => 'Saatlik İzin (Ücretsiz İzin/Kesinti)',
'diger' => 'Diğer Ücretli İzin'
];
// Saat seçenekleri (tam ve buçuk)
$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>";
}
}
// POST İŞLEMLERİ (değişmedi, sadece goto etiketi korundu)
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
csrfKontrol($_POST['csrf_token']);
$calisan_id = (int)$_POST['calisan_id'];
$izin_turu = $_POST['izin_turu'];
$aciklama = guvenlik($_POST['aciklama']);
$saatlik_sure = 0.00;
$toplam_gun = 0;
$baslangic_kayit = "";
$bitis_kayit = "";
$hata = false;
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";
if (empty($tarih) || empty($bas_saat) || empty($bit_saat)) {
$mesaj = '<div class="alert alert-danger">Hata: Saatlik izin için Tarih, Başlangıç ve bitiş saati zorunludur.</div>';
$hata = true;
goto end_of_post;
}
if (strtotime($bitis) <= strtotime($baslangic)) {
$mesaj = '<div class="alert alert-danger">Hata: Bitiş saati başlangıçtan sonra olmalıdır.</div>';
$hata = true;
goto end_of_post;
}
$diff_saniye = strtotime($bitis) - strtotime($baslangic);
$ham_saat = $diff_saniye / 3600;
if ($ham_saat <= 0) {
$mesaj = '<div class="alert alert-danger">Hata: Saatlik izin süresi sıfırdan büyük olmalıdır.</div>';
$hata = true;
goto end_of_post;
}
// ÖĞLE MOLASI DÜŞÜMÜ (yeni kural)
$dt_tarih = new DateTime($tarih);
$gun_no = $dt_tarih->format('N'); // 1=Pzt ... 5=Cuma
if ($gun_no >= 1 && $gun_no <= 5) {
$mola_bas = strtotime($tarih . ' 12:00:00');
$mola_bit = strtotime($tarih . ' 13:00:00');
$izin_bas = strtotime($baslangic);
$izin_bit = strtotime($bitis);
$kesisim_bas = max($izin_bas, $mola_bas);
$kesisim_bit = min($izin_bit, $mola_bit);
if ($kesisim_bit > $kesisim_bas) {
$kesisim_saniye = $kesisim_bit - $kesisim_bas;
$kesisim_saat = $kesisim_saniye / 3600;
$saatlik_sure = round($ham_saat - $kesisim_saat, 2);
} else {
$saatlik_sure = round($ham_saat, 2);
}
} else {
$saatlik_sure = round($ham_saat, 2);
}
if ($saatlik_sure <= 0) {
$mesaj = '<div class="alert alert-danger">Hata: Net Saatlik izin süresi sıfırdan büyük olmalıdır (Moladan sonra).</div>';
$hata = true;
goto end_of_post;
}
$baslangic_kayit = $baslangic;
$bitis_kayit = $bitis;
} else {
$baslangic = $_POST['baslangic_gunluk'];
$bitis = $_POST['bitis_gunluk'];
if (empty($baslangic) || empty($bitis)) {
$mesaj = '<div class="alert alert-danger">Hata: Başlangıç ve bitiş tarihleri zorunludur.</div>';
$hata = true;
goto end_of_post;
}
$dt_bas = new DateTime($baslangic);
$dt_bit = new DateTime($bitis);
$interval = $dt_bas->diff($dt_bit);
$toplam_gun = $interval->days + 1;
if ($toplam_gun <= 0) {
$mesaj = '<div class="alert alert-danger">Hata: İzin süresi en az 1 gün olmalıdır.</div>';
$hata = true;
goto end_of_post;
}
$baslangic_kayit = $baslangic . " 08:00:00";
$bitis_kayit = $bitis . " 18:00:00";
}
// ÇAKIŞMA KONTROLÜ
if (!$hata) {
$kontrol_bas = date('Y-m-d', strtotime($baslangic_kayit));
$kontrol_bit = date('Y-m-d', strtotime($bitis_kayit));
if ($izin_turu != 'saatlik') {
$sql_izin_cakisma = "
SELECT COUNT(*) FROM izin_talepleri
WHERE calisan_id = ?
AND durum = 'onaylandi'
AND izin_turu != 'saatlik'
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([$calisan_id, $kontrol_bas, $kontrol_bit]);
if ($stmt_izin_cakisma->fetchColumn() > 0) {
$mesaj = '<div class="alert alert-danger">Hata: Bu tarihler arasında personel için zaten onaylanmış <strong>TAM GÜN İZİN</strong> kaydı bulunmaktadır!</div>';
$hata = true;
}
}
if (!$hata) {
$sql_mesai_cakisma = "
SELECT COUNT(*) FROM mesai_hareketleri
WHERE calisan_id = ?
AND durum = 'onaylandi'
AND tarih BETWEEN ? AND ?";
$stmt_mesai_cakisma = $pdo->prepare($sql_mesai_cakisma);
$stmt_mesai_cakisma->execute([$calisan_id, $kontrol_bas, $kontrol_bit]);
if ($stmt_mesai_cakisma->fetchColumn() > 0) {
$mesaj = '<div class="alert alert-danger">Hata: Bu tarihler arasında personel için zaten onaylanmış <strong>MESAİ</strong> kaydı bulunmaktadır!</div>';
$hata = true;
}
}
}
// KAYIT
if (!$hata) {
$sql = "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 (?, ?, ?, ?, ?, ?, ?, ?, ?, 'onaylandi', NOW())";
try {
$pdo->prepare($sql)->execute([
$calisan_id,
$kullanici_id,
$kullanici_id,
$izin_turu,
$baslangic_kayit,
$bitis_kayit,
$toplam_gun,
$saatlik_sure,
$aciklama
]);
$log_detay = "Yön. İzin Girişi: {$toplam_gun} Gün / {$saatlik_sure} Saat ({$izin_turu}) Personel ID: {$calisan_id}";
logKaydet($pdo, $kullanici_id, 'ekleme', $log_detay, 'izin_talepleri', $pdo->lastInsertId());
$mesaj = '<div class="alert alert-success border-success border-5 border-start shadow-sm">
<h5 class="alert-heading fw-bold"><i class="fas fa-check-circle me-2"></i>Başarılı!</h5>
İzin kaydı personel adına otomatik onaylanarak sisteme eklendi.
</div>';
} catch (PDOException $e) {
$mesaj = '<div class="alert alert-danger">Veritabanı Hatası: ' . htmlspecialchars($e->getMessage()) . '</div>';
}
}
}
end_of_post:
// AJAX bakiye sorgusu (değişmedi)
if (isset($_GET['action']) && $_GET['action'] == 'get_bakiye' && isset($_GET['personel_id'])) {
$personel_id_bakiye = (int)$_GET['personel_id'];
$stmt_u = $pdo->prepare("SELECT ise_giris_tarihi, devreden_izin, rol FROM kullanicilar WHERE id = ?");
$stmt_u->execute([$personel_id_bakiye]);
$user_data = $stmt_u->fetch();
$kalan_bakiye = 0;
if ($user_data) {
$ise_giris = new DateTime($user_data['ise_giris_tarihi']);
$bugun = new DateTime();
$kidem_yil = $ise_giris->diff($bugun)->y;
$yasal_hak = ($kidem_yil >= 15) ? 26 : (($kidem_yil >= 5) ? 20 : 14);
if ($user_data['rol'] == 'stajyer') $yasal_hak = 0;
$toplam_hak = $yasal_hak + (float)$user_data['devreden_izin'];
$sql_kul = "SELECT SUM(toplam_gun) FROM izin_talepleri WHERE calisan_id = ? AND izin_turu = 'yillik' AND durum = 'onaylandi' AND YEAR(baslangic_tarihi) = YEAR(CURDATE())";
$stmt_kul = $pdo->prepare($sql_kul);
$stmt_kul->execute([$personel_id_bakiye]);
$kullanilan = (float)$stmt_kul->fetchColumn();
$kalan_bakiye = $toplam_hak - $kullanilan;
}
header('Content-Type: application/json');
echo json_encode(['kalan_bakiye' => number_format($kalan_bakiye, 1)]);
exit;
}
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" rel="stylesheet">
<title>Personel Adına İzin Girişi</title>
<style>
body { background-color: #f8f9fa; }
.card { border: none; border-radius: 1.5rem; overflow: hidden; }
.card-header { background: linear-gradient(135deg, #0d6efd, #0dcaf0); color: white; }
.form-control, .form-select { border-radius: 0.75rem; }
.btn-primary { border-radius: 0.75rem; padding: 0.85rem; font-weight: 600; }
.alert-important { border-left-width: 6px; }
@media (max-width: 576px) {
.container-fluid { padding: 1rem; }
h3 { font-size: 1.4rem; }
}
</style>
</head>
<body>
<div class="container-fluid py-4 py-md-5">
<div class="row justify-content-center">
<div class="col-12 col-lg-10 col-xl-8">
<h3 class="mb-4 text-center text-primary fw-bold">
<i class="fas fa-calendar-plus me-2"></i>Personel Adına İzin Girişi
</h3>
<div class="alert alert-warning alert-important mb-4" role="alert">
<h6 class="alert-heading fw-bold"><i class="fas fa-exclamation-triangle me-2"></i>Önemli Uyarı</h6>
Bu sayfadan girilen izinler <strong>otomatik onaylı</strong> olarak personel kartına yansır.
Lütfen bilgileri dikkatle kontrol edin. Tarih aralığında onaylı mesai veya tam gün izin varsa kayıt engellenir.
</div>
<div class="card shadow-lg">
<div class="card-header py-4 text-center">
<h5 class="mb-0 text-white fw-bold">İzin Bilgilerini Giriniz</h5>
</div>
<div class="card-body p-4 p-md-5">
<?php echo $mesaj; ?>
<form method="POST" id="izinGirForm" novalidate>
<input type="hidden" name="csrf_token" value="<?php echo csrfTokenOlustur(); ?>">
<!-- Personel Seçimi -->
<div class="mb-4">
<label for="calisanIdSecim" class="form-label fw-semibold">
<i class="fas fa-user me-2 text-primary"></i>Personel <span class="text-danger">*</span>
</label>
<select name="calisan_id" id="calisanIdSecim" class="form-select form-select-lg" required onchange="personelSecildi()">
<option value="">Seçiniz...</option>
<?php foreach($tum_calisanlar as $c): ?>
<option value="<?php echo $c['id']; ?>">
<?php echo htmlspecialchars($c['ad'].' '.$c['soyad']).' ('.strtoupper($c['rol']).')'; ?>
</option>
<?php endforeach; ?>
</select>
</div>
<!-- İzin Türü -->
<div class="mb-4">
<label for="izinTuru" class="form-label fw-semibold">
<i class="fas fa-tasks me-2 text-primary"></i>İzin Türü <span class="text-danger">*</span>
</label>
<select name="izin_turu" id="izinTuru" class="form-select form-select-lg" required onchange="turDegisti()">
<option value="">Seçiniz...</option>
<?php foreach($izin_turleri as $k => $v): ?>
<option value="<?php echo $k; ?>"><?php echo $v; ?></option>
<?php endforeach; ?>
</select>
<div id="bakiyeBilgisi" class="mt-3 p-3 bg-info bg-opacity-10 border border-info rounded d-none">
<i class="fas fa-info-circle me-2"></i>
<strong>Kalan Yıllık İzin Bakiyesi:</strong> <span id="bakiyeText">Yükleniyor...</span>
</div>
</div>
<!-- Günlük İzin Alanları -->
<div id="gunlukIzin" class="row g-3 mb-4">
<div class="col-md-6">
<label for="baslangicGunluk" class="form-label fw-semibold">
<i class="fas fa-calendar-alt me-2 text-primary"></i>Başlangıç Tarihi <span class="text-danger">*</span>
</label>
<input type="date" name="baslangic_gunluk" id="baslangicGunluk" class="form-control form-control-lg">
</div>
<div class="col-md-6">
<label for="bitisGunluk" class="form-label fw-semibold">
<i class="fas fa-calendar-check me-2 text-primary"></i>Bitiş Tarihi <span class="text-danger">*</span>
</label>
<input type="date" name="bitis_gunluk" id="bitisGunluk" class="form-control form-control-lg">
</div>
</div>
<!-- Saatlik İzin Alanları -->
<div id="saatlikIzin" class="d-none">
<div class="row g-3 mb-3">
<div class="col-sm-4">
<label for="saatlikTarih" class="form-label fw-semibold">
<i class="fas fa-calendar-day me-2 text-primary"></i>Tarih <span class="text-danger">*</span>
</label>
<input type="date" name="saatlik_tarih" id="saatlikTarih" class="form-control form-control-lg">
</div>
<div class="col-sm-4">
<label for="saatlikBas" class="form-label fw-semibold">
<i class="fas fa-clock me-2 text-primary"></i>Başlangıç Saati <span class="text-danger">*</span>
</label>
<select name="saatlik_bas" id="saatlikBas" class="form-select form-select-lg">
<option value="">Seçiniz</option>
<?php echo $zaman_secenekleri; ?>
</select>
</div>
<div class="col-sm-4">
<label for="saatlikBit" class="form-label fw-semibold">
<i class="far fa-clock me-2 text-primary"></i>Bitiş Saati <span class="text-danger">*</span>
</label>
<select name="saatlik_bit" id="saatlikBit" class="form-select form-select-lg">
<option value="">Seçiniz</option>
<?php echo $zaman_secenekleri; ?>
</select>
</div>
</div>
<div class="alert alert-info small">
<i class="fas fa-info-circle me-2"></i>
Saatlik izin süresi otomatik hesaplanır. Hafta içi günlerde <strong>12:00–13:00 arası öğle molası</strong> düşülür.
</div>
</div>
<!-- Açıklama -->
<div class="mb-4">
<label for="aciklama" class="form-label fw-semibold">
<i class="fas fa-comment-dots me-2 text-primary"></i>Açıklama / Not
</label>
<textarea name="aciklama" id="aciklama" class="form-control form-control-lg" rows="4" placeholder="İzin nedeni veya ek bilgi..."></textarea>
</div>
<!-- Gönder Butonu -->
<div class="d-grid">
<button type="submit" class="btn btn-primary btn-lg shadow">
<i class="fas fa-save me-2"></i> KAYDET VE ONAYLA
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
function turDegisti() {
const tur = document.getElementById('izinTuru').value;
const gunlukDiv = document.getElementById('gunlukIzin');
const saatlikDiv = document.getElementById('saatlikIzin');
const bakiyeDiv = document.getElementById('bakiyeBilgisi');
// Alanları sıfırlama ve required ayarlama
const resetFields = (isGunluk) => {
if (isGunluk) {
document.getElementById('baslangicGunluk').value = '';
document.getElementById('bitisGunluk').value = '';
document.getElementById('baslangicGunluk').required = tur !== 'saatlik';
document.getElementById('bitisGunluk').required = tur !== 'saatlik';
} else {
document.getElementById('saatlikTarih').value = '';
document.getElementById('saatlikBas').selectedIndex = 0;
document.getElementById('saatlikBit').selectedIndex = 0;
document.getElementById('saatlikTarih').required = tur === 'saatlik';
document.getElementById('saatlikBas').required = tur === 'saatlik';
document.getElementById('saatlikBit').required = tur === 'saatlik';
}
};
if (tur === 'saatlik') {
gunlukDiv.classList.add('d-none');
saatlikDiv.classList.remove('d-none');
bakiyeDiv.classList.add('d-none');
resetFields(true);
resetFields(false);
} else {
gunlukDiv.classList.remove('d-none');
saatlikDiv.classList.add('d-none');
resetFields(true);
resetFields(false);
// Yıllık izin seçiliyse ve personel seçilmişse bakiye göster
if (tur === 'yillik' && document.getElementById('calisanIdSecim').value) {
personelSecildi();
} else {
bakiyeDiv.classList.add('d-none');
}
}
}
function personelSecildi() {
const personelId = document.getElementById('calisanIdSecim').value;
const tur = document.getElementById('izinTuru').value;
const bakiyeDiv = document.getElementById('bakiyeBilgisi');
const bakiyeText = document.getElementById('bakiyeText') || bakiyeDiv;
if (tur !== 'yillik' || !personelId) {
bakiyeDiv.classList.add('d-none');
return;
}
bakiyeDiv.classList.remove('d-none');
bakiyeText.innerHTML = 'Yükleniyor...';
fetch(`izin-gir.php?action=get_bakiye&personel_id=${personelId}`)
.then(r => r.ok ? r.json() : Promise.reject())
.then(data => {
bakiyeText.innerHTML = `<strong>${data.kalan_bakiye} gün</strong>`;
})
.catch(() => {
bakiyeText.innerHTML = 'Bilgi alınamadı.';
});
}
// Sayfa yüklendiğinde başlangıç durumu
document.addEventListener('DOMContentLoaded', () => {
turDegisti();
});
</script>
<?php include '../includes/footer.php'; ?>
</body>
</html>