fix: 特殊情况处理,如参与多个促销活动,部分商品在其他促销计算后的金额不足以满足与当前参与的促销活动的优惠金额
This commit is contained in:
parent
ae93661763
commit
a33e053bc7
@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 促销价格计算业务层实现
|
* 促销价格计算业务层实现
|
||||||
@ -66,7 +67,7 @@ public class PromotionPriceUtil {
|
|||||||
List<CartSkuVO> skuVOList = tradeDTO.getSkuList();
|
List<CartSkuVO> skuVOList = tradeDTO.getSkuList();
|
||||||
|
|
||||||
// 获取map分配sku的总数,如果是最后一个商品分配金额,则将金额从百分比改为总金额扣减,避免出现小数除不尽
|
// 获取map分配sku的总数,如果是最后一个商品分配金额,则将金额从百分比改为总金额扣减,避免出现小数除不尽
|
||||||
Integer count = skuPromotionDetail.size();
|
int count = skuPromotionDetail.size();
|
||||||
|
|
||||||
//已优惠金额
|
//已优惠金额
|
||||||
Double deducted = 0D;
|
Double deducted = 0D;
|
||||||
@ -81,12 +82,12 @@ public class PromotionPriceUtil {
|
|||||||
count--;
|
count--;
|
||||||
|
|
||||||
//sku 优惠金额
|
//sku 优惠金额
|
||||||
Double skuDiscountPrice = 0d;
|
Double skuDiscountPrice;
|
||||||
|
|
||||||
//非最后一个商品,则按照比例计算
|
//非最后一个商品,则按照比例计算
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
//商品金额占比
|
//商品金额占比
|
||||||
Double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
|
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
|
||||||
//商品优惠金额
|
//商品优惠金额
|
||||||
skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
|
skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
|
||||||
//累加已优惠金额
|
//累加已优惠金额
|
||||||
@ -96,64 +97,135 @@ public class PromotionPriceUtil {
|
|||||||
else {
|
else {
|
||||||
skuDiscountPrice = CurrencyUtil.sub(discountPrice, deducted);
|
skuDiscountPrice = CurrencyUtil.sub(discountPrice, deducted);
|
||||||
}
|
}
|
||||||
//优惠券金额,则计入优惠券 ,其他则计入总的discount price
|
|
||||||
if (promotionTypeEnum == PromotionTypeEnum.COUPON) {
|
|
||||||
|
|
||||||
cartSkuVO.getPriceDetailDTO().setCouponPrice(
|
calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId);
|
||||||
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), skuDiscountPrice));
|
|
||||||
|
|
||||||
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
|
|
||||||
DiscountPriceItem.builder()
|
|
||||||
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
|
|
||||||
.skuId(cartSkuVO.getGoodsSku().getId())
|
|
||||||
.discountPrice(skuDiscountPrice)
|
|
||||||
.promotionTypeEnum(PromotionTypeEnum.COUPON)
|
|
||||||
.promotionId(activityId)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
} else if (promotionTypeEnum == PromotionTypeEnum.PLATFORM_COUPON) {
|
|
||||||
|
|
||||||
cartSkuVO.getPriceDetailDTO().setSiteCouponPrice(
|
|
||||||
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), skuDiscountPrice));
|
|
||||||
|
|
||||||
cartSkuVO.getPriceDetailDTO().setCouponPrice(
|
|
||||||
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), cartSkuVO.getPriceDetailDTO().getSiteCouponPrice()));
|
|
||||||
|
|
||||||
|
|
||||||
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
|
|
||||||
DiscountPriceItem.builder()
|
|
||||||
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
|
|
||||||
.skuId(cartSkuVO.getGoodsSku().getId())
|
|
||||||
.discountPrice(skuDiscountPrice)
|
|
||||||
.promotionTypeEnum(PromotionTypeEnum.PLATFORM_COUPON)
|
|
||||||
.promotionId(activityId)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
cartSkuVO.getPriceDetailDTO().setDiscountPrice(
|
|
||||||
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getDiscountPrice(), skuDiscountPrice));
|
|
||||||
|
|
||||||
//目前剩余的只有满减金额活动。后续如果需要调整,这里建议传递活动类型进来
|
|
||||||
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
|
|
||||||
DiscountPriceItem.builder()
|
|
||||||
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
|
|
||||||
.skuId(cartSkuVO.getGoodsSku().getId())
|
|
||||||
.discountPrice(skuDiscountPrice)
|
|
||||||
.promotionTypeEnum(PromotionTypeEnum.FULL_DISCOUNT)
|
|
||||||
.promotionId(activityId)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算购物车商品优惠金额
|
||||||
|
*
|
||||||
|
* @param cartSkuVO 购物车商品
|
||||||
|
* @param skuDiscountPrice 商品优惠金额
|
||||||
|
* @param promotionTypeEnum 优惠类型
|
||||||
|
* @param activityId 优惠活动id
|
||||||
|
*/
|
||||||
|
private static void calculateCartSkuPromotionsPrice(CartSkuVO cartSkuVO, Double skuDiscountPrice, PromotionTypeEnum promotionTypeEnum, String activityId) {
|
||||||
|
//优惠券金额,则计入优惠券 ,其他则计入总的discount price
|
||||||
|
if (promotionTypeEnum == PromotionTypeEnum.COUPON) {
|
||||||
|
|
||||||
|
cartSkuVO.getPriceDetailDTO().setCouponPrice(
|
||||||
|
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), skuDiscountPrice));
|
||||||
|
|
||||||
|
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
|
||||||
|
DiscountPriceItem.builder()
|
||||||
|
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
|
||||||
|
.skuId(cartSkuVO.getGoodsSku().getId())
|
||||||
|
.discountPrice(skuDiscountPrice)
|
||||||
|
.promotionTypeEnum(PromotionTypeEnum.COUPON)
|
||||||
|
.promotionId(activityId)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
} else if (promotionTypeEnum == PromotionTypeEnum.PLATFORM_COUPON) {
|
||||||
|
|
||||||
|
cartSkuVO.getPriceDetailDTO().setSiteCouponPrice(
|
||||||
|
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), skuDiscountPrice));
|
||||||
|
|
||||||
|
cartSkuVO.getPriceDetailDTO().setCouponPrice(
|
||||||
|
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), cartSkuVO.getPriceDetailDTO().getSiteCouponPrice()));
|
||||||
|
|
||||||
|
|
||||||
|
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
|
||||||
|
DiscountPriceItem.builder()
|
||||||
|
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
|
||||||
|
.skuId(cartSkuVO.getGoodsSku().getId())
|
||||||
|
.discountPrice(skuDiscountPrice)
|
||||||
|
.promotionTypeEnum(PromotionTypeEnum.PLATFORM_COUPON)
|
||||||
|
.promotionId(activityId)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cartSkuVO.getPriceDetailDTO().setDiscountPrice(
|
||||||
|
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getDiscountPrice(), skuDiscountPrice));
|
||||||
|
|
||||||
|
//目前剩余的只有满减金额活动。后续如果需要调整,这里建议传递活动类型进来
|
||||||
|
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
|
||||||
|
DiscountPriceItem.builder()
|
||||||
|
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
|
||||||
|
.skuId(cartSkuVO.getGoodsSku().getId())
|
||||||
|
.discountPrice(skuDiscountPrice)
|
||||||
|
.promotionTypeEnum(PromotionTypeEnum.FULL_DISCOUNT)
|
||||||
|
.promotionId(activityId)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 特殊情况处理,如参与多个促销活动,部分商品在其他促销计算后的金额不足以满足与当前参与的促销活动的优惠金额
|
||||||
|
*
|
||||||
|
* @param skuVOList 获取购物车信息
|
||||||
|
* @param skuPromotionDetail 参与活动的商品,以及商品总金额
|
||||||
|
* @param discountPrice 需要分发的优惠金额
|
||||||
|
* @param totalPrice 计算总金额
|
||||||
|
* @param promotionTypeEnum 优惠类型
|
||||||
|
* @param activityId 优惠活动id
|
||||||
|
*/
|
||||||
|
private static void calculateNotEnoughPromotionsPrice(List<CartSkuVO> skuVOList, Map<String, Double> skuPromotionDetail, Double discountPrice, Double totalPrice, PromotionTypeEnum promotionTypeEnum, String activityId) {
|
||||||
|
// 特殊情况处理,如参与多个促销活动,部分商品在其他促销计算后的金额不足以满足与当前参与的促销活动的优惠金额
|
||||||
|
// 但当前购物车内存在当前当前促销活动的其他商品且剩余金额也满足分摊不足商品的不足金额,则分摊到其他商品上
|
||||||
|
// 满足当前促销的总优惠金额
|
||||||
|
if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long matchPromotionsZeroCount = skuVOList.stream().filter(l -> l.getPriceDetailDTO().getFlowPrice() == 0 && skuPromotionDetail.containsKey(l.getGoodsSku().getId())).count();
|
||||||
|
long matchPromotionsCount = skuVOList.stream().filter(l -> skuPromotionDetail.containsKey(l.getGoodsSku().getId())).count();
|
||||||
|
if (matchPromotionsZeroCount == matchPromotionsCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 获取剩余金额不足优惠金额的商品
|
||||||
|
List<CartSkuVO> unEnoughSku = skuVOList.stream().filter(k -> {
|
||||||
|
if (skuPromotionDetail.containsKey(k.getGoodsSku().getId()) && skuPromotionDetail.size() >= 2) {
|
||||||
|
//商品金额占比
|
||||||
|
double point = CurrencyUtil.div(k.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
|
||||||
|
//商品优惠金额
|
||||||
|
Double skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
|
||||||
|
return skuDiscountPrice > k.getPriceDetailDTO().getCouponPrice();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
if (!unEnoughSku.isEmpty()) {
|
||||||
|
for (CartSkuVO cartSkuVO : skuVOList) {
|
||||||
|
if (unEnoughSku.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (skuPromotionDetail.containsKey(cartSkuVO.getGoodsSku().getId()) && unEnoughSku.stream().noneMatch(k -> k.getGoodsSku().getId().equals(cartSkuVO.getGoodsSku().getId()))) {
|
||||||
|
// 商品金额占比
|
||||||
|
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
|
||||||
|
// 商品优惠金额
|
||||||
|
Double skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
|
||||||
|
// 商品优惠金额 - 不足优惠金额 = 差额
|
||||||
|
Double sub = CurrencyUtil.sub(skuDiscountPrice, unEnoughSku.get(0).getPriceDetailDTO().getCouponPrice());
|
||||||
|
// 分摊到其他商品: 其他商品原优惠金额 + 差额
|
||||||
|
calculateCartSkuPromotionsPrice(cartSkuVO, sub, promotionTypeEnum, activityId);
|
||||||
|
// 从不足商品列表中移除
|
||||||
|
unEnoughSku.remove(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查活动有效时间
|
* 检查活动有效时间
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user