Skip to content

Commit

Permalink
✨ [Feature] Admin 티켓 수정 API #946 (#975)
Browse files Browse the repository at this point in the history
  • Loading branch information
kimjieun0301 authored Aug 23, 2024
1 parent 316883e commit eb67a56
Show file tree
Hide file tree
Showing 12 changed files with 200 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class AgendaTeamDetailResDto {

private String teamName;

private String teamContent;

private String teamLeaderIntraId;

private String teamStatus;
Expand All @@ -35,8 +37,9 @@ public class AgendaTeamDetailResDto {

@Builder
public AgendaTeamDetailResDto(String teamName, String teamLeaderIntraId, String teamStatus, String teamAward,
int teamAwardPriority, boolean teamIsPrivate, List<AgendaTeamMateResDto> teamMates) {
int teamAwardPriority, boolean teamIsPrivate, List<AgendaTeamMateResDto> teamMates, String teamContent) {
this.teamName = teamName;
this.teamContent = teamContent;
this.teamLeaderIntraId = teamLeaderIntraId;
this.teamStatus = teamStatus;
this.teamAward = teamAward;
Expand All @@ -51,6 +54,7 @@ public interface MapStruct {
AgendaTeamDetailResDto.MapStruct INSTANCE = Mappers.getMapper(AgendaTeamDetailResDto.MapStruct.class);

@Mapping(target = "teamName", source = "team.name")
@Mapping(target = "teamContent", source = "team.content")
@Mapping(target = "teamLeaderIntraId", source = "team.leaderIntraId")
@Mapping(target = "teamStatus", source = "team.status")
@Mapping(target = "teamAward", source = "team.award")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class AgendaTeamResDto {

private String teamName;

private String teamContent;

private String teamStatus;

private boolean teamIsPrivate;
Expand All @@ -34,8 +36,9 @@ public class AgendaTeamResDto {

@Builder
public AgendaTeamResDto(String teamName, String teamStatus, boolean teamIsPrivate, String teamLeaderIntraId,
int teamMateCount, UUID teamKey, String teamAward, Integer teamAwardPriority) {
int teamMateCount, UUID teamKey, String teamAward, Integer teamAwardPriority, String teamContent) {
this.teamName = teamName;
this.teamContent = teamContent;
this.teamStatus = teamStatus;
this.teamIsPrivate = teamIsPrivate;
this.teamLeaderIntraId = teamLeaderIntraId;
Expand All @@ -51,6 +54,7 @@ public interface MapStruct {
AgendaTeamResDto.MapStruct INSTANCE = Mappers.getMapper(AgendaTeamResDto.MapStruct.class);

@Mapping(target = "teamName", source = "name")
@Mapping(target = "teamContent", source = "content")
@Mapping(target = "teamStatus", source = "status")
@Mapping(target = "teamIsPrivate", source = "isPrivate")
@Mapping(target = "teamLeaderIntraId", source = "leaderIntraId")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package gg.agenda.api.admin.ticket.controller;

import javax.validation.Valid;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import gg.agenda.api.admin.ticket.controller.request.TicketAddAdminReqDto;
import gg.agenda.api.admin.ticket.controller.request.TicketChangeAdminReqDto;
import gg.agenda.api.admin.ticket.controller.response.TicketAddAdminResDto;
import gg.agenda.api.admin.ticket.service.TicketAdminService;
import lombok.RequiredArgsConstructor;
Expand All @@ -30,4 +34,19 @@ public ResponseEntity<TicketAddAdminResDto> ticketAdminAdd(@RequestParam String
TicketAddAdminResDto ticketAddAdminResDto = new TicketAddAdminResDto(ticketId);
return ResponseEntity.status(HttpStatus.CREATED).body(ticketAddAdminResDto);
}

/**
* 티켓 변경(관리자) API
*
* @param ticketId 수정할 ticketId
* @param ticketChangeAdminReqDto 변경할 프로필 정보
* @return HTTP 상태 코드와 빈 응답
*/
@PatchMapping
public ResponseEntity<String> agendaProfileModify(
@RequestParam Long ticketId,
@RequestBody @Valid TicketChangeAdminReqDto ticketChangeAdminReqDto) {
ticketAdminService.modifyTicket(ticketId, ticketChangeAdminReqDto);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package gg.agenda.api.admin.ticket.controller.request;

import java.time.LocalDateTime;
import java.util.UUID;

import org.springframework.format.annotation.DateTimeFormat;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
public class TicketChangeAdminReqDto {
private UUID issuedFromKey;
private UUID usedToKey;
private Boolean isApproved;
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime approvedAt;
private Boolean isUsed;
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime usedAt;

@Builder
public TicketChangeAdminReqDto(UUID issuedFromKey, UUID usedToKey, Boolean isApproved,
LocalDateTime approvedAt,
Boolean isUsed, LocalDateTime usedAt) {
this.issuedFromKey = issuedFromKey;
this.usedToKey = usedToKey;
this.isApproved = isApproved;
this.approvedAt = approvedAt;
this.isUsed = isUsed;
this.usedAt = usedAt;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import gg.admin.repo.agenda.AgendaProfileAdminRepository;
import gg.admin.repo.agenda.TicketAdminRepository;
import gg.agenda.api.admin.ticket.controller.request.TicketAddAdminReqDto;
import gg.agenda.api.admin.ticket.controller.request.TicketChangeAdminReqDto;
import gg.data.agenda.AgendaProfile;
import gg.data.agenda.Ticket;
import gg.utils.exception.custom.NotExistException;
Expand All @@ -22,7 +23,7 @@
public class TicketAdminService {

private final TicketAdminRepository ticketAdminRepository;
private final AgendaProfileAdminRepository agendaProfileRepository;
private final AgendaProfileAdminRepository agendaProfileAdminRepository;
private final AgendaAdminRepository agendaAdminRepository;

/**
Expand All @@ -31,7 +32,7 @@ public class TicketAdminService {
*/
@Transactional
public Long addTicket(String intraId, TicketAddAdminReqDto ticketAddAdminReqDto) {
AgendaProfile profile = agendaProfileRepository.findByIntraId(intraId)
AgendaProfile profile = agendaProfileAdminRepository.findByIntraId(intraId)
.orElseThrow(() -> new NotExistException(AGENDA_PROFILE_NOT_FOUND));

UUID issuedFromKey = ticketAddAdminReqDto.getIssuedFromKey();
Expand All @@ -50,4 +51,29 @@ public Long addTicket(String intraId, TicketAddAdminReqDto ticketAddAdminReqDto)
private boolean isRefundedTicket(UUID issuedFromKey) {
return Objects.nonNull(issuedFromKey);
}

/**
* AgendaProfile 변경 메서드
* @param ticketId 로그인한 유저의 id
* @param reqDto 변경할 프로필 정보
*/
@Transactional
public void modifyTicket(Long ticketId, TicketChangeAdminReqDto reqDto) {
Ticket ticket = ticketAdminRepository.findById(ticketId)
.orElseThrow(() -> new NotExistException(TICKET_NOT_FOUND));

UUID issuedFromKey = reqDto.getIssuedFromKey();
if (Objects.nonNull(issuedFromKey) && !agendaAdminRepository.existsByAgendaKey(issuedFromKey)) {
throw new NotExistException(AGENDA_NOT_FOUND);
}

UUID usedToKey = reqDto.getUsedToKey();
if (Objects.nonNull(usedToKey) && !agendaAdminRepository.existsByAgendaKey(usedToKey)) {
throw new NotExistException(AGENDA_NOT_FOUND);
}

ticket.updateTicketAdmin(reqDto.getIssuedFromKey(), reqDto.getUsedToKey(),
reqDto.getIsApproved(), reqDto.getApprovedAt(), reqDto.getIsUsed(), reqDto.getUsedAt());
ticketAdminRepository.save(ticket);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import gg.agenda.api.user.agendaprofile.controller.response.CurrentAttendAgendaListResDto;
import gg.agenda.api.user.agendaprofile.service.AgendaProfileFindService;
import gg.agenda.api.user.agendaprofile.service.AgendaProfileService;
import gg.agenda.api.user.agendateam.controller.response.TeamMateDto;
import gg.auth.UserDto;
import gg.auth.argumentresolver.Login;
import gg.data.agenda.AgendaTeamProfile;
Expand Down Expand Up @@ -69,9 +68,8 @@ public ResponseEntity<Void> agendaProfileModify(@Login @Parameter(hidden = true)
}

/**
* AgendaProfile 상세 조회 API
* AgendaProfile admin 여부 조회 API
* @param user 로그인한 사용자 정보
* @return AgendaProfileDetailsResDto 객체와 HTTP 상태 코드를 포함한 ResponseEntity
*/
@GetMapping("/info")
public ResponseEntity<AgendaProfileInfoDetailsResDto> myAgendaProfileInfoDetails(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
public class AttendedAgendaListResDto {
private String agendaId;
private UUID agendaKey;
private String agendaTitle;
private LocalDateTime agendaStartTime;
private LocalDateTime agendaEndTime;
Expand All @@ -28,6 +29,7 @@ public class AttendedAgendaListResDto {
public AttendedAgendaListResDto(AgendaTeamProfile agendaTeamProfile,
List<AgendaTeamProfile> agendaTeamProfileList) {
this.agendaId = agendaTeamProfile.getAgenda().getId().toString();
this.agendaKey = agendaTeamProfile.getAgenda().getAgendaKey();
this.agendaTitle = agendaTeamProfile.getAgenda().getTitle();
this.agendaStartTime = agendaTeamProfile.getAgenda().getStartTime();
this.agendaEndTime = agendaTeamProfile.getAgenda().getEndTime();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
public class CurrentAttendAgendaListResDto {
private String agendaId;
private UUID agendaKey;
private String agendaTitle;
private String agendaLocation;
private UUID teamKey;
Expand All @@ -21,6 +22,7 @@ public class CurrentAttendAgendaListResDto {

public CurrentAttendAgendaListResDto(AgendaTeamProfile agendaTeamProfile) {
this.agendaId = agendaTeamProfile.getAgenda().getId().toString();
this.agendaKey = agendaTeamProfile.getAgenda().getAgendaKey();
this.agendaTitle = agendaTeamProfile.getAgenda().getTitle();
this.agendaLocation = agendaTeamProfile.getAgenda().getLocation().toString();
this.teamKey = agendaTeamProfile.getAgendaTeam().getTeamKey();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import java.time.LocalDateTime;
import java.util.UUID;

import javax.transaction.Transactional;
Expand All @@ -21,6 +22,7 @@

import gg.admin.repo.agenda.TicketAdminRepository;
import gg.agenda.api.admin.ticket.controller.request.TicketAddAdminReqDto;
import gg.agenda.api.admin.ticket.controller.request.TicketChangeAdminReqDto;
import gg.agenda.api.admin.ticket.controller.response.TicketAddAdminResDto;
import gg.data.agenda.Agenda;
import gg.data.agenda.AgendaProfile;
Expand All @@ -33,6 +35,7 @@
import gg.utils.annotation.IntegrationTest;
import gg.utils.fixture.agenda.AgendaFixture;
import gg.utils.fixture.agenda.AgendaProfileFixture;
import gg.utils.fixture.agenda.TicketFixture;

@IntegrationTest
@Transactional
Expand All @@ -49,6 +52,8 @@ public class TicketAdminControllerTest {
@Autowired
private AgendaFixture agendaFixture;
@Autowired
private TicketFixture ticketFixture;
@Autowired
private TicketAdminRepository ticketAdminRepository;
User user;
String accessToken;
Expand Down Expand Up @@ -137,4 +142,82 @@ void createTicketWithAgendaNotExit() throws Exception {
.andExpect(status().isNotFound());
}
}

@Nested
@DisplayName("티켓 정보 변경")
class UpdateTicket {
@BeforeEach
void beforeEach() {
user = testDataUtils.createNewAdminUser(RoleType.ADMIN);
accessToken = testDataUtils.getLoginAccessTokenFromUser(user);
agendaProfile = agendaProfileFixture.createAgendaProfile(user, Location.SEOUL);
}

@Test
@DisplayName("유효한 정보로 티켓 정보를 변경합니다.")
void updateTicketWithValidData() throws Exception {
// Given
User agendaCreateUser = testDataUtils.createNewUser();
Ticket ticket = ticketFixture.createNotApporveTicket(agendaProfile);
Agenda usedAgenda = agendaFixture.createAgenda(agendaCreateUser.getIntraId(), AgendaStatus.OPEN);
Agenda refundedAgenda = agendaFixture.createAgenda(agendaCreateUser.getIntraId(), AgendaStatus.OPEN);
String content = objectMapper.writeValueAsString(
new TicketChangeAdminReqDto(refundedAgenda.getAgendaKey(), usedAgenda.getAgendaKey(), Boolean.TRUE,
LocalDateTime.now(), Boolean.TRUE, LocalDateTime.now()));

// When
mockMvc.perform(
patch("/agenda/admin/ticket")
.param("ticketId", String.valueOf(ticket.getId()))
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(content))
.andExpect(status().isNoContent());

// Then
Ticket updatedTicket = ticketAdminRepository.findById(ticket.getId()).orElseThrow();
assertThat(updatedTicket.getIssuedFrom()).isEqualTo(refundedAgenda.getAgendaKey());
assertThat(updatedTicket.getUsedTo()).isEqualTo(usedAgenda.getAgendaKey());
assertThat(updatedTicket.getIsApproved()).isTrue();
assertThat(updatedTicket.getIsUsed()).isTrue();
}

@Test
@DisplayName("존재하지않는 대회의 issuedFromKey 넣어 404 반환")
void updateTicketWithInvalidIssuedFromKey() throws Exception {
// Given
Ticket ticket = ticketFixture.createNotApporveTicket(agendaProfile);
String content = objectMapper.writeValueAsString(
new TicketChangeAdminReqDto(UUID.randomUUID(), null, Boolean.TRUE,
LocalDateTime.now(), Boolean.FALSE, LocalDateTime.now()));

// When & Then
mockMvc.perform(
patch("/agenda/admin/ticket")
.param("ticketId", String.valueOf(ticket.getId()))
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(content))
.andExpect(status().isNotFound());
}

@Test
@DisplayName("존재하지않는 대회의 usedToKey 넣어 404 반환")
void updateTicketWithInvalidUsedToKey() throws Exception {
// Given
Ticket ticket = ticketFixture.createNotApporveTicket(agendaProfile);
String content = objectMapper.writeValueAsString(
new TicketChangeAdminReqDto(null, UUID.randomUUID(), Boolean.TRUE,
LocalDateTime.now(), Boolean.TRUE, LocalDateTime.now()));

// When & Then
mockMvc.perform(
patch("/agenda/admin/ticket")
.param("ticketId", String.valueOf(ticket.getId()))
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(content))
.andExpect(status().isNotFound());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ public void getCurrentAttendAgendaListSuccess() throws Exception {
assertThat(result.length).isEqualTo(agendaTeamList.size());
for (int i = 0; i < result.length; i++) {
assertThat(result[i].getAgendaId()).isEqualTo(agendaTeamList.get(i).getAgenda().getId().toString());
assertThat(result[i].getAgendaKey()).isEqualTo(agendaTeamList.get(i).getAgenda().getAgendaKey());
assertThat(result[i].getAgendaTitle()).isEqualTo(agendaTeamList.get(i).getAgenda().getTitle());
assertThat(result[i].getAgendaLocation()).isEqualTo(
agendaTeamList.get(i).getAgenda().getLocation().toString());
Expand Down Expand Up @@ -390,6 +391,8 @@ void getAttendedAgendaListSuccess(int page) throws Exception {
for (int i = 0; i < result.size(); i++) {
assertThat(result.get(i).getAgendaId()).isEqualTo(
attendedAgendas.get(i + (page - 1) * size).getAgenda().getId().toString());
assertThat(result.get(i).getAgendaKey()).isEqualTo(
attendedAgendas.get(i + (page - 1) * size).getAgenda().getAgendaKey());
assertThat(result.get(i).getAgendaTitle()).isEqualTo(
attendedAgendas.get(i + (page - 1) * size).getAgenda().getTitle());
assertThat(result.get(i).getAgendaLocation()).isEqualTo(
Expand Down
15 changes: 15 additions & 0 deletions gg-data/src/main/java/gg/data/agenda/Ticket.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gg.data.agenda;

import java.time.LocalDateTime;
import java.util.Objects;
import java.util.UUID;

import javax.persistence.Column;
Expand Down Expand Up @@ -121,4 +122,18 @@ public void changeIsApproved() {
this.isApproved = true;
this.approvedAt = LocalDateTime.now();
}

public void updateTicketAdmin(UUID issuedFrom, UUID usedTo, Boolean isApproved, LocalDateTime approvedAt,
Boolean isUsed, LocalDateTime usedAt) {
this.issuedFrom = issuedFrom;
this.usedTo = usedTo;
this.approvedAt = approvedAt;
this.usedAt = usedAt;
if (Objects.nonNull(isUsed)) {
this.isUsed = isUsed;
}
if (Objects.nonNull(isApproved)) {
this.isApproved = isApproved;
}
}
}
Loading

0 comments on commit eb67a56

Please sign in to comment.