Browse Source

订单优惠计算

skyline 2 years ago
parent
commit
e65b67bf36

+ 33 - 20
service/src/main/java/com/kym/service/enplus/impl/EnNotifyServiceImpl.java

@@ -15,10 +15,10 @@ import com.kym.entity.miniapp.UserRechargeRights;
 import com.kym.entity.miniapp.WalletDetail;
 import com.kym.service.admin.EquipmentInfoService;
 import com.kym.service.admin.MonitorLogService;
+import com.kym.service.cache.KymCache;
 import com.kym.service.enplus.EnNotifyService;
 import com.kym.service.enplus.EnPlusService;
 import com.kym.service.miniapp.*;
-import com.kym.service.cache.KymCache;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
@@ -26,6 +26,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 
@@ -78,7 +79,6 @@ public class EnNotifyServiceImpl implements EnNotifyService {
         this.redisDBChangeUtil = redisDBChangeUtil;
     }
 
-
     /**
      * EN+ 充电站设备状态变化推送
      *
@@ -143,7 +143,6 @@ public class EnNotifyServiceImpl implements EnNotifyService {
                 """.formatted(0);
     }
 
-
     /**
      * EN+ 推送启动充电结果
      *
@@ -210,7 +209,6 @@ public class EnNotifyServiceImpl implements EnNotifyService {
                 """.formatted(startChargeSeq, 0);
     }
 
-
     /**
      * 推送停止充电结果
      *
@@ -238,7 +236,6 @@ public class EnNotifyServiceImpl implements EnNotifyService {
                 """.formatted(startChargeSeq, 0, 0);
     }
 
-
     /**
      * 推送充电订单信息
      *
@@ -280,36 +277,52 @@ public class EnNotifyServiceImpl implements EnNotifyService {
             if (orderRechargeRights != null) {
                 // 获取折扣,计算优惠
                 var discount = orderRechargeRights.getDiscount();
-                var serviceMoneyDiscount = chargeOrder.getServiceMoney() * (discount / 100); // 只保留到分,分以下不进行四舍五入
+                var serviceMoneyDiscount = (int) (chargeOrder.getServiceMoney() * (BigDecimal.valueOf(1).subtract(BigDecimal.valueOf(discount).divide(BigDecimal.valueOf(100)))).doubleValue()); // 只保留到分,分以下不进行四舍五入
                 chargeOrder
                         .setPayAmount(chargeOrder.getTotalMoney() - serviceMoneyDiscount)
                         .setDiscountAmount(serviceMoneyDiscount)
-                        .setServiceMoney(serviceMoneyDiscount);
+                        .setServiceMoneyDiscount(serviceMoneyDiscount);
 
                 orderRechargeRights.setDiscountAmount(serviceMoneyDiscount);
 
-                // 用户当前权益金余额是否足够支付本次充电费用
+                // 用户充值权益
                 var userRechargeRights = userRechargeRightsService.lambdaQuery()
                         .eq(UserRechargeRights::getUserId, chargeOrder.getUserId())
                         .eq(UserRechargeRights::getActivityId, orderRechargeRights.getActivityId())
                         .one();
 
-                userRechargeRights
-                        .setRightsBalance(userRechargeRights.getRightsBalance() - serviceMoneyDiscount)
-                        .setDiscountAmount(userRechargeRights.getDiscountAmount() + serviceMoneyDiscount);
-
-                // 账户设置优惠不可退金额
-                account.setDiscountAmount(account.getDiscountAmount() + serviceMoneyDiscount);
-
-                // 不足
+                // 用户当前权益金余额是否足够支付本次充电费用
                 if (userRechargeRights.getStatus() == UserRechargeRights.STATUS_有效) {
-                    // 如果优惠后的实付金额大于权益金余额,那么实际优惠金额需要通过权益金余额反推
-                    if (chargeOrder.getPayAmount() > userRechargeRights.getRightsBalance()) {
-                        var realDiscountAmount = userRechargeRights.getRightsBalance() / (100 - discount); // 只保留到分,分以下不进行四舍五入
+                    if (chargeOrder.getPayAmount() <= userRechargeRights.getRightsBalance()) {
+                        userRechargeRights
+                                // 用户权益包余额扣减当前订单实付金额
+                                .setRightsBalance(userRechargeRights.getRightsBalance() - chargeOrder.getPayAmount())
+                                .setDiscountAmount(userRechargeRights.getDiscountAmount() + serviceMoneyDiscount);
+
+                        // 账户设置优惠不可退金额
+                        account.setDiscountAmount(account.getDiscountAmount() + serviceMoneyDiscount);
+                        if (chargeOrder.getPayAmount().intValue() == userRechargeRights.getRightsBalance().intValue()) {
+                            userRechargeRights.setStatus(UserRechargeRights.STATUS_无效);
+                        }
+                    } else {
+                        // 不足(用户当前权益金余额是否足够支付本次充电费用)
+                        // 如果优惠后的实付金额大于权益金余额,那么实际优惠金额需要通过权益金余额反推
+                        // 通过权益金余额,反推最多扣减多少服务费
+                        // rightBalance = elecMoney + serviceMoney * (1-discount)
+                        // 订单中elecMoney与serviceMoney的比值是一定的
+                        var ratio = BigDecimal.valueOf(chargeOrder.getElecMoney()).divide(BigDecimal.valueOf(chargeOrder.getServiceMoney()), 2, RoundingMode.HALF_UP);
+                        // (ratio * realServiceMoney) + (realServiceMoney * (100 - discount)/100) = rightBalance
+                        var discountRate = BigDecimal.valueOf(discount).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
+                        var userRightBalance = BigDecimal.valueOf(userRechargeRights.getRightsBalance());
+                        // 真实可以覆盖的服务费金额
+                        var realServiceMoney = userRightBalance.divide(ratio.add(BigDecimal.valueOf(1)).subtract(discountRate), 2, RoundingMode.HALF_UP);
+                        // 实际优惠金额 = 实际可以覆盖的服务费金额 * 折扣率
+                        var realDiscountAmount = realServiceMoney.multiply(BigDecimal.valueOf(1).subtract(discountRate)).intValue();
                         chargeOrder
+                                // 实付金额
                                 .setPayAmount(chargeOrder.getTotalMoney() - realDiscountAmount)
                                 .setDiscountAmount(realDiscountAmount)
-                                .setServiceMoney(realDiscountAmount);
+                                .setServiceMoneyDiscount(realDiscountAmount);
                         // 余额扣完,总优惠金额加上最后一次真实优惠金额,此条用户权益结束,状态设置为无效
                         userRechargeRights
                                 .setRightsBalance(0)