|
@@ -51,6 +51,7 @@ import com.kmall.admin.service.mk.MkActivitiesService;
|
|
import com.kmall.admin.service.mk.store.MkStoreCampMinusService;
|
|
import com.kmall.admin.service.mk.store.MkStoreCampMinusService;
|
|
import com.kmall.admin.service.mk.store.MkStoreTicketDiscountService;
|
|
import com.kmall.admin.service.mk.store.MkStoreTicketDiscountService;
|
|
import com.kmall.admin.service.record.NewRetailOrderRestoreStockRecordService;
|
|
import com.kmall.admin.service.record.NewRetailOrderRestoreStockRecordService;
|
|
|
|
+import com.kmall.admin.service.vip.Mall2PointsRulesService;
|
|
import com.kmall.admin.utils.CalculateTax;
|
|
import com.kmall.admin.utils.CalculateTax;
|
|
import com.kmall.admin.utils.ShiroUtils;
|
|
import com.kmall.admin.utils.ShiroUtils;
|
|
import com.kmall.admin.utils.data.response.ResponseMessage;
|
|
import com.kmall.admin.utils.data.response.ResponseMessage;
|
|
@@ -194,6 +195,8 @@ public class OrderServiceImpl implements OrderService {
|
|
@Autowired
|
|
@Autowired
|
|
private Mall2PointsRulesDao pointsRulesDao; // 积分规则
|
|
private Mall2PointsRulesDao pointsRulesDao; // 积分规则
|
|
@Autowired
|
|
@Autowired
|
|
|
|
+ private Mall2PointsRulesService mall2PointsRulesService;
|
|
|
|
+ @Autowired
|
|
private Mall2MemberPointsDao memberPointsDao; // 用户积分
|
|
private Mall2MemberPointsDao memberPointsDao; // 用户积分
|
|
@Autowired
|
|
@Autowired
|
|
private Mall2MemberConsumptionRecordsDao memberConsumptionRecordsDao; // 会员消费记录
|
|
private Mall2MemberConsumptionRecordsDao memberConsumptionRecordsDao; // 会员消费记录
|
|
@@ -2495,8 +2498,8 @@ public class OrderServiceImpl implements OrderService {
|
|
if (stockMap.containsKey(sku)) {
|
|
if (stockMap.containsKey(sku)) {
|
|
// 当前出区数
|
|
// 当前出区数
|
|
Integer exitRegionNumber = goodsDto.getExitRegionNumber();
|
|
Integer exitRegionNumber = goodsDto.getExitRegionNumber();
|
|
- // 保税仓库存 + 门店库存 - 出区数 >= 购买数
|
|
|
|
- if (!((warehouseStock + stockNum) - exitRegionNumber >= sellVolume)) {
|
|
|
|
|
|
+ // 保税仓库存 + 门店库存 - 出区数 > 购买数
|
|
|
|
+ if (!((warehouseStock + stockNum) - exitRegionNumber > sellVolume)) {
|
|
// 库存不足
|
|
// 库存不足
|
|
LOGGER.error("sku:【{}】库存不足,门店可用库存:【{}】,仓库可用库存:【{}】,购买数量:【{}】", sku, stockNum, warehouseStock, sellVolume);
|
|
LOGGER.error("sku:【{}】库存不足,门店可用库存:【{}】,仓库可用库存:【{}】,购买数量:【{}】", sku, stockNum, warehouseStock, sellVolume);
|
|
throw new ServiceException(String.format("sku:【%s】库存不足,门店可用库存:【%s】,仓库可用库存:【%s】,购买数量:【%s】", sku, stockNum, warehouseStock, sellVolume));
|
|
throw new ServiceException(String.format("sku:【%s】库存不足,门店可用库存:【%s】,仓库可用库存:【%s】,购买数量:【%s】", sku, stockNum, warehouseStock, sellVolume));
|
|
@@ -2738,20 +2741,36 @@ public class OrderServiceImpl implements OrderService {
|
|
saleRecordDao.save(saleRecordEntity);
|
|
saleRecordDao.save(saleRecordEntity);
|
|
}
|
|
}
|
|
|
|
|
|
- // TODO 查询积分规则,根据积分生成规则进行增加会员积分
|
|
|
|
- Mall2PointsRulesEntity pointsRules = null;
|
|
|
|
-
|
|
|
|
|
|
+ // TODO 查询当前时间积分规则,根据积分生成规则进行增加会员积分
|
|
|
|
+ Integer userEntityId = userEntity.getId();
|
|
|
|
+ Integer memberScore = order.getActual_price().intValue();
|
|
|
|
+ //List<Mall2PointsRulesEntity> mall2PointsRulesEntities = mall2PointsRulesService.queryListByTime(new Date()).stream().sorted().collect(Collectors.toList());
|
|
|
|
+ /*mall2PointsRulesEntities.forEach(mall2PointsRulesEntity -> {
|
|
|
|
+ // 查询明细
|
|
|
|
+ Integer pointsType = mall2PointsRulesEntity.getPointsType();
|
|
|
|
+ if (pointsType.equals(Constants.MemberScoreRulesEnum.TWO.getCode())) {
|
|
|
|
+ // 商品,优先级最高,查询
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ } else if (pointsType.equals(Constants.MemberScoreRulesEnum.ONE.getCode())) {
|
|
|
|
+ // 商品类别
|
|
|
|
+ } else if (pointsType.equals(Constants.MemberScoreRulesEnum.ZERO.getCode())) {
|
|
|
|
+ // 门店
|
|
|
|
+ } else {
|
|
|
|
+ LOGGER.error("未知的积分生成规则类型:{}", pointsType);
|
|
|
|
+ }
|
|
|
|
+ });*/
|
|
// 增加该会员的积分
|
|
// 增加该会员的积分
|
|
- Mall2MemberPointsEntity memberPointsEntity = memberPointsDao.queryByUserId(userEntity.getId());
|
|
|
|
|
|
+ Mall2MemberPointsEntity memberPointsEntity = memberPointsDao.queryByUserId(userEntityId);
|
|
if (memberPointsEntity == null) {
|
|
if (memberPointsEntity == null) {
|
|
memberPointsEntity = new Mall2MemberPointsEntity();
|
|
memberPointsEntity = new Mall2MemberPointsEntity();
|
|
- memberPointsEntity.setUserId(userEntity.getId() + "");
|
|
|
|
- memberPointsEntity.setPoints(order.getActual_price().intValue());
|
|
|
|
|
|
+ memberPointsEntity.setUserId(userEntityId + "");
|
|
|
|
+ memberPointsEntity.setPoints(memberScore);
|
|
memberPointsEntity.setCreaterSn(userId + "");
|
|
memberPointsEntity.setCreaterSn(userId + "");
|
|
memberPointsEntity.setCreateTime(new Date());
|
|
memberPointsEntity.setCreateTime(new Date());
|
|
memberPointsDao.save(memberPointsEntity);
|
|
memberPointsDao.save(memberPointsEntity);
|
|
} else {
|
|
} else {
|
|
- memberPointsEntity.setPoints(order.getActual_price().add(new BigDecimal(memberPointsEntity.getPoints())).intValue());
|
|
|
|
|
|
+ memberPointsEntity.setPoints(memberScore + memberPointsEntity.getPoints());
|
|
memberPointsEntity.setModerSn(userId + "");
|
|
memberPointsEntity.setModerSn(userId + "");
|
|
memberPointsEntity.setModTime(new Date());
|
|
memberPointsEntity.setModTime(new Date());
|
|
memberPointsDao.update(memberPointsEntity);
|
|
memberPointsDao.update(memberPointsEntity);
|
|
@@ -3038,6 +3057,9 @@ public class OrderServiceImpl implements OrderService {
|
|
memberOrderInfoSyncDTO.setOrderAmount(order.getActual_price());
|
|
memberOrderInfoSyncDTO.setOrderAmount(order.getActual_price());
|
|
memberOrderInfoSyncDTO.setOrderScore(deductionScore);
|
|
memberOrderInfoSyncDTO.setOrderScore(deductionScore);
|
|
BeanUtils.copyProperties(memberOrderInfoSyncDTO, haiKongMemberOrderSyncResendEntity);
|
|
BeanUtils.copyProperties(memberOrderInfoSyncDTO, haiKongMemberOrderSyncResendEntity);
|
|
|
|
+ Date date = new Date();
|
|
|
|
+ haiKongMemberOrderSyncResendEntity.setCreateTime(date);
|
|
|
|
+ haiKongMemberOrderSyncResendEntity.setLastResendTime(date);
|
|
try {
|
|
try {
|
|
String body = JacksonUtil.toJson(memberOrderInfoSyncDTO);
|
|
String body = JacksonUtil.toJson(memberOrderInfoSyncDTO);
|
|
LOGGER.info("请求会员系统同步消费订单接口!请求体:{}", body);
|
|
LOGGER.info("请求会员系统同步消费订单接口!请求体:{}", body);
|
|
@@ -3077,6 +3099,9 @@ public class OrderServiceImpl implements OrderService {
|
|
memberScoreChangeDTO.setOutBizNo(order.getOrder_sn());
|
|
memberScoreChangeDTO.setOutBizNo(order.getOrder_sn());
|
|
memberScoreChangeDTO.setScore(score);
|
|
memberScoreChangeDTO.setScore(score);
|
|
BeanUtils.copyProperties(memberScoreChangeDTO, haiKongMemberScoreChangeRecordEntity);
|
|
BeanUtils.copyProperties(memberScoreChangeDTO, haiKongMemberScoreChangeRecordEntity);
|
|
|
|
+ Date date = new Date();
|
|
|
|
+ haiKongMemberScoreChangeRecordEntity.setCreateTime(date);
|
|
|
|
+ haiKongMemberScoreChangeRecordEntity.setModifyTime(date);
|
|
try {
|
|
try {
|
|
String body = JacksonUtil.toJson(memberScoreChangeDTO);
|
|
String body = JacksonUtil.toJson(memberScoreChangeDTO);
|
|
LOGGER.info("请求会员系统积分变动接口!请求体:{}", body);
|
|
LOGGER.info("请求会员系统积分变动接口!请求体:{}", body);
|
|
@@ -4010,7 +4035,7 @@ public class OrderServiceImpl implements OrderService {
|
|
/*
|
|
/*
|
|
* 活动相关规则:
|
|
* 活动相关规则:
|
|
* 1. 优先优惠券再去计算积分
|
|
* 1. 优先优惠券再去计算积分
|
|
- * 2. 满赠的赠品商品在推送定时时零售价为0
|
|
|
|
|
|
+ * 2. 满赠的赠品商品在推送订单时零售价为0
|
|
* 3. 任何活动都优先于积分计算
|
|
* 3. 任何活动都优先于积分计算
|
|
* 4. 活动之间具有互斥性
|
|
* 4. 活动之间具有互斥性
|
|
*/
|
|
*/
|
|
@@ -4033,6 +4058,9 @@ public class OrderServiceImpl implements OrderService {
|
|
List<Integer> categoryIdList = goodsEntities.stream().map(GoodsEntity::getCategoryId).collect(Collectors.toList());
|
|
List<Integer> categoryIdList = goodsEntities.stream().map(GoodsEntity::getCategoryId).collect(Collectors.toList());
|
|
// 活动互斥标识
|
|
// 活动互斥标识
|
|
AtomicBoolean activityFlag = new AtomicBoolean(true);
|
|
AtomicBoolean activityFlag = new AtomicBoolean(true);
|
|
|
|
+ // 限时特价活动标识
|
|
|
|
+ AtomicBoolean promotionActivityFlag = new AtomicBoolean(false);
|
|
|
|
+ List<String> promotionSkuList = new ArrayList<>();
|
|
// 判断活动类型并排序,再确定购物栏中商品是否满足活动条件
|
|
// 判断活动类型并排序,再确定购物栏中商品是否满足活动条件
|
|
mkActivitiesEntityList.stream().sorted().forEach(mkActivitiesEntity -> {
|
|
mkActivitiesEntityList.stream().sorted().forEach(mkActivitiesEntity -> {
|
|
String mkaStoreId = mkActivitiesEntity.getMkaStoreId();
|
|
String mkaStoreId = mkActivitiesEntity.getMkaStoreId();
|
|
@@ -4056,6 +4084,11 @@ public class OrderServiceImpl implements OrderService {
|
|
String entityGoodsSn = mkActivitiesPromotionEntity.getSku();
|
|
String entityGoodsSn = mkActivitiesPromotionEntity.getSku();
|
|
BigDecimal activityPrice = mkActivitiesPromotionEntity.getActivityPrice();
|
|
BigDecimal activityPrice = mkActivitiesPromotionEntity.getActivityPrice();
|
|
String shopSn = mkActivitiesPromotionEntity.getShopSn();
|
|
String shopSn = mkActivitiesPromotionEntity.getShopSn();
|
|
|
|
+ String rejectScore = mkActivitiesPromotionEntity.getRejectScore();
|
|
|
|
+ // 如果与积分抵扣互斥的,记录sku
|
|
|
|
+ if (!org.springframework.util.StringUtils.isEmpty(rejectScore) && Constants.PromotionActivityRejectEnum.REJECT.getCode().equals(rejectScore)) {
|
|
|
|
+ promotionSkuList.add(entityGoodsSn);
|
|
|
|
+ }
|
|
goodsEntities.forEach(goodsEntity -> {
|
|
goodsEntities.forEach(goodsEntity -> {
|
|
String sku = goodsEntity.getSku();
|
|
String sku = goodsEntity.getSku();
|
|
String prodBarcode = goodsEntity.getProdBarcode();
|
|
String prodBarcode = goodsEntity.getProdBarcode();
|
|
@@ -4071,6 +4104,7 @@ public class OrderServiceImpl implements OrderService {
|
|
goodsDetailsDto.setDiscountedPrice(retailPrice.subtract(activityPrice));
|
|
goodsDetailsDto.setDiscountedPrice(retailPrice.subtract(activityPrice));
|
|
goodsDetailsDtos.add(goodsDetailsDto);
|
|
goodsDetailsDtos.add(goodsDetailsDto);
|
|
activityFlag.set(false);
|
|
activityFlag.set(false);
|
|
|
|
+ promotionActivityFlag.set(true);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
@@ -4301,7 +4335,7 @@ public class OrderServiceImpl implements OrderService {
|
|
Integer score = memberInfoDTO.getScore();
|
|
Integer score = memberInfoDTO.getScore();
|
|
if (Objects.nonNull(score) && score > 0) {
|
|
if (Objects.nonNull(score) && score > 0) {
|
|
// 有积分
|
|
// 有积分
|
|
- afterDiscountPrice = calculatePreferentialPrice(orderTotalPrice, score, storeId, memberCode, calculateOrderDiscountPriceResponseVO);
|
|
|
|
|
|
+ afterDiscountPrice = calculatePreferentialPrice(orderTotalPrice, score, storeId, memberCode, calculateOrderDiscountPriceResponseVO, goodsDetailsDtos, promotionActivityFlag, promotionSkuList);
|
|
LOGGER.info("会员【{}】,当前积分:{},积分抵扣后的订单金额:{},积分抵扣前的订单金额:{}", memberCode, score, afterDiscountPrice, orderTotalPrice);
|
|
LOGGER.info("会员【{}】,当前积分:{},积分抵扣后的订单金额:{},积分抵扣前的订单金额:{}", memberCode, score, afterDiscountPrice, orderTotalPrice);
|
|
calculateOrderDiscountPriceResponseVO.setOrderTotalPrice(afterDiscountPrice);
|
|
calculateOrderDiscountPriceResponseVO.setOrderTotalPrice(afterDiscountPrice);
|
|
calculateOrderDiscountPriceResponseVO.setGoodsDetailsDtos(goodsDetailsDtos);
|
|
calculateOrderDiscountPriceResponseVO.setGoodsDetailsDtos(goodsDetailsDtos);
|
|
@@ -4330,13 +4364,17 @@ public class OrderServiceImpl implements OrderService {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 计算积分抵扣后的订单总金额
|
|
* 计算积分抵扣后的订单总金额
|
|
- * @param orderTotalPrice 订单商品详情
|
|
|
|
|
|
+ * @param orderTotalPrice 订单商品总价
|
|
* @param score 积分
|
|
* @param score 积分
|
|
* @param storeId 门店id
|
|
* @param storeId 门店id
|
|
* @param memberCode 会员码
|
|
* @param memberCode 会员码
|
|
|
|
+ * @param goodsDetailsDtos 订单商品详情
|
|
|
|
+ * @param calculateOrderDiscountPriceResponseVO 响应数据
|
|
|
|
+ * @param promotionActivityFlag 是否参与了积分抵扣活动
|
|
|
|
+ * @param promotionSkuList 参与了积分抵扣活动的sku集合
|
|
* @return 积分抵扣后的订单总金额
|
|
* @return 积分抵扣后的订单总金额
|
|
*/
|
|
*/
|
|
- private BigDecimal calculatePreferentialPrice(BigDecimal orderTotalPrice, Integer score, String storeId, String memberCode, CalculateOrderDiscountPriceResponseVO calculateOrderDiscountPriceResponseVO) {
|
|
|
|
|
|
+ private BigDecimal calculatePreferentialPrice(BigDecimal orderTotalPrice, Integer score, String storeId, String memberCode, CalculateOrderDiscountPriceResponseVO calculateOrderDiscountPriceResponseVO, List<GoodsDetailsDto> goodsDetailsDtos, AtomicBoolean promotionActivityFlag, List<String> promotionSkuList) {
|
|
// 1. 判断是否有积分,是否需要计算积分抵扣后的价格
|
|
// 1. 判断是否有积分,是否需要计算积分抵扣后的价格
|
|
AtomicBoolean isCalculateScorePrice = new AtomicBoolean(false);
|
|
AtomicBoolean isCalculateScorePrice = new AtomicBoolean(false);
|
|
if (Objects.nonNull(score) && score > 0) {
|
|
if (Objects.nonNull(score) && score > 0) {
|
|
@@ -4351,6 +4389,10 @@ public class OrderServiceImpl implements OrderService {
|
|
LOGGER.warn("用户【{}】的积分数量为:{},最低需要30积分才能抵扣!", memberCode, score);
|
|
LOGGER.warn("用户【{}】的积分数量为:{},最低需要30积分才能抵扣!", memberCode, score);
|
|
return orderTotalPrice;
|
|
return orderTotalPrice;
|
|
} else {
|
|
} else {
|
|
|
|
+ // 积分取整
|
|
|
|
+ int scoreInteger = score % scoreLimit == 0 ? score : score - (score % scoreLimit);
|
|
|
|
+ // 积分的50%
|
|
|
|
+ int scoreIntegerHalf = scoreInteger * scoreLimit / 100;
|
|
// 3-2. 计算出积分能抵扣的价格
|
|
// 3-2. 计算出积分能抵扣的价格
|
|
int scoreMayDeductionPrice = (int) (score / scoreLimit);
|
|
int scoreMayDeductionPrice = (int) (score / scoreLimit);
|
|
BigDecimal scoreMayDeductionPriceDecimal = new BigDecimal(scoreMayDeductionPrice);
|
|
BigDecimal scoreMayDeductionPriceDecimal = new BigDecimal(scoreMayDeductionPrice);
|
|
@@ -4359,17 +4401,48 @@ public class OrderServiceImpl implements OrderService {
|
|
// 积分能抵扣的金额大于订单总额的50%,按50%抵扣
|
|
// 积分能抵扣的金额大于订单总额的50%,按50%抵扣
|
|
scoreMayDeductionPriceDecimal = halfPrice;
|
|
scoreMayDeductionPriceDecimal = halfPrice;
|
|
}
|
|
}
|
|
|
|
+ // 参与了积分抵扣活动,不互斥的情况下
|
|
|
|
+ if (promotionActivityFlag.get() && !CollectionUtils.isEmpty(promotionSkuList)) {
|
|
|
|
+ BigDecimal shareScore = BigDecimal.ZERO;
|
|
|
|
+ BigDecimal scoreIntegerDecimal = BigDecimal.valueOf(scoreInteger);
|
|
|
|
+ BigDecimal scoreLimitDecimal = BigDecimal.valueOf(scoreLimit);
|
|
|
|
+ BigDecimal goodsDetailScoreDeductionPrice = BigDecimal.ZERO;
|
|
|
|
+ for (int i = 0; i < goodsDetailsDtos.size(); i++) {
|
|
|
|
+ GoodsDetailsDto goodsDetailsDto = goodsDetailsDtos.get(i);
|
|
|
|
+ // 抵扣积分分摊
|
|
|
|
+ int index = goodsDetailsDtos.size() - 1;
|
|
|
|
+ if (promotionSkuList.contains(goodsDetailsDto.getSku()) && i < index) {
|
|
|
|
+ // 计算抵扣
|
|
|
|
+ // 商品总价
|
|
|
|
+ BigDecimal actualPaymentAmount = goodsDetailsDto.getActualPaymentAmount();
|
|
|
|
+ BigDecimal scoreIntegerHalfDecimal = BigDecimal.valueOf(scoreIntegerHalf);
|
|
|
|
+ // 分摊积分
|
|
|
|
+ shareScore = shareScore.add(actualPaymentAmount.divide(scoreIntegerDecimal.multiply(scoreIntegerHalfDecimal), 2, BigDecimal.ROUND_HALF_UP));
|
|
|
|
+ // 保留两位小数,四舍五入
|
|
|
|
+ BigDecimal discountedPrice = shareScore.divide(scoreLimitDecimal, 2, BigDecimal.ROUND_HALF_UP);
|
|
|
|
+ goodsDetailScoreDeductionPrice = goodsDetailScoreDeductionPrice.add(discountedPrice);
|
|
|
|
+ goodsDetailsDto.setDiscountedPrice(discountedPrice);
|
|
|
|
+ }
|
|
|
|
+ if (i == index) {
|
|
|
|
+ BigDecimal discountedPrice = scoreIntegerDecimal.subtract(shareScore).divide(scoreLimitDecimal, 2, BigDecimal.ROUND_HALF_UP);
|
|
|
|
+ goodsDetailScoreDeductionPrice = goodsDetailScoreDeductionPrice.add(discountedPrice);
|
|
|
|
+ goodsDetailsDto.setDiscountedPrice(discountedPrice);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ scoreMayDeductionPriceDecimal = goodsDetailScoreDeductionPrice;
|
|
|
|
+ }
|
|
|
|
+
|
|
orderTotalPrice = orderTotalPrice.subtract(scoreMayDeductionPriceDecimal);
|
|
orderTotalPrice = orderTotalPrice.subtract(scoreMayDeductionPriceDecimal);
|
|
- int afterScore = score - scoreMayDeductionPriceDecimal.multiply(new BigDecimal(scoreLimit)).intValue();
|
|
|
|
|
|
+ int afterScore = score - scoreIntegerHalf;
|
|
calculateOrderDiscountPriceResponseVO.setAfterScore(afterScore);
|
|
calculateOrderDiscountPriceResponseVO.setAfterScore(afterScore);
|
|
calculateOrderDiscountPriceResponseVO.setScoreLimit(scoreLimit);
|
|
calculateOrderDiscountPriceResponseVO.setScoreLimit(scoreLimit);
|
|
- calculateOrderDiscountPriceResponseVO.setDeductionScore(score - afterScore);
|
|
|
|
|
|
+ calculateOrderDiscountPriceResponseVO.setDeductionScore(scoreIntegerHalf);
|
|
calculateOrderDiscountPriceResponseVO.setOrderTotalPrice(orderTotalPrice);
|
|
calculateOrderDiscountPriceResponseVO.setOrderTotalPrice(orderTotalPrice);
|
|
calculateOrderDiscountPriceResponseVO.setScoreDeductionPrice(scoreMayDeductionPriceDecimal);
|
|
calculateOrderDiscountPriceResponseVO.setScoreDeductionPrice(scoreMayDeductionPriceDecimal);
|
|
LOGGER.info("会员【{}】,当前积分:{},抵扣订单金额后剩余积分:{}", memberCode, score, afterScore);
|
|
LOGGER.info("会员【{}】,当前积分:{},抵扣订单金额后剩余积分:{}", memberCode, score, afterScore);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- LOGGER.info("会员【{}】的积分为0,不参加积分抵扣!", memberCode);
|
|
|
|
|
|
+ LOGGER.info("会员【{}】的积分小于积分抵扣最低值,不参加积分抵扣!", memberCode);
|
|
}
|
|
}
|
|
return orderTotalPrice;
|
|
return orderTotalPrice;
|
|
}
|
|
}
|