getCourseTable method

Future<List<ScheduleDto>> getCourseTable({
  1. required String username,
  2. required SemesterDto semester,
})

Fetches the course schedule table for a specific student and semester.

Returns a list of course offerings enrolled by the student, including:

  • Course details (name, credits, hours)
  • Schedule information (days, periods, classroom)
  • Teacher and class information
  • Enrollment status and remarks

The username should be a student ID, and semester should be obtained from getCourseSemesterList.

Throws an Exception if no courses are found for the given semester.

Implementation

Future<List<ScheduleDto>> getCourseTable({
  required String username,
  required SemesterDto semester,
}) async {
  final queryParameters = {
    'format': '-2',
    'code': username,
    'year': semester.year,
    'sem': semester.term,
  };

  // Fetch Chinese and English pages in parallel
  final (zhResponse, enResponse) = await (
    _courseDio.get('tw/Select.jsp', queryParameters: queryParameters),
    _courseDio
        .get('en/Select.jsp', queryParameters: queryParameters)
        .then<Response?>((r) => r, onError: (_) => null),
  ).wait;

  final courses = _parseZhCourseTable(zhResponse.data);
  final englishNames = switch (enResponse) {
    final r? => _parseEnCourseTable(r.data),
    null => <_EnglishCourseNames>[],
  };

  // Merge English names into Chinese-parsed DTOs by index - both tables
  // list courses in the same order
  return courses.indexed.map((pair) {
    final (index, dto) = pair;
    final en = englishNames.elementAtOrNull(index);
    if (en == null) return dto;

    return (
      number: dto.number,
      course: (
        id: dto.course?.id,
        nameZh: dto.course?.nameZh,
        nameEn: en.courseName,
      ),
      phase: dto.phase,
      credits: dto.credits,
      hours: dto.hours,
      type: dto.type,
      teacher: (
        id: dto.teacher?.id,
        nameZh: dto.teacher?.nameZh,
        nameEn: en.teacherName,
      ),
      classes: dto.classes
          ?.map(
            (c) => (
              id: c.id,
              nameZh: c.nameZh,
              nameEn: en.classes.firstWhereOrNull((e) => e.id == c.id)?.name,
            ),
          )
          .toList(),
      schedule: dto.schedule,
      status: dto.status,
      language: dto.language,
      syllabusId: dto.syllabusId,
      remarks: dto.remarks,
    );
  }).toList();
}