Initial import
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
$page_title = 'เพิ่มนักศึกษา';
|
||||
require_once __DIR__ . '/../includes/functions.php';
|
||||
require_once __DIR__ . '/../includes/header.php';
|
||||
|
||||
$curricula = getCurricula();
|
||||
$faculties = getFacultyList();
|
||||
$message = '';
|
||||
$error = '';
|
||||
$advisor_curriculum_id = isAdvisor() ? getCurrentUserCurriculumId() : null;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$student_code = trim($_POST['student_code'] ?? '');
|
||||
$name_th = trim($_POST['name_th'] ?? '');
|
||||
$name_en = trim($_POST['name_en'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$curriculum_id = $advisor_curriculum_id ?: intval($_POST['curriculum_id'] ?? 0);
|
||||
$faculty = trim($_POST['faculty'] ?? '');
|
||||
$graduated_institution = trim($_POST['graduated_institution'] ?? '');
|
||||
$previous_qualification = trim($_POST['previous_qualification'] ?? '');
|
||||
$enrollment_year = intval($_POST['enrollment_year'] ?? date('Y'));
|
||||
|
||||
if (empty($student_code) || empty($name_th) || empty($curriculum_id)) {
|
||||
$error = 'กรุณากรอกข้อมูลให้ครบถ้วน (รหัสนักศึกษา, ชื่อ-นามสกุล, สาขาวิชา)';
|
||||
} else {
|
||||
try {
|
||||
$advisor_id = isAdvisor() ? getCurrentUserId() : null;
|
||||
$stmt = getDB()->prepare("INSERT INTO students (student_code, name_th, name_en, email, faculty, graduated_institution, curriculum_id, enrollment_year, advisor_id, previous_qualification) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$student_code, $name_th, $name_en, $email, $faculty, $graduated_institution, $curriculum_id, $enrollment_year, $advisor_id, $previous_qualification ?: null]);
|
||||
$message = 'เพิ่มนักศึกษาสำเร็จ';
|
||||
echo "<script>window.location.href='view.php?id=" . getDB()->lastInsertId() . "';</script>";
|
||||
exit;
|
||||
} catch (PDOException $e) {
|
||||
if ($e->getCode() == 23000) {
|
||||
$error = 'รหัสนักศึกษานี้มีอยู่ในระบบแล้ว';
|
||||
} else {
|
||||
$error = 'เกิดข้อผิดพลาด: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="card">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h4 class="mb-0"><i class="bi bi-person-plus"></i> เพิ่มนักศึกษาใหม่</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if ($message): ?>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($message) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
||||
<?php endif; ?>
|
||||
<form method="POST" class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">รหัสนักศึกษา <span class="text-danger">*</span></label>
|
||||
<input type="text" name="student_code" class="form-control" required maxlength="20">
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<label class="form-label">ชื่อ-นามสกุล (ภาษาไทย) <span class="text-danger">*</span></label>
|
||||
<input type="text" name="name_th" class="form-control" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">ชื่อ-นามสกุล (ภาษาอังกฤษ)</label>
|
||||
<input type="text" name="name_en" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">อีเมล</label>
|
||||
<input type="email" name="email" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">สาขาวิชา <span class="text-danger">*</span></label>
|
||||
<?php if ($advisor_curriculum_id): ?>
|
||||
<input type="text" class="form-control" value="<?php foreach($curricula as $c) { if ($c['id'] == $advisor_curriculum_id) { echo htmlspecialchars($c['code'] . ' - ' . $c['name_th']); break; } } ?>" disabled>
|
||||
<input type="hidden" name="curriculum_id" value="<?= $advisor_curriculum_id ?>">
|
||||
<?php else: ?>
|
||||
<select name="curriculum_id" class="form-select" required>
|
||||
<option value="">-- เลือกสาขาวิชา --</option>
|
||||
<?php foreach ($curricula as $c): ?>
|
||||
<option value="<?= $c['id'] ?>" data-faculty="<?= $c['code'] == 'DT' ? '12' : '12' ?>"><?= htmlspecialchars($c['code']) ?> - <?= htmlspecialchars($c['name_th']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">คณะ</label>
|
||||
<select name="faculty" class="form-select">
|
||||
<option value="">-- เลือกคณะ --</option>
|
||||
<option value="คณะนวัตกรรมดิจิทัลเทคโนโลยี">คณะนวัตกรรมดิจิทัลเทคโนโลยี (12)</option>
|
||||
<option value="คณะบริหารธุรกิจ">คณะบริหารธุรกิจ (11)</option>
|
||||
<option value="คณะศึกษาศาสตร์และศิลปศาสตร์">คณะศึกษาศาสตร์และศิลปศาสตร์ (13)</option>
|
||||
<option value="คณะบัญชี">คณะบัญชี (14)</option>
|
||||
<option value="คณะนิติศาสตร์และรัฐศาสตร์">คณะนิติศาสตร์และรัฐศาสตร์ (15)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">ชื่อสถาบันที่จบ</label>
|
||||
<input type="text" name="graduated_institution" class="form-control" placeholder="ชื่อสถานศึกษาเดิม">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">วุฒิเดิม</label>
|
||||
<select name="previous_qualification" class="form-select">
|
||||
<option value="">-- เลือกวุฒิเดิม --</option>
|
||||
<option value="ม.6 (กศน,สกร)">ม.6 (กศน,สกร)</option>
|
||||
<option value="ปวช.3">ปวช.3</option>
|
||||
<option value="ปวส.2">ปวส.2</option>
|
||||
<option value="ปริญญาตรีใบที่ 2">ปริญญาตรีใบที่ 2</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">ปีการศึกษาที่เข้าศึกษา</label>
|
||||
<input type="number" name="enrollment_year" class="form-control" value="<?= date('Y') + 543 ?>" min="2569" step="1">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button type="submit" class="btn btn-success"><i class="bi bi-save"></i> บันทึก</button>
|
||||
<a href="list.php" class="btn btn-secondary"><i class="bi bi-arrow-left"></i> กลับ</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php require_once __DIR__ . '/../includes/footer.php'; ?>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../includes/functions.php';
|
||||
requireLogin();
|
||||
$id = intval($_GET['id'] ?? 0);
|
||||
requireStudentAccess($id);
|
||||
$student = getStudent($id);
|
||||
if (!$student) {
|
||||
header('Location: list.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = getDB()->prepare("DELETE FROM students WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
} catch (PDOException $e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
header('Location: list.php');
|
||||
exit;
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
$page_title = 'แก้ไขนักศึกษา';
|
||||
require_once __DIR__ . '/../includes/functions.php';
|
||||
require_once __DIR__ . '/../includes/header.php';
|
||||
|
||||
$id = intval($_GET['id'] ?? 0);
|
||||
requireStudentAccess($id);
|
||||
$student = getStudent($id);
|
||||
if (!$student) {
|
||||
echo '<div class="alert alert-danger">ไม่พบข้อมูลนักศึกษา</div>';
|
||||
require_once __DIR__ . '/../includes/footer.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
$curricula = getCurricula();
|
||||
$faculties = getFacultyList();
|
||||
$error = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$student_code = trim($_POST['student_code'] ?? '');
|
||||
$name_th = trim($_POST['name_th'] ?? '');
|
||||
$name_en = trim($_POST['name_en'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$curriculum_id = intval($_POST['curriculum_id'] ?? 0);
|
||||
$faculty = trim($_POST['faculty'] ?? '');
|
||||
$graduated_institution = trim($_POST['graduated_institution'] ?? '');
|
||||
$previous_qualification = trim($_POST['previous_qualification'] ?? '');
|
||||
$enrollment_year = intval($_POST['enrollment_year'] ?? date('Y'));
|
||||
|
||||
if (empty($student_code) || empty($name_th) || empty($curriculum_id)) {
|
||||
$error = 'กรุณากรอกข้อมูลให้ครบถ้วน';
|
||||
} else {
|
||||
try {
|
||||
$stmt = getDB()->prepare("UPDATE students SET student_code=?, name_th=?, name_en=?, email=?, faculty=?, graduated_institution=?, curriculum_id=?, enrollment_year=?, previous_qualification=? WHERE id=?");
|
||||
$stmt->execute([$student_code, $name_th, $name_en, $email, $faculty, $graduated_institution, $curriculum_id, $enrollment_year, $previous_qualification ?: null, $id]);
|
||||
echo "<script>window.location.href='view.php?id=$id';</script>";
|
||||
exit;
|
||||
} catch (PDOException $e) {
|
||||
$error = 'เกิดข้อผิดพลาด: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="card">
|
||||
<div class="card-header bg-warning">
|
||||
<h4 class="mb-0"><i class="bi bi-pencil"></i> แก้ไขข้อมูลนักศึกษา</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
||||
<?php endif; ?>
|
||||
<form method="POST" class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">รหัสนักศึกษา <span class="text-danger">*</span></label>
|
||||
<input type="text" name="student_code" class="form-control" required value="<?= htmlspecialchars($student['student_code']) ?>">
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<label class="form-label">ชื่อ-นามสกุล (ภาษาไทย) <span class="text-danger">*</span></label>
|
||||
<input type="text" name="name_th" class="form-control" required value="<?= htmlspecialchars($student['name_th']) ?>">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">ชื่อ-นามสกุล (ภาษาอังกฤษ)</label>
|
||||
<input type="text" name="name_en" class="form-control" value="<?= htmlspecialchars($student['name_en']) ?>">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">อีเมล</label>
|
||||
<input type="email" name="email" class="form-control" value="<?= htmlspecialchars($student['email'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">สาขาวิชา <span class="text-danger">*</span></label>
|
||||
<select name="curriculum_id" class="form-select" required>
|
||||
<option value="">-- เลือกสาขาวิชา --</option>
|
||||
<?php foreach ($curricula as $c): ?>
|
||||
<option value="<?= $c['id'] ?>" <?= $c['id'] == $student['curriculum_id'] ? 'selected' : '' ?>><?= htmlspecialchars($c['code']) ?> - <?= htmlspecialchars($c['name_th']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">คณะ</label>
|
||||
<select name="faculty" class="form-select">
|
||||
<option value="">-- เลือกคณะ --</option>
|
||||
<option value="คณะนวัตกรรมดิจิทัลเทคโนโลยี" <?= $student['faculty'] == 'คณะนวัตกรรมดิจิทัลเทคโนโลยี' ? 'selected' : '' ?>>คณะนวัตกรรมดิจิทัลเทคโนโลยี (12)</option>
|
||||
<option value="คณะบริหารธุรกิจ" <?= $student['faculty'] == 'คณะบริหารธุรกิจ' ? 'selected' : '' ?>>คณะบริหารธุรกิจ (11)</option>
|
||||
<option value="คณะศึกษาศาสตร์และศิลปศาสตร์" <?= $student['faculty'] == 'คณะศึกษาศาสตร์และศิลปศาสตร์' ? 'selected' : '' ?>>คณะศึกษาศาสตร์และศิลปศาสตร์ (13)</option>
|
||||
<option value="คณะบัญชี" <?= $student['faculty'] == 'คณะบัญชี' ? 'selected' : '' ?>>คณะบัญชี (14)</option>
|
||||
<option value="คณะนิติศาสตร์และรัฐศาสตร์" <?= $student['faculty'] == 'คณะนิติศาสตร์และรัฐศาสตร์' ? 'selected' : '' ?>>คณะนิติศาสตร์และรัฐศาสตร์ (15)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">ชื่อสถาบันที่จบ</label>
|
||||
<input type="text" name="graduated_institution" class="form-control" value="<?= htmlspecialchars($student['graduated_institution']) ?>">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">วุฒิเดิม</label>
|
||||
<select name="previous_qualification" class="form-select">
|
||||
<option value="">-- เลือกวุฒิเดิม --</option>
|
||||
<?php
|
||||
$quals = ['ม.6 (กศน,สกร)', 'ปวช.3', 'ปวส.2', 'ปริญญาตรีใบที่ 2'];
|
||||
foreach ($quals as $q):
|
||||
$sel = ($student['previous_qualification'] == $q) ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?= htmlspecialchars($q) ?>" <?= $sel ?>><?= htmlspecialchars($q) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">ปีการศึกษาที่เข้าศึกษา</label>
|
||||
<select name="enrollment_year" class="form-select">
|
||||
<?php for ($y = date('Y')+543; $y >= 2560; $y--): ?>
|
||||
<option value="<?= $y ?>" <?= $y == $student['enrollment_year'] ? 'selected' : '' ?>><?= $y ?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button type="submit" class="btn btn-warning"><i class="bi bi-save"></i> บันทึกการแก้ไข</button>
|
||||
<a href="view.php?id=<?= $id ?>" class="btn btn-secondary"><i class="bi bi-arrow-left"></i> กลับ</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php require_once __DIR__ . '/../includes/footer.php'; ?>
|
||||
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
$page_title = 'นำเข้า CSV';
|
||||
require_once __DIR__ . '/../includes/functions.php';
|
||||
requireLogin();
|
||||
|
||||
$student_id = intval($_GET['student_id'] ?? 0);
|
||||
|
||||
if (isset($_GET['template'])) {
|
||||
header('Content-Type: text/csv; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename=import_template.csv');
|
||||
echo "\xEF\xBB\xBF";
|
||||
$cols = $student_id ? ['course_code','course_name','credits','grade','course_type','semester','academic_year','lecture','practice','self_study','notes','group_id'] : ['student_code','course_code','course_name','credits','grade','course_type','semester','academic_year','lecture','practice','self_study','notes','group_id'];
|
||||
echo implode(',', $cols) . "\n";
|
||||
if ($student_id) {
|
||||
echo "1012301,การเขียนโปรแกรมเบื้องต้น,3,A,เรียนปกติ,1,2569,2,1,3,,\n";
|
||||
} else {
|
||||
echo "STU001,1012301,การเขียนโปรแกรมเบื้องต้น,3,A,เรียนปกติ,1,2569,2,1,3,,\n";
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($student_id) {
|
||||
requireStudentAccess($student_id);
|
||||
$student = getStudent($student_id);
|
||||
if (!$student) { echo '<div class="alert alert-danger">ไม่พบนักศึกษา</div>'; require_once __DIR__ . '/../includes/footer.php'; exit; }
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../includes/header.php';
|
||||
|
||||
$results = [];
|
||||
$total_success = 0;
|
||||
$total_error = 0;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file']) && $_FILES['csv_file']['error'] === UPLOAD_ERR_OK) {
|
||||
$tmp = $_FILES['csv_file']['tmp_name'];
|
||||
// Read all rows at once
|
||||
$all_rows = [];
|
||||
$handle = fopen($tmp, 'r');
|
||||
if ($handle) {
|
||||
while (($r = fgetcsv($handle)) !== false) $all_rows[] = $r;
|
||||
fclose($handle);
|
||||
}
|
||||
if (empty($all_rows)) { $results[] = 'ไฟล์ CSV ว่างเปล่า'; $total_error++; }
|
||||
else {
|
||||
$first = $all_rows[0];
|
||||
$first[0] = preg_replace('/^\xEF\xBB\xBF/', '', $first[0]);
|
||||
$first = array_map(function($v) { return trim($v, " \t\n\r\0\x0B\""); }, $first);
|
||||
// Auto-detect header: if first cell starts with a digit, it's data (no header)
|
||||
$has_header = !preg_match('/^\d/', $first[0]);
|
||||
if ($has_header) {
|
||||
$header_norm = array_map(function($v) {
|
||||
return preg_replace('/[^a-z0-9_]/', '', str_replace(' ', '_', strtolower(trim($v))));
|
||||
}, $first);
|
||||
$results[] = "พบหัวคอลัมน์: " . implode(', ', $first);
|
||||
$col_map = [];
|
||||
$expected = $student_id ? ['course_code','course_name','credits','grade','course_type','semester','academic_year','lecture','practice','self_study','notes','group_id'] : ['student_code','course_code','course_name','credits','grade','course_type','semester','academic_year','lecture','practice','self_study','notes','group_id'];
|
||||
foreach ($expected as $e) {
|
||||
$idx = array_search($e, $header_norm);
|
||||
if ($idx !== false) $col_map[$e] = $idx;
|
||||
}
|
||||
array_shift($all_rows);
|
||||
} else {
|
||||
$results[] = "ไม่พบแถวหัวคอลัมน์ — ใช้ตำแหน่งคอลัมน์ตามลำดับ";
|
||||
if ($student_id) {
|
||||
$col_map = ['course_code' => 0, 'course_name' => 1, 'credits' => 2, 'grade' => 3, 'course_type' => 4, 'semester' => 5, 'academic_year' => 6, 'lecture' => 7, 'practice' => 8, 'self_study' => 9, 'notes' => 10, 'group_id' => 11];
|
||||
} else {
|
||||
$col_map = ['student_code' => 0, 'course_code' => 1, 'course_name' => 2, 'credits' => 3, 'grade' => 4, 'course_type' => 5, 'semester' => 6, 'academic_year' => 7, 'lecture' => 8, 'practice' => 9, 'self_study' => 10, 'notes' => 11, 'group_id' => 12];
|
||||
}
|
||||
}
|
||||
$db = getDB();
|
||||
foreach ($all_rows as $idx => $row) {
|
||||
$line = $idx + 1;
|
||||
$c = fn($k) => $col_map[$k] ?? null;
|
||||
if ($student_id) {
|
||||
$student = getStudent($student_id);
|
||||
$student_code = $student['student_code'];
|
||||
} else {
|
||||
$student_code = trim($row[$c('student_code')] ?? '');
|
||||
}
|
||||
$course_code = trim($row[$c('course_code')] ?? '');
|
||||
$course_name = trim($row[$c('course_name')] ?? '');
|
||||
$credits = floatval($row[$c('credits')] ?? 0);
|
||||
$grade = trim($row[$c('grade')] ?? '');
|
||||
$course_type_col = trim($row[$c('course_type')] ?? '');
|
||||
$semester = trim($row[$c('semester')] ?? '');
|
||||
$academic_year = trim($row[$c('academic_year')] ?? '');
|
||||
$lecture = intval($row[$c('lecture')] ?? 0);
|
||||
$practice = intval($row[$c('practice')] ?? 0);
|
||||
$self_study = intval($row[$c('self_study')] ?? 0);
|
||||
$notes = trim($row[$c('notes')] ?? '');
|
||||
$group_id = intval($row[$c('group_id')] ?? 0);
|
||||
|
||||
if (empty($course_code) || empty($course_name) || $credits <= 0) {
|
||||
$results[] = "แถวที่ $line: ข้าม (ข้อมูลไม่ครบ: course_code, course_name, credits)";
|
||||
$total_error++;
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!$student_id) {
|
||||
$stmt = $db->prepare("SELECT id, curriculum_id, advisor_id FROM students WHERE student_code = ?");
|
||||
$stmt->execute([$student_code]);
|
||||
$student = $stmt->fetch();
|
||||
if (!$student) {
|
||||
$results[] = "แถวที่ $line: ไม่พบรหัสนักศึกษา '$student_code'";
|
||||
$total_error++;
|
||||
continue;
|
||||
}
|
||||
if (isAdvisor() && $student['advisor_id'] != getCurrentUserId()) {
|
||||
$results[] = "แถวที่ $line: นักศึกษา '$student_code' ไม่อยู่ในที่ปรึกษาของคุณ";
|
||||
$total_error++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$curriculum_course = findCourseInCurriculum($student['curriculum_id'], $course_code);
|
||||
$course_id = null;
|
||||
if ($curriculum_course) {
|
||||
$course_id = $curriculum_course['id'];
|
||||
} elseif ($group_id > 0) {
|
||||
$stmt = $db->prepare("SELECT id FROM courses WHERE group_id = ? AND code = ?");
|
||||
$stmt->execute([$group_id, $course_code]);
|
||||
$existing = $stmt->fetch();
|
||||
if ($existing) {
|
||||
$course_id = $existing['id'];
|
||||
} else {
|
||||
$stmt = $db->prepare("INSERT INTO courses (group_id, code, name_th, credits, lecture_hours, practice_hours, self_study_hours, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?, 0)");
|
||||
$stmt->execute([$group_id, $course_code, $course_name, $credits, $lecture, $practice, $self_study]);
|
||||
$course_id = $db->lastInsertId();
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = $db->prepare("INSERT INTO student_courses (student_id, course_id, course_code, course_name_th, credits, lecture_hours, practice_hours, self_study_hours, grade, course_type, semester, academic_year, source_type, notes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'manual', ?)");
|
||||
$stmt->execute([$student['id'], $course_id, $course_code, $course_name, $credits, $lecture, $practice, $self_study, $grade ?: null, $course_type_col ?: null, $semester ?: null, $academic_year ?: null, $notes]);
|
||||
$results[] = "แถวที่ $line: ✓ $student_code - $course_code ($course_name)";
|
||||
$total_success++;
|
||||
} catch (PDOException $e) {
|
||||
$results[] = "แถวที่ $line: ผิดพลาด - " . $e->getMessage();
|
||||
$total_error++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<h4><i class="bi bi-upload"></i> นำเข้ารายวิชาจากไฟล์ CSV</h4>
|
||||
<div class="text-muted small">รองรับไฟล์ .csv ตามรูปแบบคอลัมน์ที่ระบบกำหนด</div>
|
||||
</div>
|
||||
<a href="<?= $student_id ? 'view.php?id=' . $student_id : 'list.php' ?>" class="btn btn-secondary"><i class="bi bi-arrow-left"></i> กลับ</a>
|
||||
</div>
|
||||
|
||||
<?php if ($student_id): ?>
|
||||
<div class="alert alert-info">กำลังนำเข้าสำหรับนักศึกษา: <strong><?= htmlspecialchars($student['student_code'] ?? '') ?> - <?= htmlspecialchars($student['name_th'] ?? '') ?></strong> (ไม่ต้องระบุ student_code ใน CSV)</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="mb-0"><i class="bi bi-filetype-csv"></i> เลือกไฟล์สำหรับนำเข้า</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">เลือกไฟล์ CSV</label>
|
||||
<input type="file" name="csv_file" class="form-control" accept=".csv" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">รูปแบบไฟล์</label>
|
||||
<p class="text-muted small mb-2">ไฟล์ CSV ต้องมีหัวคอลัมน์ด้านล่างนี้ (คั่นด้วย comma):</p>
|
||||
<code class="d-block p-2 bg-light rounded small"><?= $student_id ? 'course_code,course_name,credits,grade,course_type,semester,academic_year,lecture,practice,self_study,notes,group_id' : 'student_code,course_code,course_name,credits,grade,course_type,semester,academic_year,lecture,practice,self_study,notes,group_id' ?></code>
|
||||
<p class="text-muted small mt-2 mb-0">คอลัมน์ที่จำเป็น: <strong><?= $student_id ? 'course_code, course_name, credits' : 'student_code, course_code, course_name, credits' ?></strong></p>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary"><i class="bi bi-cloud-upload"></i> นำเข้า</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mt-3">
|
||||
<div class="card-body">
|
||||
<p class="mb-1 fw-bold">📥 ดาวน์โหลด Template</p>
|
||||
<a href="import_csv.php?template=1<?= $student_id ? '&student_id=' . $student_id : '' ?>" class="btn btn-outline-success btn-sm"><i class="bi bi-download"></i> template.csv</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<?php if ($total_success > 0 || $total_error > 0): ?>
|
||||
<div class="card">
|
||||
<div class="card-header bg-<?= $total_error > 0 ? 'warning' : 'success' ?> text-white d-flex justify-content-between">
|
||||
<span><i class="bi bi-list-check"></i> ผลลัพธ์</span>
|
||||
<span>สำเร็จ <?= $total_success ?> | ล้มเหลว <?= $total_error ?></span>
|
||||
</div>
|
||||
<div class="card-body" style="max-height:500px;overflow-y:auto">
|
||||
<ul class="list-unstyled mb-0 small">
|
||||
<?php foreach ($results as $r): ?>
|
||||
<li class="mb-1 <?= str_starts_with($r, 'แถว') && str_contains($r, '✓') ? 'text-success' : (str_starts_with($r, 'แถว') ? 'text-danger' : 'text-muted') ?>"><?= htmlspecialchars($r) ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once __DIR__ . '/../includes/footer.php'; ?>
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
$page_title = 'รายชื่อนักศึกษา';
|
||||
require_once __DIR__ . '/../includes/functions.php';
|
||||
require_once __DIR__ . '/../includes/header.php';
|
||||
|
||||
$students = getStudents();
|
||||
$db = getDB();
|
||||
$credits_map = [];
|
||||
if (!empty($students)) {
|
||||
$ids = array_column($students, 'id');
|
||||
$placeholders = implode(',', array_fill(0, count($ids), '?'));
|
||||
$stmt = $db->prepare("
|
||||
SELECT
|
||||
student_id,
|
||||
COALESCE(SUM(CASE WHEN source_type = 'transfer' THEN credits ELSE 0 END), 0) AS transfer_total,
|
||||
COALESCE(SUM(CASE WHEN source_type = 'manual' THEN credits ELSE 0 END), 0) AS manual_total,
|
||||
COALESCE(SUM(credits), 0) AS total
|
||||
FROM student_courses
|
||||
WHERE student_id IN ($placeholders)
|
||||
GROUP BY student_id
|
||||
");
|
||||
$stmt->execute($ids);
|
||||
foreach ($stmt->fetchAll() as $row) {
|
||||
$credits_map[$row['student_id']] = [
|
||||
'transfer' => floatval($row['transfer_total']),
|
||||
'manual' => floatval($row['manual_total']),
|
||||
'total' => floatval($row['total'])
|
||||
];
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<h4><i class="bi bi-people"></i> รายชื่อนักศึกษา</h4>
|
||||
<div class="text-muted small">ทั้งหมด <?= count($students) ?> รายการ</div>
|
||||
</div>
|
||||
<a href="add.php" class="btn btn-primary"><i class="bi bi-person-plus"></i> เพิ่มนักศึกษา</a>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
|
||||
<h4 class="mb-0"><i class="bi bi-table"></i> ตารางข้อมูลนักศึกษา</h4>
|
||||
<span class="badge bg-primary"><?= count($students) ?> รายการ</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if (empty($students)): ?>
|
||||
<div class="alert alert-info">ยังไม่มีข้อมูลนักศึกษา <a href="add.php">คลิกเพิ่มนักศึกษา</a></div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-bordered">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>รหัสนักศึกษา</th>
|
||||
<th>ชื่อ-นามสกุล</th>
|
||||
<th>สาขาวิชา</th>
|
||||
<th>คณะ</th>
|
||||
<th>สถาบันที่จบ</th>
|
||||
<th>วุฒิเดิม</th>
|
||||
<th>ปีการศึกษา</th>
|
||||
<th class="text-center">หน่วยกิตที่เทียบโอน</th>
|
||||
<th class="text-center">หน่วยกิตที่เรียนแล้ว</th>
|
||||
<th class="text-center">หน่วยกิตทั้งหมดที่เทียบโอนและเรียนแล้ว</th>
|
||||
<th>การจัดการ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($students as $s): ?>
|
||||
<tr>
|
||||
<td><strong><?= htmlspecialchars($s['student_code']) ?></strong></td>
|
||||
<td><?= htmlspecialchars($s['name_th']) ?></td>
|
||||
<td><span class="badge bg-<?= $s['curriculum_code'] == 'DT' ? 'primary' : 'success' ?>"><?= htmlspecialchars($s['curriculum_code']) ?></span></td>
|
||||
<td><small><?= htmlspecialchars($s['faculty'] ?: '-') ?></small></td>
|
||||
<td><small><?= htmlspecialchars($s['graduated_institution'] ?: '-') ?></small></td>
|
||||
<td><small><?= htmlspecialchars($s['previous_qualification'] ?: '-') ?></small></td>
|
||||
<td><?= $s['enrollment_year'] ?></td>
|
||||
<td class="text-center"><?= $credits_map[$s['id']]['transfer'] ?? 0 ?></td>
|
||||
<td class="text-center"><?= $credits_map[$s['id']]['manual'] ?? 0 ?></td>
|
||||
<td class="text-center fw-bold"><?= $credits_map[$s['id']]['total'] ?? 0 ?></td>
|
||||
<td>
|
||||
<div class="action-buttons">
|
||||
<a href="view.php?id=<?= $s['id'] ?>" class="btn btn-info btn-sm"><i class="bi bi-eye"></i> ดูข้อมูล</a>
|
||||
<a href="edit.php?id=<?= $s['id'] ?>" class="btn btn-warning btn-sm"><i class="bi bi-pencil"></i> แก้ไข</a>
|
||||
<a href="delete.php?id=<?= $s['id'] ?>" class="btn btn-danger btn-sm" onclick="return confirm('ยืนยันการลบข้อมูลนักศึกษา?')"><i class="bi bi-trash"></i> ลบ</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php require_once __DIR__ . '/../includes/footer.php'; ?>
|
||||
@@ -0,0 +1,389 @@
|
||||
<?php
|
||||
$page_title = 'ข้อมูลนักศึกษา';
|
||||
require_once __DIR__ . '/../includes/functions.php';
|
||||
require_once __DIR__ . '/../includes/header.php';
|
||||
|
||||
$id = intval($_GET['id'] ?? 0);
|
||||
requireStudentAccess($id);
|
||||
$student = getStudent($id);
|
||||
if (!$student) {
|
||||
echo '<div class="alert alert-danger">ไม่พบข้อมูลนักศึกษา</div>';
|
||||
require_once __DIR__ . '/../includes/footer.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_GET['added'])) {
|
||||
$msg_class = 'success';
|
||||
$msg_text = 'เพิ่มรายวิชาเรียบร้อยแล้ว';
|
||||
if ($_GET['added'] === '0') $msg_text = 'ไม่พบรายวิชาใหม่จากไฟล์ (อาจซ้ำหรือไม่ตรงหลักสูตร)';
|
||||
echo "<div class='alert alert-$msg_class alert-dismissible fade show'>$msg_text<button type='button' class='btn-close' data-bs-dismiss='alert'></button></div>";
|
||||
}
|
||||
if (isset($_GET['error'])) {
|
||||
$err = $_GET['error'];
|
||||
$map = ['upload_failed' => 'อัปโหลดไฟล์ล้มเหลว', 'no_text' => 'ไม่พบข้อความในไฟล์ PDF', 'invalid_data' => 'ข้อมูลไม่ถูกต้อง'];
|
||||
$txt = $map[$err] ?? $err;
|
||||
echo "<div class='alert alert-danger alert-dismissible fade show'>$txt<button type='button' class='btn-close' data-bs-dismiss='alert'></button></div>";
|
||||
}
|
||||
|
||||
$summary = getStudentSummary($id);
|
||||
$student_courses = getStudentCourses($id);
|
||||
|
||||
// เรียง: ลงเรียนปกติ+ยังไม่ออกเกรด → เทียบโอน/ออกเกรดแล้ว
|
||||
usort($student_courses, function($a, $b) {
|
||||
$isUngraded = fn($r) => $r['grade'] === null || $r['grade'] === '' || $r['grade'] === '-' || mb_strpos((string)$r['grade'], 'กำลัง') === 0;
|
||||
$a_ungraded = $isUngraded($a);
|
||||
$b_ungraded = $isUngraded($b);
|
||||
if ($a_ungraded && !$b_ungraded) return -1;
|
||||
if (!$a_ungraded && $b_ungraded) return 1;
|
||||
return strcasecmp($a['course_code'], $b['course_code']);
|
||||
});
|
||||
|
||||
$total_curriculum_credits = getTotalCurriculumCredits($student['curriculum_id']);
|
||||
$total_completed = getCompletedCreditsTotal($id);
|
||||
$transfer_credits = getTransferCreditsTotal($id);
|
||||
$remaining_credits = max(0, $total_curriculum_credits - $total_completed);
|
||||
$is_dbc = ($student['curriculum_code'] == 'DBC');
|
||||
?>
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<h4><i class="bi bi-person-vcard"></i> <?= htmlspecialchars($student['student_code']) ?> - <?= htmlspecialchars($student['name_th']) ?></h4>
|
||||
<div class="text-muted small"><?= htmlspecialchars($student['curriculum_code']) ?> - <?= htmlspecialchars($student['curriculum_name']) ?></div>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<a href="edit.php?id=<?= $id ?>" class="btn btn-warning btn-sm"><i class="bi bi-pencil"></i> แก้ไข</a>
|
||||
<a href="<?= BASE_URL ?>/reports/transfer_report.php?student_id=<?= $id ?>" class="btn btn-dark btn-sm" target="_blank"><i class="bi bi-file-earmark-text"></i> ผลการประเมินเทียบโอน</a>
|
||||
<a href="<?= BASE_URL ?>/reports/print_summary.php?student_id=<?= $id ?>" class="btn btn-primary btn-sm" target="_blank"><i class="bi bi-printer"></i> พิมพ์สรุปผล</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header bg-info text-white d-flex justify-content-between align-items-center">
|
||||
<h4 class="mb-0"><i class="bi bi-person-vcard"></i> ข้อมูลนักศึกษา</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-sm table-borderless">
|
||||
<tr><td style="width:180px;"><strong>รหัสนักศึกษา:</strong></td><td><?= htmlspecialchars($student['student_code']) ?></td></tr>
|
||||
<tr><td><strong>ชื่อ-นามสกุล:</strong></td><td><?= htmlspecialchars($student['name_th']) ?> (<?= htmlspecialchars($student['name_en']) ?>)</td></tr>
|
||||
<tr><td><strong>อีเมล:</strong></td><td><?= htmlspecialchars($student['email'] ?? '-') ?></td></tr>
|
||||
<tr><td><strong>สาขาวิชา:</strong></td><td><span class="badge bg-<?= $is_dbc ? 'success' : 'primary' ?> fs-6"><?= htmlspecialchars($student['curriculum_code']) ?> - <?= htmlspecialchars($student['curriculum_name']) ?></span></td></tr>
|
||||
<tr><td><strong>คณะ:</strong></td><td><?= htmlspecialchars($student['faculty'] ?: '-') ?></td></tr>
|
||||
<tr><td><strong>สถาบันที่จบ:</strong></td><td><?= htmlspecialchars($student['graduated_institution'] ?: '-') ?></td></tr>
|
||||
<tr><td><strong>วุฒิเดิม:</strong></td><td><?= htmlspecialchars($student['previous_qualification'] ?: '-') ?></td></tr>
|
||||
<tr><td><strong>ปีการศึกษาที่เข้าศึกษา:</strong></td><td><?= $student['enrollment_year'] ?></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card stat-card mb-3"><div class="card-body">
|
||||
<span class="stat-icon"><i class="bi bi-arrow-left-right"></i></span>
|
||||
<div class="stat-label">หน่วยกิตที่เทียบโอนได้</div>
|
||||
<div class="stat-value"><?= $transfer_credits ?></div>
|
||||
</div></div>
|
||||
<div class="card stat-card mb-3"><div class="card-body">
|
||||
<span class="stat-icon"><i class="bi bi-check2-circle"></i></span>
|
||||
<div class="stat-label">หน่วยกิตที่เรียนผ่านแล้วทั้งหมด</div>
|
||||
<div class="stat-value"><?= $total_completed ?></div>
|
||||
</div></div>
|
||||
<div class="card stat-card"><div class="card-body">
|
||||
<span class="stat-icon"><i class="bi bi-mortarboard"></i></span>
|
||||
<div class="stat-label">หน่วยกิตที่ต้องเรียนอีก</div>
|
||||
<div class="stat-value"><?= $remaining_credits ?> / <?= $total_curriculum_credits ?></div>
|
||||
<div class="progress mt-2" style="height: 12px;">
|
||||
<div class="progress-bar bg-success" style="width: <?= min(100, ($total_completed / $total_curriculum_credits) * 100) ?>%">
|
||||
<?= $total_curriculum_credits > 0 ? round(($total_completed / $total_curriculum_credits) * 100) : 0 ?>%
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
<div class="card">
|
||||
<div class="card-header bg-<?= $is_dbc ? 'success' : 'primary' ?> text-white">
|
||||
<h5 class="mb-0"><i class="bi bi-journal-text"></i> รายวิชาตามหลักสูตร</h5>
|
||||
</div>
|
||||
<div class="card-body" style="max-height: 650px; overflow-y: auto;">
|
||||
<div class="small text-muted mb-2">
|
||||
<span class="badge bg-success"><i class="bi bi-check-circle"></i> เรียนแล้ว</span>
|
||||
<span class="badge bg-warning text-dark"><i class="bi bi-check-circle"></i> เทียบโอน</span>
|
||||
<span class="badge bg-secondary">ยังไม่เรียน</span>
|
||||
</div>
|
||||
<?php renderStudentTree($summary['groups']); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<div class="card mb-3 border-warning">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<h5 class="mb-0"><i class="bi bi-file-earmark-arrow-up"></i> นำเข้าข้อมูลเทียบโอน</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- Nav Tabs -->
|
||||
<ul class="nav nav-pills nav-justified mb-3" id="importTab" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active btn-sm" id="upload-tab" data-bs-toggle="tab" data-bs-target="#upload" type="button" role="tab" aria-controls="upload" aria-selected="true"><i class="bi bi-upload"></i> อัปโหลด PDF</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link btn-sm" id="paste-tab" data-bs-toggle="tab" data-bs-target="#paste" type="button" role="tab" aria-controls="paste" aria-selected="false"><i class="bi bi-clipboard-plus"></i> คัดลอกข้อความวาง</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" id="importTabContent">
|
||||
<!-- Tab 1: Upload File -->
|
||||
<div class="tab-pane fade show active" id="upload" role="tabpanel" aria-labelledby="upload-tab">
|
||||
<form action="<?= BASE_URL ?>/api/upload_pdf.php" method="POST" enctype="multipart/form-data" class="mb-2">
|
||||
<input type="hidden" name="student_id" value="<?= $id ?>">
|
||||
<div class="mb-3">
|
||||
<label class="form-label small text-muted">เลือกไฟล์ PDF รายวิชาที่เทียบโอน</label>
|
||||
<input type="file" name="pdf_file" class="form-control form-control-sm" accept=".pdf" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-warning btn-sm w-100"><i class="bi bi-cloud-upload"></i> อัปโหลดและวิเคราะห์</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Tab 2: Paste Text -->
|
||||
<div class="tab-pane fade" id="paste" role="tabpanel" aria-labelledby="paste-tab">
|
||||
<form action="<?= BASE_URL ?>/api/upload_text.php" method="POST" class="mb-2">
|
||||
<input type="hidden" name="student_id" value="<?= $id ?>">
|
||||
<div class="mb-3">
|
||||
<label class="form-label small text-muted">เปิดไฟล์ PDF คัดลอกข้อความทั้งหมด (Ctrl+A -> Ctrl+C) แล้ววางที่นี่</label>
|
||||
<textarea name="pdf_text" class="form-control form-control-sm" rows="5" placeholder="วางข้อความจาก PDF ที่นี่..." required></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-dark btn-sm w-100"><i class="bi bi-clipboard-check"></i> วิเคราะห์จากข้อความที่วาง</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info small mb-0 mt-2 p-2" style="font-size: 11px;">
|
||||
<i class="bi bi-info-circle"></i> ระบบจะอ่านรหัสวิชา ชื่อวิชา และหน่วยกิตโดยอัตโนมัติ เฉพาะรายวิชาที่ตรงตามหลักสูตรจะได้รับการเทียบโอน
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3 border-success">
|
||||
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0"><i class="bi bi-plus-circle"></i> เพิ่มรายวิชาที่กำลังเรียน</h5>
|
||||
<a href="import_csv.php?student_id=<?= $id ?>" class="btn btn-light btn-sm"><i class="bi bi-upload"></i> นำเข้า CSV</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="POST" action="<?= BASE_URL ?>/api/add_manual_course.php">
|
||||
<input type="hidden" name="student_id" value="<?= $id ?>">
|
||||
<div class="mb-2">
|
||||
<label class="form-label">รหัสวิชา</label>
|
||||
<input type="text" name="course_code" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">ชื่อวิชา</label>
|
||||
<input type="text" name="course_name" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">หมวดวิชา (เลือกถ้าต้องการให้แสดงในกลุ่มที่ถูกต้อง)</label>
|
||||
<select name="group_id" class="form-select">
|
||||
<option value="">-- อัตโนมัติ (จับคู่ตามรหัสวิชา) --</option>
|
||||
<?= getGroupSelectOptions($student['curriculum_id']) ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">หน่วยกิต</label>
|
||||
<input type="number" name="credits" class="form-control" step="0.5" required>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-4">
|
||||
<label class="form-label">บรรยาย</label>
|
||||
<input type="number" name="lecture" class="form-control" value="0">
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<label class="form-label">ปฏิบัติ</label>
|
||||
<input type="number" name="practice" class="form-control" value="0">
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<label class="form-label">ศึกษาด้วยตนเอง</label>
|
||||
<input type="number" name="self_study" class="form-control" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-6">
|
||||
<label class="form-label">เกรดที่ได้</label>
|
||||
<select name="grade" class="form-select">
|
||||
<option value="">-- เลือก --</option>
|
||||
<?= getGradeOptions() ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">ประเภท</label>
|
||||
<select name="course_type" class="form-select">
|
||||
<option value="">-- เลือก --</option>
|
||||
<?= getCourseTypeOptions() ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-6">
|
||||
<label class="form-label">ภาคเรียน</label>
|
||||
<select name="semester" class="form-select">
|
||||
<option value="">-- ไม่ระบุ --</option>
|
||||
<option value="1">ภาคเรียนที่ 1</option>
|
||||
<option value="2">ภาคเรียนที่ 2</option>
|
||||
<option value="summer">ภาคฤดูร้อน</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">ปีการศึกษา</label>
|
||||
<select name="academic_year" class="form-select">
|
||||
<option value="">-- ไม่ระบุ --</option>
|
||||
<?php for ($y = 2569; $y >= 2565; $y--): ?>
|
||||
<option value="<?= $y ?>"><?= $y ?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">หมายเหตุ</label>
|
||||
<textarea name="notes" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success"><i class="bi bi-plus-lg"></i> เพิ่มรายวิชา</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header bg-secondary text-white d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0"><i class="bi bi-list-check"></i> รายวิชาเทียบโอนและกำลังเรียนรอออกเกรด</h5>
|
||||
<?php
|
||||
$ungraded_total = 0;
|
||||
foreach ($student_courses as $sc_tmp) {
|
||||
if ($sc_tmp['grade'] === null || $sc_tmp['grade'] === '' || $sc_tmp['grade'] === '-' || mb_strpos((string)$sc_tmp['grade'], 'กำลัง') === 0) {
|
||||
$ungraded_total++;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div>
|
||||
<?php if ($ungraded_total > 0): ?>
|
||||
<span class="badge bg-warning text-dark"><i class="bi bi-exclamation-triangle-fill"></i> รอออกเกรด <?= $ungraded_total ?> วิชา</span>
|
||||
<?php endif; ?>
|
||||
<span class="badge bg-light text-dark"><?= count($student_courses) ?> รายการ | <?= $total_completed ?> หน่วยกิต</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body" style="max-height: 400px; overflow-y: auto;">
|
||||
<?php if (empty($student_courses)): ?>
|
||||
<div class="text-muted text-center py-3">ยังไม่มีรายวิชาที่บันทึก</div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>รหัสวิชา</th>
|
||||
<th>ชื่อวิชา</th>
|
||||
<th>หน่วยกิต</th>
|
||||
<th>เกรด</th>
|
||||
<th>ภาคเรียน</th>
|
||||
<th>ปีการศึกษา</th>
|
||||
<th>ประเภท</th>
|
||||
<th style="width:40px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$t = 0;
|
||||
$ungraded_count = 0;
|
||||
$graded_count = 0;
|
||||
$isUngraded2 = fn($r) => $r['grade'] === null || $r['grade'] === '' || $r['grade'] === '-' || mb_strpos((string)$r['grade'], 'กำลัง') === 0;
|
||||
foreach ($student_courses as $sc_check) {
|
||||
if ($isUngraded2($sc_check)) $ungraded_count++;
|
||||
else $graded_count++;
|
||||
}
|
||||
$printed_ungraded_header = false;
|
||||
$printed_separator = false;
|
||||
foreach ($student_courses as $sc):
|
||||
$t += $sc['credits'];
|
||||
$is_ungraded = $isUngraded2($sc);
|
||||
if ($is_ungraded && !$printed_ungraded_header) {
|
||||
$printed_ungraded_header = true;
|
||||
echo '<tr class="table-secondary"><td colspan="8" class="text-center small py-1"><i class="bi bi-clock-history"></i> รายวิชาที่กำลังเรียน/รอออกเกรด</td></tr>';
|
||||
}
|
||||
if (!$is_ungraded && !$printed_separator && $printed_ungraded_header) {
|
||||
$printed_separator = true;
|
||||
echo '<tr class="table-dark"><td colspan="8" class="text-center small py-1"><i class="bi bi-check-all"></i> รายวิชาที่เทียบโอน/ออกเกรดแล้ว</td></tr>';
|
||||
}
|
||||
?>
|
||||
<tr class="<?= $is_ungraded ? 'table-warning' : '' ?>">
|
||||
<td>
|
||||
<?php if ($is_ungraded): ?><i class="bi bi-exclamation-triangle-fill text-warning me-1" title="ยังไม่ออกเกรด"></i><?php endif; ?>
|
||||
<code><?= htmlspecialchars($sc['course_code']) ?></code>
|
||||
</td>
|
||||
<td class="small"><?= htmlspecialchars($sc['course_name_th']) ?></td>
|
||||
<td><?= $sc['credits'] ?></td>
|
||||
<td>
|
||||
<form method="POST" action="<?= BASE_URL ?>/api/update_grade.php" class="d-inline">
|
||||
<input type="hidden" name="id" value="<?= $sc['id'] ?>">
|
||||
<input type="hidden" name="student_id" value="<?= $id ?>">
|
||||
<select name="grade" class="form-select form-select-sm <?= $is_ungraded ? 'border-warning' : '' ?>" style="width:auto;min-width:60px" onchange="this.form.submit()">
|
||||
<option value="">-</option>
|
||||
<?php $grades = ['A','B+','B','C+','C','D+','D','F','S','U','กำลังเรียน']; foreach ($grades as $g): ?>
|
||||
<option value="<?= $g ?>" <?= $sc['grade'] == $g ? 'selected' : '' ?>><?= $g ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</form>
|
||||
</td>
|
||||
<td class="small"><?= htmlspecialchars($sc['semester'] ? 'ภาค ' . $sc['semester'] : '-') ?></td>
|
||||
<td class="small"><?= htmlspecialchars($sc['academic_year'] ?: '-') ?></td>
|
||||
<td><span class="badge bg-<?= $sc['source_type'] == 'transfer' ? 'warning text-dark' : 'success' ?>"><?= htmlspecialchars($sc['course_type'] ?: ($sc['source_type'] == 'transfer' ? 'เทียบโอน' : 'เรียนแล้ว')) ?></span></td>
|
||||
<td><a href="<?= BASE_URL ?>/api/delete_course.php?id=<?= $sc['id'] ?>&student_id=<?= $id ?>" class="btn btn-danger btn-sm py-0 px-1" onclick="return confirm('ลบรายวิชานี้?')"><i class="bi bi-x"></i></a></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<tfoot class="table-secondary fw-bold">
|
||||
<tr><td colspan="2" class="text-end">รวม</td><td><?= $t ?></td><td colspan="5"></td></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php require_once __DIR__ . '/../includes/footer.php'; ?>
|
||||
|
||||
<?php
|
||||
function renderStudentTree($nodes, $level = 0) {
|
||||
foreach ($nodes as $node) {
|
||||
$g = $node['group'];
|
||||
echo '<div class="mb-2" style="margin-left: ' . ($level * 15) . 'px;">';
|
||||
echo '<div class="fw-bold small text-secondary">' . htmlspecialchars($g['name_th']);
|
||||
if ($g['min_credits'] > 0) {
|
||||
echo ' <small class="text-muted">(' . $g['min_credits'] . ' หน่วยกิต)</small>';
|
||||
}
|
||||
echo '</div>';
|
||||
|
||||
foreach ($node['courses'] as $course) {
|
||||
$status_class = '';
|
||||
$status_badge = '<span class="badge bg-secondary status-badge">ยังไม่เรียน</span>';
|
||||
if (isset($course['_completed'])) {
|
||||
$sc = $course['_completed'];
|
||||
$label = $sc['course_type'] ?: ($sc['source_type'] == 'transfer' ? 'เทียบโอน' : 'เรียนแล้ว');
|
||||
$grade_part = $sc['grade'] ? ' เกรด ' . htmlspecialchars($sc['grade']) : '';
|
||||
if ($sc['source_type'] == 'transfer') {
|
||||
$status_class = 'bg-warning bg-opacity-10';
|
||||
$status_badge = '<span class="badge bg-warning text-dark status-badge"><i class="bi bi-check-circle"></i> ' . $label . $grade_part . '</span>';
|
||||
} else {
|
||||
$status_class = 'bg-success bg-opacity-10';
|
||||
$status_badge = '<span class="badge bg-success status-badge"><i class="bi bi-check-circle"></i> ' . $label . $grade_part . '</span>';
|
||||
}
|
||||
}
|
||||
echo '<div class="course-item d-flex justify-content-between align-items-center py-1 px-2 ' . $status_class . '">';
|
||||
echo '<div><code>' . htmlspecialchars($course['code']) . '</code> <span class="small">' . htmlspecialchars($course['name_th']) . '</span></div>';
|
||||
echo '<div><span class="badge-credit small">' . $course['credits'] . '(' . $course['lecture_hours'] . '-' . $course['practice_hours'] . '-' . $course['self_study_hours'] . ')</span> ' . $status_badge . '</div>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
if (!empty($node['children'])) {
|
||||
renderStudentTree($node['children'], $level + 1);
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user