fix class progress unit numbers calculation

This commit is contained in:
root
2026-03-31 00:16:55 -04:00
parent d2abbc1458
commit ed67836701
2 changed files with 85 additions and 39 deletions
+84 -38
View File
@@ -432,13 +432,11 @@ class AdminProgressController extends BaseController
$allowedSubjects = array_values(array_filter($allowedSubjects));
$counts = [];
$latestWeekBySection = [];
$sectionClassMap = [];
foreach ($rows as $row) {
$sectionId = (int) ($row['class_section_id'] ?? 0);
$subject = (string) ($row['subject'] ?? '');
$weekStart = (string) ($row['week_start'] ?? '');
if ($sectionId === 0 || $subject === '' || $weekStart === '') {
if ($sectionId === 0 || $subject === '') {
continue;
}
if (! empty($allowedSubjects) && ! in_array($subject, $allowedSubjects, true)) {
@@ -447,45 +445,41 @@ class AdminProgressController extends BaseController
if (! isset($sectionClassMap[$sectionId])) {
$sectionClassMap[$sectionId] = $this->classSectionModel->getClassId($sectionId);
}
if (
! isset($latestWeekBySection[$sectionId])
|| $weekStart > $latestWeekBySection[$sectionId]
) {
$latestWeekBySection[$sectionId] = $weekStart;
}
}
$curriculumChapters = $this->buildCurriculumChapterMap(array_values(array_filter($sectionClassMap)));
$curriculumUnits = $this->buildCurriculumUnitMap(array_values(array_filter($sectionClassMap)));
foreach ($rows as $row) {
$sectionId = (int) ($row['class_section_id'] ?? 0);
$subject = (string) ($row['subject'] ?? '');
$weekStart = (string) ($row['week_start'] ?? '');
if ($sectionId === 0 || $subject === '' || $weekStart === '') {
if ($sectionId === 0 || $subject === '') {
continue;
}
if (! empty($allowedSubjects) && ! in_array($subject, $allowedSubjects, true)) {
continue;
}
if (empty($latestWeekBySection[$sectionId]) || $weekStart !== $latestWeekBySection[$sectionId]) {
continue;
}
$subjectSlug = $this->resolveSubjectSlug($subject);
$classId = $sectionClassMap[$sectionId] ?? null;
$chapterSet = [];
if ($classId && $subjectSlug && ! empty($curriculumChapters[$classId][$subjectSlug])) {
$chapterSet = $curriculumChapters[$classId][$subjectSlug];
$chapterToUnit = [];
if ($classId && $subjectSlug && ! empty($curriculumUnits[$classId][$subjectSlug]['chapter_to_unit'])) {
$chapterToUnit = $curriculumUnits[$classId][$subjectSlug]['chapter_to_unit'];
}
$unitKeys = $this->extractUnitKeys((string) ($row['unit_title'] ?? ''), $chapterToUnit);
foreach ($unitKeys as $unitKey) {
$key = $subjectSlug . '|' . $unitKey;
$counts[$sectionId][$key] = true;
}
$counts[$sectionId] = ($counts[$sectionId] ?? 0) + $this->countChapterSegments(
(string) ($row['unit_title'] ?? ''),
$chapterSet
);
}
return $counts;
$totals = [];
foreach ($counts as $sectionId => $unitSet) {
$totals[$sectionId] = count($unitSet);
}
return $totals;
}
protected function buildCurriculumChapterMap(array $classIds): array
protected function buildCurriculumUnitMap(array $classIds): array
{
$classIds = array_values(array_filter(array_map('intval', $classIds)));
if (empty($classIds)) {
@@ -501,10 +495,15 @@ class AdminProgressController extends BaseController
$classId = (int) ($row['class_id'] ?? 0);
$subject = (string) ($row['subject'] ?? '');
$chapter = trim((string) ($row['chapter_name'] ?? ''));
$unitNumber = $row['unit_number'] ?? null;
if ($classId === 0 || $subject === '' || $chapter === '') {
continue;
}
$map[$classId][$subject][$chapter] = true;
if ($unitNumber === null || $unitNumber === '') {
continue;
}
$unitKey = (string) $unitNumber;
$map[$classId][$subject]['chapter_to_unit'][$chapter] = $unitKey;
}
return $map;
@@ -522,46 +521,93 @@ class AdminProgressController extends BaseController
return null;
}
protected function countChapterSegments(string $unitTitle, array $chapterSet): int
protected function countUnitSegments(string $unitTitle, array $chapterToUnit): int
{
$unitTitle = trim($unitTitle);
if ($unitTitle === '') {
return 1;
return 0;
}
$parts = array_filter(array_map('trim', explode(';', $unitTitle)), static fn ($part) => $part !== '');
if (! $parts) {
return 1;
return 0;
}
$count = 0;
$seen = [];
foreach ($parts as $part) {
$chapter = $this->extractChapterFromSegment($part);
$key = $chapter !== '' ? $chapter : $part;
if (! empty($chapterSet) && $chapter !== '' && empty($chapterSet[$chapter])) {
[$unitPart, $chapterPart] = $this->splitUnitChapterSegment($part);
$key = $this->resolveUnitKey($unitPart, $chapterPart, $chapterToUnit);
if ($key === '') {
$key = $part;
}
if (isset($seen[$key])) {
continue;
}
$seen[$key] = true;
$count++;
}
return $count > 0 ? $count : 1;
return count($seen);
}
protected function extractChapterFromSegment(string $segment): string
protected function splitUnitChapterSegment(string $segment): array
{
$segment = trim($segment);
if ($segment === '') {
return '';
return ['', ''];
}
$pos = strrpos($segment, '/');
if ($pos === false) {
return $segment;
return [$segment, ''];
}
return trim(substr($segment, $pos + 1));
$unitPart = trim(substr($segment, 0, $pos));
$chapterPart = trim(substr($segment, $pos + 1));
return [$unitPart, $chapterPart];
}
protected function extractUnitKeys(string $unitTitle, array $chapterToUnit): array
{
$unitTitle = trim($unitTitle);
if ($unitTitle === '') {
return [];
}
$parts = array_filter(array_map('trim', explode(';', $unitTitle)), static fn ($part) => $part !== '');
if (! $parts) {
return [];
}
$keys = [];
foreach ($parts as $part) {
[$unitPart, $chapterPart] = $this->splitUnitChapterSegment($part);
$key = $this->resolveUnitKey($unitPart, $chapterPart, $chapterToUnit);
if ($key === '') {
continue;
}
$keys[$key] = true;
}
return array_keys($keys);
}
protected function resolveUnitKey(string $unitPart, string $chapterPart, array $chapterToUnit): string
{
if ($chapterPart !== '' && ! empty($chapterToUnit[$chapterPart])) {
return (string) $chapterToUnit[$chapterPart];
}
if (empty($chapterToUnit)) {
if (preg_match('/\bunit\s*(\d+)\b/i', $unitPart, $matches)) {
return (string) $matches[1];
}
return '';
}
if (preg_match('/\bunit\s*(\d+)\b/i', $unitPart, $matches)) {
return (string) $matches[1];
}
if ($unitPart !== '') {
return $unitPart;
}
if ($chapterPart !== '') {
return $chapterPart;
}
return '';
}
protected function buildSectionStat(int $submitted, int $expectedDays): array