Skip to content

Commit

Permalink
MARA-30 : 식재료 상세 CRUD 기능 구현 (#11)
Browse files Browse the repository at this point in the history
* 식재료(Ingredient) 껍데기 구현

* 식재료 생성 기능 구현

* 식재료 조회 기능 구현

* 식재료 업데이트 기능 구현

* 식재료 삭제 기능 구현

* 식재료 전체 조회 기능 구현

* ktlint 적용

* 식재료 상세 엔티티, 컨트롤러 껍데기 구현

* 식재료 상세 서비스 껍데기 구현

* 식재료 상세 Repository, RequestDTO 구현

* 식재료 상세 CRUD 구현

* 냉장고 ID 기준 식재료 상세 조회 껍데기 구현

* 식재료 상세 Request, Response DTO 통합

* ingredientDetailId var -> val 변경

* ingredientDetail request, response DTO 통합

* 냉장고 id별 식재료 상세 리스트 조회 기능 구현

* ktlint 적용

* ingredientDetailUpdateRequest 구현

* memo -> nullable , isDeleted -> not null 반영

* 조회 조건 isDeleted is false 추가

* /det -> /detail 명시화

* isDeleted 기본 값 false 설정

* request memo nullable 적용 및 entity isDeleted default value false 적용
  • Loading branch information
jhkang1517 authored Jan 26, 2024
1 parent 8832194 commit 741fddb
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 0 deletions.
45 changes: 45 additions & 0 deletions src/main/kotlin/mara/server/domain/ingredient/IngredientDetail.kt
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -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<Long> {
return success(ingredientDetailService.createIngredientDetail(ingredientDetailRequest))
}

@GetMapping("/{id}")
fun getIngredientDetail(@PathVariable(name = "id") id: Long): CommonResponse<IngredientDetailResponse> {
return success(ingredientDetailService.getIngredientDetail(id))
}

@GetMapping("/refrig/{id}")
fun getIngredientDetailList(@PathVariable(name = "id") refrigeratorId: Long): CommonResponse<List<IngredientDetailResponse>> {
return success(ingredientDetailService.getIngredientDetailList(refrigeratorId))
}

@PutMapping("/{id}")
fun updateIngredientDetail(@PathVariable(name = "id") id: Long, @RequestBody ingredientDetailUpdateRequest: IngredientDetailUpdateRequest): CommonResponse<IngredientDetailResponse> {
return success(ingredientDetailService.updateIngredientDetail(id, ingredientDetailUpdateRequest))
}

@DeleteMapping("/{id}")
fun deleteIngredient(@PathVariable(name = "id") id: Long): CommonResponse<String> {
return success(ingredientDetailService.deleteIngredientDetail(id))
}
}
Original file line number Diff line number Diff line change
@@ -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<IngredientDetail>.toIngredientResponseList(): List<IngredientDetailResponse> {
return this.map { IngredientDetailResponse(it) }
}
Original file line number Diff line number Diff line change
@@ -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<IngredientDetail, Long> {

fun findIngredientDetailByIngredientDetailIdAndIsDeletedIsFalse(ingredientDetailId: Long): Optional<IngredientDetail>
fun findIngredientDetailsByRefrigeratorAndIsDeletedIsFalse(refrigerator: Refrigerator): Optional<List<IngredientDetail>>
}
Original file line number Diff line number Diff line change
@@ -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<IngredientDetailResponse> {
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"
}
}

0 comments on commit 741fddb

Please sign in to comment.