diff --git a/.gitignore b/.gitignore index 0f9a7bd0..0e74aedd 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ bin/ out/ !**/src/main/**/out/ !**/src/test/**/out/ +dodam-application/dodam-rest-api/src/main/resources/dodamdodam-firebase-key.json ### NetBeans ### /nbproject/private/ diff --git a/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/OutGoingUseCase.java b/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/OutGoingUseCase.java index 69d380c5..328d7601 100644 --- a/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/OutGoingUseCase.java +++ b/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/OutGoingUseCase.java @@ -2,6 +2,7 @@ import b1nd.dodam.core.util.ZonedDateTimeUtil; import b1nd.dodam.domain.rds.member.entity.Student; +import b1nd.dodam.domain.rds.member.enumeration.ActiveStatus; import b1nd.dodam.domain.rds.member.repository.StudentRepository; import b1nd.dodam.domain.rds.member.repository.TeacherRepository; import b1nd.dodam.domain.rds.outgoing.entity.OutGoing; @@ -11,6 +12,7 @@ import b1nd.dodam.restapi.auth.infrastructure.security.support.MemberAuthenticationHolder; import b1nd.dodam.restapi.outgoing.application.data.req.ApplyOutGoingReq; import b1nd.dodam.restapi.outgoing.application.data.req.RejectOutGoingReq; +import b1nd.dodam.restapi.outgoing.application.data.res.OutGoingMealCountRes; import b1nd.dodam.restapi.outgoing.application.data.res.OutGoingRes; import b1nd.dodam.restapi.support.data.Response; import b1nd.dodam.restapi.support.data.ResponseData; @@ -48,8 +50,15 @@ public Response cancel(Long id) { return Response.noContent("외출 취소 성공"); } + @Transactional(readOnly = true) + public ResponseData getMealDemandDuringOuting(LocalDate date) { + Long nonEatersCount = outGoingService.getTodayCountByDinnerOrNotAndDate(Boolean.FALSE, date); + Long eatersCount = studentRepository.countByMemberStatus(ActiveStatus.ACTIVE) - nonEatersCount; + return ResponseData.ok("외출 중 급식 수요 조회 성공", new OutGoingMealCountRes(eatersCount, nonEatersCount)); + } + private void throwExceptionWhenStudentIsNotApplicant(OutGoing outGoing) { - if(outGoing.isNotApplicant(studentRepository.getByMember(memberAuthenticationHolder.current()))) { + if (outGoing.isNotApplicant(studentRepository.getByMember(memberAuthenticationHolder.current()))) { throw new NotOutGoingApplicantException(); } } diff --git a/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/data/req/ApplyOutGoingReq.java b/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/data/req/ApplyOutGoingReq.java index af908649..27f80f4c 100644 --- a/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/data/req/ApplyOutGoingReq.java +++ b/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/data/req/ApplyOutGoingReq.java @@ -7,13 +7,20 @@ import java.time.LocalDateTime; -public record ApplyOutGoingReq(@NotBlank String reason, @NotNull LocalDateTime startAt, @NotNull LocalDateTime endAt) { +public record ApplyOutGoingReq( + @NotBlank String reason, + @NotNull LocalDateTime startAt, + @NotNull LocalDateTime endAt, + Boolean dinnerOrNot + ) { public OutGoing toEntity(Student student) { + Boolean dinner = (dinnerOrNot != null) ? dinnerOrNot : true; return OutGoing.builder() .reason(reason) .student(student) .startAt(startAt) .endAt(endAt) + .dinnerOrNot(dinner) .build(); } } diff --git a/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/data/res/OutGoingMealCountRes.java b/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/data/res/OutGoingMealCountRes.java new file mode 100644 index 00000000..ca3af9a0 --- /dev/null +++ b/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/application/data/res/OutGoingMealCountRes.java @@ -0,0 +1,7 @@ +package b1nd.dodam.restapi.outgoing.application.data.res; + +public record OutGoingMealCountRes( + Long eatersCount, + Long nonEatersCount +) { +} diff --git a/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/presentation/OutGoingController.java b/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/presentation/OutGoingController.java index 965aa4c4..c1154677 100644 --- a/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/presentation/OutGoingController.java +++ b/dodam-application/dodam-rest-api/src/main/java/b1nd/dodam/restapi/outgoing/presentation/OutGoingController.java @@ -3,6 +3,7 @@ import b1nd.dodam.restapi.outgoing.application.OutGoingUseCase; import b1nd.dodam.restapi.outgoing.application.data.req.ApplyOutGoingReq; import b1nd.dodam.restapi.outgoing.application.data.req.RejectOutGoingReq; +import b1nd.dodam.restapi.outgoing.application.data.res.OutGoingMealCountRes; import b1nd.dodam.restapi.outgoing.application.data.res.OutGoingRes; import b1nd.dodam.restapi.support.data.Response; import b1nd.dodam.restapi.support.data.ResponseData; @@ -56,4 +57,9 @@ public ResponseData> getMy() { return useCase.getMy(); } -} + @GetMapping("/meal-demand") + public ResponseData getMealDemand(@RequestParam LocalDate date) { + return useCase.getMealDemandDuringOuting(date); + } + +} \ No newline at end of file diff --git a/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/member/repository/StudentRepository.java b/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/member/repository/StudentRepository.java index 2aea420d..643c9e97 100644 --- a/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/member/repository/StudentRepository.java +++ b/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/member/repository/StudentRepository.java @@ -2,6 +2,7 @@ import b1nd.dodam.domain.rds.member.entity.Member; import b1nd.dodam.domain.rds.member.entity.Student; +import b1nd.dodam.domain.rds.member.enumeration.ActiveStatus; import b1nd.dodam.domain.rds.member.exception.StudentNotFoundException; import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; @@ -36,4 +37,6 @@ default List getByIds(List ids) { throw new StudentNotFoundException(); } -} + Long countByMemberStatus(ActiveStatus memberStatus); + +} \ No newline at end of file diff --git a/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/entity/OutGoing.java b/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/entity/OutGoing.java index 02595acb..571b9e48 100644 --- a/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/entity/OutGoing.java +++ b/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/entity/OutGoing.java @@ -47,8 +47,11 @@ public class OutGoing extends BaseEntity { private String rejectReason; + @NotNull + private Boolean dinnerOrNot; + @Builder - public OutGoing(String reason, LocalDateTime startAt, LocalDateTime endAt, Student student) { + public OutGoing(String reason, LocalDateTime startAt, LocalDateTime endAt, Student student, Boolean dinnerOrNot) { isInvalidPeriod(startAt, endAt); this.reason = reason; @@ -56,6 +59,7 @@ public OutGoing(String reason, LocalDateTime startAt, LocalDateTime endAt, Stude this.endAt = endAt; this.status = ApprovalStatus.PENDING; this.student = student; + this.dinnerOrNot = dinnerOrNot; } public void modifyStatus(Teacher teacher, ApprovalStatus status, String rejectReason) { diff --git a/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/repository/OutGoingRepository.java b/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/repository/OutGoingRepository.java index 55a3a90b..2c16523a 100644 --- a/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/repository/OutGoingRepository.java +++ b/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/repository/OutGoingRepository.java @@ -3,6 +3,7 @@ import b1nd.dodam.domain.rds.member.entity.Student; import b1nd.dodam.domain.rds.outgoing.entity.OutGoing; import b1nd.dodam.domain.rds.outgoing.exception.OutGoingNotFoundException; +import b1nd.dodam.domain.rds.support.enumeration.ApprovalStatus; import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -25,4 +26,6 @@ default OutGoing getById(Long id) { @EntityGraph(attributePaths = {"student.member"}) List findByStudentAndEndAtGreaterThanEqual(Student student, LocalDateTime now); + @Query("SELECT COUNT(o) FROM OutGoing o WHERE o.dinnerOrNot = :dinnerOrNot AND o.status = :status AND o.startAt BETWEEN :startOfDay AND :endOfDay") + Long countByDinnerOrNotAndStatusAndStartAtBetween(Boolean dinnerOrNot, ApprovalStatus status, LocalDateTime startOfDay, LocalDateTime endOfDay); } diff --git a/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/service/OutGoingService.java b/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/service/OutGoingService.java index 59a79dca..80e21928 100644 --- a/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/service/OutGoingService.java +++ b/dodam-system-domain/dodam-domain-rds/src/main/java/b1nd/dodam/domain/rds/outgoing/service/OutGoingService.java @@ -4,10 +4,13 @@ import b1nd.dodam.domain.rds.outgoing.entity.OutGoing; import b1nd.dodam.domain.rds.outgoing.exception.OutGoingNotFoundException; import b1nd.dodam.domain.rds.outgoing.repository.OutGoingRepository; +import b1nd.dodam.domain.rds.support.enumeration.ApprovalStatus; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.List; @Service @@ -37,4 +40,9 @@ public List getByStudent(Student student, LocalDateTime now) { return repository.findByStudentAndEndAtGreaterThanEqual(student, now); } + public Long getTodayCountByDinnerOrNotAndDate(Boolean dinnerOrNot, LocalDate date){ + LocalDateTime startOfDay = date.atStartOfDay(); + LocalDateTime endOfDay = date.atTime(LocalTime.MAX); + return repository.countByDinnerOrNotAndStatusAndStartAtBetween(dinnerOrNot, ApprovalStatus.ALLOWED, startOfDay, endOfDay); + } }