Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keep track of multiple attempts + improve saving #31

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
21 changes: 18 additions & 3 deletions app/Http/Controllers/StudentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,34 @@ public static function getStudentScoresForBlok($group, $cohortId, $onlyForUser =

// Pre-compute the scores for each feedback moment up to the current week.
$feedbackScores = $feedbackmomenten->mapWithKeys(function($fm) use ($scores) {
return [$fm->id => $scores->where('feedbackmoment_id', $fm->id)->pluck('score', 'student_id')];
// Note that because this plucks the key to the student_id, it will overwrite any duplicate student_id's with
// the last one. This is fine, because we only want the last score for each student.
// TODO: Or do we want the highest score for each student?
return [
$fm->id => $scores->where('feedbackmoment_id', $fm->id)->mapWithKeys(function($score) {
return [
$score->student_id => [
'score' => $score->score,
'attempt' => $score->attempt
]
];
})->toArray()
];
});

$students = $students->map(function($user) use ($blok, $group, $feedbackScores, $totalPointsToGainUntilNow, $totalBpointsToGainUntilNow) {

// Calculate total points by summing the highest scores for each feedback moment.
$totalPoints = collect($feedbackScores)->map(function ($scores, $fmId) use ($user) {
return $scores[$user['id']] ?? 0;
return $scores[$user['id']]['score'] ?? 0;
})->sum();

// Prepare the scores per feedback moment for the student.
$feedbackmomentenScores = collect($feedbackScores)->mapWithKeys(function ($scores, $fmId) use ($user) {
return [$fmId => $scores[$user['id']] ?? null];
return [$fmId => $scores[$user['id']] ?? [
'score' => null,
'attempt' => null
]];
});

$totalBpoints = DB::table('student_scores_b')->where('student_id', $user['id'])->sum('score');
Expand Down
59 changes: 59 additions & 0 deletions app/Livewire/Concerns/CanFloodFill.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace App\Livewire\Concerns;

trait CanFloodFill
{
public $floodFillValue = -1;
public $floodFillCount;
public $floodFillSubject;

public function startFloodFill($feedbackmomentId)
{
$studentCount = count($this->students);
$feedbackmoment = $this->blok->vakken->pluck('feedbackmomenten')->flatten()->firstWhere('id', $feedbackmomentId);

// Count the students that have a score for this feedbackmoment and wont be affected by the floodfill
$studentsWithScore = 0;

foreach($this->students as $student)
{
if(isset($student->feedbackmomenten[$feedbackmomentId]['score']))
$studentsWithScore++;
}

$count = $studentCount - $studentsWithScore;

// TODO: Nice message that tells the user nobody will be affected by the floodfill
if ($count == 0)
return;

$this->floodFillCount = $count;
$this->floodFillSubject = $feedbackmoment;
$this->floodFillValue = $feedbackmoment->points;
}

public function doFloodFill()
{
foreach($this->students as $key => $student)
{
if(!isset($student->feedbackmomenten[$this->floodFillSubject->id]['score']))
{
$student->feedbackmomenten[$this->floodFillSubject->id] = [
'attempt' => 1,
'score' => $this->floodFillValue,
];
$this->updatedStudents($this->floodFillValue, $key . '.feedbackmomenten.' . $this->floodFillSubject->id . '.score');
}
}

$this->cancelFloodFill();
}

public function cancelFloodFill()
{
$this->floodFillValue = -1;
$this->floodFillSubject = null;
$this->floodFillCount = null;
}
}
91 changes: 91 additions & 0 deletions app/Livewire/Concerns/CanManageAttempts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

namespace App\Livewire\Concerns;

use App\Models\StudentScore;

trait CanManageAttempts
{
public $manageAttempts = [];
public $manageAttemptsNew = -1;
public $manageAttemptsStudent;
public $manageAttemptsFeedbackmoment;

public function startManageAttempts($studentId, $feedbackmomentId)
{
$student = $this->students->firstWhere('id', $studentId);
$feedbackmoment = $this->blok->vakken->pluck('feedbackmomenten')->flatten()->firstWhere('id', $feedbackmomentId);

$this->manageAttempts = StudentScore::where('student_id', $studentId)
->where('feedbackmoment_id', $feedbackmomentId)
->get()
->mapWithKeys(function ($score) {
return [
$score->id => [
'attempt' => $score->attempt,
'score' => $score->score,
]
];
})
->toArray();
$this->manageAttemptsStudent = $student;
$this->manageAttemptsFeedbackmoment = $feedbackmoment;
}

public function removeAttempt($scoreId)
{
StudentScore::find($scoreId)->delete();
unset($this->manageAttempts[$scoreId]);
$this->updateStudentScores();
}

public function doManageAttempts()
{
$highestAttempt = 1;
foreach ($this->manageAttempts as $id => $attempt) {
StudentScore::find($id)->update([
'attempt' => $attempt['attempt'],
'score' => $attempt['score'],
]);

if ($highestAttempt < $attempt['attempt']) {
$highestAttempt = $attempt['attempt'];
}
}

if ($this->manageAttemptsNew > -1) {
$updatedScores = [
[
'student_id' => $this->manageAttemptsStudent->id,
'feedbackmoment_id' => $this->manageAttemptsFeedbackmoment->id,
'teacher_id' => auth()->user()->id,
'score' => $this->manageAttemptsNew ?: 0,
'attempt' => $highestAttempt + 1,
],
];

StudentScore::updateFeedbackForStudents($updatedScores);
$this->manageAttemptsNew = -1;
}

$this->cancelManageAttempts();
}

public function cancelManageAttempts()
{
$this->manageAttempts = [];
$this->manageAttemptsStudent = null;
$this->manageAttemptsFeedbackmoment = null;
$this->manageAttemptsNew = -1;
}

public function addNewAttempt()
{
$this->manageAttemptsNew = 0;
}

public function removeNewAttempt()
{
$this->manageAttemptsNew = -1;
}
}
Loading