Json을 입력받아 LocalDate 타입으로 변환 후 컨트롤러 로직을 실행
@PostMapping("/revenueExpenditure")
public ResponseEntity<CreateRevenueExpenditureResponse> addRevenueExpenditure(@RequestBody CreateRevenueExpenditureRequest request) {
return ResponseEntity.ok(new CreateRevenueExpenditureResponse(assetService.addRevenueExpenditure(request)));
}
@AllArgsConstructor
public class CreateRevenueExpenditureRequest {
@ApiModelProperty(value = "수익, 지출 타입", example = "REVENUE", required = true)
private RevenueExpenditureType revenueExpenditureType;
@ApiModelProperty(value = "해당 년월일", example = "2022-04-19", required = true)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
private LocalDate date;
@ApiModelProperty(value = "카테고리 이름", example = "월급", required = true)
private String categoryName;
@ApiModelProperty(value = "결제 수단", example = "신용 카드")
private String paymentMethod;
@ApiModelProperty(value = "금액", example = "6500", required = true)
private int cost;
@ApiModelProperty(value = "내용", example = "신전 떡볶이")
private String content;
}
@Transactional
public Long addRevenueExpenditure(CreateRevenueExpenditureRequest request) {
User user = userUtil.findCurrentUser();
return revenueExpenditureRepository.save(RevenueExpenditure.builder()
.revenueExpenditureType(request.getRevenueExpenditureType())
.content(request.getContent())
.cost(request.getCost())
.date(request.getDate())
.categoryName(request.getCategoryName())
.paymentMethod(request.getPaymentMethod())
.user(user)
.build()).getId();
}
RequestBody
에서 시간을 다음과 같이 보낼 수 있다.date
: 2022-05-30위와 같이 LocalDate
는 해당년도, 월, 일 까지 지원한다.
그냥 Json으로 보낸다고 되는게 아니고 위의 RequestDto
에서 다음과 같이 포맷팅 설정을 해줘야한다.
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
private LocalDate date;
이번엔 날짜를
QueryString
으로 보내서 조회
@ApiOperation(value = "수익 지출 내역 조회", notes = "해당 년 월, page, size 를 입력받아 한달 수익 지출 내역을 조회하는 API")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "해당 수익 지출 내역을 정상적으로 조회한 경우"),
@ApiResponse(responseCode = "404", description = "회원 Id OR 예산 금액 Id를 찾지 못한 경우")
})
@ApiImplicitParam(name = "month", value = "해당 년 월", example = "2022-04", required = true)
@GetMapping("/revenueExpenditure")
public ResponseEntity<RevenueExpenditureSumResponse> getRevenueExpenditures(@RequestParam String month, Pageable pageable) {
return ResponseEntity.ok(assetService.findRevenueExpenditureByMonth(month, pageable));
}
LocalDate
타입은 해당 년, 월, 일을 다 적어줘야 하기 때문에 String
으로 값을 받았다.public RevenueExpenditureSumResponse findRevenueExpenditureByMonth(String month, Pageable pageable) {
User user = userUtil.findCurrentUser();
Page<RevenueExpenditureResponse> revenueExpenditure = revenueExpenditureRepository.findRevenueAndExpenditureByMonth(LocalDate.parse(month + "-01"), pageable, user.getId());
Budget budget = budgetRepository.findBudgetAmountByUserId(user.getId())
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_BUDGET));
List<RevenueExpenditure> revenueExpenditureList = revenueExpenditureRepository.findRevenueExpenditure(LocalDate.parse(month + "-01"), user.getId());
int revenue = getRevenueExpenditure(revenueExpenditureList, TYPE_REVENUE);
int expenditure = getRevenueExpenditure(revenueExpenditureList, TYPE_EXPENDITURE);
int remainingBudget = budget.getBudgetAmount() - expenditure;
return RevenueExpenditureSumResponse.of(revenue, expenditure, remainingBudget, revenueExpenditure);
}
/**
* 수익 지출 타입을 받아서 합을 반환해주는 메소드
*/
private int getRevenueExpenditure(List<RevenueExpenditure> revenueExpenditureList, String type) {
return revenueExpenditureList
.stream()
.filter(r -> r.getRevenueExpenditureType().toString().equals(type))
.mapToInt(RevenueExpenditure::getCost)
.sum();
}
Service
로직에서 String
받은 파라미터를 LocalDate.parse
를 이용해서 바인딩 해주었다.public Page<RevenueExpenditureResponse> findRevenueAndExpenditureByMonth(LocalDate month, Pageable pageable, Long userId) {
List<RevenueExpenditureResponse> content = queryFactory
.select(new QRevenueExpenditureResponse(
revenueExpenditure.date,
revenueExpenditure.categoryName,
revenueExpenditure.content,
revenueExpenditure.paymentMethod,
revenueExpenditure.cost
))
.from(revenueExpenditure)
.innerJoin(revenueExpenditure.user, user)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.where(revenueExpenditure.date
.between(month.withDayOfMonth(1), month.withDayOfMonth(month.lengthOfMonth()))
.and(user.id.eq(userId)))
.orderBy(revenueExpenditure.date.desc())
.fetch();
long countQuery = queryFactory
.selectFrom(revenueExpenditure)
.where(revenueExpenditure.date
.between(month.withDayOfMonth(1), month.withDayOfMonth(month.lengthOfMonth()))
.and(user.id.eq(userId)))
.fetchCount();
return PageableExecutionUtils.getPage(content, pageable, () -> countQuery);
}
LocalDate
타입으로 넘겨받은 후 between
으로 1일부터 말일까지의 데이터를 가져왔다.Postman 테스트 결과
LocalDate
를 사용할 수 없어서 어쩔 수 없이 컨트롤러에서 String
으로 받아서 Service
로직에서 파싱을 해주었다.