Commit 4e9fe4bc547fa8d8f9172b5e68b482fba74bd1c8

Authored by YunaiV
1 parent 084d4bab

price:完成限时折扣的价格计算~

yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountProductDO.java
... ... @@ -32,6 +32,12 @@ public class DiscountProductDO extends BaseDO {
32 32 */
33 33 private Long activityId;
34 34 /**
  35 + * 限时折扣活动的名字
  36 + *
  37 + * 冗余 {@link DiscountActivityDO#getName()}
  38 + */
  39 + private String activityName;
  40 + /**
35 41 * 商品 SPU 编号
36 42 *
37 43 * 关联 ProductSpuDO 的 id 编号
... ...
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceServiceImpl.java
... ... @@ -107,33 +107,35 @@ public class PriceServiceImpl implements PriceService {
107 107 Integer memberPrice = memberDiscount != null ? (int) (orderItem.getPayPrice() * memberDiscount / 100) : null;
108 108 Integer promotionPrice = discountProduct != null ? discountProduct.getPromotionPrice() * orderItem.getCount() : null;
109 109 if (memberPrice == null) {
110   -
  110 + calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice);
111 111 } else if (promotionPrice == null) {
112   - calculatePriceByMemberDiscount(orderItem, memberDiscount, memberPrice, priceCalculate);
  112 + calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice);
113 113 } else if (memberPrice < promotionPrice) {
114   -
  114 + calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice);
115 115 } else {
116   - calculatePriceByMemberDiscount(orderItem, memberDiscount, memberPrice, priceCalculate);
  116 + calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice);
117 117 }
118 118 });
119 119 }
120 120  
121   - private void calculatePriceByMemberDiscount(PriceCalculateRespDTO.OrderItem orderItem,
122   - Double memberDiscount, Integer memberPrice,
123   - PriceCalculateRespDTO priceCalculate) {
  121 + private void calculatePriceByMemberDiscount(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem,
  122 + Integer memberPrice) {
124 123 // 记录优惠明细
125   - addPromotion(priceCalculate, orderItem, null,
126   - PromotionTypeEnum.MEMBER.getName(),
  124 + addPromotion(priceCalculate, orderItem, null, PromotionTypeEnum.MEMBER.getName(),
127 125 PromotionTypeEnum.MEMBER.getType(), PromotionLevelEnum.SKU.getLevel(), memberPrice,
128 126 true, StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice)));
129 127 // 修改 SKU 的优惠
130 128 modifyOrderItemPayPrice(orderItem, memberPrice, priceCalculate);
131 129 }
132 130  
133   - private void calculatePriceByDiscountActivity(PriceCalculateRespDTO.OrderItem orderItem,
134   - DiscountProductDO discountProduct, Integer promotionPrice,
135   - PriceCalculateRespDTO priceCalculate) {
136   -
  131 + private void calculatePriceByDiscountActivity(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem,
  132 + DiscountProductDO discountProduct, Integer promotionPrice) {
  133 + // 记录优惠明细
  134 + addPromotion(priceCalculate, orderItem, discountProduct.getActivityId(), discountProduct.getActivityName(),
  135 + PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), PromotionLevelEnum.SKU.getLevel(), promotionPrice,
  136 + true, StrUtil.format("限时折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - promotionPrice)));
  137 + // 修改 SKU 的优惠
  138 + modifyOrderItemPayPrice(orderItem, promotionPrice, priceCalculate);
137 139 }
138 140  
139 141 private void addPromotion(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem,
... ...
yudao-module-mall/yudao-module-market-biz/src/test/java/cn/iocoder/yudao/module/market/service/price/PriceServiceTest.java
1 1 package cn.iocoder.yudao.module.market.service.price;
2 2  
  3 +import cn.hutool.core.map.MapUtil;
3 4 import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
4 5 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
5 6 import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
6 7 import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
  8 +import cn.iocoder.yudao.module.market.dal.dataobject.discount.DiscountProductDO;
7 9 import cn.iocoder.yudao.module.market.enums.common.PromotionLevelEnum;
8 10 import cn.iocoder.yudao.module.market.enums.common.PromotionTypeEnum;
9 11 import cn.iocoder.yudao.module.market.service.discount.DiscountService;
... ... @@ -13,7 +15,9 @@ import org.junit.jupiter.api.Test;
13 15 import org.mockito.InjectMocks;
14 16 import org.mockito.Mock;
15 17  
  18 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
16 19 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  20 +import static java.util.Arrays.asList;
17 21 import static java.util.Collections.singletonList;
18 22 import static org.junit.jupiter.api.Assertions.*;
19 23 import static org.mockito.ArgumentMatchers.eq;
... ... @@ -55,8 +59,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
55 59 assertEquals(order.getPayPrice(), 180);
56 60 assertNull(order.getCouponId());
57 61 // 断言 OrderItem 部分
58   - PriceCalculateRespDTO.OrderItem orderItem = order.getItems().get(0);
59 62 assertEquals(order.getItems().size(), 1);
  63 + PriceCalculateRespDTO.OrderItem orderItem = order.getItems().get(0);
60 64 assertEquals(orderItem.getSkuId(), 10L);
61 65 assertEquals(orderItem.getCount(), 2);
62 66 assertEquals(orderItem.getOriginalPrice(), 200);
... ... @@ -66,8 +70,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
66 70 assertEquals(orderItem.getOrderPartPrice(), 0);
67 71 assertEquals(orderItem.getOrderDividePrice(), 180);
68 72 // 断言 Promotion 部分
69   - PriceCalculateRespDTO.Promotion promotion = priceCalculate.getPromotions().get(0);
70 73 assertEquals(priceCalculate.getPromotions().size(), 1);
  74 + PriceCalculateRespDTO.Promotion promotion = priceCalculate.getPromotions().get(0);
71 75 assertNull(promotion.getId());
72 76 assertEquals(promotion.getName(), "会员折扣");
73 77 assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType());
... ... @@ -83,4 +87,84 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
83 87 assertEquals(promotionItem.getDiscountPrice(), 20);
84 88 }
85 89  
  90 + @Test
  91 + public void testCalculatePrice_discountActivity() {
  92 + // 准备参数
  93 + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId())
  94 + .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2),
  95 + new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3)));
  96 + // mock 方法(商品 SKU 信息)
  97 + ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100));
  98 + ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50));
  99 + when(productSkuApi.getSkuList(eq(SetUtils.asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02));
  100 + // mock 方法(限时折扣 DiscountActivity 信息)
  101 + DiscountProductDO discountProduct01 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(1000L).setActivityName("活动 1000 号")
  102 + .setSkuId(10L).setPromotionPrice(80));
  103 + DiscountProductDO discountProduct02 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(2000L).setActivityName("活动 2000 号")
  104 + .setSkuId(20L).setPromotionPrice(40));
  105 + when(discountService.getMatchDiscountProducts(eq(SetUtils.asSet(10L, 20L)))).thenReturn(
  106 + MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map());
  107 +
  108 + // 调用
  109 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO);
  110 + // 断言 Order 部分
  111 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder();
  112 + assertEquals(order.getOriginalPrice(), 350);
  113 + assertEquals(order.getDiscountPrice(), 0);
  114 + assertEquals(order.getPointPrice(), 0);
  115 + assertEquals(order.getDeliveryPrice(), 0);
  116 + assertEquals(order.getPayPrice(), 280);
  117 + assertNull(order.getCouponId());
  118 + // 断言 OrderItem 部分
  119 + assertEquals(order.getItems().size(), 2);
  120 + PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0);
  121 + assertEquals(orderItem01.getSkuId(), 10L);
  122 + assertEquals(orderItem01.getCount(), 2);
  123 + assertEquals(orderItem01.getOriginalPrice(), 200);
  124 + assertEquals(orderItem01.getOriginalUnitPrice(), 100);
  125 + assertEquals(orderItem01.getDiscountPrice(), 40);
  126 + assertEquals(orderItem01.getPayPrice(), 160);
  127 + assertEquals(orderItem01.getOrderPartPrice(), 0);
  128 + assertEquals(orderItem01.getOrderDividePrice(), 160);
  129 + PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1);
  130 + assertEquals(orderItem02.getSkuId(), 20L);
  131 + assertEquals(orderItem02.getCount(), 3);
  132 + assertEquals(orderItem02.getOriginalPrice(), 150);
  133 + assertEquals(orderItem02.getOriginalUnitPrice(), 50);
  134 + assertEquals(orderItem02.getDiscountPrice(), 30);
  135 + assertEquals(orderItem02.getPayPrice(), 120);
  136 + assertEquals(orderItem02.getOrderPartPrice(), 0);
  137 + assertEquals(orderItem02.getOrderDividePrice(), 120);
  138 + // 断言 Promotion 部分
  139 + assertEquals(priceCalculate.getPromotions().size(), 2);
  140 + PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0);
  141 + assertEquals(promotion01.getId(), 1000L);
  142 + assertEquals(promotion01.getName(), "活动 1000 号");
  143 + assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType());
  144 + assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel());
  145 + assertEquals(promotion01.getOriginalPrice(), 200);
  146 + assertEquals(promotion01.getDiscountPrice(), 40);
  147 + assertTrue(promotion01.getMeet());
  148 + assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.40 元");
  149 + PriceCalculateRespDTO.PromotionItem promotionItem01 = promotion01.getItems().get(0);
  150 + assertEquals(promotion01.getItems().size(), 1);
  151 + assertEquals(promotionItem01.getSkuId(), 10L);
  152 + assertEquals(promotionItem01.getOriginalPrice(), 200);
  153 + assertEquals(promotionItem01.getDiscountPrice(), 40);
  154 + PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1);
  155 + assertEquals(promotion02.getId(), 2000L);
  156 + assertEquals(promotion02.getName(), "活动 2000 号");
  157 + assertEquals(promotion02.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType());
  158 + assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel());
  159 + assertEquals(promotion02.getOriginalPrice(), 150);
  160 + assertEquals(promotion02.getDiscountPrice(), 30);
  161 + assertTrue(promotion02.getMeet());
  162 + assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.30 元");
  163 + PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0);
  164 + assertEquals(promotion02.getItems().size(), 1);
  165 + assertEquals(promotionItem02.getSkuId(), 20L);
  166 + assertEquals(promotionItem02.getOriginalPrice(), 150);
  167 + assertEquals(promotionItem02.getDiscountPrice(), 30);
  168 + }
  169 +
86 170 }
... ...