diff --git a/src/main/kotlin/com/petqua/application/cart/CartProductService.kt b/src/main/kotlin/com/petqua/application/cart/CartProductService.kt index d65fbe1f..64f4153e 100644 --- a/src/main/kotlin/com/petqua/application/cart/CartProductService.kt +++ b/src/main/kotlin/com/petqua/application/cart/CartProductService.kt @@ -4,6 +4,7 @@ import com.petqua.application.cart.dto.CartProductWithSupportedOptionResponse import com.petqua.application.cart.dto.DeleteCartProductCommand import com.petqua.application.cart.dto.SaveCartProductCommand import com.petqua.application.cart.dto.UpdateCartProductOptionCommand +import com.petqua.common.domain.Money import com.petqua.common.domain.existByIdOrThrow import com.petqua.common.domain.findByIdOrThrow import com.petqua.common.util.throwExceptionWhen @@ -27,7 +28,6 @@ import com.petqua.exception.product.ProductException import com.petqua.exception.product.ProductExceptionType.NOT_FOUND_PRODUCT import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional -import java.math.BigDecimal @Transactional @Service @@ -86,7 +86,7 @@ class CartProductService( ) } - private fun validateDeliveryFee(product: Product, deliveryMethod: DeliveryMethod, deliveryFee: BigDecimal) { + private fun validateDeliveryFee(product: Product, deliveryMethod: DeliveryMethod, deliveryFee: Money) { product.getDeliveryFee(deliveryMethod) .also { throwExceptionWhen(it != deliveryFee) { CartProductException(DIFFERENT_DELIVERY_FEE) } } } diff --git a/src/main/kotlin/com/petqua/application/cart/dto/CartProductDtos.kt b/src/main/kotlin/com/petqua/application/cart/dto/CartProductDtos.kt index a2d8a13c..00f5fe3c 100644 --- a/src/main/kotlin/com/petqua/application/cart/dto/CartProductDtos.kt +++ b/src/main/kotlin/com/petqua/application/cart/dto/CartProductDtos.kt @@ -1,5 +1,6 @@ package com.petqua.application.cart.dto +import com.petqua.common.domain.Money import com.petqua.domain.cart.CartProduct import com.petqua.domain.cart.CartProductQuantity import com.petqua.domain.delivery.DeliveryMethod @@ -14,7 +15,7 @@ data class SaveCartProductCommand( val quantity: Int, val sex: Sex, val deliveryMethod: DeliveryMethod, - val deliveryFee: BigDecimal, + val deliveryFee: Money, ) { fun toCartProduct(): CartProduct { return CartProduct( @@ -23,7 +24,7 @@ data class SaveCartProductCommand( quantity = CartProductQuantity(quantity), sex = sex, deliveryMethod = deliveryMethod, - deliveryFee = deliveryFee.setScale(2), + deliveryFee = deliveryFee, ) } } @@ -35,7 +36,7 @@ data class UpdateCartProductOptionCommand( val quantity: CartProductQuantity, val sex: Sex, val deliveryMethod: DeliveryMethod, - val deliveryFee: BigDecimal, + val deliveryFee: Money, ) data class DeleteCartProductCommand( @@ -78,7 +79,7 @@ data class CartProductWithSupportedOptionResponse( description = "상품 가격", example = "30000" ) - val productPrice: Int, + val productPrice: Money, @Schema( description = "가격 할인율", @@ -90,7 +91,7 @@ data class CartProductWithSupportedOptionResponse( description = "할인 가격(판매 가격)", example = "21000" ) - val productDiscountPrice: Int, + val productDiscountPrice: Money, @Schema( description = "봉달(장바구니) 수량", @@ -116,7 +117,7 @@ data class CartProductWithSupportedOptionResponse( description = "배송비", example = "3000" ) - val deliveryFee: BigDecimal, + val deliveryFee: Money, @Schema( description = "판매 여부(품절 및 삭제 확인)", @@ -129,37 +130,37 @@ data class CartProductWithSupportedOptionResponse( description = "안전 배송 가격 (null인 경우 지원 X)", example = "5000" ) - val safeDeliveryFee: BigDecimal?, + val safeDeliveryFee: Money?, @Schema( description = "일반 배송 가격 (null인 경우 지원 X)", example = "3000" ) - val commonDeliveryFee: BigDecimal?, + val commonDeliveryFee: Money?, @Schema( description = "픽업 배송 가격 (null인 경우 지원 X)", example = "0" ) - val pickUpDeliveryFee: BigDecimal?, + val pickUpDeliveryFee: Money?, @Schema( description = "수컷 추가 가격 (null인 경우 지원 X)", example = "1000" ) - val maleAdditionalPrice: BigDecimal?, + val maleAdditionalPrice: Money?, @Schema( description = "암컷 추가 가격 (null인 경우 지원 X)", example = "1000" ) - val femaleAdditionalPrice: BigDecimal?, + val femaleAdditionalPrice: Money?, ) { constructor( cartProductResponse: CartProductResponse, - maleAdditionalPrice: BigDecimal?, - femaleAdditionalPrice: BigDecimal?, + maleAdditionalPrice: Money?, + femaleAdditionalPrice: Money?, ) : this( id = cartProductResponse.id, storeName = cartProductResponse.storeName, @@ -188,17 +189,17 @@ data class CartProductResponse( val productId: Long, val productName: String, val productThumbnailUrl: String, - val productPrice: Int, + val productPrice: Money, val productDiscountRate: Int, - val productDiscountPrice: Int, + val productDiscountPrice: Money, val quantity: Int, val sex: Sex, val deliveryMethod: String, - val deliveryFee: BigDecimal, + val deliveryFee: Money, val isOnSale: Boolean, - val safeDeliveryFee: BigDecimal?, - val commonDeliveryFee: BigDecimal?, - val pickUpDeliveryFee: BigDecimal?, + val safeDeliveryFee: Money?, + val commonDeliveryFee: Money?, + val pickUpDeliveryFee: Money?, ) { constructor( @@ -211,9 +212,9 @@ data class CartProductResponse( productId = product?.id ?: 0L, productName = product?.name ?: "", productThumbnailUrl = product?.thumbnailUrl ?: "", - productPrice = product?.price?.intValueExact() ?: 0, + productPrice = product?.price ?: Money.from(BigDecimal.ZERO), productDiscountRate = product?.discountRate ?: 0, - productDiscountPrice = product?.discountPrice?.intValueExact() ?: 0, + productDiscountPrice = product?.discountPrice ?: Money.from(BigDecimal.ZERO), quantity = cartProduct.quantity.value, sex = cartProduct.sex, deliveryMethod = cartProduct.deliveryMethod.name, diff --git a/src/main/kotlin/com/petqua/application/order/OrderService.kt b/src/main/kotlin/com/petqua/application/order/OrderService.kt index 845592fa..60cb80a2 100644 --- a/src/main/kotlin/com/petqua/application/order/OrderService.kt +++ b/src/main/kotlin/com/petqua/application/order/OrderService.kt @@ -3,6 +3,7 @@ package com.petqua.application.order import com.petqua.application.order.dto.SaveOrderCommand import com.petqua.application.order.dto.SaveOrderResponse import com.petqua.application.payment.infra.PaymentGatewayClient +import com.petqua.common.domain.Money import com.petqua.common.domain.findByIdOrThrow import com.petqua.common.util.throwExceptionWhen import com.petqua.domain.order.Order @@ -70,8 +71,8 @@ class OrderService( ?: throw ProductException(INVALID_PRODUCT_OPTION) throwExceptionWhen( - productCommand.orderPrice.setScale(2) != (product.discountPrice + productOption.additionalPrice) * productCommand.quantity.toBigDecimal() - || productCommand.deliveryFee.setScale(2) != product.getDeliveryFee(productCommand.deliveryMethod) + productCommand.orderPrice != (product.discountPrice + productOption.additionalPrice) * productCommand.quantity.toBigDecimal() + || productCommand.deliveryFee != product.getDeliveryFee(productCommand.deliveryMethod) ) { OrderException( ORDER_PRICE_NOT_MATCH @@ -89,11 +90,11 @@ class OrderService( } val orderDeliveryFee = groupBy.map { (storeDeliveryMethod, products) -> val deliveryMethod = storeDeliveryMethod.second - products.first().getDeliveryFee(deliveryMethod).toInt() + products.first().getDeliveryFee(deliveryMethod).value.toInt() // TODO int로 바꾼 이유? }.sum() // 4. 총 결제 금액 검증 - throwExceptionWhen(command.totalAmount != orderDeliveryFee.toBigDecimal() + command.orderProductCommands.sumOf { it.orderPrice }) { + throwExceptionWhen(command.totalAmount != Money.from(orderDeliveryFee.toBigDecimal() + command.orderProductCommands.sumOf { it.orderPrice.value })) { OrderException( ORDER_PRICE_NOT_MATCH ) diff --git a/src/main/kotlin/com/petqua/application/order/dto/OrderDtos.kt b/src/main/kotlin/com/petqua/application/order/dto/OrderDtos.kt index f432a8da..ef36fedc 100644 --- a/src/main/kotlin/com/petqua/application/order/dto/OrderDtos.kt +++ b/src/main/kotlin/com/petqua/application/order/dto/OrderDtos.kt @@ -1,31 +1,31 @@ package com.petqua.application.order.dto +import com.petqua.common.domain.Money import com.petqua.domain.delivery.DeliveryMethod import com.petqua.domain.order.OrderProduct import com.petqua.domain.order.ShippingNumber import com.petqua.domain.product.Product import com.petqua.domain.product.option.ProductOption import com.petqua.domain.product.option.Sex -import java.math.BigDecimal data class SaveOrderCommand( val memberId: Long, val shippingAddressId: Long, val shippingRequest: String?, val orderProductCommands: List, - val totalAmount: BigDecimal, + val totalAmount: Money, ) data class OrderProductCommand( val productId: Long, val quantity: Int, - val originalPrice: BigDecimal, + val originalPrice: Money, val discountRate: Int, - val discountPrice: BigDecimal, - val orderPrice: BigDecimal, + val discountPrice: Money, + val orderPrice: Money, val sex: Sex, - val additionalPrice: BigDecimal, - val deliveryFee: BigDecimal, + val additionalPrice: Money, + val deliveryFee: Money, val deliveryMethod: DeliveryMethod, ) { @@ -33,7 +33,7 @@ data class OrderProductCommand( return ProductOption( sex = sex, productId = productId, - additionalPrice = additionalPrice.setScale(2), + additionalPrice = additionalPrice, ) } @@ -44,12 +44,12 @@ data class OrderProductCommand( ): OrderProduct { return OrderProduct( quantity = quantity, - originalPrice = originalPrice.setScale(2), + originalPrice = originalPrice, discountRate = discountRate, - discountPrice = discountPrice.setScale(2), - deliveryFee = deliveryFee.setScale(2), + discountPrice = discountPrice, + deliveryFee = deliveryFee, shippingNumber = shippingNumber, - orderPrice = orderPrice.setScale(2), + orderPrice = orderPrice, productId = productId, productName = product.name, thumbnailUrl = product.thumbnailUrl, diff --git a/src/main/kotlin/com/petqua/application/payment/PaymentDtos.kt b/src/main/kotlin/com/petqua/application/payment/PaymentDtos.kt index 05af9714..38d2b50f 100644 --- a/src/main/kotlin/com/petqua/application/payment/PaymentDtos.kt +++ b/src/main/kotlin/com/petqua/application/payment/PaymentDtos.kt @@ -1,18 +1,18 @@ package com.petqua.application.payment +import com.petqua.common.domain.Money import com.petqua.domain.order.OrderNumber import com.petqua.domain.payment.tosspayment.TossPaymentType import com.petqua.exception.payment.FailPaymentCode import com.petqua.exception.payment.FailPaymentException import com.petqua.exception.payment.FailPaymentExceptionType.ORDER_NUMBER_MISSING_EXCEPTION -import java.math.BigDecimal data class SucceedPaymentCommand( val memberId: Long, val paymentType: TossPaymentType, val orderNumber: OrderNumber, val paymentKey: String, - val amount: BigDecimal, + val amount: Money, ) { fun toPaymentConfirmRequest(): PaymentConfirmRequestToPG { return PaymentConfirmRequestToPG( @@ -28,7 +28,7 @@ data class SucceedPaymentCommand( paymentType: String, orderId: String, paymentKey: String, - amount: BigDecimal, + amount: Money, ): SucceedPaymentCommand { return SucceedPaymentCommand( memberId = memberId, diff --git a/src/main/kotlin/com/petqua/application/payment/PaymentGatewayDtos.kt b/src/main/kotlin/com/petqua/application/payment/PaymentGatewayDtos.kt index 91664721..f801cb08 100644 --- a/src/main/kotlin/com/petqua/application/payment/PaymentGatewayDtos.kt +++ b/src/main/kotlin/com/petqua/application/payment/PaymentGatewayDtos.kt @@ -1,17 +1,17 @@ package com.petqua.application.payment +import com.petqua.common.domain.Money import com.petqua.domain.order.OrderName import com.petqua.domain.order.OrderNumber import com.petqua.domain.payment.tosspayment.TossPayment import com.petqua.domain.payment.tosspayment.TossPaymentMethod import com.petqua.domain.payment.tosspayment.TossPaymentStatus import com.petqua.domain.payment.tosspayment.TossPaymentType -import java.math.BigDecimal data class PaymentConfirmRequestToPG( val orderNumber: OrderNumber, val paymentKey: String, - val amount: BigDecimal, + val amount: Money, ) data class PaymentResponseFromPG( @@ -23,18 +23,18 @@ data class PaymentResponseFromPG( val mid: String, val currency: String, val method: String, - val totalAmount: BigDecimal, - val balanceAmount: BigDecimal, + val totalAmount: Money, + val balanceAmount: Money, val status: String, val requestedAt: String, val approvedAt: String, val useEscrow: Boolean, val lastTransactionKey: String?, - val suppliedAmount: BigDecimal, - val vat: BigDecimal, + val suppliedAmount: Money, + val vat: Money, val cultureExpense: Boolean, - val taxFreeAmount: BigDecimal, - val taxExemptionAmount: BigDecimal, + val taxFreeAmount: Money, + val taxExemptionAmount: Money, val cancels: List?, val isPartialCancelable: Boolean, val card: CardResponseFromPG?, @@ -69,19 +69,19 @@ data class PaymentResponseFromPG( } data class CancelResponseFromPG( - val cancelAmount: BigDecimal, + val cancelAmount: Money, val cancelReason: String, - val taxFreeAmount: BigDecimal, - val taxExemptionAmount: BigDecimal, - val refundableAmount: BigDecimal, - val easyPayDiscountAmount: BigDecimal, + val taxFreeAmount: Money, + val taxExemptionAmount: Money, + val refundableAmount: Money, + val easyPayDiscountAmount: Money, val canceledAt: String, val transactionKey: String, val receiptKey: String?, ) data class CardResponseFromPG( - val amount: BigDecimal, + val amount: Money, val issuerCode: String, val acquirerCode: String?, val number: String, @@ -139,8 +139,8 @@ data class CheckoutResponseFromPG( data class EasyPayResponseFromPG( val provider: String, - val amount: BigDecimal, - val discountAmount: BigDecimal, + val amount: Money, + val discountAmount: Money, ) data class FailureResponseFromPG( @@ -153,8 +153,8 @@ data class CashReceiptResponseFromPG( val receiptKey: String, val issueNumber: String, val receiptUrl: String, - val amount: BigDecimal, - val taxFreeAmount: BigDecimal, + val amount: Money, + val taxFreeAmount: Money, ) data class CashReceiptHistoryResponseFromPG( @@ -166,8 +166,8 @@ data class CashReceiptHistoryResponseFromPG( val receiptUrl: String, val businessNumber: String, val transactionType: String, - val amount: BigDecimal, - val taxFreeAmount: BigDecimal, + val amount: Money, + val taxFreeAmount: Money, val issueStatus: String, val failure: FailureResponseFromPG, val customerIdentityNumber: String, @@ -175,7 +175,7 @@ data class CashReceiptHistoryResponseFromPG( ) data class DiscountResponseFromPG( - val amount: BigDecimal, + val amount: Money, ) data class PaymentErrorResponseFromPG( diff --git a/src/main/kotlin/com/petqua/application/payment/PaymentService.kt b/src/main/kotlin/com/petqua/application/payment/PaymentService.kt index d3cf53ee..3bc005f4 100644 --- a/src/main/kotlin/com/petqua/application/payment/PaymentService.kt +++ b/src/main/kotlin/com/petqua/application/payment/PaymentService.kt @@ -26,7 +26,7 @@ class PaymentService( OrderException(ORDER_NOT_FOUND) } order.validateOwner(command.memberId) - order.validateAmount(command.amount.setScale(2)) + order.validateAmount(command.amount) } fun processPayment(tossPayment: TossPayment): OrderPayment { diff --git a/src/main/kotlin/com/petqua/application/product/dto/ProductDtos.kt b/src/main/kotlin/com/petqua/application/product/dto/ProductDtos.kt index 7559ea2c..2d85d275 100644 --- a/src/main/kotlin/com/petqua/application/product/dto/ProductDtos.kt +++ b/src/main/kotlin/com/petqua/application/product/dto/ProductDtos.kt @@ -1,5 +1,6 @@ package com.petqua.application.product.dto +import com.petqua.common.domain.Money import com.petqua.common.domain.dto.CursorBasedPaging import com.petqua.common.domain.dto.DEFAULT_LAST_VIEWED_ID import com.petqua.common.domain.dto.PADDING_FOR_HAS_NEXT_PAGE @@ -15,7 +16,6 @@ import com.petqua.domain.product.dto.ProductSearchCondition import com.petqua.domain.product.dto.ProductWithInfoResponse import com.petqua.domain.product.review.ProductReviewRecommendation import io.swagger.v3.oas.annotations.media.Schema -import java.math.BigDecimal data class ProductDetailResponse( @Schema( @@ -46,7 +46,7 @@ data class ProductDetailResponse( description = "상품 가격", example = "30000" ) - val price: Int, + val price: Money, @Schema( description = "상품 판매점", @@ -64,7 +64,7 @@ data class ProductDetailResponse( description = "할인 가격(판매 가격)", example = "21000" ) - val discountPrice: Int, + val discountPrice: Money, @Schema( description = "찜 개수", @@ -112,31 +112,31 @@ data class ProductDetailResponse( description = "안전 배송 가격", example = "5000" ) - val safeDeliveryFee: BigDecimal?, + val safeDeliveryFee: Money?, @Schema( description = "일반 배송 가격", example = "3000" ) - val commonDeliveryFee: BigDecimal?, + val commonDeliveryFee: Money?, @Schema( description = "픽업 배송 가격", example = "0" ) - val pickUpDeliveryFee: BigDecimal?, + val pickUpDeliveryFee: Money?, @Schema( description = "수컷 추가 가격 (null인 경우 지원 X)", example = "0" ) - val maleAdditionalPrice: BigDecimal?, + val maleAdditionalPrice: Money?, @Schema( description = "암컷 추가 가격 (null인 경우 지원 X)", example = "2000" ) - val femaleAdditionalPrice: BigDecimal?, + val femaleAdditionalPrice: Money?, @Schema( description = "사육 온도 최소", @@ -179,8 +179,8 @@ data class ProductDetailResponse( imageUrls: List, descriptionImageUrls: List, isWished: Boolean, - maleAdditionalPrice: BigDecimal?, - femaleAdditionalPrice: BigDecimal?, + maleAdditionalPrice: Money?, + femaleAdditionalPrice: Money?, ) : this( id = productWithInfoResponse.id, name = productWithInfoResponse.name, diff --git a/src/main/kotlin/com/petqua/common/config/DataInitializer.kt b/src/main/kotlin/com/petqua/common/config/DataInitializer.kt index 4ae3b5c1..7cbc5849 100644 --- a/src/main/kotlin/com/petqua/common/config/DataInitializer.kt +++ b/src/main/kotlin/com/petqua/common/config/DataInitializer.kt @@ -1,5 +1,6 @@ package com.petqua.common.config +import com.petqua.common.domain.Money import com.petqua.domain.announcement.Announcement import com.petqua.domain.announcement.AnnouncementRepository import com.petqua.domain.auth.Authority.MEMBER @@ -183,15 +184,15 @@ class DataInitializer( else -> category2.id } val safeDeliveryFee = when { - (it % 4) == 0 -> 5000.toBigDecimal() + (it % 4) == 0 -> Money.from(5000L) else -> null } val commonDeliveryFee = when { - (it % 5) == 0 -> 3000.toBigDecimal() + (it % 5) == 0 -> Money.from(3000L) else -> null } val pickUpDeliveryFee = when { - (it % 2) == 0 -> BigDecimal.ZERO + (it % 2) == 0 -> Money.from(0L) else -> null } val reviewCount = (1..5).random() @@ -220,10 +221,10 @@ class DataInitializer( Product( name = "상품$it", categoryId = categoryId, - price = BigDecimal.valueOf(80000L).setScale(2), + price = Money.from(80000L), storeId = store.id, discountRate = 50, - discountPrice = BigDecimal(40000L).setScale(2), + discountPrice = Money.from(40000L), wishCount = WishCount(100), reviewCount = reviewCount, reviewTotalScore = (1..reviewCount).sum(), @@ -247,7 +248,7 @@ class DataInitializer( ProductOption( productId = it.id, sex = sex, - additionalPrice = BigDecimal.ZERO, + additionalPrice = Money.from(0L), ) } productOptionRepository.saveAll(productOptions) diff --git a/src/main/kotlin/com/petqua/common/config/StringToMoneyConverter.kt b/src/main/kotlin/com/petqua/common/config/StringToMoneyConverter.kt new file mode 100644 index 00000000..f864d86f --- /dev/null +++ b/src/main/kotlin/com/petqua/common/config/StringToMoneyConverter.kt @@ -0,0 +1,12 @@ +package com.petqua.common.config + +import com.petqua.common.domain.Money +import org.springframework.core.convert.converter.Converter +import org.springframework.stereotype.Component + +@Component +class StringToMoneyConverter : Converter { + override fun convert(source: String): Money? { + return Money.from(source.toBigDecimal()) + } +} diff --git a/src/main/kotlin/com/petqua/common/config/WebConfig.kt b/src/main/kotlin/com/petqua/common/config/WebConfig.kt index a1e018db..db8ec9fa 100644 --- a/src/main/kotlin/com/petqua/common/config/WebConfig.kt +++ b/src/main/kotlin/com/petqua/common/config/WebConfig.kt @@ -20,6 +20,7 @@ class WebConfig( override fun addFormatters(registry: FormatterRegistry) { registry.addConverter(OauthServerTypeConverter()) + registry.addConverter(StringToMoneyConverter()) } override fun addArgumentResolvers(resolvers: MutableList) { diff --git a/src/main/kotlin/com/petqua/common/domain/Money.kt b/src/main/kotlin/com/petqua/common/domain/Money.kt new file mode 100644 index 00000000..07d0bee1 --- /dev/null +++ b/src/main/kotlin/com/petqua/common/domain/Money.kt @@ -0,0 +1,92 @@ +package com.petqua.common.domain + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JsonDeserializer +import com.fasterxml.jackson.databind.JsonSerializer +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.petqua.common.util.setDefaultScale +import jakarta.persistence.Embeddable +import java.math.BigDecimal + +private class MoneyDeserializer : JsonDeserializer() { + override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Money { + val value = p.codec.readValue(p, String::class.java) + return Money.from(value.toBigDecimal()) + } +} + +private class MoneySerializer : JsonSerializer() { + override fun serialize(money: Money, gen: JsonGenerator, serializers: SerializerProvider) { + gen.writeNumber(money.value.intValueExact()) // TODO INT? BigDecimal? + } +} + +@JsonDeserialize(using = MoneyDeserializer::class) +@JsonSerialize(using = MoneySerializer::class) +@Embeddable +data class Money private constructor ( + val value: BigDecimal +) { + + companion object { + fun from(value: Long): Money { + return Money(BigDecimal.valueOf(value).setDefaultScale()) + } + + fun from(value: BigDecimal): Money { + return Money(value.setDefaultScale()) + } + } + + operator fun plus(other: Money): Money { + return Money(this.value + other.value) + } + + operator fun plus(other: BigDecimal): Money { + return Money(this.value.plus(other)) + } + + operator fun plus(other: Long): Money { + return Money(this.value.plus(BigDecimal.valueOf(other))) + } + + operator fun minus(other: Money): Money { + return Money(this.value - other.value) + } + + operator fun minus(other: BigDecimal): Money { + return Money(this.value.minus(other)) + } + + operator fun minus(other: Long): Money { + return Money(this.value.minus(BigDecimal.valueOf(other))) + } + + operator fun div(other: Money): Money { + return Money(this.value / other.value) + } + + operator fun div(other: BigDecimal): Money { + return Money(this.value.div(other)) + } + + operator fun div(divisor: Long): Money { + return Money(this.value.div(BigDecimal.valueOf(divisor))) + } + + operator fun times(other: Money): Money { + return Money(this.value * other.value) + } + + operator fun times(other: BigDecimal): Money { + return Money(this.value.times(other)) + } + + operator fun times(other: Long): Money { + return Money(this.value.times(BigDecimal.valueOf(other))) + } +} diff --git a/src/main/kotlin/com/petqua/domain/cart/CartProduct.kt b/src/main/kotlin/com/petqua/domain/cart/CartProduct.kt index ea26c74a..5980b48b 100644 --- a/src/main/kotlin/com/petqua/domain/cart/CartProduct.kt +++ b/src/main/kotlin/com/petqua/domain/cart/CartProduct.kt @@ -1,6 +1,7 @@ package com.petqua.domain.cart import com.petqua.common.domain.BaseEntity +import com.petqua.common.domain.Money import com.petqua.common.util.throwExceptionWhen import com.petqua.domain.delivery.DeliveryMethod import com.petqua.domain.product.option.Sex @@ -39,8 +40,9 @@ class CartProduct( @Column(nullable = false) var deliveryMethod: DeliveryMethod, - @Column(nullable = false) - var deliveryFee: BigDecimal, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "delivery_fee", nullable = false)) + var deliveryFee: Money, ) : BaseEntity() { fun validateOwner(accessMemberId: Long) { @@ -51,7 +53,7 @@ class CartProduct( quantity: CartProductQuantity, sex: Sex, deliveryMethod: DeliveryMethod, - deliveryFee: BigDecimal, + deliveryFee: Money, ) { this.quantity = quantity this.sex = sex diff --git a/src/main/kotlin/com/petqua/domain/order/Order.kt b/src/main/kotlin/com/petqua/domain/order/Order.kt index 41da0e72..e866bda8 100644 --- a/src/main/kotlin/com/petqua/domain/order/Order.kt +++ b/src/main/kotlin/com/petqua/domain/order/Order.kt @@ -1,6 +1,7 @@ package com.petqua.domain.order import com.petqua.common.domain.BaseEntity +import com.petqua.common.domain.Money import com.petqua.common.util.throwExceptionWhen import com.petqua.exception.order.OrderException import com.petqua.exception.order.OrderExceptionType.FORBIDDEN_ORDER @@ -48,11 +49,12 @@ class Order( @Column(nullable = false) var status: OrderStatus, - @Column(nullable = false) - val totalAmount: BigDecimal, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "total_amount")) + val totalAmount: Money, ) : BaseEntity() { - fun validateAmount(amount: BigDecimal) { + fun validateAmount(amount: Money) { throwExceptionWhen(totalAmount != amount) { throw OrderException(PAYMENT_PRICE_NOT_MATCH) } diff --git a/src/main/kotlin/com/petqua/domain/order/OrderProduct.kt b/src/main/kotlin/com/petqua/domain/order/OrderProduct.kt index 7d455428..bc3eb5de 100644 --- a/src/main/kotlin/com/petqua/domain/order/OrderProduct.kt +++ b/src/main/kotlin/com/petqua/domain/order/OrderProduct.kt @@ -1,5 +1,6 @@ package com.petqua.domain.order +import com.petqua.common.domain.Money import com.petqua.domain.delivery.DeliveryMethod import com.petqua.domain.product.option.Sex import jakarta.persistence.AttributeOverride @@ -15,24 +16,29 @@ data class OrderProduct( @Column(nullable = false) val quantity: Int, - @Column(nullable = false) - val originalPrice: BigDecimal, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "original_price", nullable = false)) + val originalPrice: Money, @Column(nullable = false) val discountRate: Int, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "discount_price", nullable = false)) @Column(nullable = false) - val discountPrice: BigDecimal, + val discountPrice: Money, - @Column(nullable = false) - val deliveryFee: BigDecimal, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "delivery_fee", nullable = false)) + val deliveryFee: Money, @Embedded @AttributeOverride(name = "value", column = Column(name = "shippingNumber")) var shippingNumber: ShippingNumber, - @Column(nullable = false) - val orderPrice: BigDecimal, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "order_price", nullable = false)) + val orderPrice: Money, @Column(nullable = false) val productId: Long = 0, diff --git a/src/main/kotlin/com/petqua/domain/payment/tosspayment/TossPayment.kt b/src/main/kotlin/com/petqua/domain/payment/tosspayment/TossPayment.kt index d0d01f34..823d50f2 100644 --- a/src/main/kotlin/com/petqua/domain/payment/tosspayment/TossPayment.kt +++ b/src/main/kotlin/com/petqua/domain/payment/tosspayment/TossPayment.kt @@ -1,5 +1,6 @@ package com.petqua.domain.payment.tosspayment +import com.petqua.common.domain.Money import com.petqua.domain.order.OrderName import com.petqua.domain.order.OrderNumber import jakarta.persistence.AttributeOverride @@ -11,7 +12,6 @@ import jakarta.persistence.Enumerated import jakarta.persistence.GeneratedValue import jakarta.persistence.GenerationType.IDENTITY import jakarta.persistence.Id -import java.math.BigDecimal @Entity class TossPayment( @@ -33,8 +33,9 @@ class TossPayment( @Column(nullable = false) val method: TossPaymentMethod, - @Column(nullable = false) - val totalAmount: BigDecimal, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "total_amount", nullable = false)) + val totalAmount: Money, @Enumerated(STRING) @Column(nullable = false) diff --git a/src/main/kotlin/com/petqua/domain/product/Product.kt b/src/main/kotlin/com/petqua/domain/product/Product.kt index b6fae75b..4f6b235d 100644 --- a/src/main/kotlin/com/petqua/domain/product/Product.kt +++ b/src/main/kotlin/com/petqua/domain/product/Product.kt @@ -1,6 +1,7 @@ package com.petqua.domain.product import com.petqua.common.domain.BaseEntity +import com.petqua.common.domain.Money import com.petqua.common.domain.SoftDeleteEntity import com.petqua.domain.delivery.DeliveryMethod import com.petqua.domain.product.review.ProductReviewStatistics @@ -14,7 +15,6 @@ import jakarta.persistence.Entity import jakarta.persistence.GeneratedValue import jakarta.persistence.GenerationType import jakarta.persistence.Id -import java.math.BigDecimal @Entity class Product( @@ -27,8 +27,9 @@ class Product( @Column(nullable = false) val categoryId: Long, - @Column(nullable = false) - val price: BigDecimal, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "price", nullable = false)) + val price: Money, @Column(nullable = false) val storeId: Long, @@ -36,8 +37,9 @@ class Product( @Column(nullable = false) val discountRate: Int = 0, - @Column(nullable = false) - val discountPrice: BigDecimal = price, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "discount_price", nullable = false)) + val discountPrice: Money = price, @Embedded @AttributeOverride(name = "value", column = Column(name = "wish_count", nullable = false)) @@ -55,11 +57,17 @@ class Product( @Column(nullable = false) var isDeleted: Boolean = false, - val safeDeliveryFee: BigDecimal?, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "safe_delivery_fee")) + val safeDeliveryFee: Money?, - val commonDeliveryFee: BigDecimal?, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "common_delivery_fee")) + val commonDeliveryFee: Money?, - val pickUpDeliveryFee: BigDecimal?, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "pick_up_delivery_fee")) + val pickUpDeliveryFee: Money?, val productDescriptionId: Long?, @@ -79,7 +87,7 @@ class Product( wishCount = wishCount.decrease() } - fun getDeliveryFee(deliveryMethod: DeliveryMethod): BigDecimal { + fun getDeliveryFee(deliveryMethod: DeliveryMethod): Money { return when (deliveryMethod) { DeliveryMethod.SAFETY -> safeDeliveryFee ?: throw ProductException(INVALID_DELIVERY_METHOD) DeliveryMethod.COMMON -> commonDeliveryFee ?: throw ProductException(INVALID_DELIVERY_METHOD) diff --git a/src/main/kotlin/com/petqua/domain/product/dto/ProductDtos.kt b/src/main/kotlin/com/petqua/domain/product/dto/ProductDtos.kt index c63190c3..e182bc4d 100644 --- a/src/main/kotlin/com/petqua/domain/product/dto/ProductDtos.kt +++ b/src/main/kotlin/com/petqua/domain/product/dto/ProductDtos.kt @@ -1,5 +1,6 @@ package com.petqua.domain.product.dto +import com.petqua.common.domain.Money import com.petqua.common.util.throwExceptionWhen import com.petqua.domain.delivery.DeliveryMethod import com.petqua.domain.product.Product @@ -10,7 +11,6 @@ import com.petqua.domain.product.detail.info.ProductInfo import com.petqua.exception.product.ProductException import com.petqua.exception.product.ProductExceptionType import io.swagger.v3.oas.annotations.media.Schema -import java.math.BigDecimal data class ProductReadCondition( val canDeliverSafely: Boolean? = null, @@ -63,19 +63,19 @@ data class ProductWithInfoResponse( val name: String, val family: String, val species: String, - val price: Int, + val price: Money, val storeName: String, val discountRate: Int, - val discountPrice: Int, + val discountPrice: Money, val wishCount: Int, val reviewCount: Int, val reviewAverageScore: Double, val thumbnailUrl: String, val descriptionTitle: String, val descriptionContent: String, - val safeDeliveryFee: BigDecimal?, - val commonDeliveryFee: BigDecimal?, - val pickUpDeliveryFee: BigDecimal?, + val safeDeliveryFee: Money?, + val commonDeliveryFee: Money?, + val pickUpDeliveryFee: Money?, val optimalTemperatureMin: Int, val optimalTemperatureMax: Int, val difficultyLevel: String, @@ -93,10 +93,10 @@ data class ProductWithInfoResponse( name = product.name, family = category.family.name, species = category.species.name, - price = product.price.intValueExact(), + price = product.price, storeName = storeName, discountRate = product.discountRate, - discountPrice = product.discountPrice.intValueExact(), + discountPrice = product.discountPrice, wishCount = product.wishCount.value, reviewCount = product.reviewCount, reviewAverageScore = product.averageReviewScore(), @@ -142,7 +142,7 @@ data class ProductResponse( description = "상품 가격", example = "30000" ) - val price: Int, + val price: Money, @Schema( description = "상품 판매점", @@ -160,7 +160,7 @@ data class ProductResponse( description = "할인 가격(판매 가격)", example = "21000" ) - val discountPrice: Int, + val discountPrice: Money, @Schema( description = "찜 개수", @@ -190,19 +190,19 @@ data class ProductResponse( description = "안전 배송 가격", example = "5000" ) - val safeDeliveryFee: BigDecimal?, + val safeDeliveryFee: Money?, @Schema( description = "일반 배송 가격", example = "3000" ) - val commonDeliveryFee: BigDecimal?, + val commonDeliveryFee: Money?, @Schema( description = "픽업 배송 가격", example = "0" ) - val pickUpDeliveryFee: BigDecimal?, + val pickUpDeliveryFee: Money?, @Schema( description = "찜 여부", @@ -214,10 +214,10 @@ data class ProductResponse( product.id, product.name, product.categoryId, - product.price.intValueExact(), + product.price, storeName, product.discountRate, - product.discountPrice.intValueExact(), + product.discountPrice, product.wishCount.value, product.reviewCount, product.averageReviewScore(), diff --git a/src/main/kotlin/com/petqua/domain/product/option/ProductOption.kt b/src/main/kotlin/com/petqua/domain/product/option/ProductOption.kt index a06852a1..179c3b80 100644 --- a/src/main/kotlin/com/petqua/domain/product/option/ProductOption.kt +++ b/src/main/kotlin/com/petqua/domain/product/option/ProductOption.kt @@ -1,14 +1,16 @@ package com.petqua.domain.product.option import com.petqua.common.domain.BaseEntity +import com.petqua.common.domain.Money +import jakarta.persistence.AttributeOverride import jakarta.persistence.Column +import jakarta.persistence.Embedded import jakarta.persistence.Entity import jakarta.persistence.EnumType.STRING import jakarta.persistence.Enumerated import jakarta.persistence.GeneratedValue import jakarta.persistence.GenerationType import jakarta.persistence.Id -import java.math.BigDecimal @Entity class ProductOption( @@ -22,8 +24,9 @@ class ProductOption( @Enumerated(STRING) val sex: Sex, - @Column(nullable = false) - val additionalPrice: BigDecimal, + @Embedded + @AttributeOverride(name = "value", column = Column(name = "additional_price", nullable = false)) + val additionalPrice: Money, ) : BaseEntity() { fun hasDistinctSex(): Boolean { diff --git a/src/main/kotlin/com/petqua/presentation/cart/dto/CartProductDtos.kt b/src/main/kotlin/com/petqua/presentation/cart/dto/CartProductDtos.kt index 4ab013ab..89d80225 100644 --- a/src/main/kotlin/com/petqua/presentation/cart/dto/CartProductDtos.kt +++ b/src/main/kotlin/com/petqua/presentation/cart/dto/CartProductDtos.kt @@ -2,6 +2,7 @@ package com.petqua.presentation.cart.dto import com.petqua.application.cart.dto.SaveCartProductCommand import com.petqua.application.cart.dto.UpdateCartProductOptionCommand +import com.petqua.common.domain.Money import com.petqua.domain.cart.CartProductQuantity import com.petqua.domain.delivery.DeliveryMethod import com.petqua.domain.product.option.Sex @@ -39,7 +40,7 @@ data class SaveCartProductRequest( description = "배송비", example = "3000" ) - val deliveryFee: BigDecimal, + val deliveryFee: Money, ) { fun toCommand(memberId: Long): SaveCartProductCommand { @@ -79,7 +80,7 @@ data class UpdateCartProductOptionRequest( description = "배송비", example = "3000" ) - val deliveryFee: BigDecimal, + val deliveryFee: Money, ) { fun toCommand(memberId: Long, cartProductId: Long): UpdateCartProductOptionCommand { diff --git a/src/main/kotlin/com/petqua/presentation/order/dto/OrderDtos.kt b/src/main/kotlin/com/petqua/presentation/order/dto/OrderDtos.kt index 05fdf657..4b28193d 100644 --- a/src/main/kotlin/com/petqua/presentation/order/dto/OrderDtos.kt +++ b/src/main/kotlin/com/petqua/presentation/order/dto/OrderDtos.kt @@ -2,6 +2,7 @@ package com.petqua.presentation.order.dto import com.petqua.application.order.dto.OrderProductCommand import com.petqua.application.order.dto.SaveOrderCommand +import com.petqua.common.domain.Money import com.petqua.domain.delivery.DeliveryMethod import com.petqua.domain.product.option.Sex import java.math.BigDecimal @@ -10,7 +11,7 @@ data class SaveOrderRequest( val shippingAddressId: Long, val shippingRequest: String?, val orderProductRequests: List, - val totalAmount: BigDecimal, + val totalAmount: Money, ) { fun toCommand(memberId: Long): SaveOrderCommand { @@ -28,13 +29,13 @@ data class OrderProductRequest( val productId: Long, val storeId: Long, val quantity: Int, - val originalPrice: BigDecimal, + val originalPrice: Money, val discountRate: Int, - val discountPrice: BigDecimal, - val orderPrice: BigDecimal, + val discountPrice: Money, + val orderPrice: Money, val sex: String, - val additionalPrice: BigDecimal, - val deliveryFee: BigDecimal, + val additionalPrice: Money, + val deliveryFee: Money, val deliveryMethod: String, ) { diff --git a/src/main/kotlin/com/petqua/presentation/payment/PaymentDtos.kt b/src/main/kotlin/com/petqua/presentation/payment/PaymentDtos.kt index a8319578..2bed0a7c 100644 --- a/src/main/kotlin/com/petqua/presentation/payment/PaymentDtos.kt +++ b/src/main/kotlin/com/petqua/presentation/payment/PaymentDtos.kt @@ -2,13 +2,13 @@ package com.petqua.presentation.payment import com.petqua.application.payment.FailPaymentCommand import com.petqua.application.payment.SucceedPaymentCommand -import java.math.BigDecimal +import com.petqua.common.domain.Money data class SucceedPaymentRequest( val paymentType: String, val orderId: String, val paymentKey: String, - val amount: BigDecimal, + val amount: Money, ) { fun toCommand(memberId: Long): SucceedPaymentCommand { diff --git a/src/main/kotlin/com/petqua/presentation/product/dto/WishProductDtos.kt b/src/main/kotlin/com/petqua/presentation/product/dto/WishProductDtos.kt index 1a469e40..464d3916 100644 --- a/src/main/kotlin/com/petqua/presentation/product/dto/WishProductDtos.kt +++ b/src/main/kotlin/com/petqua/presentation/product/dto/WishProductDtos.kt @@ -160,10 +160,10 @@ data class WishProductResponse( product.id, product.name, product.categoryId, - product.price.intValueExact(), + product.price.value.intValueExact(), // TODO int로 바꾼 이유가 있나? storeName, product.discountRate, - product.discountPrice.intValueExact(), + product.discountPrice.value.intValueExact(), product.wishCount.value, product.reviewCount, product.averageReviewScore(), diff --git a/src/test/kotlin/com/petqua/application/order/OrderServiceTest.kt b/src/test/kotlin/com/petqua/application/order/OrderServiceTest.kt index 57181a56..ecdaac51 100644 --- a/src/test/kotlin/com/petqua/application/order/OrderServiceTest.kt +++ b/src/test/kotlin/com/petqua/application/order/OrderServiceTest.kt @@ -101,7 +101,7 @@ class OrderServiceTest( orderProductCommand( productId = productB.id, sex = productOptionB.sex, - additionalPrice = productOptionB.additionalPrice, + additionalPrice = productOptionB.additionalPrice.value, ), ) val command = saveOrderCommand( @@ -130,7 +130,7 @@ class OrderServiceTest( orderProductCommand( productId = productA.id, sex = productOptionA.sex, - additionalPrice = productOptionA.additionalPrice, + additionalPrice = productOptionA.additionalPrice.value, ), ) @@ -187,22 +187,22 @@ class OrderServiceTest( val orderProductCommands = listOf( orderProductCommand( productId = productA.id, - originalPrice = productA.price, + originalPrice = productA.price.value, discountRate = productA.discountRate, - discountPrice = productA.discountPrice, + discountPrice = productA.discountPrice.value, sex = productOptionA.sex, orderPrice = BigDecimal.TEN, - additionalPrice = productOptionA.additionalPrice, + additionalPrice = productOptionA.additionalPrice.value, deliveryMethod = COMMON, ), orderProductCommand( productId = productB.id, - originalPrice = productB.price, + originalPrice = productB.price.value, discountRate = productB.discountRate, - discountPrice = productB.discountPrice, + discountPrice = productB.discountPrice.value, sex = productOptionB.sex, orderPrice = 9.toBigDecimal(), - additionalPrice = productOptionB.additionalPrice, + additionalPrice = productOptionB.additionalPrice.value, deliveryMethod = SAFETY, ), ) @@ -253,22 +253,22 @@ class OrderServiceTest( val orderProductCommands = listOf( orderProductCommand( productId = productA.id, - originalPrice = productA.price, + originalPrice = productA.price.value, discountRate = productA.discountRate, - discountPrice = productA.discountPrice, + discountPrice = productA.discountPrice.value, sex = productOptionA.sex, orderPrice = BigDecimal.TEN, - additionalPrice = productOptionA.additionalPrice, + additionalPrice = productOptionA.additionalPrice.value, deliveryFee = 1.toBigDecimal(), ), orderProductCommand( productId = productB.id, - originalPrice = productB.price, + originalPrice = productB.price.value, discountRate = productB.discountRate, - discountPrice = productB.discountPrice, + discountPrice = productB.discountPrice.value, sex = productOptionB.sex, orderPrice = 9.toBigDecimal(), - additionalPrice = productOptionB.additionalPrice, + additionalPrice = productOptionB.additionalPrice.value, deliveryFee = 5000.toBigDecimal(), ), ) @@ -332,34 +332,34 @@ class OrderServiceTest( val orderProductCommands = listOf( orderProductCommand( productId = productA1.id, - originalPrice = productA1.price, + originalPrice = productA1.price.value, discountRate = productA1.discountRate, - discountPrice = productA1.discountPrice, + discountPrice = productA1.discountPrice.value, sex = productOptionA1.sex, orderPrice = BigDecimal.ONE, - additionalPrice = productOptionA1.additionalPrice, + additionalPrice = productOptionA1.additionalPrice.value, deliveryFee = 3000.toBigDecimal(), deliveryMethod = COMMON, ), orderProductCommand( productId = productA2.id, - originalPrice = productA2.price, + originalPrice = productA2.price.value, discountRate = productA2.discountRate, - discountPrice = productA2.discountPrice, + discountPrice = productA2.discountPrice.value, sex = productOptionA2.sex, orderPrice = BigDecimal.ONE, - additionalPrice = productOptionA2.additionalPrice, + additionalPrice = productOptionA2.additionalPrice.value, deliveryFee = 3000.toBigDecimal(), deliveryMethod = COMMON, ), orderProductCommand( productId = productB.id, - originalPrice = productB.price, + originalPrice = productB.price.value, discountRate = productB.discountRate, - discountPrice = productB.discountPrice, + discountPrice = productB.discountPrice.value, sex = productOptionB.sex, orderPrice = BigDecimal.ONE, - additionalPrice = productOptionB.additionalPrice, + additionalPrice = productOptionB.additionalPrice.value, deliveryFee = 5000.toBigDecimal(), deliveryMethod = SAFETY, ), @@ -430,34 +430,34 @@ class OrderServiceTest( val orderProductCommands = listOf( orderProductCommand( productId = productA1.id, - originalPrice = productA1.price, + originalPrice = productA1.price.value, discountRate = productA1.discountRate, - discountPrice = productA1.discountPrice, + discountPrice = productA1.discountPrice.value, sex = productOptionA1.sex, orderPrice = BigDecimal.ONE, - additionalPrice = productOptionA1.additionalPrice, + additionalPrice = productOptionA1.additionalPrice.value, deliveryFee = 3000.toBigDecimal(), deliveryMethod = COMMON, ), orderProductCommand( productId = productA2.id, - originalPrice = productA2.price, + originalPrice = productA2.price.value, discountRate = productA2.discountRate, - discountPrice = productA2.discountPrice, + discountPrice = productA2.discountPrice.value, sex = productOptionA2.sex, orderPrice = BigDecimal.ONE, - additionalPrice = productOptionA2.additionalPrice, + additionalPrice = productOptionA2.additionalPrice.value, deliveryFee = 3000.toBigDecimal(), deliveryMethod = COMMON, ), orderProductCommand( productId = productB.id, - originalPrice = productB.price, + originalPrice = productB.price.value, discountRate = productB.discountRate, - discountPrice = productB.discountPrice, + discountPrice = productB.discountPrice.value, sex = productOptionB.sex, orderPrice = BigDecimal.ONE, - additionalPrice = productOptionB.additionalPrice, + additionalPrice = productOptionB.additionalPrice.value, deliveryFee = 5000.toBigDecimal(), deliveryMethod = SAFETY, ), diff --git a/src/test/kotlin/com/petqua/application/payment/PaymentFacadeServiceTest.kt b/src/test/kotlin/com/petqua/application/payment/PaymentFacadeServiceTest.kt index 6c76b922..81b53e30 100644 --- a/src/test/kotlin/com/petqua/application/payment/PaymentFacadeServiceTest.kt +++ b/src/test/kotlin/com/petqua/application/payment/PaymentFacadeServiceTest.kt @@ -66,7 +66,7 @@ class PaymentFacadeServiceTest( command = succeedPaymentCommand( memberId = order.memberId, orderNumber = order.orderNumber, - amount = order.totalAmount, + amount = order.totalAmount.value, ) ) @@ -82,7 +82,7 @@ class PaymentFacadeServiceTest( command = succeedPaymentCommand( memberId = order.memberId, orderNumber = order.orderNumber, - amount = order.totalAmount, + amount = order.totalAmount.value, ) ) @@ -94,7 +94,7 @@ class PaymentFacadeServiceTest( val payment = payments[0] payment.orderNumber shouldBe order.orderNumber - payment.totalAmount shouldBe order.totalAmount.setScale(2) + payment.totalAmount shouldBe order.totalAmount } } @@ -128,7 +128,7 @@ class PaymentFacadeServiceTest( command = succeedPaymentCommand( memberId = order.memberId, orderNumber = orderNumber, - amount = order.totalAmount, + amount = order.totalAmount.value, ) ) }.exceptionType() shouldBe ORDER_NOT_FOUND @@ -151,7 +151,7 @@ class PaymentFacadeServiceTest( command = succeedPaymentCommand( memberId = invalidOrder.memberId, orderNumber = invalidOrder.orderNumber, - amount = invalidOrder.totalAmount, + amount = invalidOrder.totalAmount.value, ) ) }.exceptionType() shouldBe ORDER_CAN_NOT_PAY @@ -167,7 +167,7 @@ class PaymentFacadeServiceTest( command = succeedPaymentCommand( memberId = memberId, orderNumber = order.orderNumber, - amount = order.totalAmount, + amount = order.totalAmount.value, ) ) }.exceptionType() shouldBe FORBIDDEN_ORDER @@ -183,7 +183,7 @@ class PaymentFacadeServiceTest( command = succeedPaymentCommand( memberId = order.memberId, orderNumber = order.orderNumber, - amount = amount, + amount = amount.value, ) ) }.exceptionType() shouldBe PAYMENT_PRICE_NOT_MATCH @@ -207,7 +207,7 @@ class PaymentFacadeServiceTest( command = succeedPaymentCommand( memberId = order.memberId, orderNumber = order.orderNumber, - amount = order.totalAmount, + amount = order.totalAmount.value, ) ) }.exceptionType() shouldBe UNAUTHORIZED_KEY diff --git a/src/test/kotlin/com/petqua/domain/cart/CartProductTest.kt b/src/test/kotlin/com/petqua/domain/cart/CartProductTest.kt index 127fc862..2c949c93 100644 --- a/src/test/kotlin/com/petqua/domain/cart/CartProductTest.kt +++ b/src/test/kotlin/com/petqua/domain/cart/CartProductTest.kt @@ -1,5 +1,6 @@ package com.petqua.domain.cart +import com.petqua.common.domain.Money import com.petqua.domain.delivery.DeliveryMethod import com.petqua.domain.product.option.Sex.FEMALE import com.petqua.domain.product.option.Sex.MALE @@ -18,14 +19,14 @@ class CartProductTest : StringSpec({ quantity = CartProductQuantity(5), sex = FEMALE, deliveryMethod = DeliveryMethod.COMMON, - deliveryFee = 3000.toBigDecimal(), + deliveryFee = Money.from(3000L), ) cartProduct.updateOptions( quantity = CartProductQuantity(10), sex = MALE, deliveryMethod = DeliveryMethod.COMMON, - deliveryFee = 3000.toBigDecimal(), + deliveryFee = Money.from(3000L), ) assertSoftly(cartProduct) { @@ -42,7 +43,7 @@ class CartProductTest : StringSpec({ quantity = CartProductQuantity(5), sex = MALE, deliveryMethod = DeliveryMethod.COMMON, - deliveryFee = 3000.toBigDecimal(), + deliveryFee = Money.from(3000L), ) shouldThrow { diff --git a/src/test/kotlin/com/petqua/domain/order/OrderTest.kt b/src/test/kotlin/com/petqua/domain/order/OrderTest.kt index 0cb7c964..17176be1 100644 --- a/src/test/kotlin/com/petqua/domain/order/OrderTest.kt +++ b/src/test/kotlin/com/petqua/domain/order/OrderTest.kt @@ -1,5 +1,6 @@ package com.petqua.domain.order +import com.petqua.common.domain.Money import com.petqua.domain.order.OrderStatus.CANCELED import com.petqua.domain.order.OrderStatus.ORDER_CREATED import com.petqua.exception.order.OrderException @@ -23,7 +24,7 @@ class OrderTest : StringSpec({ ) shouldNotThrow { - order.validateAmount(TEN) + order.validateAmount(Money.from(TEN)) } } @@ -33,7 +34,7 @@ class OrderTest : StringSpec({ ) shouldThrow { - order.validateAmount(ONE) + order.validateAmount(Money.from(ONE)) }.exceptionType() shouldBe PAYMENT_PRICE_NOT_MATCH } diff --git a/src/test/kotlin/com/petqua/presentation/payment/PaymentControllerTest.kt b/src/test/kotlin/com/petqua/presentation/payment/PaymentControllerTest.kt index 4bbd1220..5b04a327 100644 --- a/src/test/kotlin/com/petqua/presentation/payment/PaymentControllerTest.kt +++ b/src/test/kotlin/com/petqua/presentation/payment/PaymentControllerTest.kt @@ -62,7 +62,7 @@ class PaymentControllerTest( accessToken = accessToken, succeedPaymentRequest = succeedPaymentRequest( orderId = order.orderNumber.value, - amount = order.totalAmount + amount = order.totalAmount.value ) ) @@ -78,7 +78,7 @@ class PaymentControllerTest( val payment = payments[0] payment.orderNumber shouldBe order.orderNumber - payment.totalAmount shouldBe order.totalAmount.setScale(2) + payment.totalAmount shouldBe order.totalAmount } } @@ -110,7 +110,7 @@ class PaymentControllerTest( accessToken = accessToken, succeedPaymentRequest = succeedPaymentRequest( orderId = orderNumber, - amount = order.totalAmount + amount = order.totalAmount.value ) ) @@ -138,7 +138,7 @@ class PaymentControllerTest( accessToken = accessToken, succeedPaymentRequest = succeedPaymentRequest( orderId = invalidOrder.orderNumber.value, - amount = invalidOrder.totalAmount + amount = invalidOrder.totalAmount.value ) ) @@ -159,7 +159,7 @@ class PaymentControllerTest( accessToken = otherAccessToken, succeedPaymentRequest = succeedPaymentRequest( orderId = order.orderNumber.value, - amount = order.totalAmount + amount = order.totalAmount.value ) ) @@ -180,7 +180,7 @@ class PaymentControllerTest( accessToken = accessToken, succeedPaymentRequest = succeedPaymentRequest( orderId = order.orderNumber.value, - amount = wrongAmount + amount = wrongAmount.value ) ) @@ -209,7 +209,7 @@ class PaymentControllerTest( accessToken = accessToken, succeedPaymentRequest = succeedPaymentRequest( orderId = order.orderNumber.value, - amount = order.totalAmount + amount = order.totalAmount.value ) ) diff --git a/src/test/kotlin/com/petqua/test/fake/FakeTossPaymentsApiClient.kt b/src/test/kotlin/com/petqua/test/fake/FakeTossPaymentsApiClient.kt index 8f74de25..19d7c376 100644 --- a/src/test/kotlin/com/petqua/test/fake/FakeTossPaymentsApiClient.kt +++ b/src/test/kotlin/com/petqua/test/fake/FakeTossPaymentsApiClient.kt @@ -4,6 +4,7 @@ import com.petqua.application.payment.CardResponseFromPG import com.petqua.application.payment.PaymentConfirmRequestToPG import com.petqua.application.payment.PaymentResponseFromPG import com.petqua.application.payment.infra.TossPaymentsApiClient +import com.petqua.common.domain.Money import com.petqua.domain.payment.tosspayment.TossPaymentMethod import com.petqua.domain.payment.tosspayment.TossPaymentStatus import com.petqua.domain.payment.tosspayment.TossPaymentType @@ -32,10 +33,10 @@ class FakeTossPaymentsApiClient : TossPaymentsApiClient { useEscrow = false, lastTransactionKey = null, suppliedAmount = paymentConfirmRequestToPG.amount, - vat = BigDecimal.ZERO, + vat = Money.from(0L), cultureExpense = false, - taxFreeAmount = BigDecimal.ZERO, - taxExemptionAmount = BigDecimal.ZERO, + taxFreeAmount = Money.from(0L), + taxExemptionAmount = Money.from(0L), cancels = null, isPartialCancelable = true, card = CardResponseFromPG( diff --git a/src/test/kotlin/com/petqua/test/fixture/CartProductFixtures.kt b/src/test/kotlin/com/petqua/test/fixture/CartProductFixtures.kt index e3c1c717..f516fbc0 100644 --- a/src/test/kotlin/com/petqua/test/fixture/CartProductFixtures.kt +++ b/src/test/kotlin/com/petqua/test/fixture/CartProductFixtures.kt @@ -2,6 +2,7 @@ package com.petqua.test.fixture import com.petqua.application.cart.dto.SaveCartProductCommand import com.petqua.application.cart.dto.UpdateCartProductOptionCommand +import com.petqua.common.domain.Money import com.petqua.common.util.setDefaultScale import com.petqua.domain.cart.CartProduct import com.petqua.domain.cart.CartProductQuantity @@ -29,7 +30,7 @@ fun cartProduct( quantity = CartProductQuantity(quantity), sex = sex, deliveryMethod = deliveryMethod, - deliveryFee = deliveryFee, + deliveryFee = Money.from(deliveryFee), ) } @@ -48,7 +49,7 @@ fun saveCartProductCommand( quantity = quantity, sex = sex, deliveryMethod = deliveryMethod, - deliveryFee = deliveryFee.setDefaultScale(), + deliveryFee = Money.from(deliveryFee), ) } @@ -66,7 +67,7 @@ fun updateCartProductOptionCommand( quantity = CartProductQuantity(quantity), sex = sex, deliveryMethod = deliveryMethod, - deliveryFee = deliveryFee.setDefaultScale(), + deliveryFee = Money.from(deliveryFee), ) } @@ -83,7 +84,7 @@ fun saveCartProductRequest( quantity = quantity, sex = sex, deliveryMethod = deliveryMethod, - deliveryFee = deliveryFee.setDefaultScale(), + deliveryFee = Money.from(deliveryFee), ) } @@ -97,7 +98,7 @@ fun updateCartProductOptionRequest( quantity = quantity, sex = sex, deliveryMethod = deliveryMethod, - deliveryFee = deliveryFee.setDefaultScale(), + deliveryFee = Money.from(deliveryFee), ) } diff --git a/src/test/kotlin/com/petqua/test/fixture/OrderFixture.kt b/src/test/kotlin/com/petqua/test/fixture/OrderFixture.kt index 59be3de4..2efe70bc 100644 --- a/src/test/kotlin/com/petqua/test/fixture/OrderFixture.kt +++ b/src/test/kotlin/com/petqua/test/fixture/OrderFixture.kt @@ -2,7 +2,7 @@ package com.petqua.test.fixture import com.petqua.application.order.dto.OrderProductCommand import com.petqua.application.order.dto.SaveOrderCommand -import com.petqua.common.util.setDefaultScale +import com.petqua.common.domain.Money import com.petqua.domain.delivery.DeliveryMethod import com.petqua.domain.delivery.DeliveryMethod.COMMON import com.petqua.domain.delivery.DeliveryMethod.SAFETY @@ -81,7 +81,7 @@ fun order( ), isAbleToCancel = isAbleToCancel, status = status, - totalAmount = totalAmount, + totalAmount = Money.from(totalAmount), ) } @@ -121,12 +121,12 @@ fun orderProduct( ): OrderProduct { return OrderProduct( quantity = quantity, - originalPrice = originalPrice, + originalPrice = Money.from(originalPrice), discountRate = discountRate, - discountPrice = discountPrice, - deliveryFee = deliveryFee, + discountPrice = Money.from(discountPrice), + deliveryFee = Money.from(deliveryFee), shippingNumber = shippingNumber, - orderPrice = orderPrice, + orderPrice = Money.from(orderPrice), productId = productId, productName = productName, thumbnailUrl = thumbnailUrl, @@ -149,7 +149,7 @@ fun saveOrderCommand( shippingAddressId = shippingAddressId, shippingRequest = shippingRequest, orderProductCommands = orderProductCommands, - totalAmount = totalAmount.setDefaultScale(), + totalAmount = Money.from(totalAmount), ) } @@ -168,13 +168,13 @@ fun orderProductCommand( return OrderProductCommand( productId = productId, quantity = quantity, - originalPrice = originalPrice.setDefaultScale(), + originalPrice = Money.from(originalPrice), discountRate = discountRate, - discountPrice = discountPrice.setDefaultScale(), - orderPrice = orderPrice.setDefaultScale(), + discountPrice = Money.from(discountPrice), + orderPrice = Money.from(orderPrice), sex = sex, - additionalPrice = additionalPrice.setDefaultScale(), - deliveryFee = deliveryFee.setDefaultScale(), + additionalPrice = Money.from(additionalPrice), + deliveryFee = Money.from(deliveryFee), deliveryMethod = deliveryMethod, ) } diff --git a/src/test/kotlin/com/petqua/test/fixture/PaymentFixtures.kt b/src/test/kotlin/com/petqua/test/fixture/PaymentFixtures.kt index 53ecbca4..4724f07a 100644 --- a/src/test/kotlin/com/petqua/test/fixture/PaymentFixtures.kt +++ b/src/test/kotlin/com/petqua/test/fixture/PaymentFixtures.kt @@ -2,6 +2,7 @@ package com.petqua.test.fixture import com.petqua.application.payment.FailPaymentCommand import com.petqua.application.payment.SucceedPaymentCommand +import com.petqua.common.domain.Money import com.petqua.domain.order.OrderNumber import com.petqua.domain.payment.tosspayment.TossPaymentType import com.petqua.domain.payment.tosspayment.TossPaymentType.NORMAL @@ -22,7 +23,7 @@ fun succeedPaymentCommand( paymentType = paymentType, orderNumber = orderNumber, paymentKey = paymentKey, - amount = amount, + amount = Money.from(amount), ) } @@ -36,7 +37,7 @@ fun succeedPaymentRequest( paymentType = paymentType, orderId = orderId, paymentKey = paymentKey, - amount = amount, + amount = Money.from(amount), ) } diff --git a/src/test/kotlin/com/petqua/test/fixture/ProductFixtures.kt b/src/test/kotlin/com/petqua/test/fixture/ProductFixtures.kt index c1c93fc2..23c63b5b 100644 --- a/src/test/kotlin/com/petqua/test/fixture/ProductFixtures.kt +++ b/src/test/kotlin/com/petqua/test/fixture/ProductFixtures.kt @@ -1,6 +1,7 @@ package com.petqua.test.fixture import com.petqua.application.product.dto.ProductDetailResponse +import com.petqua.common.domain.Money import com.petqua.common.util.setDefaultScale import com.petqua.domain.keyword.ProductKeyword import com.petqua.domain.product.Product @@ -21,7 +22,7 @@ import com.petqua.domain.product.option.ProductOption import com.petqua.domain.product.option.Sex import java.math.BigDecimal -fun product( +fun product( // TODO Money로? id: Long = 0L, name: String = "name", categoryId: Long = 0, @@ -44,18 +45,18 @@ fun product( id = id, name = name, categoryId = categoryId, - price = price.setDefaultScale(), + price = Money.from(price.setDefaultScale()), storeId = storeId, discountRate = discountRate, - discountPrice = discountPrice.setDefaultScale(), + discountPrice = Money.from(discountPrice.setDefaultScale()), wishCount = WishCount(wishCount), reviewCount = reviewCount, reviewTotalScore = reviewTotalScore, thumbnailUrl = thumbnailUrl, isDeleted = isDeleted, - safeDeliveryFee = safeDeliveryFee?.setDefaultScale(), - commonDeliveryFee = commonDeliveryFee?.setDefaultScale(), - pickUpDeliveryFee = pickUpDeliveryFee?.setDefaultScale(), + safeDeliveryFee = safeDeliveryFee?.let { Money.from(it) }, + commonDeliveryFee = commonDeliveryFee?.let { Money.from(it) }, + pickUpDeliveryFee = pickUpDeliveryFee?.let { Money.from(it) }, productDescriptionId = productDescriptionId, productInfoId = productInfoId ) @@ -115,7 +116,7 @@ fun productOption( id = id, productId = productId, sex = sex, - additionalPrice = additionalPrice, + additionalPrice = Money.from(additionalPrice), ) } @@ -148,10 +149,10 @@ fun productDetailResponse( name = product.name, family = category.family.name, species = category.species.name, - price = product.price.intValueExact(), + price = product.price, storeName = storeName, discountRate = product.discountRate, - discountPrice = product.discountPrice.intValueExact(), + discountPrice = product.discountPrice, wishCount = product.wishCount.value, reviewCount = product.reviewCount, reviewAverageScore = product.averageReviewScore(), @@ -162,8 +163,8 @@ fun productDetailResponse( safeDeliveryFee = product.safeDeliveryFee, commonDeliveryFee = product.commonDeliveryFee, pickUpDeliveryFee = product.pickUpDeliveryFee, - maleAdditionalPrice = maleAdditionalPrice?.setScale(2), - femaleAdditionalPrice = femaleAdditionalPrice?.setScale(2), + maleAdditionalPrice = maleAdditionalPrice?.let { Money.from(it) }, + femaleAdditionalPrice = femaleAdditionalPrice?.let { Money.from(it) }, optimalTemperatureMin = productInfo.optimalTemperature.optimalTemperatureMin, optimalTemperatureMax = productInfo.optimalTemperature.optimalTemperatureMax, difficultyLevel = productInfo.difficultyLevel.description, @@ -182,10 +183,10 @@ fun productResponse( id = product.id, name = product.name, categoryId = product.categoryId, - price = product.price.intValueExact(), + price = product.price, storeName = storeName, discountRate = product.discountRate, - discountPrice = product.discountPrice.intValueExact(), + discountPrice = product.discountPrice, wishCount = product.wishCount.value, reviewCount = product.reviewCount, reviewAverageScore = product.averageReviewScore(),