fix enrollment logic, add financial aid, fix class distribution
Tests / PHPUnit (push) Failing after 1m6s
Tests / PHPUnit (push) Failing after 1m6s
This commit is contained in:
@@ -152,17 +152,17 @@
|
||||
<div class="card-body">
|
||||
<div class="row g-3 align-items-end mb-2">
|
||||
<div class="col-md-2">
|
||||
<label for="sectionCount" class="form-label">Number of Sections</label>
|
||||
<label for="sectionCount" class="form-label">Max Number of Sections</label>
|
||||
<input type="number" min="1" id="sectionCount" class="form-control" placeholder="e.g. 2" />
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label for="minStudents" class="form-label">Minimum Students</label>
|
||||
<label for="minStudents" class="form-label">Min Students Per Section</label>
|
||||
<input type="number" min="1" id="minStudents" class="form-control" placeholder="e.g. 20" />
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<!--div class="col-md-2">
|
||||
<label for="maxStudents" class="form-label">Maximum Students</label>
|
||||
<input type="number" min="1" id="maxStudents" class="form-control" placeholder="Optional" />
|
||||
</div>
|
||||
</div-->
|
||||
<div class="col-md-3 d-flex gap-2">
|
||||
<button type="button" id="refreshTotalsBtn" class="btn btn-outline-secondary">Refresh Totals</button>
|
||||
<button type="button" id="generateAllBtn" class="btn btn-primary">Generate All</button>
|
||||
@@ -217,6 +217,13 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tblBody"></tbody>
|
||||
<tfoot class="table-light">
|
||||
<tr>
|
||||
<th>Total</th>
|
||||
<th class="text-end" id="allStudentsTotal">0</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -247,6 +254,7 @@
|
||||
}, $classes ?? [])), JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||||
|
||||
const tblBody = document.getElementById('tblBody');
|
||||
const allStudentsTotal = document.getElementById('allStudentsTotal');
|
||||
const sectionCountInput = document.getElementById('sectionCount');
|
||||
const minInput = document.getElementById('minStudents');
|
||||
const maxInput = document.getElementById('maxStudents');
|
||||
@@ -352,6 +360,20 @@
|
||||
});
|
||||
});
|
||||
|
||||
if (!resolvedClassId && selectedClassId > 0) {
|
||||
const firstSection = (sectionsByClassId[String(selectedClassId)] || [])[0] || null;
|
||||
if (firstSection) {
|
||||
select.value = String(firstSection.id);
|
||||
resolvedClassId = selectedClassId;
|
||||
} else {
|
||||
const baseClass = baseClasses.find(c => c.class_id === selectedClassId) || null;
|
||||
if (baseClass) {
|
||||
select.value = String(baseClass.class_section_id);
|
||||
resolvedClassId = selectedClassId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const selectedOption = select.options[select.selectedIndex] || null;
|
||||
if (!resolvedClassId && selectedOption) {
|
||||
resolvedClassId = parseInt(selectedOption.dataset.classId || '0', 10);
|
||||
@@ -380,8 +402,10 @@
|
||||
function buildInitialTable(rows) {
|
||||
tblBody.innerHTML = '';
|
||||
rowIndexByClassId = {};
|
||||
let allTotal = 0;
|
||||
|
||||
rows.forEach(function(r){
|
||||
allTotal += parseInt(r.total || '0', 10) || 0;
|
||||
const tr = document.createElement('tr');
|
||||
tr.dataset.classId = r.class_id;
|
||||
tr.dataset.classSectionId = r.class_section_id;
|
||||
@@ -417,13 +441,16 @@
|
||||
renderSectionsForRow(r.class_section_id, r.sections, r.students || []);
|
||||
}
|
||||
});
|
||||
if (allStudentsTotal) {
|
||||
allStudentsTotal.textContent = String(allTotal);
|
||||
}
|
||||
applyStudentSearch();
|
||||
}
|
||||
|
||||
function runDistribution(baseSectionId, baseName) {
|
||||
const sectionCount = parseInt(sectionCountInput.value || '0', 10);
|
||||
const minStudents = parseInt(minInput.value || '0', 10);
|
||||
const maxStudents = parseInt(maxInput.value || '0', 10);
|
||||
const maxStudents = parseInt((maxInput && maxInput.value) || '0', 10);
|
||||
if (!sectionCount || sectionCount <= 0 || !minStudents || minStudents <= 0) {
|
||||
msgEl.textContent = 'Enter number of sections and minimum students first.';
|
||||
return;
|
||||
@@ -611,6 +638,7 @@
|
||||
student_name: assignment.student_name || 'Student',
|
||||
age_at_reference: assignment.age_at_reference ?? null,
|
||||
gender: assignment.gender || '',
|
||||
previous_final_score: assignment.previous_final_score ?? null,
|
||||
last_year_class_section: assignment.last_year_class_section || '',
|
||||
class_id: parseInt(assignment.class_id || section.class_id || '0', 10),
|
||||
class_section_id: parseInt(assignment.class_section_id || section.class_section_id || '0', 10),
|
||||
@@ -623,6 +651,27 @@
|
||||
return out;
|
||||
}
|
||||
|
||||
function assignmentStats(assignments) {
|
||||
const stats = { male: 0, female: 0, scoreTotal: 0, scoreCount: 0 };
|
||||
(Array.isArray(assignments) ? assignments : []).forEach(function(assignment){
|
||||
const gender = String(assignment.gender || '').trim().toLowerCase();
|
||||
if (gender === 'female' || gender === 'f') {
|
||||
stats.female++;
|
||||
} else if (gender === 'male' || gender === 'm') {
|
||||
stats.male++;
|
||||
}
|
||||
|
||||
const score = Number(assignment.previous_final_score);
|
||||
if (Number.isFinite(score)) {
|
||||
stats.scoreTotal += score;
|
||||
stats.scoreCount++;
|
||||
}
|
||||
});
|
||||
|
||||
stats.averageScore = stats.scoreCount ? stats.scoreTotal / stats.scoreCount : null;
|
||||
return stats;
|
||||
}
|
||||
|
||||
function renderClassRoster(tr, assignments) {
|
||||
const wrap = document.createElement('div');
|
||||
wrap.className = 'distribution-class-roster';
|
||||
@@ -641,6 +690,23 @@
|
||||
title.appendChild(count);
|
||||
wrap.appendChild(title);
|
||||
|
||||
const stats = assignmentStats(assignments);
|
||||
const meta = document.createElement('div');
|
||||
meta.className = 'distribution-meta';
|
||||
if (stats.averageScore !== null) {
|
||||
const avg = document.createElement('span');
|
||||
avg.className = 'badge text-bg-light';
|
||||
avg.textContent = 'Avg ' + stats.averageScore.toFixed(2);
|
||||
meta.appendChild(avg);
|
||||
}
|
||||
if (stats.male || stats.female) {
|
||||
const gender = document.createElement('span');
|
||||
gender.className = 'badge text-bg-light';
|
||||
gender.textContent = 'M ' + stats.male + ' / F ' + stats.female;
|
||||
meta.appendChild(gender);
|
||||
}
|
||||
if (meta.children.length) wrap.appendChild(meta);
|
||||
|
||||
if (!assignments.length) {
|
||||
const empty = document.createElement('div');
|
||||
empty.className = 'distribution-empty';
|
||||
|
||||
Reference in New Issue
Block a user