diff --git a/src/main/java/com/provedcode/config/InitConfig.java b/src/main/java/com/provedcode/config/InitConfig.java index fe066d2..369ae3c 100644 --- a/src/main/java/com/provedcode/config/InitConfig.java +++ b/src/main/java/com/provedcode/config/InitConfig.java @@ -21,9 +21,9 @@ public void run(String... args) throws Exception { // TODO: Method to change passwords for already created users from data.sql userInfoRepository.saveAll( userInfoRepository.findAll().stream() - .map(i -> { - i.setPassword(passwordEncoder.encode(i.getPassword())); - return i; - }).toList()); + .map(i -> { + i.setPassword(passwordEncoder.encode(i.getPassword())); + return i; + }).toList()); } -} +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/config/PageProperties.java b/src/main/java/com/provedcode/config/PageProperties.java index f3e17d3..7b57de3 100644 --- a/src/main/java/com/provedcode/config/PageProperties.java +++ b/src/main/java/com/provedcode/config/PageProperties.java @@ -1,14 +1,8 @@ package com.provedcode.config; import jakarta.annotation.PostConstruct; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; @Validated @@ -23,4 +17,4 @@ public record PageProperties( void print() { log.info("page-props = {} ", this); } -} +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/config/PropsConfig.java b/src/main/java/com/provedcode/config/PropsConfig.java index 2cfe88e..febe40f 100644 --- a/src/main/java/com/provedcode/config/PropsConfig.java +++ b/src/main/java/com/provedcode/config/PropsConfig.java @@ -1,9 +1,4 @@ package com.provedcode.config; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; - - public class PropsConfig { -} +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/config/SecurityConfig.java b/src/main/java/com/provedcode/config/SecurityConfig.java index 044a13d..da00f3b 100644 --- a/src/main/java/com/provedcode/config/SecurityConfig.java +++ b/src/main/java/com/provedcode/config/SecurityConfig.java @@ -154,4 +154,4 @@ JwtEncoder jwtEncoder(KeyPair keyPair) { var jwkSet = new ImmutableJWKSet<>(new JWKSet(jwk)); return new NimbusJwtEncoder(jwkSet); } -} +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java b/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java index 575e4a5..1c63234 100644 --- a/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java +++ b/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java @@ -11,4 +11,4 @@ public class TalentExceptionHandler { private ResponseEntity responseStatusExceptionHandler(ResponseStatusException exception) { return ResponseEntity.status(exception.getStatusCode()).body(exception.getBody()); } -} +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/controller/TalentController.java b/src/main/java/com/provedcode/talent/controller/TalentController.java index e009148..06ea805 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentController.java @@ -52,5 +52,4 @@ FullTalentDTO editTalent(@PathVariable("talent-id") long id, SessionInfoDTO deleteTalent(@PathVariable("id") long id, Authentication authentication) { return talentService.deleteTalentById(id, authentication); } - -} +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/controller/TalentProofController.java b/src/main/java/com/provedcode/talent/controller/TalentProofController.java index eae466c..60f6201 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentProofController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentProofController.java @@ -6,6 +6,7 @@ import com.provedcode.talent.model.dto.ProofDTO; import com.provedcode.talent.service.TalentProofService; import com.provedcode.user.model.dto.SessionInfoDTO; +import jakarta.validation.Valid; import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.http.ResponseEntity; @@ -29,37 +30,47 @@ Page getAllProofs(@RequestParam(value = "page") Optional page return talentProofService.getAllProofsPage(page, size, orderBy).map(talentProofMapper::toProofDTO); } + @GetMapping("/proofs/{proof-id}") @PreAuthorize("hasRole('TALENT')") - @DeleteMapping("/{talent-id}/proofs/{proof-id}") - SessionInfoDTO deleteProof(@PathVariable(value = "talent-id") long talentId, - @PathVariable(value = "proof-id") long proofId, - Authentication authentication) { - return talentProofService.deleteProofById(talentId, proofId, authentication); + ProofDTO getTalentProof(@PathVariable(value = "proof-id") long proofId, + Authentication authentication) { + return talentProofMapper.toProofDTO(talentProofService.getTalentProof(proofId, authentication)); } + @GetMapping("/{talent-id}/proofs") @PreAuthorize("hasRole('TALENT')") + FullProofDTO getTalentInformationWithProofs(Authentication authentication, + @PathVariable("talent-id") Long talentId, + @RequestParam(value = "page") Optional page, + @RequestParam(value = "size") Optional size, + @RequestParam(value = "order-by") Optional orderBy, + @RequestParam(value = "sort-by", defaultValue = "created") String... sortBy) { + return talentProofService.getTalentProofs(talentId, page, size, orderBy, authentication, sortBy); + } + @PostMapping("/{talent-id}/proofs") + @PreAuthorize("hasRole('TALENT')") ResponseEntity addProof(@PathVariable(value = "talent-id") long talentId, @RequestBody AddProofDTO addProofDTO, Authentication authentication) { return talentProofService.addProof(addProofDTO, talentId, authentication); } - @GetMapping("/{talent-id}/proofs") + @PatchMapping("/{talent-id}/proofs/{proof-id}") @PreAuthorize("hasRole('TALENT')") - FullProofDTO getTalentInformationWithProofs(Authentication authentication, - @PathVariable("talent-id") Long talentId, - @RequestParam(value = "page") Optional page, - @RequestParam(value = "size") Optional size, - @RequestParam(value = "direction") Optional direction, - @RequestParam(value = "sort", defaultValue = "created") String... sort) { - return talentProofService.getTalentProofs(talentId, page, size, direction, authentication, sort); + ProofDTO editProof(Authentication authentication, + @PathVariable("talent-id") long talentId, + @PathVariable("proof-id") long proofId, + @RequestBody @Valid ProofDTO proof) { + return talentProofMapper.toProofDTO( + talentProofService.editTalentProof(talentId, proofId, proof, authentication)); } + @DeleteMapping("/{talent-id}/proofs/{proof-id}") @PreAuthorize("hasRole('TALENT')") - @GetMapping("/proofs/{proof-id}") - ProofDTO getTalentProof(@PathVariable(value = "proof-id") long proofId, - Authentication authentication) { - return talentProofService.getTalentProof(proofId, authentication); + SessionInfoDTO deleteProof(@PathVariable(value = "talent-id") long talentId, + @PathVariable(value = "proof-id") long proofId, + Authentication authentication) { + return talentProofService.deleteProofById(talentId, proofId, authentication); } -} +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/mapper/TalentMapper.java b/src/main/java/com/provedcode/talent/mapper/TalentMapper.java index b3d25e2..43bcc88 100644 --- a/src/main/java/com/provedcode/talent/mapper/TalentMapper.java +++ b/src/main/java/com/provedcode/talent/mapper/TalentMapper.java @@ -4,6 +4,7 @@ import com.provedcode.talent.model.dto.ShortTalentDTO; import com.provedcode.talent.model.entity.*; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.mapstruct.MappingConstants; import org.mapstruct.ReportingPolicy; @@ -28,5 +29,6 @@ default FullTalentDTO talentToFullTalentDTO(Talent talent) { .build(); } + @Mapping(target = "talents", expression = "java(talent.getTalentTalents().stream().map(t->t.getTalentName()).toList())") ShortTalentDTO talentToShortTalentDTO(Talent talent); -} +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/mapper/TalentProofMapper.java b/src/main/java/com/provedcode/talent/mapper/TalentProofMapper.java index 89f636f..5dbcffc 100644 --- a/src/main/java/com/provedcode/talent/mapper/TalentProofMapper.java +++ b/src/main/java/com/provedcode/talent/mapper/TalentProofMapper.java @@ -9,11 +9,9 @@ @Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = MappingConstants.ComponentModel.SPRING) public interface TalentProofMapper { - @Mapping(source = "talentId", target = "id") @Mapping(source = "created", target = "created", dateFormat = "dd-MM-yyyy HH:mm:ss") ProofDTO toProofDTO(TalentProof talentProof); - @Mapping(source = "id", target = "talentId") @Mapping(target = "id", ignore = true) @Mapping(source = "created", target = "created", dateFormat = "dd-MM-yyyy HH:mm:ss") TalentProof toTalentProof(ProofDTO proofDTO); diff --git a/src/main/java/com/provedcode/talent/mapper/impl/TalentMapperImpl.java b/src/main/java/com/provedcode/talent/mapper/impl/TalentMapperImpl.java deleted file mode 100644 index 6a404d4..0000000 --- a/src/main/java/com/provedcode/talent/mapper/impl/TalentMapperImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -//package com.provedcode.talent.mapper.impl; -// -//import com.provedcode.talent.mapper.TalentMapper; -//import com.provedcode.talent.model.dto.FullTalentDTO; -//import com.provedcode.talent.model.dto.ShortTalentDTO; -//import com.provedcode.talent.model.entity.*; -//import org.springframework.stereotype.Component; -// -//@Component -//public class TalentMapperImpl implements TalentMapper { -// @Override -// public ShortTalentDTO talentToShortTalentDTO(Talent talent) { -// return ShortTalentDTO.builder() -// .id(talent.getId()) -// .image(talent.getImage()) -// .firstName(talent.getFirstName()) -// .lastName(talent.getLastName()) -// .specialization(talent.getSpecialization()) -// .talents(talent.getTalentTalents().stream().map(TalentTalents::getTalentName).toList()) -// .build(); -// } -// -// @Override -// public FullTalentDTO talentToFullTalentDTO(Talent talent) { -// return FullTalentDTO.builder() -// .id(talent.getId()) -// .firstName(talent.getFirstName()) -// .lastName(talent.getLastName()) -// .bio(talent.getTalentDescription() != null ? talent.getTalentDescription().getBio() : null) -// .additionalInfo(talent.getTalentDescription() != null ? talent.getTalentDescription() -// .getAdditionalInfo() : null) -// .image(talent.getImage()) -// .specialization(talent.getSpecialization()) -// .links(talent.getTalentLinks().stream().map(TalentLink::getLink).toList()) -// .contacts(talent.getTalentContacts().stream().map(TalentContact::getContact).toList()) -// .talents(talent.getTalentTalents().stream().map(TalentTalents::getTalentName).toList()) -// .attachedFiles( -// talent.getTalentAttachedFiles().stream().map(TalentAttachedFile::getAttachedFile) -// .toList()) -// .build(); -// } -//} diff --git a/src/main/java/com/provedcode/talent/mapper/impl/TalentProofMapperImpl.java b/src/main/java/com/provedcode/talent/mapper/impl/TalentProofMapperImpl.java deleted file mode 100644 index aa1361d..0000000 --- a/src/main/java/com/provedcode/talent/mapper/impl/TalentProofMapperImpl.java +++ /dev/null @@ -1,15 +0,0 @@ -//package com.provedcode.talent.mapper.impl; -// -//import com.provedcode.talent.model.dto.ProofDTO; -//import com.provedcode.talent.model.entity.TalentProof; -//import org.springframework.stereotype.Component; -// -//@Component -//public class TalentProofMapperImpl { -// public ProofDTO toProofDTO(TalentProof talentProof) { -// return ProofDTO.builder() -// .id(talentProof.getTalentId()) -// .proof(talentProof.getProof()) -// .build(); -// } -//} diff --git a/src/main/java/com/provedcode/talent/model/dto/ProofDTO.java b/src/main/java/com/provedcode/talent/model/dto/ProofDTO.java index e5036cf..ebb47ab 100644 --- a/src/main/java/com/provedcode/talent/model/dto/ProofDTO.java +++ b/src/main/java/com/provedcode/talent/model/dto/ProofDTO.java @@ -1,13 +1,18 @@ package com.provedcode.talent.model.dto; import com.provedcode.talent.model.ProofStatus; +import jakarta.validation.constraints.NotNull; import lombok.Builder; +import org.hibernate.validator.constraints.URL; + @Builder public record ProofDTO( long id, + @URL String link, String text, + @NotNull ProofStatus status, String created ) { diff --git a/src/main/java/com/provedcode/talent/model/entity/Talent.java b/src/main/java/com/provedcode/talent/model/entity/Talent.java index 28cf24c..e2c8dec 100644 --- a/src/main/java/com/provedcode/talent/model/entity/Talent.java +++ b/src/main/java/com/provedcode/talent/model/entity/Talent.java @@ -7,7 +7,9 @@ import org.hibernate.validator.constraints.URL; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; @Builder @Accessors(chain = true) @@ -44,4 +46,6 @@ public class Talent { private List talentContacts = new ArrayList<>(); @OneToMany(fetch = FetchType.EAGER, mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) private List talentAttachedFiles = new ArrayList<>(); + @OneToMany(fetch = FetchType.EAGER, mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) + private List talentProofs = new ArrayList<>(); } \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/model/entity/TalentProof.java b/src/main/java/com/provedcode/talent/model/entity/TalentProof.java index 942e56a..11e3108 100644 --- a/src/main/java/com/provedcode/talent/model/entity/TalentProof.java +++ b/src/main/java/com/provedcode/talent/model/entity/TalentProof.java @@ -5,10 +5,12 @@ import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.*; +import lombok.experimental.Accessors; import org.hibernate.validator.constraints.URL; import java.time.LocalDateTime; +@Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor @Builder diff --git a/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java b/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java index 8624c8d..9bf8ffb 100644 --- a/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java +++ b/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java @@ -5,11 +5,16 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import java.util.List; import java.util.Optional; public interface TalentProofRepository extends JpaRepository { Page findByTalentIdAndStatus(Long talentId, ProofStatus status, Pageable pageable); Page findByTalentId(Long talentId, Pageable pageable); + + List deleteByTalentId(Long talentId); + Page findByStatus(ProofStatus status, Pageable pageable); } \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index 482fae2..4e9e9bf 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -9,10 +9,10 @@ import com.provedcode.talent.model.entity.TalentProof; import com.provedcode.talent.repo.TalentProofRepository; import com.provedcode.talent.repo.TalentRepository; +import com.provedcode.talent.utill.ValidateTalentForCompliance; import com.provedcode.user.model.dto.SessionInfoDTO; import com.provedcode.user.model.entity.UserInfo; import com.provedcode.user.repo.UserInfoRepository; -import com.provedcode.talent.utill.ValidateTalentForCompliance; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -28,6 +28,7 @@ import java.net.URI; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.Optional; import static org.springframework.http.HttpStatus.*; @@ -35,6 +36,7 @@ @Service @AllArgsConstructor @Slf4j +@Transactional public class TalentProofService { TalentProofRepository talentProofRepository; TalentRepository talentRepository; @@ -42,6 +44,7 @@ public class TalentProofService { PageProperties pageProperties; ValidateTalentForCompliance validateTalentForCompliance; + @Transactional(readOnly = true) public Page getAllProofsPage(Optional page, Optional size, Optional orderBy) { if (page.orElse(pageProperties.defaultPageNum()) < 0) { @@ -53,76 +56,53 @@ public Page getAllProofsPage(Optional page, Optional talent = talentRepository.findById(talentId); - Optional talentProof = talentProofRepository.findById(proofId); - Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); - validateTalentForCompliance.userVerification(talent, talentProof, userInfo, talentId, proofId); - talentProofRepository.delete(talentProof.orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED))); - return new SessionInfoDTO("deleted", "null"); - } - - public ResponseEntity addProof(AddProofDTO addProofDTO, long talentId, Authentication authentication) { - - Optional talent = talentRepository.findById(talentId); - Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); - - validateTalentForCompliance.userVerification(talent, userInfo, talentId); + public TalentProof getTalentProof(long proofId, Authentication authentication) { + TalentProof talentProof = talentProofRepository.findById(proofId).orElseThrow( + () -> new ResponseStatusException(NOT_FOUND, String.format("proof with id = %d not found", proofId))); + UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()).orElseThrow( + () -> new ResponseStatusException(NOT_FOUND, "user with this token not found")); - TalentProof talentProof = TalentProof.builder() - .talent(talent.get()) - .talentId(talentId) - .link(addProofDTO.link()) - .text(addProofDTO.text()) - .status(ProofStatus.DRAFT) - .created(LocalDateTime.now()) - .build(); - - talentProofRepository.save(talentProof); - - URI location = ServletUriComponentsBuilder - .fromCurrentRequest() - .replacePath("/api/talents/proofs/{id}") - .buildAndExpand(talentProof.getId()) - .toUri(); - - return ResponseEntity.created(location).build(); + if (talentProof.getTalentId().equals(userInfo.getTalentId()) || + talentProof.getStatus().equals(ProofStatus.PUBLISHED)) { + return talentProof; + } else { + throw new ResponseStatusException(FORBIDDEN); + } } + @Transactional(readOnly = true) public FullProofDTO getTalentProofs(Long talentId, Optional page, Optional size, Optional direction, Authentication authentication, String... sortProperties) { Talent talent = talentRepository.findById(talentId) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, - "Talent with id = %s not found".formatted( - talentId))); + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, + "Talent with id = %s not found".formatted( + talentId))); UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, - "Talent with id = %s not found".formatted( - talentId))); + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, + "Talent with id = %s not found".formatted( + talentId))); Page proofs; PageRequest pageRequest; String sortDirection = direction.orElseGet(Sort.DEFAULT_DIRECTION::name); @@ -134,7 +114,7 @@ public FullProofDTO getTalentProofs(Long talentId, Optional page, Optio throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); } if (!sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name()) && - !sortDirection.equalsIgnoreCase(Sort.Direction.DESC.name())) { + !sortDirection.equalsIgnoreCase(Sort.Direction.DESC.name())) { throw new ResponseStatusException(BAD_REQUEST, "'direction' query param must be equals ASC or DESC"); } @@ -155,39 +135,82 @@ public FullProofDTO getTalentProofs(Long talentId, Optional page, Optio } return FullProofDTO.builder() - .id(talent.getId()) - .image(talent.getImage()) - .firstName(talent.getFirstName()) - .lastName(talent.getLastName()) - .specialization(talent.getSpecialization()) - .proofs(proofs.map(i -> ProofDTO.builder() - .id(i.getId()) - .created(i.getCreated().toString()) - .link(i.getLink()) - .text(i.getText()) - .status(i.getStatus()).build())) - .build(); + .id(talent.getId()) + .image(talent.getImage()) + .firstName(talent.getFirstName()) + .lastName(talent.getLastName()) + .specialization(talent.getSpecialization()) + .proofs(proofs.map(i -> ProofDTO.builder() + .id(i.getId()) + .created(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss") + .format(i.getCreated())) + .link(i.getLink()) + .text(i.getText()) + .status(i.getStatus()).build())) + .build(); } - public ProofDTO getTalentProof(long proofId, Authentication authentication) { - Optional talentProof = talentProofRepository.findById(proofId); + public ResponseEntity addProof(AddProofDTO addProofDTO, long talentId, Authentication authentication) { + Optional talent = talentRepository.findById(talentId); Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); - if (talentProof.isEmpty()) { - throw new ResponseStatusException(NOT_FOUND); - } + validateTalentForCompliance.userVerification(talent, userInfo, talentId); + + TalentProof talentProof = TalentProof.builder() + .talent(talent.get()) + .talentId(talentId) + .link(addProofDTO.link()) + .text(addProofDTO.text()) + .status(ProofStatus.DRAFT) + .created(LocalDateTime.now()) + .build(); - if (talentProof.get().getTalentId() == userInfo.get().getTalentId() || - talentProof.get().getStatus().equals(ProofStatus.PUBLISHED)) { - return ProofDTO.builder() - .id(talentProof.get().getTalentId()) - .link(talentProof.get().getLink()) - .status(talentProof.get().getStatus()) - .created(talentProof.get().getCreated().toString()) - .text(talentProof.get().getText()) - .build(); + talentProofRepository.save(talentProof); + + URI location = ServletUriComponentsBuilder + .fromCurrentRequest() + .replacePath("/api/talents/proofs/{id}") + .buildAndExpand(talentProof.getId()) + .toUri(); + + return ResponseEntity.created(location).build(); + } + + public TalentProof editTalentProof(long talentId, long proofId, ProofDTO proof, Authentication authentication) { + Optional talent = talentRepository.findById(talentId); + Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); + Optional talentProof = talentProofRepository.findById(proofId); + + validateTalentForCompliance.userAndProofVerification(talent, talentProof, userInfo, talentId, proofId); + + TalentProof oldProof = talentProof.get(); + ProofStatus oldProofStatus = oldProof.getStatus(); + + if (oldProofStatus != ProofStatus.DRAFT && proof.status() == ProofStatus.DRAFT) + throw new ResponseStatusException(FORBIDDEN, "you cannot change proofs status to DRAFT"); + if (oldProofStatus == ProofStatus.DRAFT && proof.status() == ProofStatus.HIDDEN) + throw new ResponseStatusException(FORBIDDEN, + "you cannot change proofs status from DRAFT to HIDDEN, it should be PUBLISHED"); + + if (proof.link() == null && proof.text() == null) { + oldProof.setStatus(proof.status()); } else { - throw new ResponseStatusException(FORBIDDEN); + if (oldProofStatus != ProofStatus.DRAFT) + throw new ResponseStatusException(FORBIDDEN, "you cannot edit proofs without DRAFT status"); + + oldProof.setLink(proof.link()) + .setText(proof.text() != null ? proof.text() : oldProof.getText()) + .setStatus(proof.status()); } + return talentProofRepository.save(oldProof); + } + + public SessionInfoDTO deleteProofById(long talentId, long proofId, Authentication authentication) { + Optional talent = talentRepository.findById(talentId); + Optional talentProof = talentProofRepository.findById(proofId); + Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); + validateTalentForCompliance.userAndProofVerification(talent, talentProof, userInfo, talentId, proofId); + talentProofRepository.delete(talentProof.orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED))); + return new SessionInfoDTO("deleted", "null"); } } \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java b/src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java index 92c341f..31a33bb 100644 --- a/src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java +++ b/src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java @@ -3,12 +3,16 @@ import com.provedcode.config.PageProperties; import com.provedcode.talent.model.dto.FullTalentDTO; import com.provedcode.talent.model.entity.*; +import com.provedcode.talent.repo.TalentProofRepository; import com.provedcode.talent.repo.TalentRepository; import com.provedcode.talent.service.TalentService; +import com.provedcode.talent.utill.ValidateTalentForCompliance; +import com.provedcode.user.model.Role; import com.provedcode.user.model.dto.SessionInfoDTO; +import com.provedcode.user.model.entity.Authority; import com.provedcode.user.model.entity.UserInfo; +import com.provedcode.user.repo.AuthorityRepository; import com.provedcode.user.repo.UserInfoRepository; -import com.provedcode.talent.utill.ValidateTalentForCompliance; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -28,6 +32,8 @@ @AllArgsConstructor @Transactional public class TalentServiceImpl implements TalentService { + AuthorityRepository authorityRepository; + TalentProofRepository talentProofRepository; TalentRepository talentRepository; UserInfoRepository userInfoRepository; PageProperties pageProperties; @@ -44,7 +50,7 @@ public Page getTalentsPage(Optional page, Optional siz throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); } return talentRepository.findAll(PageRequest.of(page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()))); + size.orElse(pageProperties.defaultPageSize()))); } @@ -80,64 +86,62 @@ public Talent editTalent(long id, FullTalentDTO fullTalent, Authentication authe .setBio(fullTalent.bio()); } else { oldTalentDescription = TalentDescription.builder() - .talentId(oldTalentId) - .additionalInfo(fullTalent.additionalInfo()) - .bio(fullTalent.bio()) - .talent(oldTalent) - .build(); + .talentId(oldTalentId) + .additionalInfo(fullTalent.additionalInfo()) + .bio(fullTalent.bio()) + .talent(oldTalent) + .build(); } oldTalentTalents.clear(); if (fullTalent.talents() != null) { oldTalentTalents.addAll(fullTalent.talents().stream().map(s -> TalentTalents.builder() - .talentId(oldTalentId) - .talent(oldTalent) - .talentName(s) - .build()).toList()); + .talentId(oldTalentId) + .talent(oldTalent) + .talentName(s) + .build()).toList()); } oldTalentLinks.clear(); if (fullTalent.links() != null) { oldTalentLinks.addAll(fullTalent.links().stream().map(l -> TalentLink.builder() - .talentId(oldTalentId) - .talent(oldTalent) - .link(l) - .build()).toList()); + .talentId(oldTalentId) + .talent(oldTalent) + .link(l) + .build()).toList()); } oldTalentContacts.clear(); if (fullTalent.contacts() != null) { oldTalentContacts.addAll(fullTalent.contacts().stream().map(s -> TalentContact.builder() - .talentId(oldTalentId) - .talent(oldTalent) - .contact(s) - .build()).toList()); + .talentId(oldTalentId) + .talent(oldTalent) + .contact(s) + .build()).toList()); } oldTalentAttachedFile.clear(); if (fullTalent.attachedFiles() != null) { oldTalentAttachedFile.addAll(fullTalent.attachedFiles().stream().map(s -> TalentAttachedFile.builder() - .talentId( - oldTalentId) - .talent(oldTalent) - .attachedFile(s) - .build()) - .toList()); + .talentId( + oldTalentId) + .talent(oldTalent) + .attachedFile(s) + .build()) + .toList()); } oldTalent.setFirstName(fullTalent.firstName()) - .setLastName(fullTalent.lastName()) - .setSpecialization(fullTalent.specialization()) - .setImage(fullTalent.image()) - .setTalentDescription(oldTalentDescription) - .setTalentTalents(oldTalentTalents) - .setTalentLinks(oldTalentLinks) - .setTalentContacts(oldTalentContacts) - .setTalentAttachedFiles(oldTalentAttachedFile); - - Talent newTalent = talentRepository.save(oldTalent); - - return newTalent; + .setLastName(fullTalent.lastName()) + .setSpecialization(fullTalent.specialization()) + .setImage(fullTalent.image()) + .setTalentDescription(oldTalentDescription) + .setTalentTalents(oldTalentTalents) + .setTalentLinks(oldTalentLinks) + .setTalentContacts(oldTalentContacts) + .setTalentAttachedFiles(oldTalentAttachedFile); + + return talentRepository.save(oldTalent); } @Override @@ -147,8 +151,13 @@ public SessionInfoDTO deleteTalentById(long id, Authentication authentication) { validateTalentForCompliance.userVerification(talent, userInfo, id); - userInfoRepository.delete(userInfo.orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED))); - talentRepository.delete(talent.orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED))); + UserInfo user = userInfo.orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED)); + Talent entity = talent.orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED)); + + user.getAuthorities().clear(); + userInfoRepository.delete(user); + talentRepository.delete(entity); + return new SessionInfoDTO("deleted", "null"); } -} +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/utill/ValidateTalentForCompliance.java b/src/main/java/com/provedcode/talent/utill/ValidateTalentForCompliance.java index 3f2d486..aad59af 100644 --- a/src/main/java/com/provedcode/talent/utill/ValidateTalentForCompliance.java +++ b/src/main/java/com/provedcode/talent/utill/ValidateTalentForCompliance.java @@ -23,9 +23,9 @@ public void userVerification(Optional talent, Optional userInf } } - public void userVerification(Optional talent, - Optional talentProof, - Optional userInfo, long talentId, long proofId) { + public void userAndProofVerification(Optional talent, + Optional talentProof, + Optional userInfo, long talentId, long proofId) { if (talent.isEmpty() && userInfo.isEmpty()) { throw new ResponseStatusException(NOT_FOUND, String.format("talent with id = %d not found", talentId)); } diff --git a/src/main/java/com/provedcode/user/model/entity/Authority.java b/src/main/java/com/provedcode/user/model/entity/Authority.java index 36f2471..03b7bac 100644 --- a/src/main/java/com/provedcode/user/model/entity/Authority.java +++ b/src/main/java/com/provedcode/user/model/entity/Authority.java @@ -24,6 +24,6 @@ public class Authority { @NotNull @Column(name = "authority", length = 20) private Role authority; - @ManyToMany(fetch = FetchType.EAGER, mappedBy = "authorities", cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @ManyToMany(fetch = FetchType.EAGER, mappedBy = "authorities") private Set userInfoes = new LinkedHashSet<>(); } \ No newline at end of file diff --git a/src/main/java/com/provedcode/user/model/entity/UserInfo.java b/src/main/java/com/provedcode/user/model/entity/UserInfo.java index 38b1d33..d2b5183 100644 --- a/src/main/java/com/provedcode/user/model/entity/UserInfo.java +++ b/src/main/java/com/provedcode/user/model/entity/UserInfo.java @@ -35,7 +35,7 @@ public class UserInfo { @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "talent_id", insertable = false, updatable = false) private Talent talent; - @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "user_authorities", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "authority_id")) diff --git a/src/main/java/com/provedcode/user/repo/UserInfoRepository.java b/src/main/java/com/provedcode/user/repo/UserInfoRepository.java index 50f93ee..0b1e73d 100644 --- a/src/main/java/com/provedcode/user/repo/UserInfoRepository.java +++ b/src/main/java/com/provedcode/user/repo/UserInfoRepository.java @@ -6,6 +6,7 @@ import java.util.Optional; public interface UserInfoRepository extends JpaRepository { + long deleteByTalentId(Long talentId); boolean existsByLogin(String login); Optional findByLogin(String login); diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 930f0aa..9e659a0 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -1,4 +1,4 @@ spring.datasource.username=sa spring.datasource.url=jdbc:h2:mem:testdb;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH logging.level.web=DEBUG -logging.level.sql=DEBUG +logging.level.sql=DEBUG \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 8a3220d..fb12397 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -1,5 +1,5 @@ -#spring.datasource.url=jdbc:postgresql://${DB_URL} spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.username=${DB_LOGIN} spring.datasource.password=${DB_PASSWORD} -spring.datasource.url=jdbc:postgresql://${DB_URL} \ No newline at end of file +#spring.datasource.url=jdbc:postgresql://${DB_URL} +spring.datasource.url=jdbc:h2://${DB_URL};MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH \ No newline at end of file