Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.ecommerce.application.port.`in`.OrderUseCase
import com.ecommerce.application.port.out.CouponPort
import com.ecommerce.application.port.out.ItemPort
import com.ecommerce.application.port.out.OrderPort
import com.ecommerce.domain.coupon.Coupon
import com.ecommerce.domain.event.DeductStockEvent
import com.ecommerce.domain.order.Order
import org.springframework.context.ApplicationEventPublisher
Expand All @@ -27,11 +28,7 @@ class OrderService(
val items = itemPort.getItemsIn(orderItems.map { it.itemId })
items.forEach { it.isSelling() }

order.calculateOriginPrice(items)

order.couponId?.let {
applyCouponTo(order)
}
order.calculatePrice(items, applyCouponTo(order))

order = orderPort.commandOrder(order)

Expand All @@ -41,11 +38,13 @@ class OrderService(
return order
}

private fun applyCouponTo(order: Order) {
private fun applyCouponTo(order: Order): Coupon {
if (order.couponId == null) return Coupon.none()

val userCoupon = couponPort.findUserCouponBy(order.couponId!!, order.userId)
couponPort.commandUserCoupon(userCoupon.use())

order.calculateDiscountPrice(userCoupon.coupon)
return userCoupon.coupon
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,21 @@ class Coupon(
override fun calculateDiscount(price: BigDecimal, discount: Long): BigDecimal {
return BigDecimal.valueOf(discount)
}
},
NONE {
override fun calculateDiscount(price: BigDecimal, discount: Long): BigDecimal {
return BigDecimal.ZERO
}
};

abstract fun calculateDiscount(price: BigDecimal, discount: Long): BigDecimal
}

companion object {
fun none(): Coupon =
Coupon(0L, "none", DiscountType.NONE, 0L, 0, 0L)
}

fun calculateDiscount(price: BigDecimal): BigDecimal {
return this.type.calculateDiscount(price, this.discount)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,16 @@ class Order(
PENDING, COMPLETED, CANCEL
}

fun calculateOriginPrice(items: List<Item>) {
fun calculatePrice(items: List<Item>, coupon: Coupon) {
val quantityOfItem = this.orderItems.associate { it.itemId to BigDecimal.valueOf(it.quantity) }

this.originPrice = items.sumOf {
it.price * quantityOfItem[it.id]!!
it.price * quantityOfItem[it.id]!!
}

this.totalPrice = this.originPrice
}

fun calculateDiscountPrice(coupon: Coupon) {
this.discountPrice = coupon.calculateDiscount(this.originPrice)

this.totalPrice = this.originPrice - this.discountPrice
this.totalPrice = this.originPrice.minus(this.discountPrice)
}

fun complete(): Order {
Expand Down
65 changes: 29 additions & 36 deletions ecommerce-domain/src/test/kotlin/com/ecommerce/domain/OrderTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import com.ecommerce.domain.order.OrderItem
import org.assertj.core.api.Assertions.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.DynamicTest
import org.junit.jupiter.api.TestFactory
import org.junit.jupiter.api.Test
import java.math.BigDecimal

class OrderTest {
Expand All @@ -30,45 +29,39 @@ class OrderTest {
}
}

@DisplayName("주문 금액 계산")
@TestFactory
fun calculateOrderPrice(): List<DynamicTest> {
@DisplayName("쿠폰 타입별 주문 금액 계산")
@Test
fun calculateOrderPriceOnCouponType() {
// given
val orderQuantity = 2L
val orderItem = items.map { OrderItem(null, it.id, orderQuantity) }
val order = Order(null, 1L, 1L, orderItem)

var expectOriginPrice = BigDecimal.ZERO

return listOf(
DynamicTest.dynamicTest("총 주문 금액이 계산 된다.") {
// when
order.calculateOriginPrice(items)

// then
expectOriginPrice = items.sumOf {
it.price * (BigDecimal.valueOf(orderQuantity))
}
assertThat(order.originPrice).isEqualTo(expectOriginPrice)
assertThat(order.originPrice).isEqualTo(order.totalPrice)
},
DynamicTest.dynamicTest("할인 금액 계산") {
val coupon = Coupon(1L, "쿠폰 A", Coupon.DiscountType.RATE, 10L, 30, 10L)
val testCases = listOf(
Coupon(1L, "10% 할인", Coupon.DiscountType.RATE, 10L, 30, 10L),
Coupon(2L, "1,000원 할인", Coupon.DiscountType.AMOUNT, 1000L, 30, 10L),
Coupon(0L, "할인 없음", Coupon.DiscountType.NONE, 0L, 0, 0L)
)

// when
order.calculateDiscountPrice(coupon)
testCases.forEach { coupon ->
// when
val orderQuantity = 2L
val orderItem = items.map { OrderItem(null, it.id, orderQuantity) }
val order = Order(null, 1L, 1L, orderItem)

// then
val expectDiscountPrice = expectOriginPrice * (
BigDecimal.valueOf(coupon.discount).divide(BigDecimal.valueOf(100))
)
assertThat(order.discountPrice).isEqualTo(expectDiscountPrice)
order.calculatePrice(items, coupon)

val expectTotalPrice = expectOriginPrice - expectDiscountPrice
assertThat(expectOriginPrice).isNotEqualTo(expectTotalPrice)
assertThat(order.totalPrice).isEqualTo(expectTotalPrice)
// then
val expectOriginPrice = items.sumOf {
it.price * (BigDecimal.valueOf(orderQuantity))
}
)
val expectDiscountPrice = when (coupon.type) {
Coupon.DiscountType.RATE -> expectOriginPrice * BigDecimal.valueOf(coupon.discount).divide(BigDecimal.valueOf(100))
Coupon.DiscountType.AMOUNT -> BigDecimal.valueOf(coupon.discount)
Coupon.DiscountType.NONE -> BigDecimal.ZERO
}
val expectTotalPrice = expectOriginPrice.minus(expectDiscountPrice)

assertThat(order.originPrice).isEqualTo(expectOriginPrice)
assertThat(order.discountPrice).isEqualTo(expectDiscountPrice)
assertThat(order.totalPrice).isEqualTo(expectTotalPrice)
}
}

}