PYBS (Personel Yönetim Bilgi Sistemi)
<?php
// modules/izin-talep.php
session_start();
require_once '../config/db.php';
require_once '../config/functions.php';
// Yetki: Tüm personel
yetkiKontrol(['root', 'yonetici', 'mudur', 'vardiya_amiri', 'calisan', 'stajyer', 'muhasebe', 'insan_kaynaklari']);
include '../includes/header.php';
include '../includes/menu.php';
// --- Bakiye Hesaplama Fonksiyonu ---
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();
$u_bilgi = $pdo->query("SELECT ise_giris_tarihi, devreden_izin, dogum_tarihi FROM kullanicilar WHERE id = $calisan_id")->fetch();
if (empty($donemler)) {
if (!$u_bilgi) return ['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);
$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 = ($i > 5 && $i < 15) ? 20 : (($i >= 15) ? 26 : 14);
if (($yas <= 18 || $yas >= 50) && $hak < 20) {
$hak = 20;
}
$toplam_hak += $hak;
}
$kullanilan = $pdo->query("SELECT SUM(toplam_gun) FROM izin_talepleri WHERE calisan_id = $calisan_id AND izin_turu = 'yillik' AND durum != 'reddedildi'")->fetchColumn();
return ['kalan' => $toplam_hak - $kullanilan, 'calisma_yili' => $calisma_yili, 'ise_giris' => $donemler[0]['ise_giris']];
}
}
// --- ÇAKIŞMA KONTROL ---
function cakismaVarMi($pdo, $calisan_id, $bas, $bit) {
$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;
}
$mesaj = '';
$kullanici_id = $_SESSION['kullanici_id'];
$bakiye_bilgi = yillikIzinHesapla($pdo, $kullanici_id);
$kalan_bakiye = $bakiye_bilgi['kalan'];
$u_cinsiyet = $pdo->query("SELECT cinsiyet FROM kullanicilar WHERE id = $kullanici_id")->fetchColumn();
$yoneticiler = $pdo->query("SELECT id, ad, soyad, rol FROM kullanicilar WHERE rol IN ('yonetici', 'mudur') AND durum=1 AND id != $kullanici_id")->fetchAll();
$tatiller = $pdo->query("SELECT tarih FROM resmi_tatiller")->fetchAll(PDO::FETCH_COLUMN);
$tatiller_json = json_encode($tatiller);
// --- İ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']
];
$izin_ayarlari_json = json_encode($izin_ayarlari);
$zaman_secenekleri = "";
for($s=0;$s<24;$s++) {
foreach(['00','30'] as $d) {
$zaman_secenekleri .= "<option value='".sprintf('%02d:%s',$s,$d)."'>".sprintf('%02d:%s',$s,$d)."</option>";
}
}
// İptal İşlemi
if (isset($_GET['iptal_id'])) {
$iptal_id = (int)$_GET['iptal_id'];
$pdo->prepare("DELETE FROM izin_talepleri WHERE id = ? AND calisan_id = ? AND durum = 'beklemede'")->execute([$iptal_id, $kullanici_id]);
$mesaj = "<div class='alert alert-warning'>Talebiniz iptal edildi.</div>";
}
// POST İşlemleri
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
csrfKontrol($_POST['csrf_token']);
$hedef = $_POST['hedef_yonetici_id'];
$izin_turu = $_POST['izin_turu'];
$aciklama = guvenlik($_POST['aciklama']);
$hata = false;
if ($izin_turu == 'sut_izni' && $u_cinsiyet !== 'Kadın') {
$mesaj = '<div class="alert alert-danger">Hata: Süt izni sadece kadın personel içindir.</div>'; $hata = true;
}
if (!$hata && $izin_turu == 'yillik') {
if ($bakiye_bilgi['calisma_yili'] < 1) {
$mesaj = '<div class="alert alert-danger fw-bold"><i class="fas fa-ban"></i> HATA: 1 yıllık kıdem dolmadı.</div>'; $hata = true;
} elseif ((float)$_POST['gun_sayisi'] > $kalan_bakiye) {
$mesaj = '<div class="alert alert-danger"><i class="fas fa-exclamation-circle"></i> Yetersiz bakiye.</div>'; $hata = true;
}
}
if (!$hata) {
$ayar = $izin_ayarlari[$izin_turu];
// SAATLİK VEYA 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_saat_bas'];
$sut_bit = $_POST['sut_saat_bit'];
// Saat farkı hesapla
$t1 = strtotime($sut_bas);
$t2 = strtotime($sut_bit);
$fark = round(($t2 - $t1)/3600, 2);
if($fark <= 0) {
$mesaj = '<div class="alert alert-danger">Hata: Bitiş saati başlangıçtan büyük olmalıdır.</div>';
} elseif($fark > 1.5) {
$mesaj = '<div class="alert alert-danger fw-bold"><i class="fas fa-ban"></i> HATA: Yasal olarak süt izni günlük 1.5 saati geçemez!</div>';
} else {
$current = new DateTime($bas_t);
$end = new DateTime($bit_t);
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("INSERT INTO izin_talepleri (calisan_id, hedef_yonetici_id, izin_turu, baslangic_tarihi, bitis_tarihi, toplam_gun, saatlik_sure, aciklama, durum) VALUES (?, ?, 'sut_izni', ?, ?, 0, ?, ?, 'beklemede')");
while ($current <= $end) {
$ymd = $current->format('Y-m-d');
$gun_no = $current->format('N');
if ($gun_no != 7 && !in_array($ymd, $tatiller)) {
$db_bas = "$ymd $sut_bas:00";
$db_bit = "$ymd $sut_bit:00";
if (cakismaVarMi($pdo, $kullanici_id, $db_bas, $db_bit)) {
throw new Exception("Tarihlerden birinde ($ymd) zaten bir izin kaydı mevcut.");
}
$stmt->execute([$kullanici_id, $hedef, $db_bas, $db_bit, $fark, $aciklama]);
}
$current->modify('+1 day');
}
$pdo->commit();
$mesaj = '<div class="alert alert-success">Süt izni talebi başarıyla oluşturuldu.</div>';
} catch (Exception $e) {
$pdo->rollBack();
$mesaj = '<div class="alert alert-danger"><i class="fas fa-exclamation-circle"></i> '.$e->getMessage().'</div>';
}
}
} else { // Normal 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_bas = max($t1, $mola_bas);
$overlap_bit = min($t2, $mola_bit);
$overlap = max(0, $overlap_bit - $overlap_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 saat aralığı.</div>";
} elseif (cakismaVarMi($pdo, $kullanici_id, $db_bas, $db_bit)) {
$mesaj = '<div class="alert alert-danger"><i class="fas fa-exclamation-circle"></i> HATA: Bu tarih ve saatte zaten bir talebiniz/izniniz var.</div>';
} else {
$pdo->prepare("INSERT INTO izin_talepleri (calisan_id, hedef_yonetici_id, izin_turu, baslangic_tarihi, bitis_tarihi, toplam_gun, saatlik_sure, aciklama, durum) VALUES (?, ?, 'saatlik', ?, ?, 0, ?, ?, 'beklemede')")->execute([$kullanici_id, $hedef, $db_bas, $db_bit, $diff, $aciklama]);
$mesaj = "<div class='alert alert-success'>Saatlik izin iletildi. ($diff Saat)</div>";
}
}
} else { // Günlük İzinler
$bas = $_POST['baslangic_tarihi_gun'];
$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');
$gecerli = true;
if ($kural == 'yillik' && ($day == 7 || in_array($ymd, $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, $kullanici_id, $db_bas, $db_bit)) {
$mesaj = '<div class="alert alert-danger"><i class="fas fa-exclamation-circle"></i> HATA: Seçilen tarih aralığında zaten bir izniniz/talebiniz var.</div>';
} else {
$pdo->prepare("INSERT INTO izin_talepleri (calisan_id, hedef_yonetici_id, izin_turu, baslangic_tarihi, bitis_tarihi, toplam_gun, aciklama, durum) VALUES (?, ?, ?, ?, ?, ?, ?, 'beklemede')")
->execute([$kullanici_id, $hedef, $izin_turu, $db_bas, $db_bit, $gun, $aciklama]);
$mesaj = '<div class="alert alert-success">İzin talebiniz iletildi.</div>';
}
}
}
}
$gecmis = $pdo->query("SELECT i.*, y.ad as y_ad, y.soyad as y_soyad FROM izin_talepleri i LEFT JOIN kullanicilar y ON i.hedef_yonetici_id = y.id WHERE i.calisan_id = $kullanici_id ORDER BY i.baslangic_tarihi DESC")->fetchAll();
?>
<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 pb-5">
<div class="row g-3 mb-4">
<div class="col-12">
<div class="card bg-primary text-white shadow rounded-4 overflow-hidden border-0" style="background: linear-gradient(45deg, #1e5c8e, #2A7BB8);">
<div class="card-body p-4 d-flex justify-content-between align-items-center">
<div>
<h6 class="text-white-50 text-uppercase fw-bold mb-1">Kalan Yıllık İzin Hakkı</h6>
<h1 class="display-3 fw-bold mb-0"><?php echo (float)$kalan_bakiye; ?></h1>
<small class="opacity-75">Kıdem: <?php echo $bakiye_bilgi['calisma_yili']; ?> Yıl</small>
</div>
<div class="text-center opacity-25"><i class="fas fa-umbrella-beach fa-4x"></i></div>
</div>
</div>
</div>
</div>
<?php if($mesaj): ?><div class="mb-3"><?php echo $mesaj; ?></div><?php endif; ?>
<div class="row">
<div class="col-lg-5 mb-4">
<div class="card border-0 shadow-sm rounded-4 h-100">
<div class="card-header bg-white py-3 border-bottom-0"><h5 class="mb-0 fw-bold text-dark"><i class="fas fa-plus-circle text-primary me-2"></i> Yeni İzin Talebi</h5></div>
<div class="card-body p-4 pt-0">
<form method="POST" id="izinForm">
<input type="hidden" name="csrf_token" value="<?php echo csrfTokenOlustur(); ?>">
<div class="row g-3 mb-3">
<div class="col-12">
<label class="fw-bold small">Onaylayacak Yönetici</label>
<select name="hedef_yonetici_id" class="form-select bg-light" required>
<option value="">Seçiniz...</option>
<?php foreach($yoneticiler as $y) echo "<option value='{$y['id']}'>{$y['ad']} {$y['soyad']}</option>"; ?>
</select>
</div>
<div class="col-12">
<label class="fw-bold small">İzin Türü</label>
<select name="izin_turu" id="izinTuru" class="form-select bg-light" 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>
</div>
<div id="gunlukAlan">
<div class="row g-3 mb-3 bg-light p-3 rounded border">
<div class="col-md-6"><label class="small fw-bold">Başlangıç</label><input type="text" name="baslangic_tarihi_gun" id="basTarih" class="form-control bg-white" required></div>
<div class="col-md-6"><label class="small fw-bold">Gün Sayısı</label><input type="number" name="gun_sayisi" id="gunSayisi" class="form-control" step="0.5" onkeyup="hesapla()" onchange="hesapla()"></div>
<div class="col-md-12"><label class="small fw-bold">Bitiş Tarihi</label><input type="text" id="bitTarih" class="form-control bg-white" readonly></div>
<div class="col-md-12"><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 class="col-12"><small class="text-muted fst-italic" id="hesapAciklama"></small></div>
</div>
</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-6"><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-6"><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-12"><label class="small fw-bold">Hesaplanan 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_saat_bas" id="sutBas" class="form-select bg-white" onchange="sutSureHesapla()"><?php echo $zaman_secenekleri; ?></select></div>
<div class="col-6"><label class="small fw-bold">Dönüş Saati</label><select name="sut_saat_bit" id="sutBit" class="form-select bg-white" onchange="sutSureHesapla()"><?php echo $zaman_secenekleri; ?></select></div>
<div class="col-12" id="sutUyari"></div>
</div>
</div>
<div class="mb-4">
<label class="fw-bold small">Açıklama</label>
<textarea name="aciklama" class="form-control bg-light" rows="2"></textarea>
</div>
<button type="submit" id="submitBtn" class="btn btn-primary w-100 fw-bold py-2">TALEP GÖNDER <i class="fas fa-paper-plane ms-2"></i></button>
</form>
</div>
</div>
</div>
<div class="col-lg-7">
<div class="card border-0 shadow-sm rounded-4 h-100">
<div class="card-header bg-white py-3 border-bottom-0"><h5 class="mb-0 fw-bold text-dark"><i class="fas fa-history text-muted me-2"></i> Geçmiş Taleplerim</h5></div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0 small">
<thead class="bg-light"><tr><th class="ps-4">Tarih</th><th>Tür</th><th>Süre</th><th>Durum / Yönetici</th><th class="text-end pe-4">İşlem</th></tr></thead>
<tbody>
<?php foreach($gecmis as $g):
$izinTuru = trim($g['izin_turu']);
$is_saatlik = in_array($izinTuru, ['saatlik', 'sut_izni']);
// Süre Gösterimi
if ($is_saatlik) {
$sureVal = floatval($g['saatlik_sure']);
$sure_metni = ($sureVal > 0 ? $sureVal : '0') . ' Saat';
} else {
$sure_metni = floatval($g['toplam_gun']).' Gün';
}
// Saat Aralığı Gösterimi
$saat_detay = "";
if ($is_saatlik) {
$bas_dt = new DateTime($g['baslangic_tarihi']);
$bit_dt = new DateTime($g['bitis_tarihi']);
$bas_saat = $bas_dt->format('H:i');
$bit_saat = $bit_dt->format('H:i');
if ($bas_saat != '00:00' || $bit_saat != '00:00') {
$saat_detay = "<div class='text-muted mt-1 fw-normal' style='font-size:0.85em'><i class='far fa-clock text-primary me-1'></i>$bas_saat - $bit_saat</div>";
}
}
?>
<tr>
<td class="ps-4 fw-bold">
<?php echo date('d.m.Y', strtotime($g['baslangic_tarihi'])); ?>
<?php echo $saat_detay; ?>
</td>
<td>
<?php echo strtoupper(str_replace('_',' ',$izinTuru)); ?>
<?php if($izinTuru == 'sut_izni') echo '<br><span class="badge bg-danger bg-opacity-10 text-danger" style="font-size:0.6em">ANNE HAKKI</span>'; ?>
</td>
<td><span class="badge bg-light text-dark border"><?php echo $sure_metni; ?></span></td>
<td>
<span class="badge bg-<?php echo $g['durum']=='onaylandi'?'success':($g['durum']=='reddedildi'?'danger':'warning'); ?>"><?php echo ucfirst($g['durum']); ?></span><br>
<span class="text-muted" style="font-size:0.7em;"><?php echo $g['y_ad'].' '.$g['y_soyad']; ?></span>
</td>
<td class="text-end pe-4">
<?php if($g['durum']=='beklemede'): ?>
<a href="?iptal_id=<?php echo $g['id']; ?>" class="btn btn-sm btn-outline-danger py-0" onclick="return confirm('Talebi iptal etmek istiyor musunuz?')">İptal</a>
<?php else: ?>
<i class="fas fa-lock text-muted"></i>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</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; ?>;
const currentBakiye = <?php echo floatval($kalan_bakiye); ?>;
const calismaYili = <?php echo intval($bakiye_bilgi['calisma_yili']); ?>;
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 += " resmi-tatil";
else if (dayElem.dateObj.getDay() === 0) dayElem.className += " pazar-gunu";
}
};
let fpBas = flatpickr("#basTarih", { ...fpConfig, defaultDate: "today", onChange: hesapla });
flatpickr("#saatlikTarih", { ...fpConfig, defaultDate: "today" });
flatpickr("#sutBasTarih", { ...fpConfig, defaultDate: "today" });
flatpickr("#sutBitTarih", { ...fpConfig });
function turDegisti() {
const tur = document.getElementById('izinTuru').value;
const ayar = izinAyarlari[tur];
if(!ayar) return;
document.getElementById('gunSayisi').readOnly = false;
document.getElementById('gunSayisi').value = '';
let info = `${ayar.ucret}`;
if (ayar.gun > 0) {
document.getElementById('gunSayisi').value = ayar.gun;
document.getElementById('gunSayisi').readOnly = true;
info += ` | Süre: ${ayar.gun} Gün`;
}
document.getElementById('izinBilgiNotu').innerText = info;
document.getElementById('saatlikInputs').classList.add('d-none');
document.getElementById('sutInputs').classList.add('d-none');
document.getElementById('gunlukAlan').classList.add('d-none');
document.getElementById('ozelAlan').classList.add('d-none');
document.getElementById('submitBtn').disabled = false;
document.getElementById('sutUyari').innerHTML = ''; // Temizle
if(ayar.type && ayar.type === 'saat') {
document.getElementById('ozelAlan').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 {
document.getElementById('gunlukAlan').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 diff = t2 - t1;
let overlap = Math.max(0, Math.min(t2, 780) - Math.max(t1, 720)); // 12-13 arası mola
document.getElementById('saatSonuc').value = ((diff - overlap)/60).toFixed(2) + " Saat";
}
// Yeni Fonksiyon: Süt İzni 1.5 Saat Kontrolü
function sutSureHesapla() {
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');
// Validasyon
if (tur === 'yillik') {
if (calismaYili < 1) {
gunInput.classList.add('is-invalid');
} else if (gun > currentBakiye) {
gunInput.classList.add('is-invalid');
} else {
gunInput.classList.remove('is-invalid');
btn.disabled = false;
}
} else {
gunInput.classList.remove('is-invalid');
btn.disabled = false;
}
if(!basStr || !gun || gun <= 0) return;
let current = new Date(basStr);
let sayilan = 0;
while(sayilan < gun) {
let ymd = new Date(current.getTime() - (current.getTimezoneOffset() * 60000)).toISOString().split('T')[0];
let day = current.getDay();
let gecerli = true;
if(ayar.kural === 'yillik' && (day === 0 || tatiller.includes(ymd))) 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 ymd = new Date(isBasi.getTime() - (isBasi.getTimezoneOffset() * 60000)).toISOString().split('T')[0];
let day = isBasi.getDay();
if (day === 0 || tatiller.includes(ymd)) isBasi.setDate(isBasi.getDate() + 1);
else break;
}
document.getElementById('iseBaslama').value = isBasi.toLocaleDateString('tr-TR', {weekday:'long', year:'numeric', month:'long', day:'numeric'});
document.getElementById('hesapAciklama').innerText = (ayar.kural === 'yillik') ? "Yıllık İzin Kuralı: Cumartesi DAHİL, Pazar/Tatil HARİÇ." : "Takvim Günü Kuralı: Tüm günler sayılır.";
}
</script>
<?php include '../includes/footer.php'; ?>
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