diff --git a/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/domain/dto/ProfessorDto.java b/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/domain/dto/ProfessorDto.java index 6f86ec0..480c862 100644 --- a/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/domain/dto/ProfessorDto.java +++ b/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/domain/dto/ProfessorDto.java @@ -9,10 +9,9 @@ import net.shyshkin.study.fullstack.supportportal.backend.domain.ProfessorCatego import net.shyshkin.study.fullstack.supportportal.backend.domain.dto.SkillDto; import net.shyshkin.study.fullstack.supportportal.backend.domain.dto.AwardDto; -import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.web.multipart.MultipartFile; -import java.time.LocalDateTime; +import java.time.ZonedDateTime; import java.util.List; import javax.validation.constraints.Email; @@ -35,8 +34,7 @@ public class ProfessorDto { private WorkingStatus status; private ProfessorCategory category; - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC") - private LocalDateTime joinDate; + private ZonedDateTime joinDate; private MultipartFile profileImage; diff --git a/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/mapper/ProfessorMapper.java b/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/mapper/ProfessorMapper.java index a92e3b7..168f2a6 100644 --- a/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/mapper/ProfessorMapper.java +++ b/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/mapper/ProfessorMapper.java @@ -10,12 +10,12 @@ import org.mapstruct.Named; @Mapper(componentModel = "spring") public interface ProfessorMapper { - // @Mapping(target = "professorId", ignore = true) // Auto-generated - @Mapping(target = "joinDate", expression = "java(java.time.LocalDateTime.now())") // Default value + @Mapping(target = "joinDate", ignore = true) // Handled in service @Mapping(target = "status", source = "status", qualifiedByName = "stringToWorkingStatus") Professor toEntity(ProfessorDto professorDto); - @Mapping(target = "profileImage", ignore = true) // Ignore profileImage mapping + @Mapping(target = "profileImage", ignore = true) + @Mapping(target = "joinDate", expression = "java(professor.getJoinDate() != null ? professor.getJoinDate().atZone(java.time.ZoneOffset.UTC) : null)") @Mapping(target = "status", source = "status", qualifiedByName = "workingStatusToString") ProfessorDto toDto(Professor professor); @@ -28,6 +28,4 @@ public interface ProfessorMapper { default String workingStatusToString(WorkingStatus status) { return status == null ? null : status.name(); } - -} - +} \ No newline at end of file diff --git a/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/service/ProfessorServiceImpl.java b/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/service/ProfessorServiceImpl.java index dcbe000..6dca33d 100644 --- a/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/service/ProfessorServiceImpl.java +++ b/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/service/ProfessorServiceImpl.java @@ -156,21 +156,18 @@ public class ProfessorServiceImpl implements ProfessorService { @Override @Transactional public Professor addNewProfessor(ProfessorDto professorDto) { - // ✅ FIX: Removed validateNewEmail() - duplicate emails are now allowed - Professor professor = professorMapper.toEntity(professorDto); - // Set a unique identifier for the professor professor.setProfessorId(generateUuid()); professor.setJoinDate( - professorDto.getJoinDate() != null ? professorDto.getJoinDate() : LocalDateTime.now() + professorDto.getJoinDate() != null + ? professorDto.getJoinDate().toLocalDateTime() + : LocalDateTime.now() ); professor.setProfileImageUrl(generateDefaultProfileImageUrl(professor.getProfessorId())); - // Save the professor first to get the ID Professor savedProfessor = professorRepository.save(professor); - // ✅ Handle skills if provided if (professorDto.getSkills() != null && !professorDto.getSkills().isEmpty()) { Set skills = professorDto.getSkills().stream() .filter(skillDto -> skillDto.getName() != null && !skillDto.getName().trim().isEmpty()) @@ -183,7 +180,6 @@ public class ProfessorServiceImpl implements ProfessorService { savedProfessor.setSkills(skills); } - // ✅ Handle awards if provided if (professorDto.getAwards() != null && !professorDto.getAwards().isEmpty()) { Set awards = professorDto.getAwards().stream() .filter(awardDto -> awardDto.getTitle() != null && !awardDto.getTitle().trim().isEmpty()) @@ -198,10 +194,8 @@ public class ProfessorServiceImpl implements ProfessorService { savedProfessor.setAwards(awards); } - // Save again to persist the relationships Professor finalProfessor = professorRepository.save(savedProfessor); - // Handle profile image if provided if (professorDto.getProfileImage() != null) { saveProfileImage(finalProfessor, professorDto.getProfileImage()); } @@ -215,9 +209,6 @@ public class ProfessorServiceImpl implements ProfessorService { Professor professor = professorRepository.findByProfessorId(professorId) .orElseThrow(() -> new ProfessorNotFoundException("Professor not found with id: " + professorId)); - // ✅ FIX: Removed validateUpdateEmail() - duplicate emails are now allowed - - // Update basic fields professor.setFirstName(professorDto.getFirstName()); professor.setLastName(professorDto.getLastName()); professor.setEmail(professorDto.getEmail()); @@ -227,7 +218,6 @@ public class ProfessorServiceImpl implements ProfessorService { professor.setStatus(professorDto.getStatus()); professor.setCategory(professorDto.getCategory()); - // Update extended fields professor.setPhone(professorDto.getPhone()); professor.setSpecialty(professorDto.getSpecialty()); professor.setCertification(professorDto.getCertification()); @@ -237,15 +227,12 @@ public class ProfessorServiceImpl implements ProfessorService { professor.setDesignation(professorDto.getDesignation()); professor.setWorkDays(professorDto.getWorkDays()); - // ✅ Update joinDate if provided if (professorDto.getJoinDate() != null) { - professor.setJoinDate(professorDto.getJoinDate()); + professor.setJoinDate(professorDto.getJoinDate().toLocalDateTime()); } - // Create a final reference for lambda expressions final Professor professorRef = professor; - // ✅ Update skills with orphanRemoval=true if (professor.getSkills() == null) { professor.setSkills(new HashSet<>()); } @@ -263,7 +250,6 @@ public class ProfessorServiceImpl implements ProfessorService { professor.getSkills().addAll(newSkills); } - // ✅ Update awards with orphanRemoval=true if (professor.getAwards() == null) { professor.setAwards(new HashSet<>()); } @@ -285,7 +271,6 @@ public class ProfessorServiceImpl implements ProfessorService { Professor savedProfessor = professorRepository.save(professor); - // Handle profile image if provided if (professorDto.getProfileImage() != null) { saveProfileImage(savedProfessor, professorDto.getProfileImage()); } diff --git a/support-portal-backend/src/main/resources/application-dev.yml b/support-portal-backend/src/main/resources/application-dev.yml index 8054828..34d977f 100644 --- a/support-portal-backend/src/main/resources/application-dev.yml +++ b/support-portal-backend/src/main/resources/application-dev.yml @@ -1,6 +1,6 @@ spring: datasource: - url: jdbc:mysql://localhost:3306/support_portal?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC + url: jdbc:mysql://127.0.0.1:3306/support_portal?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC username: root password: root