Skip to content

Commit

Permalink
Merge pull request #59 from TrainingDiary/feature/pt-contract-swagger
Browse files Browse the repository at this point in the history
PT 계약 관련 API 수정
  • Loading branch information
marcel1315 authored Jul 17, 2024
2 parents 173ba25 + 3c48a11 commit 43ad6f9
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 118 deletions.
Original file line number Diff line number Diff line change
@@ -1,69 +1,85 @@
package com.project.trainingdiary.controller;

import com.project.trainingdiary.dto.request.AddPtContractSessionRequestDto;
import com.project.trainingdiary.dto.request.CreatePtContractRequestDto;
import com.project.trainingdiary.dto.request.TerminatePtContractRequestDto;
import com.project.trainingdiary.dto.response.CommonResponse;
import com.project.trainingdiary.dto.response.CreatePtContractResponseDto;
import com.project.trainingdiary.dto.response.PtContractResponseDto;
import com.project.trainingdiary.model.PtContractSort;
import com.project.trainingdiary.service.PtContractService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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;

@Tag(name = "6 - PT 계약")
@RestController
@AllArgsConstructor
@RequestMapping("api/pt-contracts")
public class PtContractController {

private final PtContractService ptContractService;

@Operation(
summary = "PT 계약을 생성",
description = "트레이너가 트레이니와 PT 계약을 생성함"
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공"),
@ApiResponse(responseCode = "409", description = "트레이너와 트레이니가 이미 계약이 있습니다.", content = @Content)
})
@PreAuthorize("hasRole('TRAINER')")
@PostMapping
public CommonResponse<?> createPtContract(
public ResponseEntity<CreatePtContractResponseDto> createPtContract(
@RequestBody @Valid CreatePtContractRequestDto dto
) {
ptContractService.createPtContract(dto);
return CommonResponse.created();
return ResponseEntity.ok(ptContractService.createPtContract(dto));
}

@Operation(
summary = "PT 계약 목록을 조회",
description = "자신의 PT 계약 목록을 조회함"
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공")
})
@GetMapping
public CommonResponse<?> getPtContractList(
Pageable pageable,
public ResponseEntity<Page<PtContractResponseDto>> getPtContractList(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam PtContractSort sortBy
) {
Page<PtContractResponseDto> ptContracts = ptContractService.getPtContractList(pageable, sortBy);
return CommonResponse.success(ptContracts);
}

@GetMapping("/{id}")
public CommonResponse<?> getPtContract(
@PathVariable long id
) {
PtContractResponseDto ptContract = ptContractService.getPtContract(id);
return CommonResponse.success(ptContract);
}

@PostMapping("/add-session")
public CommonResponse<?> addPtContractSession(
@RequestBody @Valid AddPtContractSessionRequestDto dto
) {
ptContractService.addPtContractSession(dto);
return CommonResponse.success();
Pageable pageable = PageRequest.of(page, size);
return ResponseEntity.ok(ptContractService.getPtContractList(pageable, sortBy));
}

@Operation(
summary = "PT 계약 종료",
description = "트레이너가 PT 계약을 종료함"
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공"),
@ApiResponse(responseCode = "404", description = "계약이 없습니다.")
})
@PreAuthorize("hasRole('TRAINER')")
@PostMapping("/terminate")
public CommonResponse<?> terminatePtContract(
public ResponseEntity<Void> terminatePtContract(
@RequestBody @Valid TerminatePtContractRequestDto dto
) {
ptContractService.terminatePtContract(dto);
return CommonResponse.success();
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.project.trainingdiary.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class CreatePtContractRequestDto {

@NotNull(message = "traineeEmail를 입력하세요")
@NotNull(message = "traineeEmail을 입력하세요")
@Schema(example = "[email protected]")
private String traineeEmail;

@PositiveOrZero(message = "sessionCount는 0 이상이어야 합니다")
private int sessionCount;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.project.trainingdiary.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
Expand All @@ -9,5 +10,6 @@
public class TerminatePtContractRequestDto {

@NotNull(message = "PT 계약 id를 입력해주세요")
@Schema(example = "1")
private Long ptContractId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.project.trainingdiary.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class CreatePtContractResponseDto {

@Schema(example = "1")
private Long ptContractId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
public class PtContractAlreadyExistException extends GlobalException {

public PtContractAlreadyExistException() {
super(HttpStatus.BAD_REQUEST, "트레이너와 트레이니가 이미 계약이 있습니다.");
super(HttpStatus.CONFLICT, "트레이너와 트레이니가 이미 계약이 있습니다.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.project.trainingdiary.dto.request.AddPtContractSessionRequestDto;
import com.project.trainingdiary.dto.request.CreatePtContractRequestDto;
import com.project.trainingdiary.dto.request.TerminatePtContractRequestDto;
import com.project.trainingdiary.dto.response.CreatePtContractResponseDto;
import com.project.trainingdiary.dto.response.PtContractResponseDto;
import com.project.trainingdiary.entity.PtContractEntity;
import com.project.trainingdiary.entity.TraineeEntity;
Expand All @@ -21,11 +22,9 @@
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class PtContractService {

private final PtContractRepository ptContractRepository;
Expand All @@ -35,17 +34,18 @@ public class PtContractService {
/**
* PT 계약 생성
*/
@Transactional
public void createPtContract(CreatePtContractRequestDto dto) {
TrainerEntity trainer = getTrainer(); // 이 메서드를 호출한 사람은 트레이너임
public CreatePtContractResponseDto createPtContract(CreatePtContractRequestDto dto) {
TrainerEntity trainer = getTrainer();
TraineeEntity trainee = getTrainee(dto.getTraineeEmail());

if (ptContractRepository.existsByTrainerIdAndTraineeId(trainer.getId(), trainee.getId())) {
throw new PtContractAlreadyExistException();
}

PtContractEntity ptContract = PtContractEntity.of(trainer, trainee, dto.getSessionCount());
PtContractEntity ptContract = PtContractEntity.of(trainer, trainee, 0);
ptContractRepository.save(ptContract);

return new CreatePtContractResponseDto(ptContract.getId());
}

/**
Expand All @@ -61,30 +61,9 @@ public Page<PtContractResponseDto> getPtContractList(Pageable pageable, PtContra
}
}

/**
* PT 계약을 id로 조회
*/
public PtContractResponseDto getPtContract(long id) {
PtContractEntity ptContract = ptContractRepository.findById(id)
.orElseThrow(PtContractNotExistException::new);

if (getMyRole().equals(UserRoleType.TRAINEE)) {
if (!ptContract.getTrainee().getEmail().equals(getEmail())) {
throw new PtContractNotExistException();
}
} else {
if (!ptContract.getTrainer().getEmail().equals(getEmail())) {
throw new PtContractNotExistException();
}
}

return ptContract.toResponseDto();
}

/**
* PT 계약 횟수를 업데이트 함
*/
@Transactional
public void addPtContractSession(AddPtContractSessionRequestDto dto) {
TrainerEntity trainer = getTrainer();

Expand All @@ -100,7 +79,6 @@ public void addPtContractSession(AddPtContractSessionRequestDto dto) {
/**
* PT 계약을 종료함
*/
@Transactional
public void terminatePtContract(TerminatePtContractRequestDto dto) {
PtContractEntity ptContract = ptContractRepository.findByIdAndIsTerminatedFalse(
dto.getPtContractId())
Expand All @@ -110,8 +88,6 @@ public void terminatePtContract(TerminatePtContractRequestDto dto) {
ptContractRepository.save(ptContract);
}

//TODO: usedSession 업데이트를 해야함 - 예약 시간이 지나는 순간에 하면 좋을 듯

private TrainerEntity getTrainer() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth.getAuthorities().stream().noneMatch(a -> a.getAuthority().equals("ROLE_TRAINER"))) {
Expand Down
6 changes: 5 additions & 1 deletion src/main/resources/application-sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,8 @@ spring:
port:

server:
forward-headers-strategy: framework # Swagger에서 https 요청이 나가도록 하기 위함
forward-headers-strategy: framework # Swagger에서 https 요청이 나가도록 하기 위함

springdoc:
swagger-ui:
tagsSorter: alpha
Loading

0 comments on commit 43ad6f9

Please sign in to comment.