diff --git a/src/main/java/com/provedcode/kudos/model/entity/Kudos.java b/src/main/java/com/provedcode/kudos/model/entity/Kudos.java index 198e433..4af769b 100644 --- a/src/main/java/com/provedcode/kudos/model/entity/Kudos.java +++ b/src/main/java/com/provedcode/kudos/model/entity/Kudos.java @@ -17,7 +17,7 @@ public class Kudos { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Long id; - @ManyToOne(cascade = CascadeType.ALL) + @ManyToOne @JoinColumn(name = "sponsor_id") private Sponsor sponsor; @ManyToOne(cascade = CascadeType.ALL) diff --git a/src/main/java/com/provedcode/sponsor/controller/SponsorController.java b/src/main/java/com/provedcode/sponsor/controller/SponsorController.java index d6a59a0..4e94b9d 100644 --- a/src/main/java/com/provedcode/sponsor/controller/SponsorController.java +++ b/src/main/java/com/provedcode/sponsor/controller/SponsorController.java @@ -2,6 +2,7 @@ import com.provedcode.sponsor.mapper.SponsorMapper; import com.provedcode.sponsor.model.dto.SponsorDTO; +import com.provedcode.sponsor.model.dto.SponsorEditDTO; import com.provedcode.sponsor.service.SponsorService; import com.provedcode.talent.model.dto.FullTalentDTO; import lombok.AllArgsConstructor; @@ -32,4 +33,19 @@ Page getSponsors(@RequestParam(value = "page") Optional pag SponsorDTO getSponsor(@PathVariable("id") long id, Authentication authentication) { return sponsorMapper.toDto(sponsorService.getSponsorById(id, authentication)); } + + @PreAuthorize("hasRole('SPONSOR')") + @PatchMapping("/sponsors/{id}") + SponsorDTO editSponsor(@PathVariable("id") long id, + @RequestBody SponsorEditDTO sponsorEditDTO, + Authentication authentication) { + return sponsorMapper.toDto(sponsorService.editSponsorById(id, sponsorEditDTO, authentication)); + } + + @PreAuthorize("hasRole('SPONSOR')") + @DeleteMapping("/sponsors/{id}") + void deleteSponsor(@PathVariable("id") long id, Authentication authentication) { + sponsorService.deleteSponsor(id, authentication); + } + } \ No newline at end of file diff --git a/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java b/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java index e01235b..adffbbd 100644 --- a/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java +++ b/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java @@ -1,8 +1,12 @@ package com.provedcode.sponsor.model.dto; +import com.fasterxml.jackson.annotation.JsonProperty; + public record SponsorDTO( Long id, + @JsonProperty("first_name") String firstName, + @JsonProperty("last_name") String lastName, String image ) { diff --git a/src/main/java/com/provedcode/sponsor/model/dto/SponsorEditDTO.java b/src/main/java/com/provedcode/sponsor/model/dto/SponsorEditDTO.java new file mode 100644 index 0000000..82867a5 --- /dev/null +++ b/src/main/java/com/provedcode/sponsor/model/dto/SponsorEditDTO.java @@ -0,0 +1,17 @@ +package com.provedcode.sponsor.model.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; + +@Builder +public record SponsorEditDTO( + Long id, + @JsonProperty("first_name") + String firstName, + @JsonProperty("last_name") + String lastName, + String image, + @JsonProperty("count_of_kudos") + Long countOfKudos +) { +} diff --git a/src/main/java/com/provedcode/sponsor/model/entity/Sponsor.java b/src/main/java/com/provedcode/sponsor/model/entity/Sponsor.java index c471d88..35ea8a0 100644 --- a/src/main/java/com/provedcode/sponsor/model/entity/Sponsor.java +++ b/src/main/java/com/provedcode/sponsor/model/entity/Sponsor.java @@ -30,6 +30,6 @@ public class Sponsor { @URL @Column(name = "image", length = 300) private String image; - @OneToMany(mappedBy = "sponsor", cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(mappedBy = "sponsor") private List kudoses = new ArrayList<>(); } \ No newline at end of file diff --git a/src/main/java/com/provedcode/sponsor/service/SponsorService.java b/src/main/java/com/provedcode/sponsor/service/SponsorService.java index 4ec1dd1..c1cc416 100644 --- a/src/main/java/com/provedcode/sponsor/service/SponsorService.java +++ b/src/main/java/com/provedcode/sponsor/service/SponsorService.java @@ -1,6 +1,10 @@ package com.provedcode.sponsor.service; import com.provedcode.config.PageProperties; +import com.provedcode.kudos.model.entity.Kudos; +import com.provedcode.kudos.repository.KudosRepository; +import com.provedcode.sponsor.model.dto.SponsorDTO; +import com.provedcode.sponsor.model.dto.SponsorEditDTO; import com.provedcode.sponsor.model.entity.Sponsor; import com.provedcode.sponsor.repository.SponsorRepository; import com.provedcode.user.model.entity.UserInfo; @@ -10,19 +14,26 @@ import org.springframework.data.domain.PageRequest; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.server.ResponseStatusException; +import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import static org.springframework.http.HttpStatus.*; @Service @AllArgsConstructor +@Transactional public class SponsorService { PageProperties pageProperties; SponsorRepository sponsorRepository; UserInfoRepository userInfoRepository; + private final KudosRepository kudosRepository; + @Transactional(readOnly = true) public Page getAllSponsors(Optional page, Optional size) { if (page.orElse(pageProperties.defaultPageNum()) < 0) { throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); @@ -31,16 +42,66 @@ public Page getAllSponsors(Optional page, Optional si throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); } return sponsorRepository.findAll(PageRequest.of(page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()))); + size.orElse(pageProperties.defaultPageSize()))); } + @Transactional(readOnly = true) public Sponsor getSponsorById(long id, Authentication authentication) { Sponsor sponsor = sponsorRepository.findById(id).orElseThrow( () -> new ResponseStatusException(NOT_FOUND, String.format("sponsor with id = %d not found", id))); - UserInfo user = userInfoRepository.findByLogin(authentication.getName()).orElseThrow(); + UserInfo user = userInfoRepository.findByLogin(authentication.getName()) + .orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED, "login is not valid")); if (!sponsor.getId().equals(user.getSponsor().getId())) throw new ResponseStatusException(FORBIDDEN, "The user cannot view someone else's profile"); return sponsor; } + + public Sponsor editSponsorById(long id, SponsorEditDTO sponsorEditDTO, Authentication authentication) { + Sponsor sponsor = sponsorRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "sponsor with id = %s not found".formatted(id))); + UserInfo user = userInfoRepository.findByLogin(authentication.getName()) + .orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED, "login is not valid")); + if (!sponsor.getId().equals(user.getSponsor().getId())) { + throw new ResponseStatusException(FORBIDDEN, "The user cannot edit someone else's profile"); + } + + if (sponsorEditDTO.firstName() != null) { + sponsor.setFirstName(sponsorEditDTO.firstName()); + } + if (sponsorEditDTO.lastName() != null) { + sponsor.setLastName(sponsorEditDTO.lastName()); + } + if (sponsorEditDTO.image() != null) { + sponsor.setImage(sponsorEditDTO.image()); + } + if (sponsorEditDTO.countOfKudos() != null) { + if (sponsorEditDTO.countOfKudos() > 0) { + List kudosList = IntStream.iterate(0, i -> i < sponsorEditDTO.countOfKudos(), i -> i + 1).boxed() + .map(i -> Kudos.builder() + .sponsor(sponsor) + .build()) + .toList(); + kudosRepository.saveAll(kudosList); + sponsor.getKudoses().addAll(kudosList); + } else { + throw new ResponseStatusException(BAD_REQUEST, "count of kudos must be greater than 0"); + } + } + return sponsorRepository.save(sponsor); + } + + public void deleteSponsor(long id, Authentication authentication) { + Sponsor sponsor = sponsorRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "sponsor with id = %s not found".formatted(id))); + UserInfo user = userInfoRepository.findByLogin(authentication.getName()) + .orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED, "login is not valid")); + if (!sponsor.getId().equals(user.getSponsor().getId())) { + throw new ResponseStatusException(FORBIDDEN, "The user cannot edit someone else's profile"); + } + + List kudosList = sponsor.getKudoses().stream().map(i -> {i.setSponsor(null); return i;}).toList(); + sponsor.setKudoses(kudosList); + userInfoRepository.delete(user); + } } \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/create-tables.sql b/src/main/resources/db/changelog/changeset/create-tables.sql index 40927c3..9324bd4 100644 --- a/src/main/resources/db/changelog/changeset/create-tables.sql +++ b/src/main/resources/db/changelog/changeset/create-tables.sql @@ -88,30 +88,33 @@ CREATE TABLE user_authorities ); drop table if exists user_info cascade; -CREATE TABLE user_info ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, - talent_id BIGINT, - sponsor_id BIGINT, - login VARCHAR(100) NOT NULL, - password VARCHAR(255) NOT NULL, - CONSTRAINT pk_user_info PRIMARY KEY (id) +CREATE TABLE user_info +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT, + sponsor_id BIGINT, + login VARCHAR(100) NOT NULL, + password VARCHAR(255) NOT NULL, + CONSTRAINT pk_user_info PRIMARY KEY (id) ); drop table if exists kudos cascade; -CREATE TABLE kudos ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, - sponsor_id BIGINT, - proof_id BIGINT, - CONSTRAINT pk_kudos PRIMARY KEY (id) +CREATE TABLE kudos +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + sponsor_id BIGINT, + proof_id BIGINT, + CONSTRAINT pk_kudos PRIMARY KEY (id) ); drop table if exists sponsor cascade; -CREATE TABLE sponsor ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, - first_name VARCHAR(20), - last_name VARCHAR(20), - image VARCHAR(300), - CONSTRAINT pk_sponsor PRIMARY KEY (id) +CREATE TABLE sponsor +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + first_name VARCHAR(20), + last_name VARCHAR(20), + image VARCHAR(300), + CONSTRAINT pk_sponsor PRIMARY KEY (id) ); ALTER TABLE talent_attached_file