diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientController.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientController.kt index f04ea9e..b6edad7 100644 --- a/src/main/kotlin/mara/server/domain/ingredient/IngredientController.kt +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientController.kt @@ -32,6 +32,11 @@ class IngredientController( return success(ingredientService.getIngredientList()) } + @GetMapping("/category") + fun getIngredientGroupListByCategory(): CommonResponse> { + return success(ingredientService.getIngredientListByCategory()) + } + @PutMapping("/{id}") fun updateIngredient( @PathVariable(name = "id") id: Long, diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetail.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetail.kt index d48937a..d9ba5f2 100644 --- a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetail.kt +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetail.kt @@ -1,6 +1,8 @@ package mara.server.domain.ingredient import jakarta.persistence.Entity +import jakarta.persistence.EnumType +import jakarta.persistence.Enumerated import jakarta.persistence.FetchType import jakarta.persistence.GeneratedValue import jakarta.persistence.GenerationType @@ -21,7 +23,9 @@ class IngredientDetail( val ingredient: Ingredient, var name: String, var quantity: Int, - var location: String, + + @Enumerated(EnumType.STRING) + var location: IngredientLocation, var memo: String?, var addDate: LocalDateTime, var expirationDate: LocalDateTime, @@ -45,3 +49,8 @@ class IngredientDetail( this.isDeleted = true } } + +enum class IngredientLocation() { + FREEZING, + REFRIGERATION +} diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailController.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailController.kt index c2be7ee..32673ee 100644 --- a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailController.kt +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailController.kt @@ -2,6 +2,10 @@ package mara.server.domain.ingredient import mara.server.common.CommonResponse import mara.server.common.success +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable +import org.springframework.data.domain.Sort +import org.springframework.data.web.PageableDefault import org.springframework.web.bind.annotation.DeleteMapping import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable @@ -9,6 +13,7 @@ import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.PutMapping 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 @RestController @@ -32,8 +37,26 @@ class IngredientDetailController( return success(ingredientDetailService.getIngredientDetailList(refrigeratorId)) } + @GetMapping("/count") + fun getIngredientDetailCount(@RequestParam("day") days: Long): CommonResponse { + return success(ingredientDetailService.getIngredientDetailCount(days)) + } + + @GetMapping("/recent") + fun getIngredientDetailRecent( + @PageableDefault( + size = 4, sort = ["expirationDate"], direction = Sort.Direction.ASC + ) + pageable: Pageable, + ): CommonResponse> { + return success(ingredientDetailService.getIngredientDetailRecent(pageable)) + } + @PutMapping("/{id}") - fun updateIngredientDetail(@PathVariable(name = "id") id: Long, @RequestBody ingredientDetailUpdateRequest: IngredientDetailUpdateRequest): CommonResponse { + fun updateIngredientDetail( + @PathVariable(name = "id") id: Long, + @RequestBody ingredientDetailUpdateRequest: IngredientDetailUpdateRequest + ): CommonResponse { return success(ingredientDetailService.updateIngredientDetail(id, ingredientDetailUpdateRequest)) } diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailDto.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailDto.kt index 1f67274..6fbcbab 100644 --- a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailDto.kt +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailDto.kt @@ -1,5 +1,6 @@ package mara.server.domain.ingredient +import org.springframework.data.domain.Page import java.time.LocalDateTime data class IngredientDetailRequest( @@ -7,7 +8,7 @@ data class IngredientDetailRequest( var ingredientId: Long, val name: String, val quantity: Int, - val location: String, + val location: IngredientLocation, val memo: String?, val addDate: LocalDateTime, val expirationDate: LocalDateTime, @@ -17,7 +18,7 @@ data class IngredientDetailRequest( data class IngredientDetailUpdateRequest( val name: String, val quantity: Int, - val location: String, + val location: IngredientLocation, val memo: String?, val addDate: LocalDateTime, val expirationDate: LocalDateTime, @@ -28,7 +29,7 @@ data class IngredientDetailResponse( val ingredientDetailId: Long, val name: String, val quantity: Int, - val location: String, + val location: IngredientLocation, val memo: String?, val addDate: LocalDateTime, val expirationDate: LocalDateTime, @@ -47,6 +48,10 @@ data class IngredientDetailResponse( ) } -fun List.toIngredientResponseList(): List { +fun List.toIngredientDetailResponseList(): List { + return this.map { IngredientDetailResponse(it) } +} + +fun Page.toIngredientDetailResponseListPage(): Page { return this.map { IngredientDetailResponse(it) } } diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailRepository.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailRepository.kt index 95dcc4a..3b3771f 100644 --- a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailRepository.kt +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailRepository.kt @@ -1,13 +1,23 @@ package mara.server.domain.ingredient import mara.server.domain.refrigerator.Refrigerator +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Query +import org.springframework.data.repository.query.Param import org.springframework.stereotype.Repository +import java.time.LocalDateTime import java.util.Optional @Repository interface IngredientDetailRepository : JpaRepository { - fun findIngredientDetailByIngredientDetailIdAndIsDeletedIsFalse(ingredientDetailId: Long): Optional fun findIngredientDetailsByRefrigeratorAndIsDeletedIsFalse(refrigerator: Refrigerator): Optional> + + @Query("SELECT count(i) from IngredientDetail i where i.refrigerator in (?1) and i.expirationDate between now() and ?2") + fun findIngredientDetailCountByRefrigeratorAndExpirationDate(refrigerator: List, expirationDay: LocalDateTime): Long + + @Query("SELECT i from IngredientDetail i where i.refrigerator in (?1)") + fun findByRefrigerators(@Param("refrigerators")refrigerators: List, pageable: Pageable): Page } diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailService.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailService.kt index f4d070d..d2c7aca 100644 --- a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailService.kt +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailService.kt @@ -1,15 +1,23 @@ package mara.server.domain.ingredient import mara.server.domain.refrigerator.RefrigeratorRepository +import mara.server.domain.user.UserService +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional +import java.time.LocalDateTime @Service class IngredientDetailService( private val ingredientDetailRepository: IngredientDetailRepository, private val refrigeratorRepository: RefrigeratorRepository, - private val ingredientRepository: IngredientRepository + private val ingredientRepository: IngredientRepository, + private val userService: UserService ) { + private val deleted = "deleted" + @Transactional fun createIngredientDetail(ingredientDetailRequest: IngredientDetailRequest): Long { val refrigeratorId = ingredientDetailRequest.refrigeratorId val refrigerator = refrigeratorRepository.findById(refrigeratorId) @@ -34,7 +42,7 @@ class IngredientDetailService( } fun getIngredientDetail(id: Long): IngredientDetailResponse { - val ingredientDetail = ingredientDetailRepository.findIngredientDetailByIngredientDetailIdAndIsDeletedIsFalse(id) + val ingredientDetail = ingredientDetailRepository.findById(id) .orElseThrow { NoSuchElementException("해당 식재료 상세가 존재하지 않습니다. ID: $id") } return IngredientDetailResponse(ingredientDetail) } @@ -45,9 +53,30 @@ class IngredientDetailService( val ingredientDetailList = ingredientDetailRepository.findIngredientDetailsByRefrigeratorAndIsDeletedIsFalse(refrigerator) .orElseThrow { NoSuchElementException("해당 식재료 상세가 존재하지 않습니다. ID: $refrigeratorId") } - return ingredientDetailList.toIngredientResponseList() + return ingredientDetailList.toIngredientDetailResponseList() + } + + fun getIngredientDetailCount(days: Long): Long { + val user = userService.getCurrentLoginUser() + val refrigeratorList = refrigeratorRepository.findRefrigeratorsByUser(user) + val expirationDate = LocalDateTime.now().plusDays(days) + + return ingredientDetailRepository.findIngredientDetailCountByRefrigeratorAndExpirationDate( + refrigeratorList, + expirationDate + ) + } + + fun getIngredientDetailRecent(pageable: Pageable): Page { + val user = userService.getCurrentLoginUser() + val refrigeratorList = refrigeratorRepository.findRefrigeratorsByUser(user) + val ingredientDetailRecentList = + ingredientDetailRepository.findByRefrigerators(refrigeratorList, pageable) + + return ingredientDetailRecentList.toIngredientDetailResponseListPage() } + @Transactional fun updateIngredientDetail( id: Long, ingredientDetailUpdateRequest: IngredientDetailUpdateRequest @@ -58,11 +87,12 @@ class IngredientDetailService( return IngredientDetailResponse(ingredientDetailRepository.save(ingredientDetail)) } + @Transactional fun deleteIngredientDetail(id: Long): String { val ingredientDetail = ingredientDetailRepository.findById(id) .orElseThrow { NoSuchElementException("해당 식재료 상세가 존재하지 않습니다. ID: $id") } ingredientDetail.delete() ingredientDetailRepository.save(ingredientDetail) - return "deleted" + return deleted } } diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDto.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDto.kt index 7fc2467..6232b5d 100644 --- a/src/main/kotlin/mara/server/domain/ingredient/IngredientDto.kt +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDto.kt @@ -23,6 +23,32 @@ data class IngredientResponse( ) } +data class IngredientGroupResponse( + val category: String, + val ingredientGroupList: List +) { + constructor(ingredientList: List) : this( + category = ingredientList.firstOrNull()?.category ?: "", + ingredientGroupList = ingredientList.map { IngredientGroup(it) } + ) +} + +data class IngredientGroup( + val id: Long, + val name: String, + val iconImage: String +) { + constructor(ingredient: Ingredient) : this( + id = ingredient.ingredientId, + name = ingredient.name, + iconImage = ingredient.iconImage + ) +} + fun List.toIngredientResponseList(): List { return this.map { IngredientResponse(it) } } + +fun List.toIngredientCategoryGroupResponseList(): List { + return this.groupBy { it.category }.values.map { IngredientGroupResponse(it) } +} diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientService.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientService.kt index 21d37fc..0cbe80f 100644 --- a/src/main/kotlin/mara/server/domain/ingredient/IngredientService.kt +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientService.kt @@ -1,12 +1,15 @@ package mara.server.domain.ingredient import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service class IngredientService( - private val ingredientRepository: IngredientRepository + private val ingredientRepository: IngredientRepository, ) { + private val deleted = "deleted" + @Transactional fun createIngredient(ingredientRequest: IngredientRequest): Long { val ingredient = Ingredient( category = ingredientRequest.category, @@ -18,7 +21,8 @@ class IngredientService( } fun getIngredient(id: Long): IngredientResponse { - val ingredient = ingredientRepository.findById(id).orElseThrow { NoSuchElementException("해당 식재료가 존재하지 않습니다. ID: $id") } + val ingredient = + ingredientRepository.findById(id).orElseThrow { NoSuchElementException("해당 식재료가 존재하지 않습니다. ID: $id") } return IngredientResponse(ingredient) } @@ -27,14 +31,22 @@ class IngredientService( return ingredientList.toIngredientResponseList() } + fun getIngredientListByCategory(): List { + val ingredientList = ingredientRepository.findAll() + return ingredientList.toIngredientCategoryGroupResponseList() + } + + @Transactional fun updateIngredient(id: Long, ingredientRequest: IngredientRequest): IngredientResponse { - val ingredient = ingredientRepository.findById(id).orElseThrow { NoSuchElementException("해당 식재료가 존재하지 않습니다. ID: $id") } + val ingredient = + ingredientRepository.findById(id).orElseThrow { NoSuchElementException("해당 식재료가 존재하지 않습니다. ID: $id") } ingredient.update(ingredientRequest) return IngredientResponse(ingredientRepository.save(ingredient)) } + @Transactional fun deleteIngredient(id: Long): String { ingredientRepository.deleteById(id) - return "deleted" + return deleted } } diff --git a/src/main/kotlin/mara/server/domain/refrigerator/Refrigerator.kt b/src/main/kotlin/mara/server/domain/refrigerator/Refrigerator.kt index 4b7de4d..de0f3b1 100644 --- a/src/main/kotlin/mara/server/domain/refrigerator/Refrigerator.kt +++ b/src/main/kotlin/mara/server/domain/refrigerator/Refrigerator.kt @@ -23,7 +23,7 @@ class Refrigerator( @Column(name = "refrigerator_id", nullable = false) val refrigeratorId: Long = 0L - fun update(refrigeratorUpdateRequest: RefrigeratorUpdateRequest) { - this.name = refrigeratorUpdateRequest.name + fun update(refrigeratorRequest: RefrigeratorRequest) { + this.name = refrigeratorRequest.name } } diff --git a/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorController.kt b/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorController.kt index 9600834..d813a17 100644 --- a/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorController.kt +++ b/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorController.kt @@ -34,9 +34,9 @@ class RefrigeratorController( @PutMapping("/{id}") fun updateRefrigerator( @PathVariable(name = "id") id: Long, - @RequestBody refrigeratorUpdateRequest: RefrigeratorUpdateRequest + @RequestBody refrigeratorRequest: RefrigeratorRequest ): CommonResponse { - return success(refrigeratorService.updateRefrigerator(id, refrigeratorUpdateRequest)) + return success(refrigeratorService.updateRefrigerator(id, refrigeratorRequest)) } @DeleteMapping("/{id}") diff --git a/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorDto.kt b/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorDto.kt index 8093775..6e0efab 100644 --- a/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorDto.kt +++ b/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorDto.kt @@ -1,11 +1,6 @@ package mara.server.domain.refrigerator data class RefrigeratorRequest( - var name: String, - val userId: Long -) - -data class RefrigeratorUpdateRequest( var name: String ) diff --git a/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorService.kt b/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorService.kt index 79e4d42..5f62952 100644 --- a/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorService.kt +++ b/src/main/kotlin/mara/server/domain/refrigerator/RefrigeratorService.kt @@ -1,17 +1,17 @@ package mara.server.domain.refrigerator -import mara.server.domain.user.UserRepository +import mara.server.domain.user.UserService import org.springframework.stereotype.Service @Service class RefrigeratorService( private val refrigeratorRepository: RefrigeratorRepository, - private val userRepository: UserRepository + private val userService: UserService ) { + private val deleted = "deleted" + fun createRefrigerator(refrigeratorRequest: RefrigeratorRequest): Long { - val userId = refrigeratorRequest.userId - val user = - userRepository.findById(userId).orElseThrow { NoSuchElementException("해당 유저가 존재하지 않습니다. ID: $userId") } + val user = userService.getCurrentLoginUser() val refrigerator = Refrigerator( name = refrigeratorRequest.name, user = user @@ -26,21 +26,20 @@ class RefrigeratorService( } fun getRefrigeratorList(userId: Long): List { - val user = - userRepository.findById(userId).orElseThrow { NoSuchElementException("해당 유저가 존재하지 않습니다. ID: $userId") } + val user = userService.getCurrentLoginUser() val refrigeratorList = refrigeratorRepository.findRefrigeratorsByUser(user) return refrigeratorList.toRefrigeratorResponseList() } - fun updateRefrigerator(id: Long, refrigeratorUpdateRequest: RefrigeratorUpdateRequest): RefrigeratorResponse { + fun updateRefrigerator(id: Long, refrigeratorRequest: RefrigeratorRequest): RefrigeratorResponse { val refrigerator = refrigeratorRepository.findById(id).orElseThrow { NoSuchElementException("해당 냉장고가 존재하지 않습니다. ID: $id") } - refrigerator.update(refrigeratorUpdateRequest) + refrigerator.update(refrigeratorRequest) return RefrigeratorResponse(refrigeratorRepository.save(refrigerator)) } fun deleteRefrigerator(id: Long): String { refrigeratorRepository.deleteById(id) - return "deleted" + return deleted } } diff --git a/src/main/kotlin/mara/server/domain/share/ShareService.kt b/src/main/kotlin/mara/server/domain/share/ShareService.kt index 50adee3..65f60a3 100644 --- a/src/main/kotlin/mara/server/domain/share/ShareService.kt +++ b/src/main/kotlin/mara/server/domain/share/ShareService.kt @@ -20,7 +20,7 @@ class ShareService( fun createShare(shareRequest: ShareRequest): Long { val ingredientDetailId = shareRequest.ingredientDetailId val ingredientDetail = - ingredientDetailRepository.findIngredientDetailByIngredientDetailIdAndIsDeletedIsFalse(ingredientDetailId) + ingredientDetailRepository.findById(ingredientDetailId) .orElseThrow { NoSuchElementException("해당 식재료가 존재하지 않습니다. ID: $ingredientDetailId") } val user = userService.getCurrentLoginUser() // 생성 보단 조회가 빈번 할것 같아, 매번 조회 할 때마다, 일자와 시간을 분리하기 보단, 저장 할 때 각각 & 일자+시간 저장 하는 방식으로 진행 @@ -97,7 +97,7 @@ class ShareService( val share = getShare(shareId) if (ingredientDetailId != share.ingredientDetail.ingredientDetailId) { val ingredientDetail = - ingredientDetailRepository.findIngredientDetailByIngredientDetailIdAndIsDeletedIsFalse( + ingredientDetailRepository.findById( ingredientDetailId ) .orElseThrow { NoSuchElementException("해당 식재료가 존재하지 않습니다. ID: $ingredientDetailId") }