Skip to content

Commit

Permalink
[Feat]: 약 추가 API 구현
Browse files Browse the repository at this point in the history
약 추가 API 관련 로직 작성

관련 Util 함수 구현

Related to: #26
  • Loading branch information
dev-Crayon committed Dec 27, 2023
1 parent 5306728 commit 96a5801
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/main/java/io/sobok/SobokSobok/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public enum ErrorCode {

// common
INVALID_REQUEST_BODY(HttpStatus.BAD_REQUEST, "잘못된 Request body입니다."),
BAD_REQUEST_EXCEPTION(HttpStatus.BAD_REQUEST, "잘못된 형식의 요청입니다."),
FILE_SAVE_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, "파일 생성에 실패했습니다."),

// auth
UNREGISTERED_USER(HttpStatus.NOT_FOUND, "등록되지 않은 사용자입니다."),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package io.sobok.SobokSobok.pill.application;

import io.sobok.SobokSobok.auth.domain.User;
import io.sobok.SobokSobok.auth.infrastructure.UserRepository;
import io.sobok.SobokSobok.exception.ErrorCode;
import io.sobok.SobokSobok.exception.model.BadRequestException;
import io.sobok.SobokSobok.exception.model.NotFoundException;
import io.sobok.SobokSobok.pill.domain.Pill;
import io.sobok.SobokSobok.pill.domain.PillSchedule;
import io.sobok.SobokSobok.pill.infrastructure.PillQueryRepository;
import io.sobok.SobokSobok.pill.infrastructure.PillRepository;
import io.sobok.SobokSobok.pill.infrastructure.PillScheduleRepository;
import io.sobok.SobokSobok.pill.ui.dto.PillRequest;
import io.sobok.SobokSobok.utils.PillUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;

@Service
@RequiredArgsConstructor
public class PillService {

private final UserRepository userRepository;
private final PillRepository pillRepository;
private final PillQueryRepository pillQueryRepository;
private final PillScheduleRepository pillScheduleRepository;

@Transactional
public void addPill(Long userId, PillRequest request) {

User user = userRepository.findById(userId)
.orElseThrow(() -> new NotFoundException(ErrorCode.UNREGISTERED_USER));

validatePillCount(user.getId());

for (String pill : request.pillName()) {
Pill newPill = pillRepository.save(Pill.builder()
.pillName(pill)
.color(PillUtil.getRandomColorNumber())
.startDate(request.startDate())
.endDate(request.endDate())
.scheduleDay(request.day())
.userId(user.getId())
.build()
);

LocalDate[] scheduleDate = PillUtil.getScheduleDateList(request.startDate(), request.endDate(), request.day().split(", "));
for (LocalDate date : scheduleDate) {
for (String time : request.timeList()) {
pillScheduleRepository.save(PillSchedule.builder()
.scheduleDate(date)
.scheduleTime(time)
.pillId(newPill.getId())
.build()
);
}
}
}
}

private void validatePillCount(Long userId) {
if (pillQueryRepository.getPillCount(userId) >= 5) {
throw new BadRequestException(ErrorCode.EXCEEDED_PILL_COUNT);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ public class PillSchedule extends BaseEntity {
@ColumnDefault("false")
private Boolean isCheck;

@Column(nullable = false)
private Long pillId;

@Builder
public PillSchedule(LocalDate scheduleDate, String scheduleTime) {
public PillSchedule(LocalDate scheduleDate, String scheduleTime, Long pillId) {
this.scheduleDate = scheduleDate;
this.scheduleTime = scheduleTime;
this.pillId = pillId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.sobok.SobokSobok.pill.infrastructure;

import io.sobok.SobokSobok.pill.domain.PillSchedule;
import org.springframework.data.jpa.repository.JpaRepository;

public interface PillScheduleRepository extends JpaRepository<PillSchedule, Long> {
}
43 changes: 43 additions & 0 deletions src/main/java/io/sobok/SobokSobok/pill/ui/PillController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.sobok.SobokSobok.pill.ui;

import io.sobok.SobokSobok.auth.domain.User;
import io.sobok.SobokSobok.common.dto.ApiResponse;
import io.sobok.SobokSobok.exception.SuccessCode;
import io.sobok.SobokSobok.pill.application.PillService;
import io.sobok.SobokSobok.pill.ui.dto.PillRequest;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
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.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/pill")
@Tag(name = "Pill", description = "약 관련 컨트롤러")
public class PillController {

private final PillService pillService;

@PostMapping("")
@Operation(
summary = "약 추가 API 메서드",
description = "내 약을 추가하는 메서드입니다."
)
public ResponseEntity<ApiResponse<Void>> addPill(
@AuthenticationPrincipal User user,
@RequestBody @Valid final PillRequest request
) {

pillService.addPill(user.getId(), request);
return ResponseEntity
.status(HttpStatus.CREATED)
.body(ApiResponse.success(SuccessCode.ADD_PILL_SUCCESS));
}
}
23 changes: 23 additions & 0 deletions src/main/java/io/sobok/SobokSobok/pill/ui/dto/PillRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.sobok.SobokSobok.pill.ui.dto;

import io.swagger.v3.oas.annotations.media.Schema;

import java.time.LocalDate;

public record PillRequest(

@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
String[] pillName,

@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
String day,

@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
String[] timeList,

@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
LocalDate startDate,

@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
LocalDate endDate
) { }
54 changes: 54 additions & 0 deletions src/main/java/io/sobok/SobokSobok/utils/PillUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.sobok.SobokSobok.utils;

import io.sobok.SobokSobok.exception.ErrorCode;
import io.sobok.SobokSobok.exception.model.BadRequestException;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class PillUtil {

public static int getRandomColorNumber() {

Random random = new Random();
return random.nextInt(5) + 1;
}

public static LocalDate[] getScheduleDateList(LocalDate startDate, LocalDate endDate, String[] days) {

List<LocalDate> matchingDates = new ArrayList<>();
LocalDate currentDate = startDate;

while (!currentDate.isAfter(endDate)) {
DayOfWeek currentDayOfWeek = currentDate.getDayOfWeek();
String currentDayOfWeekString = currentDayOfWeek.toString();

for (String day : days) {
if (currentDayOfWeekString.equalsIgnoreCase(convertToEnglishDayOfWeek(day))) {
matchingDates.add(currentDate);
break;
}
}

currentDate = currentDate.plusDays(1);
}

return matchingDates.toArray(new LocalDate[0]);
}

private static String convertToEnglishDayOfWeek(String koreanDayOfWeek) {
return switch (koreanDayOfWeek) {
case "월" -> "MONDAY";
case "화" -> "TUESDAY";
case "수" -> "WEDNESDAY";
case "목" -> "THURSDAY";
case "금" -> "FRIDAY";
case "토" -> "SATURDAY";
case "일" -> "SUNDAY";
default -> throw new BadRequestException(ErrorCode.BAD_REQUEST_EXCEPTION);
};
}
}

0 comments on commit 96a5801

Please sign in to comment.