PYBS (Personel Yönetim Bilgi Sistemi) / Ramsa/modules/tum-mesailer.php
tum-mesailer.php 408 satır • 20.41 KB
<?php
// modules/tum-mesailer.php
session_start();
require_once '../config/db.php';
require_once '../config/functions.php';

// Yetki Kontrolü
yetkiKontrol(['root', 'yonetici', 'mudur', 'vardiya_amiri', 'muhasebe', 'insan_kaynaklari']);

// Türkçe Tarih Formatı
function tarihFormatTr($tarih) {
    $aylar = [
        '01' => 'Ocak', '02' => 'Şubat', '03' => 'Mart', '04' => 'Nisan', 
        '05' => 'Mayıs', '06' => 'Haziran', '07' => 'Temmuz', '08' => 'Ağustos', 
        '09' => 'Eylül', '10' => 'Ekim', '11' => 'Kasım', '12' => 'Aralık'
    ];
    $d = date('d', strtotime($tarih));
    $m = date('m', strtotime($tarih));
    $y = date('Y', strtotime($tarih));
    return $d . ' ' . $aylar[$m] . ' ' . $y;
}

// --- AJAX: Kayıt Getir ---
if (isset($_GET['ajax']) && $_GET['ajax'] == 'kayit_getir' && isset($_GET['id'])) {
    $id = (int)$_GET['id'];
    $row = $pdo->query("SELECT * FROM mesai_hareketleri WHERE id = $id")->fetch(PDO::FETCH_ASSOC);
    if($row) { 
        $row['baslangic_saati'] = substr($row['baslangic_saati'], 0, 5); 
        $row['bitis_saati'] = substr($row['bitis_saati'], 0, 5); 
    }
    echo json_encode($row); 
    exit;
}

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

$mesaj = '';
$kullanici_id = $_SESSION['kullanici_id'];
$rol = $_SESSION['rol'];
$yuksek_yetki = in_array($rol, ['root', 'muhasebe', 'insan_kaynaklari']);

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

// Personel Listesi (Filtre için)
$personel_listesi = $pdo->query("SELECT id, ad, soyad FROM kullanicilar ORDER BY ad ASC")->fetchAll();

// --- FİLTRELEME PARAMETRELERİ ---
$filtre_durum = $_GET['filtre'] ?? 'aktif';
$filtre_personel = $_GET['personel_id'] ?? ''; // Personel ID Filtresi
$secilen_ay = $_GET['ay'] ?? date('m');
$secilen_yil = $_GET['yil'] ?? date('Y');

// --- POST: GÜNCELLEME ---
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['islem_turu']) && $_POST['islem_turu'] == 'guncelle') {
    csrfKontrol($_POST['csrf_token']);
    if(!$yuksek_yetki) die("Yetkisiz işlem.");

    $id = (int)$_POST['kayit_id'];
    $tarih = $_POST['tarih']; 
    $bas = $_POST['baslangic_saati'];
    $bit = $_POST['bitis_saati'];
    $tur = $_POST['mesai_turu'];
    $aciklama = guvenlik($_POST['aciklama']);

    $t1 = strtotime($bas);
    $t2 = strtotime($bit);
    if($t2 < $t1) $t2 += 24 * 3600; 
    
    $diff = round(($t2 - $t1) / 3600, 2);

    $sql = "UPDATE mesai_hareketleri SET tarih=?, baslangic_saati=?, bitis_saati=?, toplam_saat=?, mesai_turu=?, aciklama=? WHERE id=?";
    $stmt = $pdo->prepare($sql);
    
    if ($stmt->execute([$tarih, $bas, $bit, $diff, $tur, $aciklama, $id])) {
        logKaydet($pdo, $kullanici_id, 'guncelleme', "Mesai güncellendi (ID: $id)", 'mesai_hareketleri', $id);
        $mesaj = '<div class="alert alert-success">Kayıt başarıyla güncellendi.</div>';
    } else {
        $mesaj = '<div class="alert alert-danger">Güncelleme hatası.</div>';
    }
}

// --- GET: İŞLEMLER ---
if (isset($_GET['islem']) && isset($_GET['id'])) {
    $id = (int)$_GET['id'];
    $aksiyon = $_GET['islem'];
    
    $sql_k = "SELECT * FROM mesai_hareketleri WHERE id = ?";
    $params_k = [$id];
    if(!$yuksek_yetki) { $sql_k .= " AND hedef_yonetici_id = ?"; $params_k[] = $kullanici_id; }
    
    $stmt = $pdo->prepare($sql_k);
    $stmt->execute($params_k);
    $kayit = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($kayit) {
        $yeni_durum = ($aksiyon == 'onayla') ? 'onaylandi' : 'reddedildi';
        if ($aksiyon == 'beklemede') $yeni_durum = 'beklemede';
        
        if ($kayit['durum'] != 'beklemede' && !$yuksek_yetki) {
            $mesaj = "<div class='alert alert-warning'>Yetkisiz işlem.</div>";
        } else {
            $upd = $pdo->prepare("UPDATE mesai_hareketleri SET durum = ?, onaylayan_id = ?, onaylanma_tarihi = NOW() WHERE id = ?");
            if ($upd->execute([$yeni_durum, $kullanici_id, $id])) {
                logKaydet($pdo, $kullanici_id, 'guncelleme', "Mesai durumu: $yeni_durum", 'mesai_hareketleri', $id);
                $mesaj = "<div class='alert alert-success'>Durum güncellendi: <strong>".strtoupper($yeni_durum)."</strong></div>";
            }
        }
    }
}

// --- LİSTELEME SORGUSU ---
$sql = "SELECT m.*, k.ad, k.soyad, k.rol as k_rol, 
        o.ad as o_ad, o.soyad as o_soyad,
        y.ad as y_ad, y.soyad as y_soyad,
        (SELECT COUNT(*) FROM sistem_loglari WHERE tablo_adi='mesai_hareketleri' AND kayit_id=m.id AND islem_tipi='guncelleme') as degisiklik
        FROM mesai_hareketleri m 
        JOIN kullanicilar k ON m.calisan_id = k.id 
        LEFT JOIN kullanicilar o ON m.onaylayan_id = o.id 
        LEFT JOIN kullanicilar y ON m.hedef_yonetici_id = y.id
        WHERE 1=1 ";

// 1. Yetki Filtresi
if (!$yuksek_yetki) { 
    $sql .= " AND m.hedef_yonetici_id = $kullanici_id "; 
}

// 2. Personel Filtresi (YENİ)
if (!empty($filtre_personel)) {
    $sql .= " AND m.calisan_id = " . intval($filtre_personel);
}

// 3. Tarih Filtresi
if ($filtre_durum == 'aktif') {
    $sql .= " AND YEAR(m.tarih) = YEAR(CURDATE()) AND MONTH(m.tarih) = MONTH(CURDATE())";
} elseif ($filtre_durum == 'tarih') {
    $sql .= " AND YEAR(m.tarih) = $secilen_yil AND MONTH(m.tarih) = $secilen_ay";
}

$sql .= " ORDER BY m.tarih DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$mesailer = $stmt->fetchAll();
?>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

<style>
    .flatpickr-day.resmi-tatil { background: #ffebee !important; border-color: #ffcdd2; color: #c62828; font-weight: bold; }
    .flatpickr-day.pazar-gunu { background: #fff3e0 !important; border-color: #ffe0b2; color: #ef6c00; font-weight: bold; }
    .table-responsive { overflow-x: visible !important; } 
    .bg-kesinti { background-color: #fff5f5; }
</style>

<div class="container-fluid">
    <div class="d-flex justify-content-between align-items-center mb-3">
        <h3><i class="fas fa-clock text-primary"></i> Mesai Yönetimi</h3>
        <div class="btn-group">
            <a href="tum-mesailer-rapor.php?format=excel" target="_blank" class="btn btn-success"><i class="fas fa-file-excel"></i> Excel</a>
            <a href="tum-mesailer-rapor.php?format=pdf" target="_blank" class="btn btn-danger"><i class="fas fa-file-pdf"></i> PDF Yazdır</a>
        </div>
    </div>
    
    <?php echo $mesaj; ?>

    <div class="card bg-light border mb-4">
        <div class="card-body p-3">
            <form method="GET" class="row g-2 align-items-end">
                <div class="col-md-3">
                    <label class="small fw-bold">Personel</label>
                    <select name="personel_id" class="form-select form-select-sm">
                        <option value="">Tümü</option>
                        <?php foreach($personel_listesi as $p): ?>
                            <option value="<?php echo $p['id']; ?>" <?php echo ($filtre_personel == $p['id']) ? 'selected' : ''; ?>>
                                <?php echo htmlspecialchars($p['ad'] . ' ' . $p['soyad']); ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>

                <div class="col-md-3">
                    <label class="small fw-bold">Dönem Tipi</label>
                    <select name="filtre" id="filtreSecim" class="form-select form-select-sm" onchange="filtreDegisti()">
                        <option value="aktif" <?php echo $filtre_durum=='aktif'?'selected':''; ?>>Bu Ay (Aktif)</option>
                        <option value="tarih" <?php echo $filtre_durum=='tarih'?'selected':''; ?>>Belirli Ay Seç</option>
                        <option value="tum" <?php echo $filtre_durum=='tum'?'selected':''; ?>>Tüm Geçmiş</option>
                    </select>
                </div>

                <div class="col-md-4 tarih-secimi" style="<?php echo $filtre_durum=='tarih'?'':'display:none;'; ?>">
                    <label class="small fw-bold">Ay / Yıl Seçiniz</label>
                    <div class="input-group input-group-sm">
                        <select name="ay" class="form-select">
                            <?php 
                            $aylar_tr = ['01'=>'Ocak','02'=>'Şubat','03'=>'Mart','04'=>'Nisan','05'=>'Mayıs','06'=>'Haziran','07'=>'Temmuz','08'=>'Ağustos','09'=>'Eylül','10'=>'Ekim','11'=>'Kasım','12'=>'Aralık'];
                            foreach($aylar_tr as $k => $v) echo "<option value='$k' ".($k==$secilen_ay?'selected':'').">$v</option>"; 
                            ?>
                        </select>
                        <select name="yil" class="form-select">
                            <?php for($y=2024; $y<=date('Y')+1; $y++) echo "<option value='$y' ".($y==$secilen_yil?'selected':'').">$y</option>"; ?>
                        </select>
                    </div>
                </div>
                
                <div class="col-md-2">
                    <button type="submit" class="btn btn-primary btn-sm w-100"><i class="fas fa-filter"></i> Uygula</button>
                </div>
            </form>
        </div>
    </div>
    
    <div class="card border-0 shadow-sm">
        <div class="table-responsive">
            <table class="table table-hover align-middle mb-0" style="font-size: 0.9rem;">
                <thead class="table-dark">
                    <tr>
                        <th>Personel</th>
                        <th>Tarih</th>
                        <th>Saat Aralığı</th>
                        <th class="text-center" style="min-width: 250px;">Hesaplama Detayı</th>
                        <th>Durum / İşlem Yapan</th>
                        <th class="text-end">İşlemler</th>
                    </tr>
                </thead>
                <tbody>
                    <?php if(empty($mesailer)): ?>
                        <tr><td colspan="6" class="text-center py-4 text-muted">Kayıt bulunamadı.</td></tr>
                    <?php endif; ?>
                    <?php foreach($mesailer as $m): 
                        // İşlem Yapan
                        $islem_yapan = "";
                        if ($m['durum'] == 'beklemede') {
                            $islem_yapan = '<span class="text-muted small"><i class="fas fa-hourglass-half"></i> Bekleniyor: </span>' . $m['y_ad'] . ' ' . $m['y_soyad'];
                        } else {
                            $islem_yapan = '<span class="text-success small"><i class="fas fa-user-check"></i> </span>' . $m['o_ad'] . ' ' . $m['o_soyad'];
                        }

                        // Hesaplamalar
                        $brut_sure = (float)$m['toplam_saat'];
                        $kesinti_saati = 0;
                        $ucretsiz_izinler = ['saatlik', 'hastalik', 'ucretsiz', 'mazeret', 'diger', 'mesaiye_gelmedi'];
                        
                        $sql_izin = "SELECT izin_turu, saatlik_sure FROM izin_talepleri 
                                     WHERE calisan_id = ? AND durum = 'onaylandi' 
                                     AND ? BETWEEN DATE(baslangic_tarihi) AND DATE(bitis_tarihi)";
                        $stmt_i = $pdo->prepare($sql_izin);
                        $stmt_i->execute([$m['calisan_id'], $m['tarih']]);
                        $izin = $stmt_i->fetch();
                        
                        $izin_aciklama = "";
                        if ($izin && in_array($izin['izin_turu'], $ucretsiz_izinler)) {
                            if ($izin['izin_turu'] == 'saatlik') {
                                $kesinti_saati = (float)$izin['saatlik_sure'];
                                $izin_aciklama = "(Saatlik)";
                            } else {
                                $kesinti_saati = 9; 
                                $izin_aciklama = "(Tam Gün)";
                            }
                        }
                        
                        $net_sure = $brut_sure - $kesinti_saati;
                        if ($net_sure < 0) $net_sure = 0;
                        // ÖDENECEK HESAPLAMASI KALDIRILDI
                    ?>
                    <tr class="<?php echo ($m['degisiklik']>0)?'table-warning bg-opacity-10':''; ?>">
                        <td>
                            <strong><?php echo htmlspecialchars($m['ad'].' '.$m['soyad']); ?></strong><br>
                            <span class="badge bg-light text-dark border"><?php echo htmlspecialchars($m['k_rol']); ?></span>
                        </td>
                        <td><?php echo tarihFormatTr($m['tarih']); ?></td>
                        <td>
                            <span class="fw-bold"><?php echo substr($m['baslangic_saati'],0,5).'-'.substr($m['bitis_saati'],0,5); ?></span>
                            <br><small class="text-muted"><?php 
                                $tur_map = ['fazla_mesai'=>'Normal', 'resmi_tatil_mesaisi'=>'Resmi Tatil', 'hafta_tatili'=>'H.Tatili', 'vardiya_gece'=>'Vardiya'];
                                echo $tur_map[$m['mesai_turu']] ?? $m['mesai_turu'];
                            ?></small>
                        </td>
                        <td class="text-center">
                            <div class="d-inline-block w-100 text-start bg-light p-2 rounded border" style="font-size: 0.85rem;">
                                <div class="d-flex justify-content-between">
                                    <span class="text-muted">Brüt Mesai:</span> 
                                    <span class="fw-bold"><?php echo $brut_sure; ?> s</span>
                                </div>
                                <?php if($kesinti_saati > 0): ?>
                                <div class="d-flex justify-content-between text-danger">
                                    <span>Kesinti <?php echo $izin_aciklama; ?>:</span> 
                                    <span class="fw-bold">-<?php echo $kesinti_saati; ?> s</span>
                                </div>
                                <?php endif; ?>
                                <div class="d-flex justify-content-between border-top mt-1 pt-1">
                                    <span class="fw-bold text-dark">Net Süre:</span> 
                                    <span class="fw-bold text-primary"><?php echo $net_sure; ?> s</span>
                                </div>
                                </div>
                        </td>
                        <td>
                            <?php if($m['durum']=='onaylandi'): ?>
                                <span class="badge bg-success mb-1">Onaylı</span>
                            <?php elseif($m['durum']=='reddedildi'): ?>
                                <span class="badge bg-danger mb-1">Red/İptal</span>
                            <?php else: ?>
                                <span class="badge bg-warning text-dark mb-1">Bekliyor</span>
                            <?php endif; ?>
                            <div class="small"><?php echo $islem_yapan; ?></div>
                        </td>
                        <td class="text-end">
                            <div class="btn-group position-static">
                                <?php if($yuksek_yetki): ?>
                                    <button class="btn btn-sm btn-outline-primary" onclick="duzenle(<?php echo $m['id']; ?>)" title="Düzenle"><i class="fas fa-edit"></i></button>
                                <?php endif; ?>
                                
                                <?php if($m['durum']=='beklemede'): ?>
                                    <a href="?islem=onayla&id=<?php echo $m['id']; ?>" class="btn btn-sm btn-success" title="Onayla"><i class="fas fa-check"></i></a>
                                    <a href="?islem=reddet&id=<?php echo $m['id']; ?>" class="btn btn-sm btn-danger" title="Reddet"><i class="fas fa-times"></i></a>
                                <?php elseif($yuksek_yetki): ?>
                                    <button type="button" class="btn btn-sm btn-secondary dropdown-toggle" data-bs-toggle="dropdown"><i class="fas fa-cog"></i></button>
                                    <ul class="dropdown-menu dropdown-menu-end">
                                        <li><a class="dropdown-item text-danger" href="?islem=reddet&id=<?php echo $m['id']; ?>">İptal Et / Reddet</a></li>
                                        <li><a class="dropdown-item" href="?islem=beklemede&id=<?php echo $m['id']; ?>">Beklemeye Al</a></li>
                                    </ul>
                                <?php endif; ?>
                            </div>
                        </td>
                    </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
        </div>
    </div>
</div>

<div class="modal fade" id="editModal" tabindex="-1">
    <div class="modal-dialog">
        <form method="POST" class="modal-content">
            <div class="modal-header bg-primary text-white">
                <h5 class="modal-title">Mesai Düzenle</h5>
                <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <input type="hidden" name="csrf_token" value="<?php echo csrfTokenOlustur(); ?>">
                <input type="hidden" name="islem_turu" value="guncelle">
                <input type="hidden" name="kayit_id" id="editId">
                
                <div class="mb-3">
                    <label class="fw-bold">Tarih</label>
                    <input type="text" name="tarih" id="editTarih" class="form-control" required>
                </div>
                
                <div class="row g-2 mb-3">
                    <div class="col-6"><label class="fw-bold">Başlangıç</label><input type="time" name="baslangic_saati" id="editBas" class="form-control"></div>
                    <div class="col-6"><label class="fw-bold">Bitiş</label><input type="time" name="bitis_saati" id="editBit" class="form-control"></div>
                </div>
                
                <div class="mb-3">
                    <label class="fw-bold">Tür</label>
                    <select name="mesai_turu" id="editTur" class="form-select">
                        <option value="fazla_mesai">Normal Fazla Mesai (1.5x)</option>
                        <option value="hafta_tatili">Hafta Tatili (2.0x)</option>
                        <option value="resmi_tatil_mesaisi">Resmi Tatil (2.0x)</option>
                        <option value="vardiya_gece">Vardiya Girişi (1.5x)</option>
                    </select>
                </div>
                
                <div class="mb-3"><label class="fw-bold">Açıklama</label><textarea name="aciklama" id="editAciklama" class="form-control" rows="2"></textarea></div>
            </div>
            <div class="modal-footer bg-light"><button type="submit" class="btn btn-primary">Değişiklikleri Kaydet</button></div>
        </form>
    </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 fpConfig = {
    locale: "tr", dateFormat: "Y-m-d", altInput: true, altFormat: "d F Y",
    onDayCreate: function(dObj, dStr, fp, dayElem){
        let date = dayElem.dateObj.toISOString().split('T')[0];
        if(tatiller.includes(date)) { dayElem.className += " resmi-tatil"; dayElem.title = "Resmi Tatil"; }
        else if(dayElem.dateObj.getDay()===0) { dayElem.className += " pazar-gunu"; }
    }
};
let fpEdit = flatpickr("#editTarih", fpConfig);

function filtreDegisti() {
    const val = document.getElementById('filtreSecim').value;
    const tarihDiv = document.querySelector('.tarih-secimi');
    tarihDiv.style.display = (val === 'tarih') ? 'block' : 'none';
}

function duzenle(id) {
    const modal = new bootstrap.Modal(document.getElementById('editModal'));
    fetch(`tum-mesailer.php?ajax=kayit_getir&id=${id}`).then(r=>r.json()).then(d=>{
        document.getElementById('editId').value = d.id;
        document.getElementById('editBas').value = d.baslangic_saati;
        document.getElementById('editBit').value = d.bitis_saati;
        document.getElementById('editTur').value = d.mesai_turu;
        document.getElementById('editAciklama').value = d.aciklama;
        fpEdit.setDate(d.tarih);
        modal.show();
    });
}
</script>
<?php include '../includes/footer.php'; ?>