|
|
@@ -396,11 +396,17 @@ public class CodexServiceImpl implements CodexService {
|
|
|
if (orderDonGalaxyCoinRecord != null) {
|
|
|
orderMoney = orderMoney.add(orderDonGalaxyCoinRecord.getDeductMoney());
|
|
|
}
|
|
|
+ // 续费升级订单的实际价值还包含上一次升级使用的 Codex 抵扣。
|
|
|
+ // 若不回补这部分金额,连续升级时抵扣金额会逐级变少。
|
|
|
+ CodexDeductRecord renewCodexDeductRecord = codexDeductRecordMapper.selectOne(Wrappers.lambdaQuery(CodexDeductRecord.class)
|
|
|
+ .eq(CodexDeductRecord::getOrderId, renewOrderDon.getId()).last("limit 1"));
|
|
|
+ if (renewCodexDeductRecord != null) {
|
|
|
+ orderMoney = orderMoney.add(Optional.ofNullable(renewCodexDeductRecord.getDeductMoney()).orElse(BigDecimal.ZERO));
|
|
|
+ }
|
|
|
GoodsDonSku presentSku = skuMapper.selectById(renewSkuId);
|
|
|
if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
orderMoney = presentSku.getPrice();
|
|
|
}
|
|
|
- Long betweenDay = DateUtil.betweenDay(now, renewExpiryTime, false) + 1;
|
|
|
//当天购买的按规格原价抵扣
|
|
|
BigDecimal renewDeductMoney;
|
|
|
if (now.toDateStr().equals(DateUtil.format(renewOrderDon.getCreatedTime(), "yyyy-MM-dd"))) {
|
|
|
@@ -412,13 +418,18 @@ public class CodexServiceImpl implements CodexService {
|
|
|
relationExpiryTime = DateUtil.offsetMonth(relationExpiryTime, -presentSku.getMonths());
|
|
|
}
|
|
|
} else {
|
|
|
+ // 续费天数追加在车票尾部,不能按“下单时间 + 规格天数”从购买当天开始折旧。
|
|
|
+ // 总到期时间覆盖完整续费周期时,该笔续费应按完整价值抵扣;只有进入该周期后才按剩余天数折算。
|
|
|
+ long skuDays = presentSku.getDays() != null ? presentSku.getDays() : presentSku.getMonths() * 30L;
|
|
|
+ long relationRemainDays = DateUtil.betweenDay(now, relationExpiryTime, false) + 1;
|
|
|
+ long renewRemainDays = Math.min(skuDays, relationRemainDays);
|
|
|
//此次续费规格单价
|
|
|
BigDecimal single = getPayOrderSingle(orderMoney, presentSku);
|
|
|
//该车票抵扣金额
|
|
|
- renewDeductMoney = single.multiply(BigDecimal.valueOf(betweenDay));
|
|
|
+ renewDeductMoney = single.multiply(BigDecimal.valueOf(renewRemainDays));
|
|
|
log.info("codex车票id:{}目前续费升级规格可抵扣的金额为:{}", relationId, renewDeductMoney);
|
|
|
deductMoney = deductMoney.add(renewDeductMoney);
|
|
|
- relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -betweenDay.intValue());
|
|
|
+ relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -(int) renewRemainDays);
|
|
|
}
|
|
|
//上一个续费升级规格
|
|
|
List<OrderDon> orderDOns = codexUserRenewExpiryRecordMapper.getOtherRenewSkus(renewOrderId, relationId, userIdList);
|
|
|
@@ -427,6 +438,11 @@ public class CodexServiceImpl implements CodexService {
|
|
|
Long skuId = thisRenewOrderDon.getSkuId();
|
|
|
GoodsDonSku thisRenewSku = skuMapper.selectById(skuId);
|
|
|
BigDecimal thisOrderMoney = thisRenewOrderDon.getMoney().add(Optional.ofNullable(thisRenewOrderDon.getBalance()).orElse(BigDecimal.ZERO));
|
|
|
+ CodexDeductRecord thisRenewCodexDeductRecord = codexDeductRecordMapper.selectOne(Wrappers.lambdaQuery(CodexDeductRecord.class)
|
|
|
+ .eq(CodexDeductRecord::getOrderId, thisRenewOrderDon.getId()).last("limit 1"));
|
|
|
+ if (thisRenewCodexDeductRecord != null) {
|
|
|
+ thisOrderMoney = thisOrderMoney.add(Optional.ofNullable(thisRenewCodexDeductRecord.getDeductMoney()).orElse(BigDecimal.ZERO));
|
|
|
+ }
|
|
|
if (thisOrderMoney.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
thisOrderMoney = thisRenewSku.getPrice();
|
|
|
}
|
|
|
@@ -842,56 +858,41 @@ public class CodexServiceImpl implements CodexService {
|
|
|
.notIn(OrderDon::getStatus, Constant.noOrderStatus)
|
|
|
.orderByDesc(OrderDon::getId));
|
|
|
}
|
|
|
- //原车票订单总实付金额
|
|
|
- BigDecimal totalOrderMoney = BigDecimal.ZERO;
|
|
|
- //原车票订单总天数
|
|
|
- Integer totalDays = 0;
|
|
|
+ // 多笔订单的有效期是依次追加的,必须从最终到期时间向前逐笔划分,
|
|
|
+ // 不能把不同价格订单合并后用平均日价折算。
|
|
|
+ BigDecimal deductMoney = BigDecimal.ZERO;
|
|
|
+ Date segmentEndTime = relationExpiryTime;
|
|
|
for (OrderDon orderDon : orderDonList) {
|
|
|
- GoodsDonSku sku = skuMapper.selectById(skuId);
|
|
|
+ GoodsDonSku sku = skuMapper.selectById(orderDon.getSkuId());
|
|
|
+ long orderDays = sku.getDays() != null ? sku.getDays() : sku.getMonths() * 30L;
|
|
|
+ Date segmentStartTime = DateUtil.offsetDay(segmentEndTime, -(int) orderDays);
|
|
|
+ // 当前订单段已经全部使用,排在它前面的订单段也必然已使用完。
|
|
|
+ if (!segmentEndTime.after(now)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
BigDecimal thisOrderMoney = orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)).subtract(Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO)).add(Optional.ofNullable(orderDon.getCouponMoney()).orElse(BigDecimal.ZERO));
|
|
|
OrderDonGalaxyCoinRecord orderDonGalaxyCoinRecord = orderDonGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonGalaxyCoinRecord.class).eq(OrderDonGalaxyCoinRecord::getOrderId, orderDon.getId()).last("limit 1"));
|
|
|
if (orderDonGalaxyCoinRecord != null) {
|
|
|
thisOrderMoney = thisOrderMoney.add(orderDonGalaxyCoinRecord.getDeductMoney());
|
|
|
}
|
|
|
+ CodexDeductRecord codexDeductRecord = codexDeductRecordMapper.selectOne(Wrappers.lambdaQuery(CodexDeductRecord.class).eq(CodexDeductRecord::getOrderId, orderDon.getId()).last("limit 1"));
|
|
|
+ if (codexDeductRecord != null) {
|
|
|
+ thisOrderMoney = thisOrderMoney.add(Optional.ofNullable(codexDeductRecord.getDeductMoney()).orElse(BigDecimal.ZERO));
|
|
|
+ }
|
|
|
if (thisOrderMoney.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
thisOrderMoney = sku.getPrice();
|
|
|
}
|
|
|
- totalOrderMoney = totalOrderMoney.add(thisOrderMoney);
|
|
|
- //总时间
|
|
|
- if (sku.getDays() != null) {
|
|
|
- totalDays += sku.getDays();
|
|
|
+
|
|
|
+ if (!now.after(segmentStartTime)) {
|
|
|
+ // 该订单追加的时段尚未开始,完整价值参与抵扣。
|
|
|
+ deductMoney = deductMoney.add(thisOrderMoney);
|
|
|
} else {
|
|
|
- totalDays += sku.getMonths() * 30;
|
|
|
- }
|
|
|
- CodexDeductRecord codexDeductRecord = codexDeductRecordMapper.selectOne(Wrappers.lambdaQuery(CodexDeductRecord.class).eq(CodexDeductRecord::getOrderId, orderDon.getId()).last("limit 1"));
|
|
|
- if (codexDeductRecord != null) {
|
|
|
- totalOrderMoney = totalOrderMoney.add(Optional.ofNullable(codexDeductRecord.getDeductMoney()).orElse(BigDecimal.ZERO));
|
|
|
- }
|
|
|
- //原订单数
|
|
|
- if (orderDonList.size() == 1) {
|
|
|
- //此次订单过期时间
|
|
|
- Date thisOrderExpiryTime;
|
|
|
- if (sku.getDays() != null) {
|
|
|
- thisOrderExpiryTime = DateUtil.offsetDay(orderDon.getCreatedTime(), sku.getDays());
|
|
|
- } else {
|
|
|
- thisOrderExpiryTime = DateUtil.offsetMonth(orderDon.getCreatedTime(), sku.getMonths());
|
|
|
- }
|
|
|
- //当天购买的按规格原价抵扣
|
|
|
- if (now.toDateStr().equals(DateUtil.format(orderDon.getCreatedTime(), "yyyy-MM-dd")) && (DateUtil.betweenDay(thisOrderExpiryTime, relationExpiryTime, true) == 0)) {
|
|
|
- if (codexDeductRecord != null) {
|
|
|
- thisOrderMoney = thisOrderMoney.add(Optional.ofNullable(codexDeductRecord.getDeductMoney()).orElse(BigDecimal.ZERO));
|
|
|
- }
|
|
|
- return thisOrderMoney;
|
|
|
- }
|
|
|
+ long remainingDays = Math.min(orderDays, DateUtil.betweenDay(now, segmentEndTime, false) + 1);
|
|
|
+ BigDecimal single = thisOrderMoney.divide(BigDecimal.valueOf(orderDays), 2, RoundingMode.HALF_UP);
|
|
|
+ deductMoney = deductMoney.add(single.multiply(BigDecimal.valueOf(remainingDays)));
|
|
|
}
|
|
|
+ segmentEndTime = segmentStartTime;
|
|
|
}
|
|
|
- if (totalDays == 0) {
|
|
|
- return BigDecimal.ZERO;
|
|
|
- }
|
|
|
- Long thisDeductBetweenDay = DateUtil.betweenDay(now, relationExpiryTime, false) + 1;
|
|
|
- BigDecimal single = totalOrderMoney.divide(BigDecimal.valueOf(totalDays), 0, RoundingMode.HALF_UP);
|
|
|
- //该车票抵扣金额
|
|
|
- BigDecimal deductMoney = single.multiply(BigDecimal.valueOf(thisDeductBetweenDay));
|
|
|
return deductMoney;
|
|
|
}
|
|
|
|
|
|
@@ -1178,4 +1179,4 @@ public class CodexServiceImpl implements CodexService {
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
-}
|
|
|
+}
|