diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetail.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetail.kt new file mode 100644 index 0000000..8f1c6db --- /dev/null +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetail.kt @@ -0,0 +1,45 @@ +package mara.server.domain.ingredient + +import jakarta.persistence.Entity +import jakarta.persistence.FetchType +import jakarta.persistence.GeneratedValue +import jakarta.persistence.GenerationType +import jakarta.persistence.Id +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne +import mara.server.domain.refrigerator.Refrigerator +import java.time.LocalDateTime + +@Entity +class IngredientDetail( + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "refrigeratorId") + val refrigerator: Refrigerator, + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "ingredientId") + val ingredient: Ingredient, + var quantity: Int, + var location: String, + var memo: String?, + var addDate: LocalDateTime, + var expirationDate: LocalDateTime, + var isDeleted: Boolean = false +) { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val ingredientDetailId: Long = 0L + + fun update(ingredientDetailUpdateRequest: IngredientDetailUpdateRequest) { + this.quantity = ingredientDetailUpdateRequest.quantity + this.location = ingredientDetailUpdateRequest.location + this.memo = ingredientDetailUpdateRequest.memo + this.addDate = ingredientDetailUpdateRequest.addDate + this.expirationDate = ingredientDetailUpdateRequest.expirationDate + this.isDeleted = ingredientDetailUpdateRequest.isDeleted + } + + fun delete() { + this.isDeleted = true + } +} diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailController.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailController.kt new file mode 100644 index 0000000..c2be7ee --- /dev/null +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailController.kt @@ -0,0 +1,44 @@ +package mara.server.domain.ingredient + +import mara.server.common.CommonResponse +import mara.server.common.success +import org.springframework.web.bind.annotation.DeleteMapping +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.PutMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/ingrs/detail") +class IngredientDetailController( + private val ingredientDetailService: IngredientDetailService +) { + + @PostMapping + fun createIngredientDetail(@RequestBody ingredientDetailRequest: IngredientDetailRequest): CommonResponse { + return success(ingredientDetailService.createIngredientDetail(ingredientDetailRequest)) + } + + @GetMapping("/{id}") + fun getIngredientDetail(@PathVariable(name = "id") id: Long): CommonResponse { + return success(ingredientDetailService.getIngredientDetail(id)) + } + + @GetMapping("/refrig/{id}") + fun getIngredientDetailList(@PathVariable(name = "id") refrigeratorId: Long): CommonResponse> { + return success(ingredientDetailService.getIngredientDetailList(refrigeratorId)) + } + + @PutMapping("/{id}") + fun updateIngredientDetail(@PathVariable(name = "id") id: Long, @RequestBody ingredientDetailUpdateRequest: IngredientDetailUpdateRequest): CommonResponse { + return success(ingredientDetailService.updateIngredientDetail(id, ingredientDetailUpdateRequest)) + } + + @DeleteMapping("/{id}") + fun deleteIngredient(@PathVariable(name = "id") id: Long): CommonResponse { + return success(ingredientDetailService.deleteIngredientDetail(id)) + } +} diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailDto.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailDto.kt new file mode 100644 index 0000000..83d8814 --- /dev/null +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailDto.kt @@ -0,0 +1,48 @@ +package mara.server.domain.ingredient + +import java.time.LocalDateTime + +data class IngredientDetailRequest( + var refrigeratorId: Long, + var ingredientId: Long, + val quantity: Int, + val location: String, + val memo: String?, + val addDate: LocalDateTime, + val expirationDate: LocalDateTime, + val isDeleted: Boolean = false +) + +data class IngredientDetailUpdateRequest( + val quantity: Int, + val location: String, + val memo: String?, + val addDate: LocalDateTime, + val expirationDate: LocalDateTime, + val isDeleted: Boolean = false +) + +data class IngredientDetailResponse( + val ingredientDetailId: Long, + val quantity: Int, + val location: String, + val memo: String?, + val addDate: LocalDateTime, + val expirationDate: LocalDateTime, + val isDeleted: Boolean +) { + + constructor(ingredientDetail: IngredientDetail) : this( + ingredientDetailId = ingredientDetail.ingredientDetailId, + quantity = ingredientDetail.quantity, + location = ingredientDetail.location, + memo = ingredientDetail.memo, + addDate = ingredientDetail.addDate, + expirationDate = ingredientDetail.expirationDate, + isDeleted = ingredientDetail.isDeleted + ) +} + +fun List.toIngredientResponseList(): List { + 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 new file mode 100644 index 0000000..95dcc4a --- /dev/null +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailRepository.kt @@ -0,0 +1,13 @@ +package mara.server.domain.ingredient + +import mara.server.domain.refrigerator.Refrigerator +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository +import java.util.Optional + +@Repository +interface IngredientDetailRepository : JpaRepository { + + fun findIngredientDetailByIngredientDetailIdAndIsDeletedIsFalse(ingredientDetailId: Long): Optional + fun findIngredientDetailsByRefrigeratorAndIsDeletedIsFalse(refrigerator: Refrigerator): Optional> +} diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailService.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailService.kt new file mode 100644 index 0000000..ac51c1b --- /dev/null +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailService.kt @@ -0,0 +1,67 @@ +package mara.server.domain.ingredient + +import mara.server.domain.refrigerator.RefrigeratorRepository +import org.springframework.stereotype.Service + +@Service +class IngredientDetailService( + private val ingredientDetailRepository: IngredientDetailRepository, + private val refrigeratorRepository: RefrigeratorRepository, + private val ingredientRepository: IngredientRepository +) { + + fun createIngredientDetail(ingredientDetailRequest: IngredientDetailRequest): Long { + val refrigeratorId = ingredientDetailRequest.refrigeratorId + val refrigerator = refrigeratorRepository.findById(refrigeratorId) + .orElseThrow { NoSuchElementException("해당 냉장고가 존재하지 않습니다. ID: $refrigeratorId") } + + val ingredientId = ingredientDetailRequest.ingredientId + val ingredient = ingredientRepository.findById(ingredientId) + .orElseThrow { NoSuchElementException("해당 식재료가 존재하지 않습니다. ID: $ingredientId") } + + val ingredientDetail = IngredientDetail( + refrigerator = refrigerator, + ingredient = ingredient, + quantity = ingredientDetailRequest.quantity, + location = ingredientDetailRequest.location, + memo = ingredientDetailRequest.memo, + addDate = ingredientDetailRequest.addDate, + expirationDate = ingredientDetailRequest.expirationDate, + isDeleted = ingredientDetailRequest.isDeleted + ) + return ingredientDetailRepository.save(ingredientDetail).ingredientDetailId + } + + fun getIngredientDetail(id: Long): IngredientDetailResponse { + val ingredientDetail = ingredientDetailRepository.findIngredientDetailByIngredientDetailIdAndIsDeletedIsFalse(id) + .orElseThrow { NoSuchElementException("해당 식재료 상세가 존재하지 않습니다. ID: $id") } + return IngredientDetailResponse(ingredientDetail) + } + + fun getIngredientDetailList(refrigeratorId: Long): List { + val refrigerator = refrigeratorRepository.findById(refrigeratorId) + .orElseThrow { NoSuchElementException("해당 냉장고가 존재하지 않습니다. ID: $refrigeratorId") } + val ingredientDetailList = + ingredientDetailRepository.findIngredientDetailsByRefrigeratorAndIsDeletedIsFalse(refrigerator) + .orElseThrow { NoSuchElementException("해당 식재료 상세가 존재하지 않습니다. ID: $refrigeratorId") } + return ingredientDetailList.toIngredientResponseList() + } + + fun updateIngredientDetail( + id: Long, + ingredientDetailUpdateRequest: IngredientDetailUpdateRequest + ): IngredientDetailResponse { + val ingredientDetail = ingredientDetailRepository.findById(id) + .orElseThrow { NoSuchElementException("해당 식재료 상세가 존재하지 않습니다. ID: $id") } + ingredientDetail.update(ingredientDetailUpdateRequest) + return IngredientDetailResponse(ingredientDetailRepository.save(ingredientDetail)) + } + + fun deleteIngredientDetail(id: Long): String { + val ingredientDetail = ingredientDetailRepository.findById(id) + .orElseThrow { NoSuchElementException("해당 식재료 상세가 존재하지 않습니다. ID: $id") } + ingredientDetail.delete() + ingredientDetailRepository.save(ingredientDetail) + return "deleted" + } +}