Newer
Older
teacher-diary / src / main / java / ru / mcs / diary / parent / ParentService.java
package ru.mcs.diary.parent;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.mcs.diary.auth.AuthService;
import ru.mcs.diary.common.exception.ResourceNotFoundException;
import ru.mcs.diary.parent.dto.ParentCreateRequest;
import ru.mcs.diary.parent.dto.ParentListDto;
import ru.mcs.diary.student.StudentParentRepository;
import ru.mcs.diary.teacher.Teacher;
import ru.mcs.diary.teacher.TeacherRepository;

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class ParentService {

    private final ParentRepository parentRepository;
    private final StudentParentRepository studentParentRepository;
    private final TeacherRepository teacherRepository;
    private final AuthService authService;

    @Transactional(readOnly = true)
    public List<ParentListDto> getAllParents(Long teacherId) {
        return parentRepository.findAllByTeacherIdOrderByLastNameAsc(teacherId)
                .stream()
                .map(this::toListDto)
                .toList();
    }

    @Transactional(readOnly = true)
    public Parent getParent(Long id, Long teacherId) {
        return parentRepository.findById(id)
                .filter(p -> p.getTeacher().getId().equals(teacherId))
                .orElseThrow(() -> new ResourceNotFoundException("Родитель", id));
    }

    @Transactional
    public Parent createParent(ParentCreateRequest request, Long teacherId) {
        log.info("Creating parent: {} {}", request.getLastName(), request.getFirstName());

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

        // Проверяем уникальность email для данного преподавателя
        if (parentRepository.existsByEmailAndTeacherId(request.getEmail().toLowerCase(), teacherId)) {
            throw new IllegalArgumentException("Родитель с таким email уже существует");
        }

        Parent parent = Parent.builder()
                .firstName(request.getFirstName().trim())
                .lastName(request.getLastName().trim())
                .patronymic(request.getPatronymic() != null ? request.getPatronymic().trim() : null)
                .email(request.getEmail().toLowerCase().trim())
                .phone(request.getPhone().trim())
                .teacher(teacher)
                .enabled(false)
                .build();

        return parentRepository.save(parent);
    }

    @Transactional
    public Parent updateParent(Long id, ParentCreateRequest request, Long teacherId) {
        log.info("Updating parent: {}", id);

        Parent parent = getParent(id, teacherId);

        // Проверяем уникальность email если он изменился
        String newEmail = request.getEmail().toLowerCase().trim();
        if (!parent.getEmail().equals(newEmail) &&
                parentRepository.existsByEmailAndTeacherId(newEmail, teacherId)) {
            throw new IllegalArgumentException("Родитель с таким email уже существует");
        }

        parent.setFirstName(request.getFirstName().trim());
        parent.setLastName(request.getLastName().trim());
        parent.setPatronymic(request.getPatronymic() != null ? request.getPatronymic().trim() : null);
        parent.setEmail(newEmail);
        parent.setPhone(request.getPhone().trim());

        return parentRepository.save(parent);
    }

    @Transactional
    public void deleteParent(Long id, Long teacherId) {
        log.info("Deleting parent: {}", id);
        Parent parent = getParent(id, teacherId);
        parentRepository.delete(parent);
    }

    @Transactional
    public void sendInvite(Long id, Long teacherId) {
        Parent parent = getParent(id, teacherId);
        Teacher teacher = teacherRepository.findById(teacherId)
                .orElseThrow(() -> new ResourceNotFoundException("Преподаватель", teacherId));

        authService.sendParentInvite(parent, teacher.getFullName());
        log.info("Invite sent to parent: {}", parent.getEmail());
    }

    public long countByTeacher(Long teacherId) {
        return parentRepository.findAllByTeacherIdOrderByLastNameAsc(teacherId).size();
    }

    private ParentListDto toListDto(Parent parent) {
        return ParentListDto.builder()
                .id(parent.getId())
                .fullName(parent.getFullName())
                .email(parent.getEmail())
                .phone(parent.getPhone())
                .childrenCount(studentParentRepository.countChildrenByParentId(parent.getId()))
                .activated(parent.getEnabled())
                .build();
    }
}