fix attendance coemment in report card
This commit is contained in:
@@ -317,18 +317,27 @@ class ReportCardsController extends PrintablesBaseController
|
|||||||
$examCommentTypes = $isSecond
|
$examCommentTypes = $isSecond
|
||||||
? ['final']
|
? ['final']
|
||||||
: ($isFirst ? ['midterm'] : ['midterm', 'final']);
|
: ($isFirst ? ['midterm'] : ['midterm', 'final']);
|
||||||
$commentTypes = array_merge($examCommentTypes, ['ptap', 'attendance', 'attendance_comment']);
|
$wantedCommentTypes = array_merge($examCommentTypes, ['ptap', 'attendance']);
|
||||||
$hasCommentReview = $this->db->fieldExists('comment_review', 'score_comments');
|
$hasCommentReview = $this->db->fieldExists('comment_review', 'score_comments');
|
||||||
$commentSelect = $hasCommentReview
|
$hasCommentSemester = $this->db->fieldExists('semester', 'score_comments');
|
||||||
? 'student_id, score_type, comment, comment_review'
|
$hasCommentUpdatedAt = $this->db->fieldExists('updated_at', 'score_comments');
|
||||||
: 'student_id, score_type, comment';
|
$commentSelectParts = ['student_id', 'score_type', 'comment'];
|
||||||
|
if ($hasCommentReview) {
|
||||||
|
$commentSelectParts[] = 'comment_review';
|
||||||
|
}
|
||||||
|
if ($hasCommentSemester) {
|
||||||
|
$commentSelectParts[] = 'semester';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do NOT filter comments by score_type or semester here.
|
||||||
|
// A single bad row like "Attendance Comment", "attendance-comment", or a blank semester
|
||||||
|
// should not make one student look incomplete while the PDF can still print the comment.
|
||||||
$commentBuilder = $this->scoreCommentModel
|
$commentBuilder = $this->scoreCommentModel
|
||||||
->select($commentSelect)
|
->select(implode(', ', $commentSelectParts))
|
||||||
->whereIn('student_id', $studentIds)
|
->whereIn('student_id', $studentIds)
|
||||||
->where('school_year', $year)
|
->where('school_year', $year);
|
||||||
->whereIn('score_type', $commentTypes);
|
if ($hasCommentUpdatedAt) {
|
||||||
if ($sem !== '') {
|
$commentBuilder->orderBy('updated_at', 'DESC');
|
||||||
$this->applySemesterFilter($commentBuilder, $sem, 'semester');
|
|
||||||
}
|
}
|
||||||
$commentRows = [];
|
$commentRows = [];
|
||||||
try {
|
try {
|
||||||
@@ -336,25 +345,92 @@ class ReportCardsController extends PrintablesBaseController
|
|||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cleanComment = static function ($value): string {
|
||||||
|
$text = (string)($value ?? '');
|
||||||
|
$text = str_replace("\xc2\xa0", ' ', $text); // normalize non-breaking spaces
|
||||||
|
return trim($text);
|
||||||
|
};
|
||||||
|
|
||||||
|
$normalizeCommentType = static function ($value) use ($cleanComment): string {
|
||||||
|
$type = strtolower($cleanComment($value));
|
||||||
|
$type = preg_replace('/[^a-z0-9]+/', '_', $type);
|
||||||
|
$type = trim((string)$type, '_');
|
||||||
|
|
||||||
|
$map = [
|
||||||
|
'attendance_comment' => 'attendance',
|
||||||
|
'attendance_comments' => 'attendance',
|
||||||
|
'attendance' => 'attendance',
|
||||||
|
'attendence' => 'attendance',
|
||||||
|
'attendence_comment' => 'attendance',
|
||||||
|
'attendence_comments' => 'attendance',
|
||||||
|
'ptap_comment' => 'ptap',
|
||||||
|
'ptap_comments' => 'ptap',
|
||||||
|
'ptap' => 'ptap',
|
||||||
|
'midterm_comment' => 'midterm',
|
||||||
|
'midterm_comments' => 'midterm',
|
||||||
|
'midterm' => 'midterm',
|
||||||
|
'final_comment' => 'final',
|
||||||
|
'final_comments' => 'final',
|
||||||
|
'final' => 'final',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $map[$type] ?? $type;
|
||||||
|
};
|
||||||
|
|
||||||
|
$normalizeSemester = static function ($value) use ($cleanComment): string {
|
||||||
|
$v = strtolower($cleanComment($value));
|
||||||
|
$v = preg_replace('/[^a-z0-9]+/', ' ', $v);
|
||||||
|
$v = trim((string)$v);
|
||||||
|
if (in_array($v, ['fall', 'first', 'first semester', 'semester 1', '1'], true)) {
|
||||||
|
return 'fall';
|
||||||
|
}
|
||||||
|
if (in_array($v, ['spring', 'second', 'second semester', 'semester 2', '2'], true)) {
|
||||||
|
return 'spring';
|
||||||
|
}
|
||||||
|
return $v;
|
||||||
|
};
|
||||||
|
$wantedSemester = $normalizeSemester($sem);
|
||||||
|
|
||||||
$commentsByStudent = [];
|
$commentsByStudent = [];
|
||||||
|
$commentPriorityByStudent = [];
|
||||||
foreach ($commentRows as $row) {
|
foreach ($commentRows as $row) {
|
||||||
$sid = (int)($row['student_id'] ?? 0);
|
$sid = (int)($row['student_id'] ?? 0);
|
||||||
if ($sid <= 0) {
|
if ($sid <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$typeRaw = strtolower(trim((string)($row['score_type'] ?? '')));
|
|
||||||
if ($typeRaw === '') {
|
$typeRaw = $normalizeCommentType($row['score_type'] ?? '');
|
||||||
|
if ($typeRaw === '' || !in_array($typeRaw, $wantedCommentTypes, true)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($typeRaw === 'attendance_comment') {
|
|
||||||
$typeRaw = 'attendance';
|
$rawVal = $cleanComment($row['comment'] ?? '');
|
||||||
|
if ($typeRaw === 'attendance') {
|
||||||
|
// Attendance comments are stored in score_comments.comment.
|
||||||
|
// Do not use comment_review here, because it can be blank while the PDF comment exists.
|
||||||
|
$commentVal = $rawVal;
|
||||||
|
} else {
|
||||||
|
// For non-attendance comments, prefer reviewed text but fall back to the saved comment.
|
||||||
|
$reviewVal = $hasCommentReview ? $cleanComment($row['comment_review'] ?? '') : '';
|
||||||
|
$commentVal = $reviewVal !== '' ? $reviewVal : $rawVal;
|
||||||
}
|
}
|
||||||
$reviewVal = $hasCommentReview ? trim((string)($row['comment_review'] ?? '')) : '';
|
|
||||||
$commentVal = $hasCommentReview ? $reviewVal : trim((string)($row['comment'] ?? ''));
|
|
||||||
if ($commentVal === '') {
|
if ($commentVal === '') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$rowSemester = $hasCommentSemester ? $normalizeSemester($row['semester'] ?? '') : '';
|
||||||
|
$priority = 1;
|
||||||
|
if ($wantedSemester !== '' && $rowSemester === $wantedSemester) {
|
||||||
|
$priority = 3;
|
||||||
|
} elseif ($rowSemester === '') {
|
||||||
|
$priority = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingPriority = $commentPriorityByStudent[$sid][$typeRaw] ?? 0;
|
||||||
|
if (!isset($commentsByStudent[$sid][$typeRaw]) || $priority >= $existingPriority) {
|
||||||
$commentsByStudent[$sid][$typeRaw] = $commentVal;
|
$commentsByStudent[$sid][$typeRaw] = $commentVal;
|
||||||
|
$commentPriorityByStudent[$sid][$typeRaw] = $priority;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$isNumeric = static fn($v) => $v !== null && $v !== '' && is_numeric($v);
|
$isNumeric = static fn($v) => $v !== null && $v !== '' && is_numeric($v);
|
||||||
@@ -467,6 +543,20 @@ class ReportCardsController extends PrintablesBaseController
|
|||||||
if (trim((string)($commentSet['ptap'] ?? '')) === '') {
|
if (trim((string)($commentSet['ptap'] ?? '')) === '') {
|
||||||
$missing[] = 'PTAP comment';
|
$missing[] = 'PTAP comment';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep completeness consistent with the PDF report generation:
|
||||||
|
// the report can auto-generate an attendance comment from attendance_score.
|
||||||
|
if (trim((string)($commentSet['attendance'] ?? '')) === '' && $isNumeric($attendanceScore)) {
|
||||||
|
$autoAttendance = attendance_comment_from_score(
|
||||||
|
(float)$attendanceScore,
|
||||||
|
trim((string)($student['firstname'] ?? ''))
|
||||||
|
);
|
||||||
|
if ($autoAttendance !== null && trim((string)$autoAttendance) !== '') {
|
||||||
|
$commentSet['attendance'] = $autoAttendance;
|
||||||
|
$warnings[] = 'Attendance comment computed from attendance score';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (trim((string)($commentSet['attendance'] ?? '')) === '') {
|
if (trim((string)($commentSet['attendance'] ?? '')) === '') {
|
||||||
$missing[] = 'Attendance comment';
|
$missing[] = 'Attendance comment';
|
||||||
}
|
}
|
||||||
@@ -1531,10 +1621,16 @@ $scoresEndY = $pdf->GetY();
|
|||||||
if ($typeRaw === 'attendance_comment') {
|
if ($typeRaw === 'attendance_comment') {
|
||||||
$typeRaw = 'attendance';
|
$typeRaw = 'attendance';
|
||||||
}
|
}
|
||||||
|
$rawComment = trim((string)($row['comment'] ?? ''));
|
||||||
|
if ($typeRaw === 'attendance') {
|
||||||
|
// Attendance comments must come from score_comments.comment.
|
||||||
|
$commentVal = $rawComment;
|
||||||
|
} else {
|
||||||
$reviewVal = trim((string)($row['comment_review'] ?? ''));
|
$reviewVal = trim((string)($row['comment_review'] ?? ''));
|
||||||
$commentVal = $this->db->fieldExists('comment_review', 'score_comments')
|
$commentVal = $this->db->fieldExists('comment_review', 'score_comments') && $reviewVal !== ''
|
||||||
? $reviewVal
|
? $reviewVal
|
||||||
: trim((string)($row['comment'] ?? ''));
|
: $rawComment;
|
||||||
|
}
|
||||||
if ($commentVal === '') {
|
if ($commentVal === '') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user