From 7a2c3852579db777232c1e4eb9c6527295f40dc6 Mon Sep 17 00:00:00 2001 From: ProstoDenya01 Date: Thu, 26 Mar 2026 20:08:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BB=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D0=BD=D1=83=D0=B6=D0=BD=D1=8B=D0=BC=20=D0=BA?= =?UTF-8?q?=D1=80=D0=B8=D1=82=D0=B5=D1=80=D0=B8=D1=8F=D0=BC.=20=D0=9E?= =?UTF-8?q?=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8=D0=BB=20=D0=91=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/GroupController.java | 12 +- .../controller/ScheduleDataController.java | 106 ++++++++++++++++-- .../magistr/app/dto/CreateGroupRequest.java | 9 ++ .../app/dto/CreateScheduleDataRequest.java | 8 +- .../com/magistr/app/dto/GroupResponse.java | 8 +- .../com/magistr/app/dto/ScheduleResponse.java | 83 ++++++++------ .../com/magistr/app/model/LessonType.java | 31 +++++ .../com/magistr/app/model/ScheduleData.java | 9 +- .../com/magistr/app/model/SemesterType.java | 6 + .../com/magistr/app/model/StudentGroup.java | 11 ++ .../app/repository/LessonTypesRepository.java | 7 ++ .../repository/ScheduleDataRepository.java | 5 + .../db/migration/V2__editScheduleData.sql | 29 +++++ frontend/admin/js/views/department.js | 30 +++-- 14 files changed, 293 insertions(+), 61 deletions(-) create mode 100644 backend/src/main/java/com/magistr/app/model/LessonType.java create mode 100644 backend/src/main/java/com/magistr/app/model/SemesterType.java create mode 100644 backend/src/main/java/com/magistr/app/repository/LessonTypesRepository.java create mode 100644 backend/src/main/resources/db/migration/V2__editScheduleData.sql diff --git a/backend/src/main/java/com/magistr/app/controller/GroupController.java b/backend/src/main/java/com/magistr/app/controller/GroupController.java index fbb7590..c5eb562 100755 --- a/backend/src/main/java/com/magistr/app/controller/GroupController.java +++ b/backend/src/main/java/com/magistr/app/controller/GroupController.java @@ -46,7 +46,8 @@ public class GroupController { g.getEducationForm().getId(), g.getEducationForm().getName(), g.getDepartmentId(), - g.getCourse() + g.getCourse(), + g.getSpecialityCode() )) .toList(); logger.info("Получено {} групп", response.size()); @@ -114,6 +115,11 @@ public class GroupController { logger.error("Ошибка валидации: {}", errorMessage); return ResponseEntity.badRequest().body(Map.of("message", errorMessage)); } + if (request.getSpecialityCode() == null || request.getSpecialityCode() == 0) { + String errorMessage = "Код специальности обязателен"; + logger.error("Ошибка валидации: {}", errorMessage); + return ResponseEntity.badRequest().body(Map.of("message", errorMessage)); + } Optional efOpt = educationFormRepository.findById(request.getEducationFormId()); if (efOpt.isEmpty()) { @@ -126,6 +132,7 @@ public class GroupController { group.setEducationForm(efOpt.get()); group.setDepartmentId(request.getDepartmentId()); group.setCourse(request.getCourse()); + group.setSpecialityCode(request.getSpecialityCode()); groupRepository.save(group); logger.info("Группа успешно создана с ID - {}", group.getId()); @@ -137,7 +144,8 @@ public class GroupController { group.getEducationForm().getId(), group.getEducationForm().getName(), group.getDepartmentId(), - group.getCourse())); + group.getCourse(), + group.getSpecialityCode())); } catch (Exception e ) { logger.error("Ошибка при создании группы: {}", e.getMessage(), e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) diff --git a/backend/src/main/java/com/magistr/app/controller/ScheduleDataController.java b/backend/src/main/java/com/magistr/app/controller/ScheduleDataController.java index d289f86..6be2983 100644 --- a/backend/src/main/java/com/magistr/app/controller/ScheduleDataController.java +++ b/backend/src/main/java/com/magistr/app/controller/ScheduleDataController.java @@ -1,30 +1,43 @@ package com.magistr.app.controller; -import com.magistr.app.model.Department; -import com.magistr.app.model.ScheduleData; -import com.magistr.app.repository.DepartmentRepository; -import com.magistr.app.repository.ScheduleDataRepository; +import com.magistr.app.dto.ScheduleResponse; +import com.magistr.app.model.*; +import com.magistr.app.repository.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.util.Collections; import java.util.List; +import java.util.Map; @RestController -@RequestMapping("/api/scheduledata") +@RequestMapping("/api/department/schedule") public class ScheduleDataController { private static final Logger logger = LoggerFactory.getLogger(ScheduleDataController.class); private final ScheduleDataRepository scheduleDataRepository; + private final GroupRepository groupRepository; + private final SpecialtiesRepository specialtiesRepository; + private final SubjectRepository subjectRepository; + private final LessonTypesRepository lessonTypesRepository; + private final UserRepository userRepository; - public ScheduleDataController(ScheduleDataRepository scheduleDataRepository) { + public ScheduleDataController(ScheduleDataRepository scheduleDataRepository, GroupRepository groupRepository, SpecialtiesRepository specialtiesRepository, SubjectRepository subjectRepository, LessonTypesRepository lessonTypesRepository, UserRepository userRepository) { this.scheduleDataRepository = scheduleDataRepository; + this.groupRepository = groupRepository; + this.specialtiesRepository = specialtiesRepository; + this.subjectRepository = subjectRepository; + this.lessonTypesRepository = lessonTypesRepository; + this.userRepository = userRepository; } - @GetMapping + @GetMapping("/allList") public List getAllScheduleDataList() { logger.info("Получен запрос на получение списка данных расписаний"); try { @@ -51,4 +64,83 @@ public class ScheduleDataController { throw e; } } + + @GetMapping + public ResponseEntity getSingleScheduleData( + @RequestParam Long departmentId, + @RequestParam SemesterType semesterType, + @RequestParam String period + ) { + logger.info("Получен запрос на получение списка данных расписания по конкретным данным: departmentId = {}, semester = {}, period = {}", + departmentId, semesterType, period); + try { + List scheduleData = scheduleDataRepository.findByDepartmentIdAndSemesterTypeAndPeriod(departmentId, semesterType, period ); + + if(scheduleData.isEmpty()){ + logger.info("По параметрам: departmentId = {}, semester = {}, period = {} не найдено записей", departmentId, semesterType, period); + return ResponseEntity.ok(Map.of( + "message", "Записей не найдено" + )); + } + + List response = scheduleData.stream() + .map( s -> { + String groupName = groupRepository.findById(s.getGroupId()) + .map(StudentGroup::getName) + .orElse("Неизвестно"); + + Integer groupCourse = groupRepository.findById(s.getGroupId()) + .map(StudentGroup::getCourse) + .orElse(null); + + String specialityCode = "Неизвестно"; + StudentGroup group = groupRepository.findById(s.getGroupId()).orElse(null); + if (group != null) { + Long specialityId = group.getSpecialityCode(); + specialityCode = specialtiesRepository.findById(specialityId). + map(Speciality::getSpecialityCode) + .orElse("Неизвестно"); + } + + String subjectName = subjectRepository.findById(s.getSubjectsId()) + .map(Subject::getName) + .orElse("Неизвестно"); + + String lessonType = lessonTypesRepository.findById(s.getLessonTypeId()) + .map(LessonType::getLessonType) + .orElse("Неизвестно"); + + String teacherName = userRepository.findById(s.getTeacherId()) + .map(User::getFullName) + .orElse("Неизвестно"); + + String teacherjobTitle = userRepository.findById(s.getTeacherId()) + .map(User::getJobTitle) + .orElse("Неизвестно"); + + return new ScheduleResponse( + s.getId(), + s.getDepartmentId(), + specialityCode, + s.getSemester(), + groupName, + groupCourse, + subjectName, + lessonType, + s.getNumberOfHours(), + s.getDivision(), + teacherName, + teacherjobTitle, + s.getSemesterType(), + s.getPeriod()); + } + ) + .toList(); + logger.info("Получено {} записей для кафедры с ID - {}", response.size(), departmentId); + return ResponseEntity.ok(response); + } catch (Exception e) { + logger.error("Ошибка при получении списка данных расписаний для кафедры с ID - {}, semester - {}, period - {}: {}", departmentId, semesterType, period, e.getMessage(), e); + throw e; + } + } } \ No newline at end of file diff --git a/backend/src/main/java/com/magistr/app/dto/CreateGroupRequest.java b/backend/src/main/java/com/magistr/app/dto/CreateGroupRequest.java index 5007602..94561b0 100755 --- a/backend/src/main/java/com/magistr/app/dto/CreateGroupRequest.java +++ b/backend/src/main/java/com/magistr/app/dto/CreateGroupRequest.java @@ -7,6 +7,7 @@ public class CreateGroupRequest { private Long educationFormId; private Long departmentId; private Integer course; + private Long specialityCode; public String getName() { return name; @@ -47,4 +48,12 @@ public class CreateGroupRequest { public void setCourse(Integer course) { this.course = course; } + + public Long getSpecialityCode() { + return specialityCode; + } + + public void setSpecialityCode(Long specialityCode) { + this.specialityCode = specialityCode; + } } diff --git a/backend/src/main/java/com/magistr/app/dto/CreateScheduleDataRequest.java b/backend/src/main/java/com/magistr/app/dto/CreateScheduleDataRequest.java index 858436b..016958a 100644 --- a/backend/src/main/java/com/magistr/app/dto/CreateScheduleDataRequest.java +++ b/backend/src/main/java/com/magistr/app/dto/CreateScheduleDataRequest.java @@ -1,5 +1,7 @@ package com.magistr.app.dto; +import com.magistr.app.model.SemesterType; + public class CreateScheduleDataRequest { private Long id; private Long departmentId; @@ -10,7 +12,7 @@ public class CreateScheduleDataRequest { private Long numberOfHours; private Boolean isDivision; private Long teacherId; - private String semesterType; + private SemesterType semesterType; private String period; public Long getId() { @@ -85,11 +87,11 @@ public class CreateScheduleDataRequest { this.teacherId = teacherId; } - public String getSemesterType() { + public SemesterType getSemesterType() { return semesterType; } - public void setSemesterType(String semesterType) { + public void setSemesterType(SemesterType semesterType) { this.semesterType = semesterType; } diff --git a/backend/src/main/java/com/magistr/app/dto/GroupResponse.java b/backend/src/main/java/com/magistr/app/dto/GroupResponse.java index 9d0216b..b93cd93 100755 --- a/backend/src/main/java/com/magistr/app/dto/GroupResponse.java +++ b/backend/src/main/java/com/magistr/app/dto/GroupResponse.java @@ -9,8 +9,9 @@ public class GroupResponse { private String educationFormName; private Long departmentId; private Integer course; + private Long specialityCode; - public GroupResponse(Long id, String name, Long groupSize, Long educationFormId, String educationFormName, Long departmentId, Integer course) { + public GroupResponse(Long id, String name, Long groupSize, Long educationFormId, String educationFormName, Long departmentId, Integer course, Long specialityCode) { this.id = id; this.name = name; this.groupSize = groupSize; @@ -18,6 +19,7 @@ public class GroupResponse { this.educationFormName = educationFormName; this.departmentId = departmentId; this.course = course; + this.specialityCode = specialityCode; } public Long getId() { @@ -47,4 +49,8 @@ public class GroupResponse { public Integer getCourse() { return course; } + + public Long getSpecialityCode() { + return specialityCode; + } } diff --git a/backend/src/main/java/com/magistr/app/dto/ScheduleResponse.java b/backend/src/main/java/com/magistr/app/dto/ScheduleResponse.java index 7d906c3..67041f3 100644 --- a/backend/src/main/java/com/magistr/app/dto/ScheduleResponse.java +++ b/backend/src/main/java/com/magistr/app/dto/ScheduleResponse.java @@ -1,22 +1,30 @@ package com.magistr.app.dto; import com.fasterxml.jackson.annotation.JsonInclude; +import com.magistr.app.model.SemesterType; @JsonInclude(JsonInclude.Include.NON_NULL) public class ScheduleResponse { private Long id; + private String specialityCode; private Long departmentId; private Long semester; private Long groupId; + private String groupName; + private Integer groupCourse; private Long subjectsId; + private String subjectName; private Long lessonTypeId; + private String lessonType; private Long numberOfHours; private Boolean isDivision; private Long teacherId; - private String semesterType; + private String teacherName; + private String teacherJobTitle; + private SemesterType semesterType; private String period; - public ScheduleResponse(Long id, Long departmentId, Long semester, Long groupId, Long subjectsId, Long lessonTypeId, Long numberOfHours, Boolean isDivision, Long teacherId, String semesterType, String period) { + public ScheduleResponse(Long id, Long departmentId, Long semester, Long groupId, Long subjectsId, Long lessonTypeId, String lessonType, Long numberOfHours, Boolean isDivision, Long teacherId, SemesterType semesterType, String period) { this.id = id; this.departmentId = departmentId; this.semester = semester; @@ -30,91 +38,92 @@ public class ScheduleResponse { this.period = period; } + public ScheduleResponse(Long id, Long departmentId, String specialityCode, Long semester, String groupName, Integer groupCourse, String subjectName, String lessonType, Long numberOfHours, Boolean isDivision, String teacherName, String teacherJobTitle, SemesterType semesterType, String period) { + this.id = id; + this.departmentId = departmentId; + this.specialityCode = specialityCode; + this.semester = semester; + this.groupName = groupName; + this.groupCourse = groupCourse; + this.subjectName = subjectName; + this.lessonType = lessonType; + this.numberOfHours = numberOfHours; + this.isDivision = isDivision; + this.teacherName = teacherName; + this.teacherJobTitle = teacherJobTitle; + this.semesterType = semesterType; + this.period = period; + } + public Long getId() { return id; } - public void setId(Long id) { - this.id = id; + public String getSpecialityCode() { + return specialityCode; } public Long getDepartmentId() { return departmentId; } - public void setDepartmentId(Long departmentId) { - this.departmentId = departmentId; - } - public Long getSemester() { return semester; } - public void setSemester(Long semester) { - this.semester = semester; - } - public Long getGroupId() { return groupId; } - public void setGroupId(Long groupId) { - this.groupId = groupId; + public String getGroupName() { + return groupName; + } + + public Integer getGroupCourse() { + return groupCourse; } public Long getSubjectsId() { return subjectsId; } - public void setSubjectsId(Long subjectsId) { - this.subjectsId = subjectsId; + public String getSubjectName() { + return subjectName; } public Long getLessonTypeId() { return lessonTypeId; } - public void setLessonTypeId(Long lessonTypeId) { - this.lessonTypeId = lessonTypeId; + public String getLessonType() { + return lessonType; } public Long getNumberOfHours() { return numberOfHours; } - public void setNumberOfHours(Long numberOfHours) { - this.numberOfHours = numberOfHours; - } - public Boolean getDivision() { return isDivision; } - public void setDivision(Boolean division) { - isDivision = division; - } - public Long getTeacherId() { return teacherId; } - public void setTeacherId(Long teacherId) { - this.teacherId = teacherId; + public String getTeacherName() { + return teacherName; } - public String getSemesterType() { + public String getTeacherJobTitle() { + return teacherJobTitle; + } + + public SemesterType getSemesterType() { return semesterType; } - public void setSemesterType(String semesterType) { - this.semesterType = semesterType; - } - public String getPeriod() { return period; } - - public void setPeriod(String period) { - this.period = period; - } } diff --git a/backend/src/main/java/com/magistr/app/model/LessonType.java b/backend/src/main/java/com/magistr/app/model/LessonType.java new file mode 100644 index 0000000..6eed3ac --- /dev/null +++ b/backend/src/main/java/com/magistr/app/model/LessonType.java @@ -0,0 +1,31 @@ +package com.magistr.app.model; + +import jakarta.persistence.*; + +@Entity +@Table(name="lesson_types") +public class LessonType { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name="name", nullable = false) + private String lessonType; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getLessonType() { + return lessonType; + } + + public void setLessonType(String lessonType) { + this.lessonType = lessonType; + } +} diff --git a/backend/src/main/java/com/magistr/app/model/ScheduleData.java b/backend/src/main/java/com/magistr/app/model/ScheduleData.java index ecc7909..02c2c6b 100644 --- a/backend/src/main/java/com/magistr/app/model/ScheduleData.java +++ b/backend/src/main/java/com/magistr/app/model/ScheduleData.java @@ -34,15 +34,16 @@ public class ScheduleData { @Column(name="teacher_id", nullable = false) private Long teacherId; + @Enumerated(EnumType.STRING) @Column(name="semester_type", nullable = false) - private String semesterType; + private SemesterType semesterType; @Column(name="period", nullable = false) private String period; public ScheduleData() {} - public ScheduleData(Long id, Long departmentId, Long semester, Long groupId, Long subjectsId, Long lessonTypeId, Long numberOfHours, Boolean isDivision, Long teacherId, String semesterType, String period) { + public ScheduleData(Long id, Long departmentId, Long semester, Long groupId, Long subjectsId, Long lessonTypeId, Long numberOfHours, Boolean isDivision, Long teacherId, SemesterType semesterType, String period) { this.id = id; this.departmentId = departmentId; this.semester = semester; @@ -128,11 +129,11 @@ public class ScheduleData { this.teacherId = teacherId; } - public String getSemesterType() { + public SemesterType getSemesterType() { return semesterType; } - public void setSemesterType(String semesterType) { + public void setSemesterType(SemesterType semesterType) { this.semesterType = semesterType; } diff --git a/backend/src/main/java/com/magistr/app/model/SemesterType.java b/backend/src/main/java/com/magistr/app/model/SemesterType.java new file mode 100644 index 0000000..acf22e3 --- /dev/null +++ b/backend/src/main/java/com/magistr/app/model/SemesterType.java @@ -0,0 +1,6 @@ +package com.magistr.app.model; + +public enum SemesterType { + spring, + autumn +} diff --git a/backend/src/main/java/com/magistr/app/model/StudentGroup.java b/backend/src/main/java/com/magistr/app/model/StudentGroup.java index ed1ca2b..f901887 100755 --- a/backend/src/main/java/com/magistr/app/model/StudentGroup.java +++ b/backend/src/main/java/com/magistr/app/model/StudentGroup.java @@ -26,6 +26,9 @@ public class StudentGroup { @Column(name = "course", nullable = false) private Integer course; + @Column(name="specialty_code", nullable = false) + private Long specialityCode; + public StudentGroup() { } @@ -76,4 +79,12 @@ public class StudentGroup { public void setCourse(Integer course) { this.course = course; } + + public Long getSpecialityCode() { + return specialityCode; + } + + public void setSpecialityCode(Long specialityCode) { + this.specialityCode = specialityCode; + } } diff --git a/backend/src/main/java/com/magistr/app/repository/LessonTypesRepository.java b/backend/src/main/java/com/magistr/app/repository/LessonTypesRepository.java new file mode 100644 index 0000000..2aade40 --- /dev/null +++ b/backend/src/main/java/com/magistr/app/repository/LessonTypesRepository.java @@ -0,0 +1,7 @@ +package com.magistr.app.repository; + +import com.magistr.app.model.LessonType; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface LessonTypesRepository extends JpaRepository { +} diff --git a/backend/src/main/java/com/magistr/app/repository/ScheduleDataRepository.java b/backend/src/main/java/com/magistr/app/repository/ScheduleDataRepository.java index 82443f6..175572b 100644 --- a/backend/src/main/java/com/magistr/app/repository/ScheduleDataRepository.java +++ b/backend/src/main/java/com/magistr/app/repository/ScheduleDataRepository.java @@ -1,7 +1,12 @@ package com.magistr.app.repository; import com.magistr.app.model.ScheduleData; +import com.magistr.app.model.SemesterType; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + public interface ScheduleDataRepository extends JpaRepository { + + List findByDepartmentIdAndSemesterTypeAndPeriod(Long departmentId, SemesterType semesterType, String period); } diff --git a/backend/src/main/resources/db/migration/V2__editScheduleData.sql b/backend/src/main/resources/db/migration/V2__editScheduleData.sql new file mode 100644 index 0000000..a99481c --- /dev/null +++ b/backend/src/main/resources/db/migration/V2__editScheduleData.sql @@ -0,0 +1,29 @@ +-- ========================================== +-- Редактирование учебных групп +-- ========================================== + +ALTER TABLE student_groups +ADD COLUMN IF NOT EXISTS specialty_code INT REFERENCES specialties(id); + +UPDATE student_groups +SET specialty_code = 1 +WHERE specialty_code IS NULL; + +ALTER TABLE student_groups +ALTER COLUMN specialty_code SET NOT NULL; + +-- ========================================== +-- Редактирование данных для расписания +-- ========================================== + +INSERT INTO schedule_data (department_id, semester, group_id, subjects_id, lesson_type_id, number_of_hours, is_division, teacher_id, semester_type, period) +VALUES (1, 1, 1, 1, 3, 2, true, 1, 'autumn', '2024-2025'), + (2, 4, 2, 3, 2, 1, false, 2, 'spring', '2025-2026'), + (3, 5, 1, 2, 1, 3, true, 1, 'autumn', '2023-2024'), + (2, 4, 2, 3, 2, 1, false, 2, 'spring', '2025-2026'), + (2, 4, 2, 3, 2, 1, false, 2, 'spring', '2025-2026'), + (2, 4, 2, 3, 2, 1, false, 2, 'spring', '2025-2026'), + (1, 1, 1, 1, 1, 2, true, 2, 'autumn', '2024-2025'), + (1, 2, 2, 2, 3, 4, false, 2, 'autumn', '2024-2025'), + (1, 3, 1, 4, 2, 1, false, 1, 'autumn', '2024-2025'), + (1, 4, 2, 5, 1, 7, true, 1, 'autumn', '2024-2025'); \ No newline at end of file diff --git a/frontend/admin/js/views/department.js b/frontend/admin/js/views/department.js index 9b0a1c0..63e6388 100644 --- a/frontend/admin/js/views/department.js +++ b/frontend/admin/js/views/department.js @@ -86,8 +86,8 @@ export async function initDepartment() { Дисциплина Вид занятий Часов в неделю - Аудитория - Фамилия преподавателя + Деление на подгруппы + Преподаватель @@ -107,14 +107,30 @@ export async function initDepartment() { return schedule.map(r => ` - ${escapeHtml(r.specialty || '-')} - ${escapeHtml(r.courseSemester || '-')} + ${escapeHtml(r.specialityCode || '-')} + + ${(() => { + const course = r.groupCourse || '-'; + const semester = r.semester || '-'; + if (course === '-' && semester === '-') return '-'; + return `${course} | ${semester}`; + })()} + ${escapeHtml(r.groupName || '-')} ${escapeHtml(r.subjectName || '-')} ${escapeHtml(r.lessonType || '-')} - ${escapeHtml(r.hours || '-')} - ${escapeHtml(r.classroom || '-')} - ${escapeHtml(r.teacherName || '-')} + ${escapeHtml(r.numberOfHours || '-')} + + ${r.division === true ? '✓' : (r.division === false ? '' : escapeHtml(''))} + + + ${(() => { + const jobTitle = r.teacherJobTitle || '-'; + const teacherName = r.teacherName || '-'; + if (jobTitle === '-' && teacherName === '-') return '-'; + return `${jobTitle}, ${teacherName}`; + })()} + `).join(''); }