اذهب إلى المحتوى

السؤال

نشر (معدل)

السلام عليكم لدي منطق تالي لحساب اجازات 

بالنسبة للاجازة السنوية تكون 30 يوم في السنة و45 يوما في السنة لمن بلغ سن الخمسين او تجاوزت مدة خدمته عشرين عاما 

وفي جميع الاحوال يجب ان يتمتع الموظف بإجازة لاتقل عن 15 يوما متصلة في السنة

بالنسبة لاجازة المرضية لمدة لاتزيد علي 45 يوم متصلة او 60 يوما متقطعة خلال السنة الواحدة

اجازة الحج تكون لعشرين يوما ولاتمنح الي مرة خلال فترة الخدمة 

اجازة الزواج تكون اسبوعين ولاتمنح الي مرة واحدة خلال فترة الخدمة 

وفاة الزوج اجازة تكون 4 اشهر و10 ايام 

هدا كود ساعدني به اخي بلال لكن عندما اختار اجازة  سنوية لموظف مثلا من تاريخ 1-1-2024 الي 1-1-2025 يقبله ونوعها اجازة سنوية اليس مفترض يحسب حسب العمر اذا كان 50 ياخد 45 يوم وتجاوز 20 عام في خدمة غير ذلك 30 يوم 

ممكن تعديل علي كود ليدخل بيانات ومعرفة رصيد موظف لكل اجازة  حسب منطق وبارك الله فيكم 

<?php
include('header.php');
error_reporting(0);
ini_set('display_errors', 0);
function calculateVacationBalance($con, $emp_id, $type, $hire_date, $birth_date, $gender, $to_date) {
    $to = new DateTime($to_date);
    $hire = new DateTime($hire_date);
    $birth = new DateTime($birth_date);
    $current_year = $to->format('Y');

    // حساب سنوات الخدمة
    $service_years = $to->diff($hire)->y;
    // حساب العمر
    $age = $to->diff($birth)->y;

    // استعلام للحصول على الأيام المستخدمة
    $stmt = $con->prepare("
        SELECT COALESCE(SUM(DATEDIFF(end_date, start_date) + 1), 0) AS used_days
        FROM vacations
        WHERE emp_id = ? AND type = ? AND accept = 1
        AND YEAR(start_date) = ?
    ");
    $stmt->bind_param("iss", $emp_id, $type, $current_year);
    $stmt->execute();
    $stmt->bind_result($used_days);
    $stmt->fetch();
    $stmt->close();

    $used_days = $used_days ?: 0;

    switch ($type) {
        case 'اجازة سنوية':
            // 30 يومًا سنويًا، 45 يومًا إذا كان العمر ≥ 50 أو الخدمة ≥ 20 سنة
            $annual_days = ($age >= 50 || $service_years >= 20) ? 45 : 30;
            $balance = $annual_days - $used_days;
            // التأكد من أن الرصيد لا يقل عن 15 يومًا متصلة إذا لم يتم استخدامها
            return max(0, $balance);

        case 'اجازة مرضية':
            // 45 يومًا متصلة أو 60 يومًا متقطعة سنويًا
            $sick_balance = 60 - $used_days;
            return max(0, $sick_balance);

        case 'اجازة الحج':
            // 20 يومًا مرة واحدة خلال الخدمة
            $stmt = $con->prepare("
                SELECT COUNT(*) AS taken
                FROM vacations
                WHERE emp_id = ? AND type = 'اجازة الحج' AND accept = 1
            ");
            $stmt->bind_param("i", $emp_id);
            $stmt->execute();
            $stmt->bind_result($taken);
            $stmt->fetch();
            $stmt->close();
            return $taken > 0 ? 0 : 20;

        case 'اجازة زواج':
            // 14 يومًا مرة واحدة خلال الخدمة
            $stmt = $con->prepare("
                SELECT COUNT(*) AS taken
                FROM vacations
                WHERE emp_id = ? AND type = 'اجازة زواج' AND accept = 1
            ");
            $stmt->bind_param("i", $emp_id);
            $stmt->execute();
            $stmt->bind_result($taken);
            $stmt->fetch();
            $stmt->close();
            return $taken > 0 ? 0 : 14;

        case 'اجازة وفاة الزوج':
            // 130 يومًا (4 أشهر و10 أيام) للإناث فقط، مرة واحدة
            if ($gender !== 'أنثى') {
                return 0;
            }
            $stmt = $con->prepare("
                SELECT COUNT(*) AS taken
                FROM vacations
                WHERE emp_id = ? AND type = 'اجازة وفاة الزوج' AND accept = 1
            ");
            $stmt->bind_param("i", $emp_id);
            $stmt->execute();
            $stmt->bind_result($taken);
            $stmt->fetch();
            $stmt->close();
            return $taken > 0 ? 0 : 130;

        default:
            return 0;
    }
}

?>

<head>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
    <style>
        .rak { width: 400px; height: 300px; font-size: 14px !important;}
    </style>
</head>

<div class="col-md-9 pan1">
    <ol class="breadcrumb" style="background-color: #fff;padding-top:8px;padding-bottom:8px;color:#000;font-size:16px;">
        <li><a href="vacations.php">الاجازات</a></li>
        <li class="active">اضافة اجازة جديد</li>
    </ol>
</div>
</div>
<div class="row">
    <div class="col-md-9 pan1">
        <div class="panel" style="color:#000;">
            <div class="panel-body" style="font-size:14px; padding-left:40px;padding-right:40px;padding-bottom:25px;padding-top:25px;">
                <form method="POST" enctype="multipart/form-data">
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>الموظف</label>
                                <select name="emp_id" id="">
                                <?php
                                    $sql = "SELECT e.person_id, p.name FROM employees e JOIN people p ON e.person_id = p.id;";
                                    $result = $con->query($sql);
                                    while ($row = $result->fetch_assoc()) {
                                        echo "<option value='{$row['person_id']}'>{$row['name']}</option>";
                                    }
                                ?>
                                </select>
                            </div>
                        </div>
                        
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>نوع الاجازة</label>
                                <select name="type" id="">
                                <option value="اجازة سنوية">اجازة سنوية</option>
                                    <option value="اجازة مرضية">اجازة مرضية</option>
                                    <option value="اجازة الحج">اجازة الحج</option>
                                    <option value="اجازة زواج">اجازة زواج</option>
                                    <option value="اجازة وفاة الزوج">اجازة وفاة الزوج</option>

                                </select>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>تاريخ البداية</label>
                                <input name="start_date" type="date" class="form-control">
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>تاريخ المباشرة</label>
                                <input name="end_date" type="date" class="form-control">
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>سبب الاجازة</label>
                                <input name="reason" type="text" class="form-control" placeholder="ادخل سبب الاجازة">
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>الموافقة مسبقا</label>
                                <input name="companion" type="checkbox" class="form-control">
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <button name="submit" type="submit" class="btn btn-primary">إضافة <span class="ion-android-add"></span></button>
                                <button type="reset" class="btn btn-danger">إلغاء <span class="ion-android-delete"></span></button>
                            </div>
                        </div>
                    </div>
                </form>
                <?php
                if ($_SERVER["REQUEST_METHOD"] == "POST") {
                    $emp_id    = $_POST['emp_id'];
                    $type      = $_POST['type'];
                    $start_date = $_POST['start_date'];
                    $end_date   = $_POST['end_date'];
                    $reason    = $_POST['reason'];
                    $companion = isset($_POST['companion']) ? 1 : 0;
                    $created_at = date('Y-m-d H:i:s');
                    $start = new DateTime($start_date);
                    $end = new DateTime($end_date);
                    $interval = $start->diff($end);
                    $years  = $interval->y;
                    $months = $interval->m;
                    $days   = $interval->d;


                    $errors = [];
                    if (empty($type))        { $errors[] = 'يجب تحديد نوع الإجازة'; }
                    if (empty($start_date))  { $errors[] = 'يجب إدخال تاريخ بداية الإجازة'; }
                    if (empty($end_date))    { $errors[] = 'يجب إدخال تاريخ المباشرة'; }
                    if ($end <= $start)      { $errors[] = 'تاريخ المباشرة يجب أن يكون بعد بداية الإجازة'; }
                    if (!empty($errors)) {
                        echo implode('<br>', $errors);
                        exit;
                    }

                    mysqli_begin_transaction($con);
                    try {
                        $stmt = $con->prepare("SELECT * FROM employees WHERE person_id = ?");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $employee = $stmt->get_result()->fetch_assoc();
                        $stmt->close();

                        if (!$employee) {
                            echo "لم يتم العثور على بيانات الموظف";
                            exit;
                        }

                        // تحقق لا يوجد إجازة قيد الإجراء
                        $stmt = $con->prepare("SELECT COUNT(*) FROM vacations WHERE emp_id = ? AND accept = 0");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $stmt->bind_result($count);
                        $stmt->fetch();
                        $stmt->close();

                        if ($count > 0)
                        {
                            echo "عذرًا، هنالك إجازة قيد الإجراء للموظف الحالي، الرجاء التحقق.";
                            exit();
                        }

                        $stmt = $con->prepare("SELECT * FROM people WHERE id = ?");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $people = $stmt->get_result()->fetch_assoc();
                        $stmt->close();
                        if ($type == "اجازة سنوية")
                         {
                            $to = new DateTime($to_date);
            $hire = new DateTime($hire_date);
            $birth = new DateTime($birth_date);
            $service_years = $to->diff($hire)->y;
            $age = $to->diff($birth)->y;

            // تحديد الحد الأقصى للإجازة السنوية
            $max_annual_days = ($age >= 50 || $service_years >= 20) ? 45 : 30;

            // حساب عدد أيام الإجازة المطلوبة
            $start = new DateTime($start_date);
            $end = new DateTime($end_date);
            $interval = $start->diff($end);
            $requested_days = $interval->days + 1;

            // التحقق من أن عدد أيام الإجازة المطلوبة لا يتجاوز الحد الأقصى
            if ($requested_days > $max_annual_days)
             {
                echo "لا يمكنك طلب إجازة سنوية تتجاوز " . $max_annual_days . " يومًا. الحد الأقصى المسموح به هو: " . $max_annual_days . " يومًا.";
                exit;
            }
                        }
                        

                        if ($type == "اجازة مرضية") 
                        {
                            
                        }
                        if ($type == "اجازة الحج") 
                        {
                            
                        }
                        if ($type == "اجازة زواج") 
                        {
                            
                        }
                        if ($type == "اجازة وفاة الزوج") 
                        {
                            
                        }



                        

                        

                        $stmt = $con->prepare("INSERT INTO vacations (emp_id, years, months, days, reason, companion, type, start_date, end_date, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                        $start_date_formatted = $start->format('Y-m-d');
                        $end_date_formatted = $end->format('Y-m-d');
                        $stmt->bind_param("iiiisissss",
                            $emp_id,
                            $years,
                            $months,
                            $requested_days, // الآن أصبحت days هي فارق الأيام
                            $reason,
                            $companion,
                            $type,
                            $start_date_formatted,
                            $end_date_formatted,
                            $created_at
                        );
                        if ($stmt->execute()) {
                            echo "<script>
                                Swal.fire({
                                    title: 'رسالة تأكيد',
                                    text: 'تم إضافة بيانات اجازة موظف  بنجاح!',
                                    icon: 'success',
                                    customClass: 'rak',
                                });
                                </script>";
                            echo '<meta http-equiv="refresh" content="2;url=vacations.php" />';
                        }
                        $stmt->close();

                        mysqli_commit($con);

                    } catch (Exception $e) {
                        mysqli_rollback($con);
                        echo "خطأ: " . $e->getMessage();
                        exit;
                    }
                }
                ?>
            </div>
        </div>
    </div>
</div>
<?php
include('footer.php');
?>

 

تم التعديل في بواسطة ايمن ميلاد

Recommended Posts

  • 0
نشر

وعليكم السلام ورحمة الله وبركاته.

المنطق في الكود صحيح ولكن الخطأ في المتغيرات والبيانات التي تستخدمها.

أولا يجب الإنتباه إلى أن الدالة calculateVacationBalance لديك لا يتم إستخدامها فقط تم تعريفها.

أما المشكلة الرئيسية لديك هنا في هذا الجزء .

بتاريخ 18 دقائق مضت قال ايمن ميلاد:
$to = new DateTime($to_date);
            $hire = new DateTime($hire_date);
            $birth = new DateTime($birth_date);

لاحظ في هذا الجزء أنت تستخدم المتغيرات to_date و hire_date و birth_date وتلك المتغيرات لم يتم تعريفهم وإحضارهم من قاعدة البيانات.

لهذا يتم حساب جميع تلك التواريخ من التاريخ الحالي . أى أن تاريخ to و تاريخ hire و تاريخ birth يصبحان التاريخ الحالي عند تنفيذ الكود . ولهذا عندما يتم إحتساب الفرق يظهر الفرق دائما ب 0 . أى أنه يحسب عمر الشخص ب 0 و مدة التعيين ب 0 أيضا لهذا لا يعمل المنطق لديك.

لذلك يجب عليك إحضار بيانات تاريخ الميلاد و بيانات موعد التعين ووضعها في المتغيرات hire_date و birth_date وسيعمل معك .

يرجى توضيح أين يتم تخزين تلك البيانات في قاعدة البيانات لمساعدتك في هذا الأمر.

  • 0
نشر
بتاريخ 6 دقائق مضت قال ايمن ميلاد:

بالنسبة لتاريخ ميلاد   والجنس الموظف موجدان في جدول people 

 اما بالنسبة تاريخ مباشرة موظف فهيا في جدول employees 

اما اين اريد تخزين اجازة موظف في جدول vacations 

لم تقل إسم العمود الذي يتم تخزين البيانات فيها في جدول people  و employees  .

عموما يرجى إضافة الكود التالي قبل سطر 244 مباشرة :

$to_date = $start_date;
$hire_date = $employee->hire_date;
$birth_date = $people->birth_date;

وتأكد من إستبدال hire_date و birth_date بأسماء الأعمدة لديك . وهنا لا أقصد المتغيرات بل أقصد في employee و people .

ويجب ان يعمل معك .

  • 0
نشر (معدل)

انا عند اضافة الاجازة لاخزن بيانات الي في جدول vacations  

اما اسماء اعمدة في جدول people  الجنس gender  تاريخ الميلاد birth_date 

 في جدول employees   تاريخ التعيين start_date 

دالة تستقبل متغيرات هما نص الاتصال معرف الموظف نوع الاجازة تاريخ التعيين تاريخ الميلاد والجنس وتاريخ نهاية اجازة الذي يدخله مستخدم في input 

ماذا اكتب في باقي 

 if ($_SERVER["REQUEST_METHOD"] == "POST") {
                    $emp_id    = $_POST['emp_id'];
                    $type      = $_POST['type'];
                    $start_date = $_POST['start_date'];
                    $end_date   = $_POST['end_date'];
                    $reason    = $_POST['reason'];
                    $companion = isset($_POST['companion']) ? 1 : 0;
                    $created_at = date('Y-m-d H:i:s');
                    $start = new DateTime($start_date);
                    $end = new DateTime($end_date);
                    $interval = $start->diff($end);
                    $years  = $interval->y;
                    $months = $interval->m;
                    $days   = $interval->d;


                    $errors = [];
                    if (empty($type))        { $errors[] = 'يجب تحديد نوع الإجازة'; }
                    if (empty($start_date))  { $errors[] = 'يجب إدخال تاريخ بداية الإجازة'; }
                    if (empty($end_date))    { $errors[] = 'يجب إدخال تاريخ المباشرة'; }
                    if ($end <= $start)      { $errors[] = 'تاريخ المباشرة يجب أن يكون بعد بداية الإجازة'; }
                    if (!empty($errors)) {
                        echo implode('<br>', $errors);
                        exit;
                    }

                    mysqli_begin_transaction($con);
                    try {
                        $stmt = $con->prepare("SELECT * FROM employees WHERE person_id = ?");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $employee = $stmt->get_result()->fetch_assoc();
                        $stmt->close();

                        if (!$employee) {
                            echo "لم يتم العثور على بيانات الموظف";
                            exit;
                        }

                        // تحقق لا يوجد إجازة قيد الإجراء
                        $stmt = $con->prepare("SELECT COUNT(*) FROM vacations WHERE emp_id = ? AND accept = 0");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $stmt->bind_result($count);
                        $stmt->fetch();
                        $stmt->close();

                        if ($count > 0)
                        {
                            echo "عذرًا، هنالك إجازة قيد الإجراء للموظف الحالي، الرجاء التحقق.";
                            exit();
                        }

                        $stmt = $con->prepare("SELECT * FROM people WHERE id = ?");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $people = $stmt->get_result()->fetch_assoc();
                        $stmt->close();
                        if ($type == "اجازة سنوية")
                         {
                              $hire= new DateTime($employee['start_date']);
                              $birth_date=new DateTime($people['birth_date']);
                              $gender=$people['gender'];
                              $to=new DateTime($end_date);




            

            
                        }

 

تم التعديل في بواسطة ايمن ميلاد
  • 0
نشر
بتاريخ 2 دقائق مضت قال ايمن ميلاد:

انا عند اضافة الاجازة لاخزن بيانات الي في جدول vacations  

اما اسماء اعمدة في جدول people  الجنس gender  تاريخ الميلاد birth_date 

 في جدول employees   تاريخ مباشرة start_date 

عليك جلب التاريخ start_date من جدول employees وتاريخ الميلاد و الجنس من people، ثم حساب العمر وسنوات الخدمة فى نفس لحظة تقديم الطلب، ثم أضف التحقق من الرصيد المستحق أو الحد الأقصى لكل نوع إجازة، ومن شرط 15 يوم المتصلة فى السنة، ومنع طلب أيام أكثر من المسموح أو أقل من المطلوب.

بدل الجزء التالي لديك في الكود داخل if ($_SERVER["REQUEST_METHOD"] == "POST") :

if ($_SERVER["REQUEST_METHOD"] == "POST") {

    $emp_id     = (int)$_POST['emp_id'];
    $type       = $_POST['type'];
    $start_date = $_POST['start_date'];
    $end_date   = $_POST['end_date'];
    $reason     = $_POST['reason'];
    $companion  = isset($_POST['companion']) ? 1 : 0;
    $created_at = date('Y-m-d H:i:s');

    $errors = [];
    if (!$type)              $errors[] = 'يجب تحديد نوع الإجازة';
    if (!$start_date)        $errors[] = 'يجب إدخال تاريخ بداية الإجازة';
    if (!$end_date)          $errors[] = 'يجب إدخال تاريخ المباشرة';
    if ($end_date <= $start_date)
        $errors[] = 'تاريخ المباشرة يجب أن يكون بعد بداية الإجازة';
    if ($errors) { echo implode('<br>',$errors); exit; }

    $stmt = $con->prepare("SELECT e.start_date , p.birth_date , p.gender
                           FROM employees e
                           JOIN people p ON p.id = e.person_id
                           WHERE e.person_id = ?");
    $stmt->bind_param("i",$emp_id);
    $stmt->execute();
    $stmt->bind_result($hire_date,$birth_date,$gender);
    if(!$stmt->fetch()){ echo 'لم يتم العثور على بيانات الموظف'; exit; }
    $stmt->close();

    $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                           WHERE emp_id = ? AND accept = 0");
    $stmt->bind_param("i",$emp_id);
    $stmt->execute();  $stmt->bind_result($pending); $stmt->fetch(); $stmt->close();
    if($pending){ echo 'هناك إجازة قيد الإجراء لهذا الموظف.'; exit; }

    $start = new DateTime($start_date);
    $end   = new DateTime($end_date);
    $requested_days = $start->diff($end)->days + 1;  
    $current_year   = (int)$start->format('Y');

    switch ($type)
    {
        case 'اجازة سنوية':
      
            $to            = new DateTime($end_date);
            $age           = $to->diff( new DateTime($birth_date) )->y;
            $service_years = $to->diff( new DateTime($hire_date)  )->y;
            $annual_quota  = ($age >= 50 || $service_years >= 20) ? 45 : 30;

            $stmt = $con->prepare("SELECT COALESCE(SUM(DATEDIFF(end_date,start_date)+1),0)
                                   FROM vacations
                                   WHERE emp_id = ? AND type = 'اجازة سنوية'
                                         AND accept = 1 AND YEAR(start_date)=?");
            $stmt->bind_param("ii",$emp_id,$current_year);
            $stmt->execute(); $stmt->bind_result($used); $stmt->fetch(); $stmt->close();

            $remaining = $annual_quota - $used;
            if ($remaining <= 0){
                echo 'استهلك الموظف كامل رصيده السنوى لهذا العام.'; exit;
            }
            if ($requested_days > $remaining){
                echo "الرصيد المتبقى $remaining يوم ولا يمكنك طلب $requested_days يوم."; exit;
            }

            if ($requested_days < 15){
                $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                         WHERE emp_id = ? AND type='اجازة سنوية'
                                               AND accept = 1 AND YEAR(start_date)=?
                                               AND (DATEDIFF(end_date,start_date)+1) >= 15");
                $stmt->bind_param("ii",$emp_id,$current_year);
                $stmt->execute(); $stmt->bind_result($have15); $stmt->fetch(); $stmt->close();
                if(!$have15){
                    echo 'يجب أن يتمتع الموظف بحد أدنى 15 يوم متصلة فى السنة.'; exit;
                }
            }
        break;
      
        case 'اجازة مرضية':
            $stmt = $con->prepare("SELECT COALESCE(SUM(DATEDIFF(end_date,start_date)+1),0)
                                   FROM vacations
                                   WHERE emp_id = ? AND type = 'اجازة مرضية'
                                         AND accept = 1 AND YEAR(start_date)=?");
            $stmt->bind_param("ii",$emp_id,$current_year);
            $stmt->execute(); $stmt->bind_result($used); $stmt->fetch(); $stmt->close();

            if ($requested_days > 45){
                echo 'الحد الأقصى المستمر للإجازة المرضية هو 45 يوم.'; exit;
            }
            if ( ($used + $requested_days) > 60 ){
                $left = 60 - $used;
                echo "المتبقى من رصيد الإجازة المرضية هذا العام هو $left يوم."; exit;
            }
        break;
      
        case 'اجازة الحج':
            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                   WHERE emp_id=? AND type='اجازة الحج' AND accept=1");
            $stmt->bind_param("i",$emp_id);
            $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
            if($taken){ echo 'تمّ الحصول على إجازة الحج من قبل، لا تُمنح إلا مرة واحدة.'; exit; }
            if ($requested_days > 20){
                echo 'الحد الأقصى لإجازة الحج 20 يوم.'; exit;
            }
        break;
      
        case 'اجازة زواج':
            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                   WHERE emp_id=? AND type='اجازة زواج' AND accept=1");
            $stmt->bind_param("i",$emp_id);
            $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
            if($taken){ echo 'تمّ الحصول على إجازة زواج سابقًا، لا تُمنح إلا مرة واحدة.'; exit; }
            if ($requested_days > 14){
                echo 'الحد الأقصى لإجازة الزواج هو 14 يوم.'; exit;
            }
        break;
      
        case 'اجازة وفاة الزوج':
            if ($gender != 'أنثى'){ echo 'إجازة وفاة الزوج خاصة بالإناث فقط.'; exit; }

            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                   WHERE emp_id=? AND type='اجازة وفاة الزوج' AND accept=1");
            $stmt->bind_param("i",$emp_id);
            $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
            if($taken){ echo 'تمّ الحصول على هذه الإجازة سابقًا، لا تُمنح إلا مرة واحدة.'; exit; }

            if ($requested_days != 130){
                echo 'مدة الإجازة هى 4 أشهر و10 أيام (130 يوم) ويجب إدخال المدة كاملة.'; exit;
            }
        break;
        default: echo 'نوع الإجازة غير معروف'; exit;
    } 

    $interval  = $start->diff($end);
    $years     = $interval->y;
    $months    = $interval->m;
    $days_only = $requested_days;

    $stmt = $con->prepare("INSERT INTO vacations
           (emp_id,years,months,days,reason,companion,type,start_date,end_date,created_at)
           VALUES (?,?,?,?,?,?,?,?,?,?)");
    $stmt->bind_param("iiiisissss",
           $emp_id,$years,$months,$days_only,$reason,$companion,
           $type,$start_date,$end_date,$created_at);

    if($stmt->execute()){
        echo "<script>
                Swal.fire({title:'تم',text:'تم إضافة الإجازة بنجاح',icon:'success'});
              </script>";
        echo '<meta http-equiv="refresh" content="2;url=vacations.php">';
    } else {
        echo 'حدث خطأ أثناء الحفظ: '.$stmt->error;
    }
    $stmt->close();
}

 

  • 0
نشر
بتاريخ 12 دقائق مضت قال ايمن ميلاد:

انا عند اضافة الاجازة لاخزن بيانات الي في جدول vacations  

اما اسماء اعمدة في جدول people  الجنس gender  تاريخ الميلاد birth_date 

 في جدول employees   تاريخ التعيين start_date 

هذا هو الكود كان يوجد مشكلة في إضافة البيانات .

إليك الكود بعد التعديل :

<?php
include('header.php');
error_reporting(0);
ini_set('display_errors', 0);
function calculateVacationBalance($con, $emp_id, $type, $hire_date, $birth_date, $gender, $to_date)
{
    $to = new DateTime($to_date);
    $hire = new DateTime($hire_date);
    $birth = new DateTime($birth_date);
    $current_year = $to->format('Y');

    // حساب سنوات الخدمة
    $service_years = $to->diff($hire)->y;
    // حساب العمر
    $age = $to->diff($birth)->y;

    // استعلام للحصول على الأيام المستخدمة
    $stmt = $con->prepare("
        SELECT COALESCE(SUM(DATEDIFF(end_date, start_date) + 1), 0) AS used_days
        FROM vacations
        WHERE emp_id = ? AND type = ? AND accept = 1
        AND YEAR(start_date) = ?
    ");
    $stmt->bind_param("iss", $emp_id, $type, $current_year);
    $stmt->execute();
    $stmt->bind_result($used_days);
    $stmt->fetch();
    $stmt->close();

    $used_days = $used_days ?: 0;

    switch ($type) {
        case 'اجازة سنوية':
            // 30 يومًا سنويًا، 45 يومًا إذا كان العمر ≥ 50 أو الخدمة ≥ 20 سنة
            $annual_days = ($age >= 50 || $service_years >= 20) ? 45 : 30;
            $balance = $annual_days - $used_days;
            // التأكد من أن الرصيد لا يقل عن 15 يومًا متصلة إذا لم يتم استخدامها
            return max(0, $balance);

        case 'اجازة مرضية':
            // 45 يومًا متصلة أو 60 يومًا متقطعة سنويًا
            $sick_balance = 60 - $used_days;
            return max(0, $sick_balance);

        case 'اجازة الحج':
            // 20 يومًا مرة واحدة خلال الخدمة
            $stmt = $con->prepare("
                SELECT COUNT(*) AS taken
                FROM vacations
                WHERE emp_id = ? AND type = 'اجازة الحج' AND accept = 1
            ");
            $stmt->bind_param("i", $emp_id);
            $stmt->execute();
            $stmt->bind_result($taken);
            $stmt->fetch();
            $stmt->close();
            return $taken > 0 ? 0 : 20;

        case 'اجازة زواج':
            // 14 يومًا مرة واحدة خلال الخدمة
            $stmt = $con->prepare("
                SELECT COUNT(*) AS taken
                FROM vacations
                WHERE emp_id = ? AND type = 'اجازة زواج' AND accept = 1
            ");
            $stmt->bind_param("i", $emp_id);
            $stmt->execute();
            $stmt->bind_result($taken);
            $stmt->fetch();
            $stmt->close();
            return $taken > 0 ? 0 : 14;

        case 'اجازة وفاة الزوج':
            // 130 يومًا (4 أشهر و10 أيام) للإناث فقط، مرة واحدة
            if ($gender !== 'أنثى') {
                return 0;
            }
            $stmt = $con->prepare("
                SELECT COUNT(*) AS taken
                FROM vacations
                WHERE emp_id = ? AND type = 'اجازة وفاة الزوج' AND accept = 1
            ");
            $stmt->bind_param("i", $emp_id);
            $stmt->execute();
            $stmt->bind_result($taken);
            $stmt->fetch();
            $stmt->close();
            return $taken > 0 ? 0 : 130;

        default:
            return 0;
    }
}

?>

<head>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
    <style>
        .rak {
            width: 400px;
            height: 300px;
            font-size: 14px !important;
        }
    </style>
</head>

<div class="col-md-9 pan1">
    <ol class="breadcrumb" style="background-color: #fff;padding-top:8px;padding-bottom:8px;color:#000;font-size:16px;">
        <li><a href="vacations.php">الاجازات</a></li>
        <li class="active">اضافة اجازة جديد</li>
    </ol>
</div>
</div>
<div class="row">
    <div class="col-md-9 pan1">
        <div class="panel" style="color:#000;">
            <div class="panel-body" style="font-size:14px; padding-left:40px;padding-right:40px;padding-bottom:25px;padding-top:25px;">
                <form method="POST" enctype="multipart/form-data">
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>الموظف</label>
                                <select name="emp_id" id="">
                                    <?php
                                    $sql = "SELECT e.person_id, p.name FROM employees e JOIN people p ON e.person_id = p.id;";
                                    $result = $con->query($sql);
                                    while ($row = $result->fetch_assoc()) {
                                        echo "<option value='{$row['person_id']}'>{$row['name']}</option>";
                                    }
                                    ?>
                                </select>
                            </div>
                        </div>

                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>نوع الاجازة</label>
                                <select name="type" id="">
                                    <option value="اجازة سنوية">اجازة سنوية</option>
                                    <option value="اجازة مرضية">اجازة مرضية</option>
                                    <option value="اجازة الحج">اجازة الحج</option>
                                    <option value="اجازة زواج">اجازة زواج</option>
                                    <option value="اجازة وفاة الزوج">اجازة وفاة الزوج</option>

                                </select>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>تاريخ البداية</label>
                                <input name="start_date" type="date" class="form-control">
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>تاريخ المباشرة</label>
                                <input name="end_date" type="date" class="form-control">
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>سبب الاجازة</label>
                                <input name="reason" type="text" class="form-control" placeholder="ادخل سبب الاجازة">
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>الموافقة مسبقا</label>
                                <input name="companion" type="checkbox" class="form-control">
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <button name="submit" type="submit" class="btn btn-primary">إضافة <span class="ion-android-add"></span></button>
                                <button type="reset" class="btn btn-danger">إلغاء <span class="ion-android-delete"></span></button>
                            </div>
                        </div>
                    </div>
                </form>
                <?php
                if ($_SERVER["REQUEST_METHOD"] == "POST") {
                    $emp_id    = $_POST['emp_id'];
                    $type      = $_POST['type'];
                    $start_date = $_POST['start_date'];
                    $end_date   = $_POST['end_date'];
                    $reason    = $_POST['reason'];
                    $companion = isset($_POST['companion']) ? 1 : 0;
                    $created_at = date('Y-m-d H:i:s');
                    $start = new DateTime($start_date);
                    $end = new DateTime($end_date);
                    $interval = $start->diff($end);
                    $years  = $interval->y;
                    $months = $interval->m;
                    $days   = $interval->d;


                    $errors = [];
                    if (empty($type)) {
                        $errors[] = 'يجب تحديد نوع الإجازة';
                    }
                    if (empty($start_date)) {
                        $errors[] = 'يجب إدخال تاريخ بداية الإجازة';
                    }
                    if (empty($end_date)) {
                        $errors[] = 'يجب إدخال تاريخ المباشرة';
                    }
                    if ($end <= $start) {
                        $errors[] = 'تاريخ المباشرة يجب أن يكون بعد بداية الإجازة';
                    }
                    if (!empty($errors)) {
                        echo implode('<br>', $errors);
                        exit;
                    }

                    mysqli_begin_transaction($con);
                    try {
                        $stmt = $con->prepare("SELECT * FROM employees WHERE person_id = ?");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $employee = $stmt->get_result()->fetch_assoc();
                        $stmt->close();

                        if (!$employee) {
                            echo "لم يتم العثور على بيانات الموظف";
                            exit;
                        }

                        // تحقق لا يوجد إجازة قيد الإجراء
                        $stmt = $con->prepare("SELECT COUNT(*) FROM vacations WHERE emp_id = ? AND accept = 0");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $stmt->bind_result($count);
                        $stmt->fetch();
                        $stmt->close();

                        if ($count > 0) {
                            echo "عذرًا، هنالك إجازة قيد الإجراء للموظف الحالي، الرجاء التحقق.";
                            exit();
                        }

                        $stmt = $con->prepare("SELECT * FROM people WHERE id = ?");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $people = $stmt->get_result()->fetch_assoc();
                        $stmt->close();
                        if ($type == "اجازة سنوية") {
                            $to_date = $start_date;
                            $hire_date = $employee->start_date;
                            $birth_date = $people->birth_date;
                            $to = new DateTime($to_date);
                            $hire = new DateTime($hire_date);
                            $birth = new DateTime($birth_date);
                            $service_years = $to->diff($hire)->y;
                            $age = $to->diff($birth)->y;

                            // تحديد الحد الأقصى للإجازة السنوية
                            $max_annual_days = ($age >= 50 || $service_years >= 20) ? 45 : 30;

                            // حساب عدد أيام الإجازة المطلوبة
                            $start = new DateTime($start_date);
                            $end = new DateTime($end_date);
                            $interval = $start->diff($end);
                            $requested_days = $interval->days + 1;

                            // التحقق من أن عدد أيام الإجازة المطلوبة لا يتجاوز الحد الأقصى
                            if ($requested_days > $max_annual_days) {
                                echo "لا يمكنك طلب إجازة سنوية تتجاوز " . $max_annual_days . " يومًا. الحد الأقصى المسموح به هو: " . $max_annual_days . " يومًا.";
                                exit;
                            }
                        }


                        if ($type == "اجازة مرضية") {
                            $stmt = $con->prepare("SELECT COALESCE(SUM(DATEDIFF(end_date,start_date)+1),0)
                                   FROM vacations
                                   WHERE emp_id = ? AND type = 'اجازة مرضية'
                                         AND accept = 1 AND YEAR(start_date)=?");
                            $stmt->bind_param("ii", $emp_id, $current_year);
                            $stmt->execute();
                            $stmt->bind_result($used);
                            $stmt->fetch();
                            $stmt->close();

                            if ($requested_days > 45) {
                                echo 'الحد الأقصى المستمر للإجازة المرضية هو 45 يوم.';
                                exit;
                            }
                            if (($used + $requested_days) > 60) {
                                $left = 60 - $used;
                                echo "المتبقى من رصيد الإجازة المرضية هذا العام هو $left يوم.";
                                exit;
                            }
                        }
                        if ($type == "اجازة الحج") {
                            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                            WHERE emp_id=? AND type='اجازة الحج' AND accept=1");
                            $stmt->bind_param("i", $emp_id);
                            $stmt->execute();
                            $stmt->bind_result($taken);
                            $stmt->fetch();
                            $stmt->close();
                            if ($taken) {
                                echo 'تمّ الحصول على إجازة الحج من قبل، لا تُمنح إلا مرة واحدة.';
                                exit;
                            }
                            if ($requested_days > 20) {
                                echo 'الحد الأقصى لإجازة الحج 20 يوم.';
                                exit;
                            }
                        }
                        if ($type == "اجازة زواج") {
                            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                            WHERE emp_id=? AND type='اجازة زواج' AND accept=1");
                            $stmt->bind_param("i", $emp_id);
                            $stmt->execute();
                            $stmt->bind_result($taken);
                            $stmt->fetch();
                            $stmt->close();
                            if ($taken) {
                                echo 'تمّ الحصول على إجازة زواج سابقًا، لا تُمنح إلا مرة واحدة.';
                                exit;
                            }
                            if ($requested_days > 14) {
                                echo 'الحد الأقصى لإجازة الزواج هو 14 يوم.';
                                exit;
                            }
                        }
                        if ($type == "اجازة وفاة الزوج") {
                            if ($gender != 'أنثى') {
                                echo 'إجازة وفاة الزوج خاصة بالإناث فقط.';
                                exit;
                            }

                            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                   WHERE emp_id=? AND type='اجازة وفاة الزوج' AND accept=1");
                            $stmt->bind_param("i", $emp_id);
                            $stmt->execute();
                            $stmt->bind_result($taken);
                            $stmt->fetch();
                            $stmt->close();
                            if ($taken) {
                                echo 'تمّ الحصول على هذه الإجازة سابقًا، لا تُمنح إلا مرة واحدة.';
                                exit;
                            }

                            if ($requested_days != 130) {
                                echo 'مدة الإجازة هى 4 أشهر و10 أيام (130 يوم) ويجب إدخال المدة كاملة.';
                                exit;
                            }
                        }


                        $stmt = $con->prepare("INSERT INTO vacations (emp_id, years, months, days, reason, companion, type, start_date, end_date, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                        $start_date_formatted = $start->format('Y-m-d');
                        $end_date_formatted = $end->format('Y-m-d');
                        $stmt->bind_param(
                            'iiiisissss',
                            $emp_id,
                            $years,
                            $months,
                            $requested_days, // الآن أصبحت days هي فارق الأيام
                            $reason,
                            $companion,
                            $type,
                            $start_date_formatted,
                            $end_date_formatted,
                            $created_at
                        );
                        if ($stmt->execute()) {
                            echo "<script>
                                Swal.fire({
                                    title: 'رسالة تأكيد',
                                    text: 'تم إضافة بيانات اجازة موظف  بنجاح!',
                                    icon: 'success',
                                    customClass: 'rak',
                                });
                                </script>";
                            echo '<meta http-equiv="refresh" content="2;url=vacations.php" />';
                        }
                        $stmt->close();

                        mysqli_commit($con);
                    } catch (Exception $e) {
                        mysqli_rollback($con);
                        echo "خطأ: " . $e->getMessage();
                        exit;
                    }
                }
                ?>
            </div>
        </div>
    </div>
</div>
<?php
include('footer.php');
?>

إذا حدثت مشكلة يرجى إرفاق المشكلة هنا.

  • 0
نشر (معدل)
بتاريخ 30 دقائق مضت قال Mustafa Suleiman:

عليك جلب التاريخ start_date من جدول employees وتاريخ الميلاد و الجنس من people، ثم حساب العمر وسنوات الخدمة فى نفس لحظة تقديم الطلب، ثم أضف التحقق من الرصيد المستحق أو الحد الأقصى لكل نوع إجازة، ومن شرط 15 يوم المتصلة فى السنة، ومنع طلب أيام أكثر من المسموح أو أقل من المطلوب.

بدل الجزء التالي لديك في الكود داخل if ($_SERVER["REQUEST_METHOD"] == "POST") :

if ($_SERVER["REQUEST_METHOD"] == "POST") {

    $emp_id     = (int)$_POST['emp_id'];
    $type       = $_POST['type'];
    $start_date = $_POST['start_date'];
    $end_date   = $_POST['end_date'];
    $reason     = $_POST['reason'];
    $companion  = isset($_POST['companion']) ? 1 : 0;
    $created_at = date('Y-m-d H:i:s');

    $errors = [];
    if (!$type)              $errors[] = 'يجب تحديد نوع الإجازة';
    if (!$start_date)        $errors[] = 'يجب إدخال تاريخ بداية الإجازة';
    if (!$end_date)          $errors[] = 'يجب إدخال تاريخ المباشرة';
    if ($end_date <= $start_date)
        $errors[] = 'تاريخ المباشرة يجب أن يكون بعد بداية الإجازة';
    if ($errors) { echo implode('<br>',$errors); exit; }

    $stmt = $con->prepare("SELECT e.start_date , p.birth_date , p.gender
                           FROM employees e
                           JOIN people p ON p.id = e.person_id
                           WHERE e.person_id = ?");
    $stmt->bind_param("i",$emp_id);
    $stmt->execute();
    $stmt->bind_result($hire_date,$birth_date,$gender);
    if(!$stmt->fetch()){ echo 'لم يتم العثور على بيانات الموظف'; exit; }
    $stmt->close();

    $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                           WHERE emp_id = ? AND accept = 0");
    $stmt->bind_param("i",$emp_id);
    $stmt->execute();  $stmt->bind_result($pending); $stmt->fetch(); $stmt->close();
    if($pending){ echo 'هناك إجازة قيد الإجراء لهذا الموظف.'; exit; }

    $start = new DateTime($start_date);
    $end   = new DateTime($end_date);
    $requested_days = $start->diff($end)->days + 1;  
    $current_year   = (int)$start->format('Y');

    switch ($type)
    {
        case 'اجازة سنوية':
      
            $to            = new DateTime($end_date);
            $age           = $to->diff( new DateTime($birth_date) )->y;
            $service_years = $to->diff( new DateTime($hire_date)  )->y;
            $annual_quota  = ($age >= 50 || $service_years >= 20) ? 45 : 30;

            $stmt = $con->prepare("SELECT COALESCE(SUM(DATEDIFF(end_date,start_date)+1),0)
                                   FROM vacations
                                   WHERE emp_id = ? AND type = 'اجازة سنوية'
                                         AND accept = 1 AND YEAR(start_date)=?");
            $stmt->bind_param("ii",$emp_id,$current_year);
            $stmt->execute(); $stmt->bind_result($used); $stmt->fetch(); $stmt->close();

            $remaining = $annual_quota - $used;
            if ($remaining <= 0){
                echo 'استهلك الموظف كامل رصيده السنوى لهذا العام.'; exit;
            }
            if ($requested_days > $remaining){
                echo "الرصيد المتبقى $remaining يوم ولا يمكنك طلب $requested_days يوم."; exit;
            }

            if ($requested_days < 15){
                $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                         WHERE emp_id = ? AND type='اجازة سنوية'
                                               AND accept = 1 AND YEAR(start_date)=?
                                               AND (DATEDIFF(end_date,start_date)+1) >= 15");
                $stmt->bind_param("ii",$emp_id,$current_year);
                $stmt->execute(); $stmt->bind_result($have15); $stmt->fetch(); $stmt->close();
                if(!$have15){
                    echo 'يجب أن يتمتع الموظف بحد أدنى 15 يوم متصلة فى السنة.'; exit;
                }
            }
        break;
      
        case 'اجازة مرضية':
            $stmt = $con->prepare("SELECT COALESCE(SUM(DATEDIFF(end_date,start_date)+1),0)
                                   FROM vacations
                                   WHERE emp_id = ? AND type = 'اجازة مرضية'
                                         AND accept = 1 AND YEAR(start_date)=?");
            $stmt->bind_param("ii",$emp_id,$current_year);
            $stmt->execute(); $stmt->bind_result($used); $stmt->fetch(); $stmt->close();

            if ($requested_days > 45){
                echo 'الحد الأقصى المستمر للإجازة المرضية هو 45 يوم.'; exit;
            }
            if ( ($used + $requested_days) > 60 ){
                $left = 60 - $used;
                echo "المتبقى من رصيد الإجازة المرضية هذا العام هو $left يوم."; exit;
            }
        break;
      
        case 'اجازة الحج':
            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                   WHERE emp_id=? AND type='اجازة الحج' AND accept=1");
            $stmt->bind_param("i",$emp_id);
            $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
            if($taken){ echo 'تمّ الحصول على إجازة الحج من قبل، لا تُمنح إلا مرة واحدة.'; exit; }
            if ($requested_days > 20){
                echo 'الحد الأقصى لإجازة الحج 20 يوم.'; exit;
            }
        break;
      
        case 'اجازة زواج':
            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                   WHERE emp_id=? AND type='اجازة زواج' AND accept=1");
            $stmt->bind_param("i",$emp_id);
            $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
            if($taken){ echo 'تمّ الحصول على إجازة زواج سابقًا، لا تُمنح إلا مرة واحدة.'; exit; }
            if ($requested_days > 14){
                echo 'الحد الأقصى لإجازة الزواج هو 14 يوم.'; exit;
            }
        break;
      
        case 'اجازة وفاة الزوج':
            if ($gender != 'أنثى'){ echo 'إجازة وفاة الزوج خاصة بالإناث فقط.'; exit; }

            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                   WHERE emp_id=? AND type='اجازة وفاة الزوج' AND accept=1");
            $stmt->bind_param("i",$emp_id);
            $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
            if($taken){ echo 'تمّ الحصول على هذه الإجازة سابقًا، لا تُمنح إلا مرة واحدة.'; exit; }

            if ($requested_days != 130){
                echo 'مدة الإجازة هى 4 أشهر و10 أيام (130 يوم) ويجب إدخال المدة كاملة.'; exit;
            }
        break;
        default: echo 'نوع الإجازة غير معروف'; exit;
    } 

    $interval  = $start->diff($end);
    $years     = $interval->y;
    $months    = $interval->m;
    $days_only = $requested_days;

    $stmt = $con->prepare("INSERT INTO vacations
           (emp_id,years,months,days,reason,companion,type,start_date,end_date,created_at)
           VALUES (?,?,?,?,?,?,?,?,?,?)");
    $stmt->bind_param("iiiisissss",
           $emp_id,$years,$months,$days_only,$reason,$companion,
           $type,$start_date,$end_date,$created_at);

    if($stmt->execute()){
        echo "<script>
                Swal.fire({title:'تم',text:'تم إضافة الإجازة بنجاح',icon:'success'});
              </script>";
        echo '<meta http-equiv="refresh" content="2;url=vacations.php">';
    } else {
        echo 'حدث خطأ أثناء الحفظ: '.$stmt->error;
    }
    $stmt->close();
}

 

اخي مصطفي هل كودك هذا استغنيت عن دالة ووضعت منطق داخل كود ادخال كيف اعرف رصيد كل اجازة متبقي للموظف 

تم التعديل في بواسطة ايمن ميلاد
  • 0
نشر
بتاريخ 1 ساعة قال محمد عاطف17:

هذا هو الكود كان يوجد مشكلة في إضافة البيانات .

إليك الكود بعد التعديل :

<?php
include('header.php');
error_reporting(0);
ini_set('display_errors', 0);
function calculateVacationBalance($con, $emp_id, $type, $hire_date, $birth_date, $gender, $to_date)
{
    $to = new DateTime($to_date);
    $hire = new DateTime($hire_date);
    $birth = new DateTime($birth_date);
    $current_year = $to->format('Y');

    // حساب سنوات الخدمة
    $service_years = $to->diff($hire)->y;
    // حساب العمر
    $age = $to->diff($birth)->y;

    // استعلام للحصول على الأيام المستخدمة
    $stmt = $con->prepare("
        SELECT COALESCE(SUM(DATEDIFF(end_date, start_date) + 1), 0) AS used_days
        FROM vacations
        WHERE emp_id = ? AND type = ? AND accept = 1
        AND YEAR(start_date) = ?
    ");
    $stmt->bind_param("iss", $emp_id, $type, $current_year);
    $stmt->execute();
    $stmt->bind_result($used_days);
    $stmt->fetch();
    $stmt->close();

    $used_days = $used_days ?: 0;

    switch ($type) {
        case 'اجازة سنوية':
            // 30 يومًا سنويًا، 45 يومًا إذا كان العمر ≥ 50 أو الخدمة ≥ 20 سنة
            $annual_days = ($age >= 50 || $service_years >= 20) ? 45 : 30;
            $balance = $annual_days - $used_days;
            // التأكد من أن الرصيد لا يقل عن 15 يومًا متصلة إذا لم يتم استخدامها
            return max(0, $balance);

        case 'اجازة مرضية':
            // 45 يومًا متصلة أو 60 يومًا متقطعة سنويًا
            $sick_balance = 60 - $used_days;
            return max(0, $sick_balance);

        case 'اجازة الحج':
            // 20 يومًا مرة واحدة خلال الخدمة
            $stmt = $con->prepare("
                SELECT COUNT(*) AS taken
                FROM vacations
                WHERE emp_id = ? AND type = 'اجازة الحج' AND accept = 1
            ");
            $stmt->bind_param("i", $emp_id);
            $stmt->execute();
            $stmt->bind_result($taken);
            $stmt->fetch();
            $stmt->close();
            return $taken > 0 ? 0 : 20;

        case 'اجازة زواج':
            // 14 يومًا مرة واحدة خلال الخدمة
            $stmt = $con->prepare("
                SELECT COUNT(*) AS taken
                FROM vacations
                WHERE emp_id = ? AND type = 'اجازة زواج' AND accept = 1
            ");
            $stmt->bind_param("i", $emp_id);
            $stmt->execute();
            $stmt->bind_result($taken);
            $stmt->fetch();
            $stmt->close();
            return $taken > 0 ? 0 : 14;

        case 'اجازة وفاة الزوج':
            // 130 يومًا (4 أشهر و10 أيام) للإناث فقط، مرة واحدة
            if ($gender !== 'أنثى') {
                return 0;
            }
            $stmt = $con->prepare("
                SELECT COUNT(*) AS taken
                FROM vacations
                WHERE emp_id = ? AND type = 'اجازة وفاة الزوج' AND accept = 1
            ");
            $stmt->bind_param("i", $emp_id);
            $stmt->execute();
            $stmt->bind_result($taken);
            $stmt->fetch();
            $stmt->close();
            return $taken > 0 ? 0 : 130;

        default:
            return 0;
    }
}

?>

<head>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
    <style>
        .rak {
            width: 400px;
            height: 300px;
            font-size: 14px !important;
        }
    </style>
</head>

<div class="col-md-9 pan1">
    <ol class="breadcrumb" style="background-color: #fff;padding-top:8px;padding-bottom:8px;color:#000;font-size:16px;">
        <li><a href="vacations.php">الاجازات</a></li>
        <li class="active">اضافة اجازة جديد</li>
    </ol>
</div>
</div>
<div class="row">
    <div class="col-md-9 pan1">
        <div class="panel" style="color:#000;">
            <div class="panel-body" style="font-size:14px; padding-left:40px;padding-right:40px;padding-bottom:25px;padding-top:25px;">
                <form method="POST" enctype="multipart/form-data">
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>الموظف</label>
                                <select name="emp_id" id="">
                                    <?php
                                    $sql = "SELECT e.person_id, p.name FROM employees e JOIN people p ON e.person_id = p.id;";
                                    $result = $con->query($sql);
                                    while ($row = $result->fetch_assoc()) {
                                        echo "<option value='{$row['person_id']}'>{$row['name']}</option>";
                                    }
                                    ?>
                                </select>
                            </div>
                        </div>

                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>نوع الاجازة</label>
                                <select name="type" id="">
                                    <option value="اجازة سنوية">اجازة سنوية</option>
                                    <option value="اجازة مرضية">اجازة مرضية</option>
                                    <option value="اجازة الحج">اجازة الحج</option>
                                    <option value="اجازة زواج">اجازة زواج</option>
                                    <option value="اجازة وفاة الزوج">اجازة وفاة الزوج</option>

                                </select>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>تاريخ البداية</label>
                                <input name="start_date" type="date" class="form-control">
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>تاريخ المباشرة</label>
                                <input name="end_date" type="date" class="form-control">
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>سبب الاجازة</label>
                                <input name="reason" type="text" class="form-control" placeholder="ادخل سبب الاجازة">
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>الموافقة مسبقا</label>
                                <input name="companion" type="checkbox" class="form-control">
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <button name="submit" type="submit" class="btn btn-primary">إضافة <span class="ion-android-add"></span></button>
                                <button type="reset" class="btn btn-danger">إلغاء <span class="ion-android-delete"></span></button>
                            </div>
                        </div>
                    </div>
                </form>
                <?php
                if ($_SERVER["REQUEST_METHOD"] == "POST") {
                    $emp_id    = $_POST['emp_id'];
                    $type      = $_POST['type'];
                    $start_date = $_POST['start_date'];
                    $end_date   = $_POST['end_date'];
                    $reason    = $_POST['reason'];
                    $companion = isset($_POST['companion']) ? 1 : 0;
                    $created_at = date('Y-m-d H:i:s');
                    $start = new DateTime($start_date);
                    $end = new DateTime($end_date);
                    $interval = $start->diff($end);
                    $years  = $interval->y;
                    $months = $interval->m;
                    $days   = $interval->d;


                    $errors = [];
                    if (empty($type)) {
                        $errors[] = 'يجب تحديد نوع الإجازة';
                    }
                    if (empty($start_date)) {
                        $errors[] = 'يجب إدخال تاريخ بداية الإجازة';
                    }
                    if (empty($end_date)) {
                        $errors[] = 'يجب إدخال تاريخ المباشرة';
                    }
                    if ($end <= $start) {
                        $errors[] = 'تاريخ المباشرة يجب أن يكون بعد بداية الإجازة';
                    }
                    if (!empty($errors)) {
                        echo implode('<br>', $errors);
                        exit;
                    }

                    mysqli_begin_transaction($con);
                    try {
                        $stmt = $con->prepare("SELECT * FROM employees WHERE person_id = ?");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $employee = $stmt->get_result()->fetch_assoc();
                        $stmt->close();

                        if (!$employee) {
                            echo "لم يتم العثور على بيانات الموظف";
                            exit;
                        }

                        // تحقق لا يوجد إجازة قيد الإجراء
                        $stmt = $con->prepare("SELECT COUNT(*) FROM vacations WHERE emp_id = ? AND accept = 0");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $stmt->bind_result($count);
                        $stmt->fetch();
                        $stmt->close();

                        if ($count > 0) {
                            echo "عذرًا، هنالك إجازة قيد الإجراء للموظف الحالي، الرجاء التحقق.";
                            exit();
                        }

                        $stmt = $con->prepare("SELECT * FROM people WHERE id = ?");
                        $stmt->bind_param("i", $emp_id);
                        $stmt->execute();
                        $people = $stmt->get_result()->fetch_assoc();
                        $stmt->close();
                        if ($type == "اجازة سنوية") {
                            $to_date = $start_date;
                            $hire_date = $employee->start_date;
                            $birth_date = $people->birth_date;
                            $to = new DateTime($to_date);
                            $hire = new DateTime($hire_date);
                            $birth = new DateTime($birth_date);
                            $service_years = $to->diff($hire)->y;
                            $age = $to->diff($birth)->y;

                            // تحديد الحد الأقصى للإجازة السنوية
                            $max_annual_days = ($age >= 50 || $service_years >= 20) ? 45 : 30;

                            // حساب عدد أيام الإجازة المطلوبة
                            $start = new DateTime($start_date);
                            $end = new DateTime($end_date);
                            $interval = $start->diff($end);
                            $requested_days = $interval->days + 1;

                            // التحقق من أن عدد أيام الإجازة المطلوبة لا يتجاوز الحد الأقصى
                            if ($requested_days > $max_annual_days) {
                                echo "لا يمكنك طلب إجازة سنوية تتجاوز " . $max_annual_days . " يومًا. الحد الأقصى المسموح به هو: " . $max_annual_days . " يومًا.";
                                exit;
                            }
                        }


                        if ($type == "اجازة مرضية") {
                            $stmt = $con->prepare("SELECT COALESCE(SUM(DATEDIFF(end_date,start_date)+1),0)
                                   FROM vacations
                                   WHERE emp_id = ? AND type = 'اجازة مرضية'
                                         AND accept = 1 AND YEAR(start_date)=?");
                            $stmt->bind_param("ii", $emp_id, $current_year);
                            $stmt->execute();
                            $stmt->bind_result($used);
                            $stmt->fetch();
                            $stmt->close();

                            if ($requested_days > 45) {
                                echo 'الحد الأقصى المستمر للإجازة المرضية هو 45 يوم.';
                                exit;
                            }
                            if (($used + $requested_days) > 60) {
                                $left = 60 - $used;
                                echo "المتبقى من رصيد الإجازة المرضية هذا العام هو $left يوم.";
                                exit;
                            }
                        }
                        if ($type == "اجازة الحج") {
                            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                            WHERE emp_id=? AND type='اجازة الحج' AND accept=1");
                            $stmt->bind_param("i", $emp_id);
                            $stmt->execute();
                            $stmt->bind_result($taken);
                            $stmt->fetch();
                            $stmt->close();
                            if ($taken) {
                                echo 'تمّ الحصول على إجازة الحج من قبل، لا تُمنح إلا مرة واحدة.';
                                exit;
                            }
                            if ($requested_days > 20) {
                                echo 'الحد الأقصى لإجازة الحج 20 يوم.';
                                exit;
                            }
                        }
                        if ($type == "اجازة زواج") {
                            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                            WHERE emp_id=? AND type='اجازة زواج' AND accept=1");
                            $stmt->bind_param("i", $emp_id);
                            $stmt->execute();
                            $stmt->bind_result($taken);
                            $stmt->fetch();
                            $stmt->close();
                            if ($taken) {
                                echo 'تمّ الحصول على إجازة زواج سابقًا، لا تُمنح إلا مرة واحدة.';
                                exit;
                            }
                            if ($requested_days > 14) {
                                echo 'الحد الأقصى لإجازة الزواج هو 14 يوم.';
                                exit;
                            }
                        }
                        if ($type == "اجازة وفاة الزوج") {
                            if ($gender != 'أنثى') {
                                echo 'إجازة وفاة الزوج خاصة بالإناث فقط.';
                                exit;
                            }

                            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                   WHERE emp_id=? AND type='اجازة وفاة الزوج' AND accept=1");
                            $stmt->bind_param("i", $emp_id);
                            $stmt->execute();
                            $stmt->bind_result($taken);
                            $stmt->fetch();
                            $stmt->close();
                            if ($taken) {
                                echo 'تمّ الحصول على هذه الإجازة سابقًا، لا تُمنح إلا مرة واحدة.';
                                exit;
                            }

                            if ($requested_days != 130) {
                                echo 'مدة الإجازة هى 4 أشهر و10 أيام (130 يوم) ويجب إدخال المدة كاملة.';
                                exit;
                            }
                        }


                        $stmt = $con->prepare("INSERT INTO vacations (emp_id, years, months, days, reason, companion, type, start_date, end_date, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                        $start_date_formatted = $start->format('Y-m-d');
                        $end_date_formatted = $end->format('Y-m-d');
                        $stmt->bind_param(
                            'iiiisissss',
                            $emp_id,
                            $years,
                            $months,
                            $requested_days, // الآن أصبحت days هي فارق الأيام
                            $reason,
                            $companion,
                            $type,
                            $start_date_formatted,
                            $end_date_formatted,
                            $created_at
                        );
                        if ($stmt->execute()) {
                            echo "<script>
                                Swal.fire({
                                    title: 'رسالة تأكيد',
                                    text: 'تم إضافة بيانات اجازة موظف  بنجاح!',
                                    icon: 'success',
                                    customClass: 'rak',
                                });
                                </script>";
                            echo '<meta http-equiv="refresh" content="2;url=vacations.php" />';
                        }
                        $stmt->close();

                        mysqli_commit($con);
                    } catch (Exception $e) {
                        mysqli_rollback($con);
                        echo "خطأ: " . $e->getMessage();
                        exit;
                    }
                }
                ?>
            </div>
        </div>
    </div>
</div>
<?php
include('footer.php');
?>

إذا حدثت مشكلة يرجى إرفاق المشكلة هنا.

لماذا كود تعديل لايعمل 

<?php
include('header.php');
error_reporting(0);
ini_set('display_errors', 0);


?>

<head>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
    <style>
        .rak { width: 400px; height: 300px; font-size: 14px !important;}
    </style>
</head>

<div class="col-md-9 pan1">
    <ol class="breadcrumb" style="background-color: #fff;padding-top:8px;padding-bottom:8px;color:#000;font-size:16px;">
        <li><a href="vacations.php">الاجازات</a></li>
        <li class="active">تعديل اجازة موظف</li>
    </ol>
</div>
</div>
<div class="row">
    <div class="col-md-9 pan1">
        <div class="panel" style="color:#000;">
            <div class="panel-body" style="font-size:14px; padding-left:40px;padding-right:40px;padding-bottom:25px;padding-top:25px;">
                <form method="POST" enctype="multipart/form-data">
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>الموظف</label>
                                <select name="emp_id" id="">
                                <?php
                                    $sql = "SELECT e.person_id, p.name FROM employees e JOIN people p ON e.person_id = p.id;";
                                    $result = $con->query($sql);
                                    while ($row = $result->fetch_assoc()) {
                                        echo "<option value='{$row['person_id']}'>{$row['name']}</option>";
                                    }
                                ?>
                                </select>
                            </div>
                        </div>
                        
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>نوع الاجازة</label>
                                <select name="type" id="">
                                <option value="اجازة سنوية">اجازة سنوية</option>
                                    <option value="اجازة مرضية">اجازة مرضية</option>
                                    <option value="اجازة الحج">اجازة الحج</option>
                                    <option value="اجازة زواج">اجازة زواج</option>
                                    <option value="اجازة وفاة الزوج">اجازة وفاة الزوج</option>

                                </select>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>تاريخ البداية</label>
                                <input name="start_date" type="date" class="form-control">
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>تاريخ المباشرة</label>
                                <input name="end_date" type="date" class="form-control">
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>سبب الاجازة</label>
                                <input name="reason" type="text" class="form-control" placeholder="ادخل سبب الاجازة">
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>الموافقة مسبقا</label>
                                <input name="companion" type="checkbox" class="form-control">
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <button name="submit" type="submit" class="btn btn-primary">تحديث <span class="ion-android-add"></span></button>
                                <button type="reset" class="btn btn-danger">إلغاء <span class="ion-android-delete"></span></button>
                            </div>
                        </div>
                    </div>
                </form>
                <?php
               if ($_SERVER["REQUEST_METHOD"] == "POST")
                {

                $emp_id     = (int)$_POST['emp_id'];
                $type       = $_POST['type'];
                $start_date = $_POST['start_date'];
                $end_date   = $_POST['end_date'];
                $reason     = $_POST['reason'];
                $companion  = isset($_POST['companion']) ? 1 : 0;
                $created_at = date('Y-m-d H:i:s');
            
                $errors = [];
                if (!$type)              $errors[] = 'يجب تحديد نوع الإجازة';
                if (!$start_date)        $errors[] = 'يجب إدخال تاريخ بداية الإجازة';
                if (!$end_date)          $errors[] = 'يجب إدخال تاريخ المباشرة';
                if ($end_date <= $start_date)
                    $errors[] = 'تاريخ المباشرة يجب أن يكون بعد بداية الإجازة';
                if ($errors) { echo implode('<br>',$errors); exit; }
            
                $stmt = $con->prepare("SELECT e.start_date , p.birth_date , p.gender
                                       FROM employees e
                                       JOIN people p ON p.id = e.person_id
                                       WHERE e.person_id = ?");
                $stmt->bind_param("i",$emp_id);
                $stmt->execute();
                $stmt->bind_result($hire_date,$birth_date,$gender);
                if(!$stmt->fetch()){ echo 'لم يتم العثور على بيانات الموظف'; exit; }
                $stmt->close();
            
                $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                       WHERE emp_id = ? AND accept = 0");
                $stmt->bind_param("i",$emp_id);
                $stmt->execute();  $stmt->bind_result($pending); $stmt->fetch(); $stmt->close();
                if($pending){ echo 'هناك إجازة قيد الإجراء لهذا الموظف.'; exit; }
            
                $start = new DateTime($start_date);
                $end   = new DateTime($end_date);
                $requested_days = $start->diff($end)->days + 1;  
                $current_year   = (int)$start->format('Y');
            
                switch ($type)
                {
                    case 'اجازة سنوية':
                  
                        $to            = new DateTime($end_date);
                        $age           = $to->diff( new DateTime($birth_date) )->y;
                        $service_years = $to->diff( new DateTime($hire_date)  )->y;
                        $annual_quota  = ($age >= 50 || $service_years >= 20) ? 45 : 30;
            
                        $stmt = $con->prepare("SELECT COALESCE(SUM(DATEDIFF(end_date,start_date)+1),0)
                                               FROM vacations
                                               WHERE emp_id = ? AND type = 'اجازة سنوية'
                                                     AND accept = 1 AND YEAR(start_date)=?");
                        $stmt->bind_param("ii",$emp_id,$current_year);
                        $stmt->execute(); $stmt->bind_result($used); $stmt->fetch(); $stmt->close();
            
                        $remaining = $annual_quota - $used;
                        if ($remaining <= 0){
                            echo 'استهلك الموظف كامل رصيده السنوى لهذا العام.'; exit;
                        }
                        if ($requested_days > $remaining){
                            echo "الرصيد المتبقى $remaining يوم ولا يمكنك طلب $requested_days يوم."; exit;
                        }
            
                        if ($requested_days < 15){
                            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                                     WHERE emp_id = ? AND type='اجازة سنوية'
                                                           AND accept = 1 AND YEAR(start_date)=?
                                                           AND (DATEDIFF(end_date,start_date)+1) >= 15");
                            $stmt->bind_param("ii",$emp_id,$current_year);
                            $stmt->execute(); $stmt->bind_result($have15); $stmt->fetch(); $stmt->close();
                            if(!$have15){
                                echo 'يجب أن يتمتع الموظف بحد أدنى 15 يوم متصلة فى السنة.'; exit;
                            }
                        }
                    break;
                  
                    case 'اجازة مرضية':
                        $stmt = $con->prepare("SELECT COALESCE(SUM(DATEDIFF(end_date,start_date)+1),0)
                                               FROM vacations
                                               WHERE emp_id = ? AND type = 'اجازة مرضية'
                                                     AND accept = 1 AND YEAR(start_date)=?");
                        $stmt->bind_param("ii",$emp_id,$current_year);
                        $stmt->execute(); $stmt->bind_result($used); $stmt->fetch(); $stmt->close();
            
                        if ($requested_days > 45){
                            echo 'الحد الأقصى المستمر للإجازة المرضية هو 45 يوم.'; exit;
                        }
                        if ( ($used + $requested_days) > 60 ){
                            $left = 60 - $used;
                            echo "المتبقى من رصيد الإجازة المرضية هذا العام هو $left يوم."; exit;
                        }
                    break;
                  
                    case 'اجازة الحج':
                        $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                               WHERE emp_id=? AND type='اجازة الحج' AND accept=1");
                        $stmt->bind_param("i",$emp_id);
                        $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
                        if($taken){ echo 'تمّ الحصول على إجازة الحج من قبل، لا تُمنح إلا مرة واحدة.'; exit; }
                        if ($requested_days > 20){
                            echo 'الحد الأقصى لإجازة الحج 20 يوم.'; exit;
                        }
                    break;
                  
                    case 'اجازة زواج':
                        $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                               WHERE emp_id=? AND type='اجازة زواج' AND accept=1");
                        $stmt->bind_param("i",$emp_id);
                        $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
                        if($taken){ echo 'تمّ الحصول على إجازة زواج سابقًا، لا تُمنح إلا مرة واحدة.'; exit; }
                        if ($requested_days > 14){
                            echo 'الحد الأقصى لإجازة الزواج هو 14 يوم.'; exit;
                        }
                    break;
                  
                    case 'اجازة وفاة الزوج':
                        if ($gender != 'أنثى'){ echo 'إجازة وفاة الزوج خاصة بالإناث فقط.'; exit; }
            
                        $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                               WHERE emp_id=? AND type='اجازة وفاة الزوج' AND accept=1");
                        $stmt->bind_param("i",$emp_id);
                        $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
                        if($taken){ echo 'تمّ الحصول على هذه الإجازة سابقًا، لا تُمنح إلا مرة واحدة.'; exit; }
            
                        if ($requested_days != 130){
                            echo 'مدة الإجازة هى 4 أشهر و10 أيام (130 يوم) ويجب إدخال المدة كاملة.'; exit;
                        }
                    break;
                    default: echo 'نوع الإجازة غير معروف'; exit;
                } 
            
                $interval  = $start->diff($end);
                $years     = $interval->y;
                $months    = $interval->m;
                $days_only = $requested_days;
            
                $stmt = $con->prepare("UPDATE vacations SET
                       years = ?,
                       months = ?,
                       days = ?,
                       reason = ?,
                       companion = ?,
                       type = ?,
                       start_date = ?,
                       end_date = ?,
                       created_at = ?
                       WHERE emp_id = ?"); // Assuming emp_id is the unique identifier

$stmt->bind_param("iiissssssi",
                       $years, $months, $days_only, $reason, $companion,
                       $type, $start_date, $end_date, $created_at, $emp_id);
            
                if($stmt->execute()){
                    echo "<script>
                            Swal.fire({title:'تم',text:'تم تحديث الإجازة بنجاح',icon:'success'});
                          </script>";
                    echo '<meta http-equiv="refresh" content="2;url=vacations.php">';
                } else {
                    echo 'حدث خطأ أثناء الحفظ: '.$stmt->error;
                }
                $stmt->close();
            } 
        
                      
                
                ?>
            </div>
        </div>
    </div>
</div>
<?php
include('footer.php');
?>

 

  • 0
نشر
بتاريخ 7 دقائق مضت قال ايمن ميلاد:

كيف اعرف رصيد موظف لكل اجازة 

استخدم الدالة التالية سواء في نفس الملف أو في ملف آخر وتستطيع استدعائها:

function getVacationBalances(mysqli $con, int $empID, int $year = null): array
{
    $year        = $year ?: date('Y');
    $balances    = [];

    $stmt = $con->prepare(
        "SELECT e.start_date       AS hire_date,
                p.birth_date       AS birth_date,
                p.gender           AS gender
         FROM employees e
         JOIN people p ON p.id = e.person_id
         WHERE e.person_id = ?");
    $stmt->bind_param("i", $empID);
    $stmt->execute();
    $stmt->bind_result($hire_date, $birth_date, $gender);
    if (!$stmt->fetch()) return [];          // لا يوجد موظف
    $stmt->close();

    $to            = new DateTime("$year-12-31");
    $age           = $to->diff(new DateTime($birth_date))->y;
    $serviceYears  = $to->diff(new DateTime($hire_date))->y;

    $quota = [
        'اجازة سنوية'       => ($age >= 50 || $serviceYears >= 20) ? 45 : 30,
        'اجازة مرضية'       => 60,
        'اجازة الحج'        => 20,
        'اجازة زواج'        => 14,
        'اجازة وفاة الزوج'  => ($gender === 'أنثى' ? 130 : 0),
    ];

    $stmt = $con->prepare(
        "SELECT type,
                SUM(DATEDIFF(end_date,start_date)+1) AS used_days
         FROM vacations
         WHERE emp_id = ? AND accept = 1
               AND (
                     -- للسنة والمرضية نحصر بالسنة
                     (type IN('اجازة سنوية','اجازة مرضية') AND YEAR(start_date)=?)
                     -- لباقى الأنواع مدى الخدمة كلها
                     OR  type NOT IN('اجازة سنوية','اجازة مرضية')
                   )
         GROUP BY type");
    $stmt->bind_param("ii", $empID, $year);
    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
        $balances[$row['type']]['used'] = (int)$row['used_days'];
    }
    $stmt->close();

    foreach ($quota as $type => $q)
    {
        $used = $balances[$type]['used'] ?? 0;
        $balances[$type] = [
            'quota'     => $q,
            'used'      => $used,
            'remaining' => max(0, $q - $used)
        ];
    }

    return $balances;
}

الاستدعاء سيكون كالتالي بتمرير الرصيد الحالى للسنة الجارية للدالة getVacationBalances:

$balances = getVacationBalances($con, $emp_id);  

echo "<pre>";
foreach ($balances as $type=>$row){
    echo "$type : المستحق = {$row['quota']} | المستخدم = {$row['used']} | المتبقي = {$row['remaining']}\n";
}
echo "</pre>";

 

  • 0
نشر

بارك الله فيك اخي مصطفي 

قمت بتحميل مكتبة  tcpdf لطباعة صفحة لماذا لاتظهر صفحة 

<?php
    include("config.php");
    require_once('tcpdf/tcpdf.php');
	function generateRow(){
		$contents = '';
		$sql = "SELECT  p.id as id,
    p.name AS employee_name, 
    p.N_id AS national_id, 
    e.degree AS current_degree, 
    e.start_date AS start_date, 
    e.type AS employment_type, 
    e.status AS current_status, 
    d.name AS department_name 
FROM 
    people p 
JOIN 
    employees e ON p.id = e.person_id 
LEFT JOIN 
    sub_sections d ON e.section_id = d.id";

		//use for MySQLi OOP
		$query = $con->query($sql);
		while($row = $query->fetch_assoc()){
			$contents .= "
			<tr>
				<td>".$row['id']."</td>
				<td>".$row['name']."</td>
				<td>".$row['N_id']."</td>
                 <td>".$row['degree']."</td>
				<td>".$row['start_date']."</td>
                <td>".$row['type']."</td>
			</tr>
			";
		}
		

		return $contents;
	}

   
    $pdf = new TCPDF('P', PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
     $lg = Array();
    $lg['a_meta_charset'] = 'UTF-8';
    $lg['a_meta_dir'] = 'rtl';
    $lg['a_meta_language'] = 'ar';
   $pdf->setLanguageArray($lg);
    $pdf->setRTL(true);
    $pdf->SetFont('aealarabiya', '', 11);
    $pdf->SetCreator(PDF_CREATOR);
    $pdf->SetTitle("معلومات الموظفين");
    $pdf->SetHeaderData('', '', PDF_HEADER_TITLE, PDF_HEADER_STRING);
    $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
    $pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
    $pdf->SetDefaultMonospacedFont('aealarabiya');
    $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
    $pdf->SetMargins(PDF_MARGIN_LEFT, '11', PDF_MARGIN_RIGHT);
    $pdf->setPrintHeader(false);
    $pdf->setPrintFooter(false);
    $pdf->SetAutoPageBreak(TRUE, 11);

    $pdf->AddPage();
    $content = '';
    $content .= '
      	<h2 align="center">معلومات الموظفين</h2>
      	
      	<table border="1" cellspacing="0" cellpadding="3">
           <tr>
        <th width="5%">الرقم</th>
				<th width="20%">الاسم </th>
				<th width="20%"> الرقم الوطني</th>
				<th width="20%">الدرجة الحالية</th>
                <th width="20%">تاريخ المباشرة</th>
                <th width="20%">نوع التوظيف</th>
              
           </tr>
      ';
			 
    $content .= generateRow();
    $content .= '</table>';
    $pdf->writeHTML($content);
    $pdf->Output('emps.pdf', 'I');


?>

 

يظهر The requested URL was not found on this server.

  • 0
نشر

لماذا في تعديل البيانات لايعمل كود يقول لي تم اخد اجازة مسبقا انا اريده يعدل بيانات بنفس منطق ادخال يعني يعدل لكن بنفس شروط كل اجازة 

ممكن تعديل علي كود اخي مصطفي لكن يعدل بنفس شروط اجازة 

<?php
include('header.php');

// Assuming you have the course ID passed via GET for the update
$v_id = $_GET['id'];

// Fetch existing course data from the database
$sql = "SELECT * FROM vacations WHERE emp_id= ?";
$stmt = $con->prepare($sql);
$stmt->bind_param("i", $v_id);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
$sql2 = "SELECT * FROM people WHERE id= ?";
$stmt = $con->prepare($sql2);
$stmt->bind_param("i", $v_id);
$stmt->execute();
$result2 = $stmt->get_result();
$row2 = $result2->fetch_assoc();
?>
<!-------------------------------------------------------------------------------->
<!------------------------------------header-------------------------------------->
<!-------------------------------------------------------------------------------->

<head>
    <!-- مكتبة SweetAlert2 -->
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
    <style>
        .rak {
            width: 400px;
            height: 300px;
            font-size: 14px !important;
        }
    </style>
</head>
<div class="col-md-9 pan1">
    <ol class="breadcrumb" style="background-color: #fff; padding-top: 8px; padding-bottom: 8px; color: #000; font-size: 16px;">
        <li><a href="student.php">الاجازات</a></li>
        <li class="active">تعديل بيانات الاجازة</li>
    </ol>
</div>

<div class="row">
    <div class="col-md-9 pan1">
        <div class="panel" style="color: #000;">
            <div class="panel-body" style="font-size: 14px; padding: 25px 40px;">
                <form method="POST" enctype="multipart/form-data">
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top: 10px;">
                                <label>اسم الموظف</label>
                                <select name="emp_id" id="" class="form-control">
                             <option value="<?php echo $row2['id'] ?>"> <?php echo $row2['name'] ?> </option>
                                </select>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top: 10px;">
                                <label>نوع الاجازة</label>
                                <select name="type" id="" class="form-control">
                                <option value="اجازة سنوية">اجازة سنوية</option>
                                    <option value="اجازة مرضية">اجازة مرضية</option>
                                    <option value="اجازة الحج">اجازة الحج</option>
                                    <option value="اجازة زواج">اجازة زواج</option>
                                    <option value="اجازة وفاة الزوج">اجازة وفاة الزوج</option>

                                </select>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top: 10px;">
                                <label>تاريخ البداية</label>
                                <input type="date" class="form-control" name="start_date" id="" value="<?php echo $row['start_date']; ?>" >
                            </div>
                        </div>
                       
                    </div>
                    <div class="row">
                        <div class="col-md-4">
                           
                            <div class="form-group" style="margin-top: 10px;">
                            <label>تاريخ المباشرة</label>
                            <input type="date" class="form-control" name="end_date" id="" value="<?php echo $row['end_date']; ?>" >
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group" style="margin-top:10px;">
                                <label>سبب الاجازة</label>
                                <input name="reason" type="text" class="form-control"  value="<?php echo $row['reason']; ?>">
                            </div>
                        </div>
                    </div>
                       
                        
                    <div class="row">
                        <div class="col-md-4">
                           
                            <div class="form-group" style="margin-top: 10px;">
                                <button name="submit" type="submit" class="btn btn-primary">تحديث <span class="ion-android-add"></span></button>
                                <button type="reset" class="btn btn-danger">إلغاء <span class="ion-android-delete"></span></button>
                            </div>
                        </div>
                    </div>
                </form>
                <?php
                if ($_SERVER["REQUEST_METHOD"] == "POST") {
                    $emp_id     = (int)$_POST['emp_id'];
                    $type       = $_POST['type'];
                    $start_date = $_POST['start_date'];
                    $end_date   = $_POST['end_date'];
                    $reason     = $_POST['reason'];
                    $companion  = isset($_POST['companion']) ? 1 : 0;
                    $updated_at = date('Y-m-d H:i:s');
                
                    $errors = [];
                    if (!$type)              $errors[] = 'يجب تحديد نوع الإجازة';
                    if (!$start_date)        $errors[] = 'يجب إدخال تاريخ بداية الإجازة';
                    if (!$end_date)          $errors[] = 'يجب إدخال تاريخ المباشرة';
                    if ($end_date <= $start_date)
                        $errors[] = 'تاريخ المباشرة يجب أن يكون بعد بداية الإجازة';
                    if ($errors) { echo implode('<br>',$errors); exit; }
                
                    $stmt = $con->prepare("SELECT e.start_date , p.birth_date , p.gender
                                           FROM employees e
                                           JOIN people p ON p.id = e.person_id
                                           WHERE e.person_id = ?");
                    $stmt->bind_param("i",$emp_id);
                    $stmt->execute();
                    $stmt->bind_result($hire_date,$birth_date,$gender);
                    if(!$stmt->fetch()){ echo 'لم يتم العثور على بيانات الموظف'; exit; }
                    $stmt->close();
                
                    $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                           WHERE emp_id = ? AND accept = 0");
                    $stmt->bind_param("i",$emp_id);
                    $stmt->execute();  $stmt->bind_result($pending); $stmt->fetch(); $stmt->close();
                    if($pending){ echo 'هناك إجازة قيد الإجراء لهذا الموظف.'; exit; }
                
                    $start = new DateTime($start_date);
                    $end   = new DateTime($end_date);
                    $requested_days = $start->diff($end)->days + 1;  
                    $current_year   = (int)$start->format('Y');
                
                    switch ($type)
                    {
                        case 'اجازة سنوية':
                      
                            $to            = new DateTime($end_date);
                            $age           = $to->diff( new DateTime($birth_date) )->y;
                            $service_years = $to->diff( new DateTime($hire_date)  )->y;
                            $annual_quota  = ($age >= 50 || $service_years >= 20) ? 45 : 30;
                
                            $stmt = $con->prepare("SELECT COALESCE(SUM(DATEDIFF(end_date,start_date)+1),0)
                                                   FROM vacations
                                                   WHERE emp_id = ? AND type = 'اجازة سنوية'
                                                         AND accept = 1 AND YEAR(start_date)=?");
                            $stmt->bind_param("ii",$emp_id,$current_year);
                            $stmt->execute(); $stmt->bind_result($used); $stmt->fetch(); $stmt->close();
                
                            $remaining = $annual_quota - $used;
                            if ($remaining <= 0){
                                echo 'استهلك الموظف كامل رصيده السنوى لهذا العام.'; exit;
                            }
                            if ($requested_days > $remaining){
                                echo "الرصيد المتبقى $remaining يوم ولا يمكنك طلب $requested_days يوم."; exit;
                            }
                
                            if ($requested_days < 15){
                                $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                                         WHERE emp_id = ? AND type='اجازة سنوية'
                                                               AND accept = 1 AND YEAR(start_date)=?
                                                               AND (DATEDIFF(end_date,start_date)+1) >= 15");
                                $stmt->bind_param("ii",$emp_id,$current_year);
                                $stmt->execute(); $stmt->bind_result($have15); $stmt->fetch(); $stmt->close();
                                if(!$have15){
                                    echo 'يجب أن يتمتع الموظف بحد أدنى 15 يوم متصلة فى السنة.'; exit;
                                }
                            }
                        break;
                      
                        case 'اجازة مرضية':
                            $stmt = $con->prepare("SELECT COALESCE(SUM(DATEDIFF(end_date,start_date)+1),0)
                                                   FROM vacations
                                                   WHERE emp_id = ? AND type = 'اجازة مرضية'
                                                         AND accept = 1 AND YEAR(start_date)=?");
                            $stmt->bind_param("ii",$emp_id,$current_year);
                            $stmt->execute(); $stmt->bind_result($used); $stmt->fetch(); $stmt->close();
                
                            if ($requested_days > 45){
                                echo 'الحد الأقصى المستمر للإجازة المرضية هو 45 يوم.'; exit;
                            }
                            if ( ($used + $requested_days) > 60 ){
                                $left = 60 - $used;
                                echo "المتبقى من رصيد الإجازة المرضية هذا العام هو $left يوم."; exit;
                            }
                        break;
                      
                        case 'اجازة الحج':
                            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                                   WHERE emp_id=? AND type='اجازة الحج' AND accept=1");
                            $stmt->bind_param("i",$emp_id);
                            $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
                            if($taken){ echo 'تمّ الحصول على إجازة الحج من قبل، لا تُمنح إلا مرة واحدة.'; exit; }
                            if ($requested_days > 20){
                                echo 'الحد الأقصى لإجازة الحج 20 يوم.'; exit;
                            }
                        break;
                      
                        case 'اجازة زواج':
                            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                                   WHERE emp_id=? AND type='اجازة زواج' AND accept=1");
                            $stmt->bind_param("i",$emp_id);
                            $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
                            if($taken){ echo 'تمّ الحصول على إجازة زواج سابقًا، لا تُمنح إلا مرة واحدة.'; exit; }
                            if ($requested_days > 14){
                                echo 'الحد الأقصى لإجازة الزواج هو 14 يوم.'; exit;
                            }
                        break;
                      
                        case 'اجازة وفاة الزوج':
                            if ($gender != 'أنثى'){ echo 'إجازة وفاة الزوج خاصة بالإناث فقط.'; exit; }
                
                            $stmt = $con->prepare("SELECT COUNT(*) FROM vacations
                                                   WHERE emp_id=? AND type='اجازة وفاة الزوج' AND accept=1");
                            $stmt->bind_param("i",$emp_id);
                            $stmt->execute(); $stmt->bind_result($taken); $stmt->fetch(); $stmt->close();
                            if($taken){ echo 'تمّ الحصول على هذه الإجازة سابقًا، لا تُمنح إلا مرة واحدة.'; exit; }
                
                            if ($requested_days != 130){
                                echo 'مدة الإجازة هى 4 أشهر و10 أيام (130 يوم) ويجب إدخال المدة كاملة.'; exit;
                            }
                        break;
                        default: echo 'نوع الإجازة غير معروف'; exit;
                    } 
                
                    $interval  = $start->diff($end);
                    $years     = $interval->y;
                    $months    = $interval->m;
                    $days_only = $requested_days;

                   
$sql="UPDATE vacations SET emp_id=?,years=?,months=?,days=?,reason=?,type=?,start_date=?,end_date=?,updated_at=? WHERE emp_id = ? ";
                    

                    $stmt = $con->prepare($sql);
                    $stmt->bind_param("iiiisissssi", $emp_id,$years,$months,$days_only,$reason,
                    $type,$start_date,$end_date,$updated_at,$emp_id);

                    if ($stmt->execute()) {
                        echo "<script>
                            Swal.fire({
                                title: 'رسالة تأكيد',
                                text: 'تم تحديث بيانات الاجازة بنجاح!',
                                icon: 'success',
                                customClass: 'rak',
                            });
                        </script>";
                        echo '<meta http-equiv="refresh" content="2;url=vacations.php" />';
                    } else {
                        echo "خطأ في تحديث بيانات الاجازة: " . $stmt->error;
                    }
                } 
                ?>
            </div>
        </div>
    </div>
</div>

<!-------------------------------------------------------------------------------->
<!------------------------------------Footer-------------------------------------->
<!-------------------------------------------------------------------------------->

<?php
include('footer.php');
?>

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...