Newer
Older
teacher-diary / src / main / java / ru / mcs / diary / group / GroupService.java
@malexple malexple 20 days ago 5 KB add groups
package ru.mcs.diary.group;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.mcs.diary.common.exception.ResourceNotFoundException;
import ru.mcs.diary.group.dto.GroupCreateRequest;
import ru.mcs.diary.group.dto.GroupListDto;
import ru.mcs.diary.student.Student;
import ru.mcs.diary.student.StudentRepository;
import ru.mcs.diary.subject.Subject;
import ru.mcs.diary.subject.SubjectRepository;
import ru.mcs.diary.teacher.Teacher;
import ru.mcs.diary.teacher.TeacherRepository;

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class GroupService {

    private final GroupRepository groupRepository;
    private final SubjectRepository subjectRepository;
    private final StudentRepository studentRepository;
    private final TeacherRepository teacherRepository;

    @Transactional(readOnly = true)
    public List<GroupListDto> getAllGroups(Long teacherId) {
        return groupRepository.findAllByTeacherIdWithSubject(teacherId)
                .stream()
                .map(this::toListDto)
                .toList();
    }

    @Transactional(readOnly = true)
    public StudyGroup getGroup(Long id, Long teacherId) {
        return groupRepository.findByIdAndTeacherId(id, teacherId)
                .orElseThrow(() -> new ResourceNotFoundException("Группа", id));
    }

    @Transactional(readOnly = true)
    public StudyGroup getGroupWithStudents(Long id, Long teacherId) {
        return groupRepository.findByIdWithStudents(id, teacherId)
                .orElseThrow(() -> new ResourceNotFoundException("Группа", id));
    }

    @Transactional
    public StudyGroup createGroup(GroupCreateRequest request, Long teacherId) {
        log.info("Creating group: {}", request.getName());

        Teacher teacher = teacherRepository.findById(teacherId)
                .orElseThrow(() -> new ResourceNotFoundException("Преподаватель", teacherId));

        Subject subject = subjectRepository.findByIdAndTeacherId(request.getSubjectId(), teacherId)
                .orElseThrow(() -> new ResourceNotFoundException("Предмет", request.getSubjectId()));

        StudyGroup group = StudyGroup.builder()
                .name(request.getName().trim())
                .subject(subject)
                .pricePerLesson(request.getPricePerLesson())
                .description(request.getDescription())
                .teacher(teacher)
                .build();

        return groupRepository.save(group);
    }

    @Transactional
    public StudyGroup updateGroup(Long id, GroupCreateRequest request, Long teacherId) {
        log.info("Updating group: {}", id);

        StudyGroup group = getGroup(id, teacherId);

        Subject subject = subjectRepository.findByIdAndTeacherId(request.getSubjectId(), teacherId)
                .orElseThrow(() -> new ResourceNotFoundException("Предмет", request.getSubjectId()));

        group.setName(request.getName().trim());
        group.setSubject(subject);
        group.setPricePerLesson(request.getPricePerLesson());
        group.setDescription(request.getDescription());

        return groupRepository.save(group);
    }

    @Transactional
    public void deleteGroup(Long id, Long teacherId) {
        log.info("Deleting group: {}", id);
        StudyGroup group = getGroup(id, teacherId);
        groupRepository.delete(group);
    }

    @Transactional
    public void addStudent(Long groupId, Long studentId, Long teacherId) {
        StudyGroup group = getGroupWithStudents(groupId, teacherId);
        Student student = studentRepository.findByIdAndTeacherId(studentId, teacherId)
                .orElseThrow(() -> new ResourceNotFoundException("Ученик", studentId));

        if (group.getStudents().contains(student)) {
            throw new IllegalArgumentException("Ученик уже в группе");
        }

        group.getStudents().add(student);
        groupRepository.save(group);
        log.info("Added student {} to group {}", studentId, groupId);
    }

    @Transactional
    public void removeStudent(Long groupId, Long studentId, Long teacherId) {
        StudyGroup group = getGroupWithStudents(groupId, teacherId);
        Student student = studentRepository.findByIdAndTeacherId(studentId, teacherId)
                .orElseThrow(() -> new ResourceNotFoundException("Ученик", studentId));

        group.getStudents().remove(student);
        groupRepository.save(group);
        log.info("Removed student {} from group {}", studentId, groupId);
    }

    public long countByTeacher(Long teacherId) {
        return groupRepository.countByTeacherId(teacherId);
    }

    private GroupListDto toListDto(StudyGroup group) {
        return GroupListDto.builder()
                .id(group.getId())
                .name(group.getName())
                .subjectName(group.getSubject() != null ? group.getSubject().getName() : "—")
                .studentCount(group.getStudents().size())
                .pricePerLesson(group.getPricePerLesson())
                .build();
    }
}