Skip to content

Commit b48f787

Browse files
committed
Fix: Optimize course times display
#237
1 parent 0a19d3a commit b48f787

File tree

2 files changed

+95
-20
lines changed

2 files changed

+95
-20
lines changed

app/Models/Course.php

+43-20
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Carbon\Carbon;
1010
use Illuminate\Database\Eloquent\Casts\Attribute;
1111
use Illuminate\Database\Eloquent\Model;
12+
use Illuminate\Support\Collection;
1213
use Illuminate\Support\Facades\App;
1314
use Illuminate\Support\Str;
1415
use Spatie\Activitylog\LogOptions;
@@ -254,10 +255,10 @@ public function saveCourseTimes($newCourseTimes)
254255
->where('end', Carbon::parse($courseTime['end'])->toTimeString())
255256
->count() == 0) {
256257
$this->times()->create([
257-
'day' => $courseTime['day'],
258-
'start' => Carbon::parse($courseTime['start'])->toTimeString(),
259-
'end' => Carbon::parse($courseTime['end'])->toTimeString(),
260-
]);
258+
'day' => $courseTime['day'],
259+
'start' => Carbon::parse($courseTime['start'])->toTimeString(),
260+
'end' => Carbon::parse($courseTime['end'])->toTimeString(),
261+
]);
261262
}
262263
}
263264
}
@@ -274,7 +275,6 @@ public function saveCourseTimes($newCourseTimes)
274275
*/
275276
public function getCourseTimesAttribute()
276277
{
277-
$parsedCourseTimes = [];
278278
// TODO localize these
279279
$daysInitials = [
280280
__('Sun'),
@@ -293,28 +293,51 @@ public function getCourseTimesAttribute()
293293
$courseTimes = $this->children->first()->times;
294294
}
295295

296-
if ($courseTimes) {
297-
foreach ($courseTimes as $courseTime) {
298-
$initial = $daysInitials[$courseTime->day];
296+
foreach ($courseTimes as $courseTime) {
297+
$timeString = sprintf(
298+
'%s - %s',
299+
Carbon::parse($courseTime->start)->locale(App::getLocale())->isoFormat('LT'),
300+
Carbon::parse($courseTime->end)->locale(App::getLocale())->isoFormat('LT')
301+
);
302+
$courseTime->timeString = $timeString;
303+
$courseTime->dayString = $daysInitials[$courseTime->day];
304+
}
299305

300-
if (! isset($parsedCourseTimes[$initial])) {
301-
$parsedCourseTimes[$initial] = [];
306+
$courseTimes = $courseTimes->sortBy('day');
307+
foreach ($courseTimes->groupBy('timeString') as $groupedCourseTimes) {
308+
$currentSeq = [];
309+
foreach ($groupedCourseTimes as $courseTime) {
310+
$prevCourseTime = end($currentSeq);
311+
if ($prevCourseTime && ($courseTime->day - $prevCourseTime->day) !== 1) {
312+
$currentSeq = [];
302313
}
303-
304-
$parsedCourseTimes[$initial][] = sprintf(
305-
'%s - %s',
306-
Carbon::parse($courseTime->start)->locale(App::getLocale())->isoFormat('LT'),
307-
Carbon::parse($courseTime->end)->locale(App::getLocale())->isoFormat('LT')
308-
);
314+
$currentSeq[] = $courseTime;
315+
$courseTime->firstOfSeq = reset($currentSeq);
309316
}
310317
}
311318

312-
$result = '';
313-
foreach ($parsedCourseTimes as $day => $times) {
314-
$result .= $day.' '.implode(' / ', $times).' | ';
319+
$groups = $courseTimes->groupBy(fn (CourseTime $courseTime) => $courseTime->firstOfSeq->id)
320+
->groupBy(fn (Collection $seqGroup) => $seqGroup->count() > 1 ? 'multi_days' : 'multi_times');
321+
322+
$result = [];
323+
324+
// Instead of showing this:
325+
// Mon 9:00 - 5:00 | Tue 9:00 - 5:00 | Wed 9:00 - 5:00 | Thu 9:00 - 5:00 | Fri 9:00 - 5:00
326+
// we could show:
327+
// Mon - Fri 9:00 - 5:00
328+
foreach (collect($groups->get('multi_days', [])) as $group) {
329+
$firstDay = $group->first();
330+
$lastDay = $group->last();
331+
$result[] = "{$firstDay->dayString} - {$lastDay->dayString} {$firstDay->timeString}";
332+
}
333+
334+
// Mon 10:00 AM - 11:00 AM / 11:30 AM - 12:45 PM
335+
foreach (collect($groups->get('multi_times', []))->flatten()->groupBy('day') as $group) {
336+
$firstDay = $group->first();
337+
$result[] = "{$firstDay->dayString} {$group->pluck('timeString')->join(' / ')}";
315338
}
316339

317-
return trim($result, ' | ');
340+
return implode(' | ', $result);
318341
}
319342

320343
public function getCoursePeriodNameAttribute()

tests/Unit/CourseTest.php

+52
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,58 @@ public function course_with_two_schedules_on_same_day_is_correctly_parsed()
207207
$this->assertSame('Mon 10:00 AM - 11:00 AM / 11:30 AM - 12:45 PM', $courseTimeParsed);
208208
}
209209

210+
211+
/**
212+
* @link https://github.com/academico-sis/academico/issues/237
213+
*
214+
* @test
215+
*/
216+
public function course_with_sequential_days_is_correctly_parsed()
217+
{
218+
// given a course and events
219+
$course = factory(Course::class)->create();
220+
221+
foreach (range(1, 3) as $day) {
222+
$course->times()->create(
223+
[
224+
'course_id' => $course->id,
225+
'day' => $day,
226+
'start' => '10:00',
227+
'end' => '11:00',
228+
]
229+
);
230+
}
231+
232+
// day in the sequence but with different time
233+
$course->times()->create(
234+
[
235+
'course_id' => $course->id,
236+
'day' => 4,
237+
'start' => '10:15',
238+
'end' => '11:00',
239+
]
240+
);
241+
242+
243+
foreach (range(5, 6) as $day) {
244+
$course->times()->create(
245+
[
246+
'course_id' => $course->id,
247+
'day' => $day,
248+
'start' => '10:00',
249+
'end' => '11:00',
250+
]
251+
);
252+
}
253+
254+
$courseTimeParsed = $course->course_times;
255+
256+
$this->assertSame(
257+
'Mon - Wed 10:00 AM - 11:00 AM | Fri - Sat 10:00 AM - 11:00 AM | Thu 10:15 AM - 11:00 AM',
258+
$courseTimeParsed
259+
);
260+
}
261+
210262
/** @test */
211263
public function course_with_two_schedules_on_different_day_is_correctly_parsed()
212264
{

0 commit comments

Comments
 (0)