sys/veri_detay/#008

PYBS (Personel Yönetim Bilgi Sistemi)

Son Senkronizasyon: 16.12.2025
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'; ?>
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,561
Sinyal (Ağ Hiti)
1.54 MB
Kapasite

Ağda Paylaş