From 38b7741d060048ebfd7be48cbc5980eeaeba287b Mon Sep 17 00:00:00 2001
From: java110 <928255095@qq.com>
Date: 星期三, 16 六月 2021 19:10:12 +0800
Subject: [PATCH] 加入抄表动态单价功能

---
 java110-core/src/main/java/com/java110/core/smo/impl/ComputeFeeSMOImpl.java |  771 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 699 insertions(+), 72 deletions(-)

diff --git a/java110-core/src/main/java/com/java110/core/smo/impl/ComputeFeeSMOImpl.java b/java110-core/src/main/java/com/java110/core/smo/impl/ComputeFeeSMOImpl.java
old mode 100644
new mode 100755
index 23990e7..2650e09
--- a/java110-core/src/main/java/com/java110/core/smo/impl/ComputeFeeSMOImpl.java
+++ b/java110-core/src/main/java/com/java110/core/smo/impl/ComputeFeeSMOImpl.java
@@ -2,20 +2,29 @@
 
 import com.java110.core.smo.IComputeFeeSMO;
 import com.java110.dto.RoomDto;
-import com.java110.dto.fee.BillDto;
-import com.java110.dto.fee.BillOweFeeDto;
-import com.java110.dto.fee.FeeConfigDto;
-import com.java110.dto.fee.FeeDto;
+import com.java110.dto.community.CommunityDto;
+import com.java110.dto.contract.ContractDto;
+import com.java110.dto.contractRoom.ContractRoomDto;
+import com.java110.dto.fee.*;
 import com.java110.dto.owner.OwnerCarDto;
+import com.java110.dto.owner.OwnerDto;
 import com.java110.dto.parking.ParkingSpaceDto;
+import com.java110.dto.report.ReportCarDto;
+import com.java110.dto.report.ReportFeeDto;
+import com.java110.dto.report.ReportRoomDto;
+import com.java110.intf.community.ICommunityInnerServiceSMO;
 import com.java110.intf.community.IParkingSpaceInnerServiceSMO;
 import com.java110.intf.community.IRoomInnerServiceSMO;
 import com.java110.intf.fee.IFeeInnerServiceSMO;
+import com.java110.intf.store.IContractInnerServiceSMO;
+import com.java110.intf.store.IContractRoomInnerServiceSMO;
 import com.java110.intf.user.IOwnerCarInnerServiceSMO;
+import com.java110.intf.user.IOwnerInnerServiceSMO;
 import com.java110.po.feeReceiptDetail.FeeReceiptDetailPo;
 import com.java110.utils.constant.ResponseConstant;
 import com.java110.utils.exception.ListenerExecuteException;
 import com.java110.utils.util.Assert;
+import com.java110.utils.util.BeanConvertUtil;
 import com.java110.utils.util.DateUtil;
 import com.java110.utils.util.StringUtil;
 import org.slf4j.Logger;
@@ -23,8 +32,9 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
 import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.text.ParseException;
 import java.util.*;
 
@@ -41,21 +51,47 @@
 
     protected static final Logger logger = LoggerFactory.getLogger(ComputeFeeSMOImpl.class);
 
-    @Autowired
+    @Autowired(required = false)
     private IFeeInnerServiceSMO feeInnerServiceSMOImpl;
 
-    @Autowired
+    @Autowired(required = false)
     private IRoomInnerServiceSMO roomInnerServiceSMOImpl;
 
-    @Autowired
+    @Autowired(required = false)
     private IOwnerCarInnerServiceSMO ownerCarInnerServiceSMOImpl;
 
-    @Autowired
+    @Autowired(required = false)
     private IParkingSpaceInnerServiceSMO parkingSpaceInnerServiceSMOImpl;
+
+    @Autowired(required = false)
+    private ICommunityInnerServiceSMO communityInnerServiceSMOImpl;
+
+    @Autowired(required = false)
+    private IOwnerInnerServiceSMO ownerInnerServiceSMOImpl;
+
+    @Autowired(required = false)
+    private IContractRoomInnerServiceSMO contractRoomInnerServiceSMOImpl;
+
+    @Autowired(required = false)
+    private IContractInnerServiceSMO contractInnerServiceSMOImpl;
 
     @Override
     public Date getFeeEndTime() {
         return null;
+    }
+
+    /**
+     * 璁$畻瀹炴椂娆犺垂閲戦
+     *
+     * @param tmpFeeDto
+     */
+    public void computeEveryOweFee(FeeDto tmpFeeDto) {
+        computeEveryOweFee(tmpFeeDto, null);
+    }
+
+    @Override
+    public void computeEveryOweFee(FeeDto tmpFeeDto, RoomDto roomDto) {
+        computeFeePrice(tmpFeeDto, roomDto);
     }
 
     /**
@@ -67,7 +103,7 @@
         String billType = tmpFeeDto.getBillType();
 
         if (FeeConfigDto.BILL_TYPE_EVERY.equals(billType)) {
-            computeFeePrice(tmpFeeDto);
+            computeFeePrice(tmpFeeDto, null);
             return;
         }
         BillDto billDto = new BillDto();
@@ -97,12 +133,14 @@
         tmpFeeDto.setFeePrice(Double.parseDouble(billOweFeeDtos.get(0).getAmountOwed()));
     }
 
-    private void computeFeePrice(FeeDto feeDto) {
+    private void computeFeePrice(FeeDto feeDto, RoomDto roomDto) {
 
         if (FeeDto.PAYER_OBJ_TYPE_ROOM.equals(feeDto.getPayerObjType())) { //鎴垮眿鐩稿叧
-            computeFeePriceByRoom(feeDto);
+            computeFeePriceByRoom(feeDto, roomDto);
         } else if (FeeDto.PAYER_OBJ_TYPE_CAR.equals(feeDto.getPayerObjType())) {//杞︿綅鐩稿叧
             computeFeePriceByParkingSpace(feeDto);
+        } else if (FeeDto.PAYER_OBJ_TYPE_CONTRACT.equals(feeDto.getPayerObjType())) { //鎴垮眿鐩稿叧
+            computeFeePriceByContract(feeDto, roomDto);
         }
     }
 
@@ -110,12 +148,12 @@
         Map<String, Object> targetEndDateAndOweMonth = getTargetEndDateAndOweMonth(feeDto);
         Date targetEndDate = (Date) targetEndDateAndOweMonth.get("targetEndDate");
         double oweMonth = (double) targetEndDateAndOweMonth.get("oweMonth");
-        ParkingSpaceDto parkingSpaceDto = new ParkingSpaceDto();
-        parkingSpaceDto.setCommunityId(feeDto.getCommunityId());
-        parkingSpaceDto.setPsId(feeDto.getPayerObjId());
-        List<ParkingSpaceDto> parkingSpaceDtos = parkingSpaceInnerServiceSMOImpl.queryParkingSpaces(parkingSpaceDto);
+        OwnerCarDto ownerCarDto = new OwnerCarDto();
+        ownerCarDto.setCommunityId(feeDto.getCommunityId());
+        ownerCarDto.setCarId(feeDto.getPayerObjId());
+        List<OwnerCarDto> ownerCarDtos = ownerCarInnerServiceSMOImpl.queryOwnerCars(ownerCarDto);
 
-        if (parkingSpaceDtos == null || parkingSpaceDtos.size() < 1) { //鏁版嵁鏈夐棶棰�
+        if (ownerCarDtos == null || ownerCarDtos.size() < 1) { //鏁版嵁鏈夐棶棰�
             return;
         }
 
@@ -123,16 +161,17 @@
         double feePrice = getFeePrice(feeDto);
 
         feeDto.setFeePrice(feePrice);
-        double month = dayCompare(feeDto.getEndTime(), DateUtil.getCurrentDate());
         BigDecimal price = new BigDecimal(feeDto.getFeePrice());
         price = price.multiply(new BigDecimal(oweMonth));
         feeDto.setFeePrice(price.setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
         feeDto.setDeadlineTime(targetEndDate);
 
         //鍔ㄦ�佽垂鐢�
-        if ("4004".equals(computingFormula)) {
+        if ("4004".equals(computingFormula)
+                && FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())
+                && !FeeDto.STATE_FINISH.equals(feeDto.getState())) {
             feeDto.setAmountOwed(feeDto.getFeePrice() + "");
-            feeDto.setDeadlineTime(DateUtil.getCurrentDate());
+            //feeDto.setDeadlineTime(DateUtil.getCurrentDate()); 娆犺垂鏃ユ湡涓嶅鍏堟敞閲�
         }
 
     }
@@ -142,21 +181,13 @@
      *
      * @param feeDto
      */
-    private void computeFeePriceByRoom(FeeDto feeDto) {
+    private void computeFeePriceByRoom(FeeDto feeDto, RoomDto roomDto) {
         Map<String, Object> targetEndDateAndOweMonth = getTargetEndDateAndOweMonth(feeDto);
         Date targetEndDate = (Date) targetEndDateAndOweMonth.get("targetEndDate");
         double oweMonth = (double) targetEndDateAndOweMonth.get("oweMonth");
-        RoomDto roomDto = new RoomDto();
-        roomDto.setCommunityId(feeDto.getCommunityId());
-        roomDto.setRoomId(feeDto.getPayerObjId());
-        List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
-
-        if (roomDtos == null || roomDtos.size() < 1) { //鏁版嵁鏈夐棶棰�
-            return;
-        }
 
         String computingFormula = feeDto.getComputingFormula();
-        double feePrice = getFeePrice(feeDto);
+        double feePrice = getFeePrice(feeDto, roomDto);
         feeDto.setFeePrice(feePrice);
         //double month = dayCompare(feeDto.getEndTime(), DateUtil.getCurrentDate());
         BigDecimal price = new BigDecimal(feeDto.getFeePrice());
@@ -165,9 +196,39 @@
         feeDto.setDeadlineTime(targetEndDate);
 
         //鍔ㄦ�佽垂鐢�
-        if ("4004".equals(computingFormula)) {
+        if ("4004".equals(computingFormula)
+                && FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())
+                && !FeeDto.STATE_FINISH.equals(feeDto.getState())) {
             feeDto.setAmountOwed(feeDto.getFeePrice() + "");
-            feeDto.setDeadlineTime(DateUtil.getCurrentDate());
+            //feeDto.setDeadlineTime(DateUtil.getCurrentDate()); 娆犺垂鏃ユ湡涓嶅鍏堟敞閲�
+        }
+    }
+
+    /**
+     * 鏍规嵁鎴垮眿鏉ョ畻鍗曚环
+     *
+     * @param feeDto
+     */
+    private void computeFeePriceByContract(FeeDto feeDto, RoomDto roomDto) {
+        Map<String, Object> targetEndDateAndOweMonth = getTargetEndDateAndOweMonth(feeDto);
+        Date targetEndDate = (Date) targetEndDateAndOweMonth.get("targetEndDate");
+        double oweMonth = (double) targetEndDateAndOweMonth.get("oweMonth");
+
+        String computingFormula = feeDto.getComputingFormula();
+        double feePrice = getFeePrice(feeDto, roomDto);
+        feeDto.setFeePrice(feePrice);
+        //double month = dayCompare(feeDto.getEndTime(), DateUtil.getCurrentDate());
+        BigDecimal price = new BigDecimal(feeDto.getFeePrice());
+        price = price.multiply(new BigDecimal(oweMonth));
+        feeDto.setFeePrice(price.setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
+        feeDto.setDeadlineTime(targetEndDate);
+
+        //鍔ㄦ�佽垂鐢�
+        if ("4004".equals(computingFormula)
+                && FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())
+                && !FeeDto.STATE_FINISH.equals(feeDto.getState())) {
+            feeDto.setAmountOwed(feeDto.getFeePrice() + "");
+            //feeDto.setDeadlineTime(DateUtil.getCurrentDate()); 娆犺垂鏃ユ湡涓嶅鍏堟敞閲�
         }
     }
 
@@ -205,6 +266,28 @@
                     feeReceiptDetailPo.setArea(sub.doubleValue() + "");
                     feeReceiptDetailPo.setSquarePrice(feeDto.getSquarePrice() + "/" + feeDto.getAdditionalAmount());
                 }
+            } else if ("6006".equals(computingFormula)) {
+                String value = "";
+                List<FeeAttrDto> feeAttrDtos = feeDto.getFeeAttrDtos();
+                for (FeeAttrDto feeAttrDto : feeAttrDtos) {
+                    if (feeAttrDto.getSpecCd().equals(FeeAttrDto.SPEC_CD_PROXY_CONSUMPTION)) {
+                        value = feeAttrDto.getValue();
+                    }
+                }
+                feeReceiptDetailPo.setArea(value);
+                feeReceiptDetailPo.setSquarePrice(feeDto.getSquarePrice() + "/" + feeDto.getAdditionalAmount());
+            } else if ("7007".equals(computingFormula)) { //鑷畾涔夊叕寮�
+                feeReceiptDetailPo.setArea(roomDtos.get(0).getBuiltUpArea());
+                feeReceiptDetailPo.setSquarePrice(feeDto.getComputingFormulaText());
+            }else if ("9009".equals(computingFormula)) {
+                if (StringUtil.isEmpty(feeDto.getCurDegrees())) {
+                } else {
+                    BigDecimal curDegree = new BigDecimal(Double.parseDouble(feeDto.getCurDegrees()));
+                    BigDecimal preDegree = new BigDecimal(Double.parseDouble(feeDto.getPreDegrees()));
+                    BigDecimal sub = curDegree.subtract(preDegree).setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                    feeReceiptDetailPo.setArea(sub.doubleValue() + "");
+                    feeReceiptDetailPo.setSquarePrice(feeDto.getMwPrice() + "/" + feeDto.getAdditionalAmount());
+                }
             } else {
             }
         } else if (FeeDto.PAYER_OBJ_TYPE_CAR.equals(feeDto.getPayerObjType())) {//杞︿綅鐩稿叧
@@ -237,7 +320,36 @@
                     feeReceiptDetailPo.setArea(sub.doubleValue() + "");
                     feeReceiptDetailPo.setSquarePrice(feeDto.getSquarePrice() + "/" + feeDto.getAdditionalAmount());
                 }
-            } else {
+            } else if ("6006".equals(computingFormula)) {
+                String value = "";
+                List<FeeAttrDto> feeAttrDtos = feeDto.getFeeAttrDtos();
+                for (FeeAttrDto feeAttrDto : feeAttrDtos) {
+                    if (feeAttrDto.getSpecCd().equals(FeeAttrDto.SPEC_CD_PROXY_CONSUMPTION)) {
+                        value = feeAttrDto.getValue();
+                    }
+                }
+                feeReceiptDetailPo.setArea(value);
+                feeReceiptDetailPo.setSquarePrice(feeDto.getSquarePrice() + "/" + feeDto.getAdditionalAmount());
+            } else if ("7007".equals(computingFormula)) { //鑷畾涔夊叕寮�
+                ParkingSpaceDto parkingSpaceDto = new ParkingSpaceDto();
+                parkingSpaceDto.setCommunityId(feeDto.getCommunityId());
+                parkingSpaceDto.setPsId(ownerCarDtos.get(0).getPsId());
+                List<ParkingSpaceDto> parkingSpaceDtos = parkingSpaceInnerServiceSMOImpl.queryParkingSpaces(parkingSpaceDto);
+                if (parkingSpaceDtos == null || parkingSpaceDtos.size() < 1) { //鏁版嵁鏈夐棶棰�
+                    return;
+                }
+                feeReceiptDetailPo.setArea(parkingSpaceDtos.get(0).getArea());
+                feeReceiptDetailPo.setSquarePrice(feeDto.getComputingFormulaText());
+            } else if ("9009".equals(computingFormula)) {
+                if (StringUtil.isEmpty(feeDto.getCurDegrees())) {
+                } else {
+                    BigDecimal curDegree = new BigDecimal(Double.parseDouble(feeDto.getCurDegrees()));
+                    BigDecimal preDegree = new BigDecimal(Double.parseDouble(feeDto.getPreDegrees()));
+                    BigDecimal sub = curDegree.subtract(preDegree).setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                    feeReceiptDetailPo.setArea(sub.doubleValue() + "");
+                    feeReceiptDetailPo.setSquarePrice(feeDto.getMwPrice() + "/" + feeDto.getAdditionalAmount());
+                }
+            }else {
             }
         }
     }
@@ -260,7 +372,11 @@
                 return objName;
             }
             roomDto = roomDtos.get(0);
-            objName = roomDto.getFloorNum() + "鏍�" + roomDto.getUnitNum() + "鍗曞厓" + roomDto.getRoomNum() + "瀹�";
+            if (RoomDto.ROOM_TYPE_ROOM.equals(roomDto.getRoomType())) {
+                objName = roomDto.getFloorNum() + "-" + roomDto.getUnitNum() + "-" + roomDto.getRoomNum();
+            } else {
+                objName = roomDto.getFloorNum() + "-" + roomDto.getRoomNum();
+            }
         } else if (FeeDto.PAYER_OBJ_TYPE_CAR.equals(feeDto.getPayerObjType())) {//杞︿綅鐩稿叧
 
             OwnerCarDto ownerCarDto = new OwnerCarDto();
@@ -280,8 +396,95 @@
                 return objName;
             }
             objName = objName + "(" + parkingSpaceDtos.get(0).getAreaNum() + "鍋滆溅鍦�" + parkingSpaceDtos.get(0).getNum() + "杞︿綅)";
+        } else if (FeeDto.PAYER_OBJ_TYPE_CONTRACT.equals(feeDto.getPayerObjType())) {
+            ContractDto contractDto = new ContractDto();
+            contractDto.setContractId(feeDto.getPayerObjId());
+            contractDto.setCommunityId(feeDto.getCommunityId());
+            List<ContractDto> contractDtos = contractInnerServiceSMOImpl.queryContracts(contractDto);
+            if (contractDtos == null || contractDtos.size() < 1) { //鏁版嵁鏈夐棶棰�
+                return objName;
+            }
+            objName = contractDtos.get(0).getContractCode();
+
         }
         return objName;
+    }
+
+    @Override
+    public OwnerDto getFeeOwnerDto(FeeDto feeDto) {
+        OwnerDto ownerDto = getOwnerDtoByFeeAttr(feeDto);
+        if (ownerDto != null) {
+            return ownerDto;
+        }
+
+        if (FeeDto.PAYER_OBJ_TYPE_ROOM.equals(feeDto.getPayerObjType())) { //鎴垮眿鐩稿叧
+            ownerDto = new OwnerDto();
+            ownerDto.setRoomId(feeDto.getPayerObjId());
+            ownerDto.setCommunityId(feeDto.getCommunityId());
+            List<OwnerDto> ownerDtos = ownerInnerServiceSMOImpl.queryOwners(ownerDto);
+            Assert.listOnlyOne(ownerDtos, "涓氫富涓嶅瓨鍦�");
+            return ownerDtos.get(0);
+        }
+
+        if (FeeDto.PAYER_OBJ_TYPE_CAR.equals(feeDto.getPayerObjType())) {
+            OwnerCarDto ownerCarDto = new OwnerCarDto();
+            ownerCarDto.setCarId(feeDto.getPayerObjId());
+            ownerCarDto.setCommunityId(feeDto.getCommunityId());
+            List<OwnerCarDto> ownerCarDtos = ownerCarInnerServiceSMOImpl.queryOwnerCars(ownerCarDto);
+
+            Assert.listOnlyOne(ownerCarDtos, "杞﹁締涓嶅瓨鍦�");
+            ownerDto = new OwnerDto();
+            ownerDto.setOwnerId(ownerCarDtos.get(0).getOwnerId());
+            ownerDto.setCommunityId(feeDto.getCommunityId());
+            List<OwnerDto> ownerDtos = ownerInnerServiceSMOImpl.queryOwners(ownerDto);
+            Assert.listOnlyOne(ownerDtos, "涓氫富涓嶅瓨鍦�");
+            return ownerDtos.get(0);
+        }
+
+        if (FeeDto.PAYER_OBJ_TYPE_CONTRACT.equals(feeDto.getPayerObjType())) {
+            ContractDto contractDto = new ContractDto();
+            contractDto.setContractId(feeDto.getPayerObjId());
+            contractDto.setCommunityId(feeDto.getCommunityId());
+            List<ContractDto> contractDtos = contractInnerServiceSMOImpl.queryContracts(contractDto);
+
+            Assert.listOnlyOne(contractDtos, "鍚堝悓涓嶅瓨鍦�");
+            ownerDto = new OwnerDto();
+            ownerDto.setOwnerId(contractDtos.get(0).getObjId());
+            ownerDto.setCommunityId(feeDto.getCommunityId());
+            List<OwnerDto> ownerDtos = ownerInnerServiceSMOImpl.queryOwners(ownerDto);
+            Assert.listOnlyOne(ownerDtos, "涓氫富涓嶅瓨鍦�");
+            return ownerDtos.get(0);
+        }
+        return null;
+    }
+
+    private OwnerDto getOwnerDtoByFeeAttr(FeeDto feeDto) {
+        List<FeeAttrDto> feeAttrDtos = feeDto.getFeeAttrDtos();
+
+        if (feeAttrDtos == null || feeAttrDtos.size() < 1) {
+            return null;
+        }
+
+        OwnerDto ownerDto = new OwnerDto();
+        for (FeeAttrDto feeAttrDto : feeAttrDtos) {
+            if (feeAttrDto.getSpecCd().equals(FeeAttrDto.SPEC_CD_OWNER_ID)) {
+                ownerDto.setOwnerId(feeAttrDto.getValue());
+            }
+
+            if (feeAttrDto.getSpecCd().equals(FeeAttrDto.SPEC_CD_OWNER_NAME)) {
+                ownerDto.setName(feeAttrDto.getValue());
+            }
+
+            if (feeAttrDto.getSpecCd().equals(FeeAttrDto.SPEC_CD_OWNER_LINK)) {
+                ownerDto.setLink(feeAttrDto.getValue());
+            }
+        }
+
+        if (StringUtil.isEmpty(ownerDto.getOwnerId())) {
+            return null;
+        }
+
+        return ownerDto;
     }
 
     @Override
@@ -402,7 +605,7 @@
                     continue;
                 }
                 if (tmpRoomDto.getRoomId().equals(feeDto.getPayerObjId())) {
-                    objName = roomDto.getFloorNum() + "鏍�" + roomDto.getUnitNum() + "鍗曞厓" + roomDto.getRoomNum() + "瀹�";
+                    objName = tmpRoomDto.getFloorNum() + "-" + tmpRoomDto.getUnitNum() + "-" + tmpRoomDto.getRoomNum();
                     feeDto.setPayerObjName(objName);
                 }
             }
@@ -422,7 +625,11 @@
         Calendar endCalender = Calendar.getInstance();
         endCalender.setTime(endTime);
         endCalender.add(Calendar.MONTH, new Double(Math.floor(cycle)).intValue());
-        int hours = new Double((cycle - Math.floor(cycle)) * DateUtil.getCurrentMonthDay() * 24).intValue();
+//        Calendar futureDate = Calendar.getInstance();
+//        futureDate.setTime(endCalender.getTime());
+//        futureDate.add(Calendar.MONTH, 1);
+        int futureDay = endCalender.getActualMaximum(Calendar.DAY_OF_MONTH);
+        int hours = new Double((cycle - Math.floor(cycle)) * futureDay * 24).intValue();
         endCalender.add(Calendar.HOUR, hours);
         if (FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())) {
             return FeeDto.STATE_FINISH;
@@ -441,10 +648,16 @@
         Calendar endCalender = Calendar.getInstance();
         endCalender.setTime(endTime);
         endCalender.add(Calendar.MONTH, new Double(Math.floor(cycle)).intValue());
-        int hours = new Double((cycle - Math.floor(cycle)) * DateUtil.getCurrentMonthDay() * 24).intValue();
+//        Calendar futureDate = Calendar.getInstance();
+//        futureDate.setTime(endCalender.getTime());
+//        futureDate.add(Calendar.MONTH, 1);
+        int futureDay = endCalender.getActualMaximum(Calendar.DAY_OF_MONTH);
+        int hours = new Double((cycle - Math.floor(cycle)) * futureDay * 24).intValue();
         endCalender.add(Calendar.HOUR, hours);
         if (FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())) {
-            if (!StringUtil.isEmpty(feeDto.getCurDegrees())) {
+            if (feeDto.getDeadlineTime() != null) {
+                endCalender.setTime(feeDto.getDeadlineTime());
+            } else if (!StringUtil.isEmpty(feeDto.getCurDegrees())) {
                 endCalender.setTime(feeDto.getCurReadingTime());
             } else if (feeDto.getImportFeeEndTime() == null) {
                 endCalender.setTime(feeDto.getConfigEndTime());
@@ -467,37 +680,165 @@
     }
 
     @Override
-    public double getFeePrice(FeeDto feeDto) {
+    public double getReportFeePrice(ReportFeeDto tmpReportFeeDto, ReportRoomDto reportRoomDto, ReportCarDto reportCarDto) {
         BigDecimal feePrice = new BigDecimal(0.0);
-        if (FeeDto.PAYER_OBJ_TYPE_ROOM.equals(feeDto.getPayerObjType())) { //鎴垮眿鐩稿叧
-            String computingFormula = feeDto.getComputingFormula();
-            RoomDto roomDto = new RoomDto();
-            roomDto.setRoomId(feeDto.getPayerObjId());
-            roomDto.setCommunityId(feeDto.getCommunityId());
-            List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
-            if (roomDtos == null || roomDtos.size() != 1) {
-                throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "鏈煡鍒版埧灞嬩俊鎭紝鏌ヨ澶氭潯鏁版嵁");
-            }
-            roomDto = roomDtos.get(0);
+        if (FeeDto.PAYER_OBJ_TYPE_ROOM.equals(tmpReportFeeDto.getPayerObjType())) { //鎴垮眿鐩稿叧
+            String computingFormula = tmpReportFeeDto.getComputingFormula();
+
             if ("1001".equals(computingFormula)) { //闈㈢Н*鍗曚环+闄勫姞璐�
                 //feePrice = Double.parseDouble(feeDto.getSquarePrice()) * Double.parseDouble(roomDtos.get(0).getBuiltUpArea()) + Double.parseDouble(feeDto.getAdditionalAmount());
-                BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
-                BigDecimal builtUpArea = new BigDecimal(Double.parseDouble(roomDtos.get(0).getBuiltUpArea()));
-                BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+                BigDecimal squarePrice = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getSquarePrice()));
+                BigDecimal builtUpArea = new BigDecimal(Double.parseDouble(reportRoomDto.getBuiltUpArea()));
+                BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAdditionalAmount()));
                 feePrice = squarePrice.multiply(builtUpArea).add(additionalAmount).setScale(2, BigDecimal.ROUND_HALF_EVEN);
             } else if ("2002".equals(computingFormula)) { // 鍥哄畾璐圭敤
                 //feePrice = Double.parseDouble(feeDto.getAdditionalAmount());
-                BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+                BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAdditionalAmount()));
                 feePrice = additionalAmount.setScale(2, BigDecimal.ROUND_HALF_EVEN);
             } else if ("4004".equals(computingFormula)) {
-                feePrice = new BigDecimal(Double.parseDouble(feeDto.getAmount()));
+                feePrice = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAmount()));
             } else if ("5005".equals(computingFormula)) {
+                if (StringUtil.isEmpty(tmpReportFeeDto.getCurDegrees())) {
+                    //throw new IllegalArgumentException("鎶勮〃鏁版嵁寮傚父");
+                } else {
+                    BigDecimal curDegree = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getCurDegrees()));
+                    BigDecimal preDegree = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getPreDegrees()));
+                    BigDecimal squarePrice = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getSquarePrice()));
+                    BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAdditionalAmount()));
+                    BigDecimal sub = curDegree.subtract(preDegree);
+                    feePrice = sub.multiply(squarePrice)
+                            .add(additionalAmount)
+                            .setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                }
+            } else if ("6006".equals(computingFormula)) {
+                feePrice = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAmount()));
+            } else if ("7007".equals(computingFormula)) { //鑷畾涔夊叕寮�
+                feePrice = computeRoomCustomizeFormula(BeanConvertUtil.covertBean(tmpReportFeeDto, FeeDto.class), BeanConvertUtil.covertBean(reportRoomDto, RoomDto.class));
+            }else if ("9009".equals(computingFormula)) {
+                if (StringUtil.isEmpty(tmpReportFeeDto.getCurDegrees())) {
+                    //throw new IllegalArgumentException("鎶勮〃鏁版嵁寮傚父");
+                } else {
+                    BigDecimal curDegree = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getCurDegrees()));
+                    BigDecimal preDegree = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getPreDegrees()));
+                    BigDecimal squarePrice = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getMwPrice()));
+                    BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAdditionalAmount()));
+                    BigDecimal sub = curDegree.subtract(preDegree);
+                    feePrice = sub.multiply(squarePrice)
+                            .add(additionalAmount)
+                            .setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                }
+            } else {
+                throw new IllegalArgumentException("鏆備笉鏀寔璇ョ被鍏紡");
+            }
+        } else if (FeeDto.PAYER_OBJ_TYPE_CAR.equals(tmpReportFeeDto.getPayerObjType())) {//杞︿綅鐩稿叧
+            String computingFormula = tmpReportFeeDto.getComputingFormula();
+
+            if ("1001".equals(computingFormula)) { //闈㈢Н*鍗曚环+闄勫姞璐�
+                BigDecimal squarePrice = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getSquarePrice()));
+                BigDecimal builtUpArea = new BigDecimal(Double.parseDouble("0"));
+                BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAdditionalAmount()));
+                feePrice = squarePrice.multiply(builtUpArea).add(additionalAmount).setScale(2, BigDecimal.ROUND_HALF_EVEN);
+            } else if ("2002".equals(computingFormula)) { // 鍥哄畾璐圭敤
+                //feePrice = Double.parseDouble(feeDto.getAdditionalAmount());
+                BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAdditionalAmount()));
+                feePrice = additionalAmount.setScale(2, BigDecimal.ROUND_HALF_EVEN);
+            } else if ("4004".equals(computingFormula)) {
+                feePrice = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAmount()));
+            } else if ("5005".equals(computingFormula)) {
+                if (StringUtil.isEmpty(tmpReportFeeDto.getCurDegrees())) {
+                    throw new IllegalArgumentException("鎶勮〃鏁版嵁寮傚父");
+                } else {
+                    BigDecimal curDegree = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getCurDegrees()));
+                    BigDecimal preDegree = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getPreDegrees()));
+                    BigDecimal squarePrice = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getSquarePrice()));
+                    BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAdditionalAmount()));
+                    BigDecimal sub = curDegree.subtract(preDegree);
+                    feePrice = sub.multiply(squarePrice)
+                            .add(additionalAmount)
+                            .setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                }
+            } else if ("6006".equals(computingFormula)) {
+                feePrice = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAmount()));
+            } else if ("7007".equals(computingFormula)) { //鑷畾涔夊叕寮�
+                feePrice = computeCarCustomizeFormula(BeanConvertUtil.covertBean(tmpReportFeeDto, FeeDto.class), BeanConvertUtil.covertBean(reportCarDto, OwnerCarDto.class));
+            }else if ("9009".equals(computingFormula)) {
+                if (StringUtil.isEmpty(tmpReportFeeDto.getCurDegrees())) {
+                    throw new IllegalArgumentException("鎶勮〃鏁版嵁寮傚父");
+                } else {
+                    BigDecimal curDegree = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getCurDegrees()));
+                    BigDecimal preDegree = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getPreDegrees()));
+                    BigDecimal squarePrice = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getMwPrice()));
+                    BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(tmpReportFeeDto.getAdditionalAmount()));
+                    BigDecimal sub = curDegree.subtract(preDegree);
+                    feePrice = sub.multiply(squarePrice)
+                            .add(additionalAmount)
+                            .setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                }
+            } else {
+                throw new IllegalArgumentException("鏆備笉鏀寔璇ョ被鍏紡");
+            }
+        }
+        return feePrice.setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
+    }
+
+    @Override
+    public double getFeePrice(FeeDto feeDto) {
+        return getFeePrice(feeDto, null);
+    }
+
+    @Override
+    public double getFeePrice(FeeDto feeDto, RoomDto roomDto) {
+        BigDecimal feePrice = new BigDecimal(0.0);
+        if (FeeDto.PAYER_OBJ_TYPE_ROOM.equals(feeDto.getPayerObjType())) { //鎴垮眿鐩稿叧
+            String computingFormula = feeDto.getComputingFormula();
+            if (roomDto == null) {
+                roomDto = new RoomDto();
+                roomDto.setRoomId(feeDto.getPayerObjId());
+                roomDto.setCommunityId(feeDto.getCommunityId());
+                List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
+                if (roomDtos == null || roomDtos.size() != 1) {
+                    throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "鏈煡鍒版埧灞嬩俊鎭紝鏌ヨ澶氭潯鏁版嵁");
+                }
+                roomDto = roomDtos.get(0);
+            }
+            if ("1001".equals(computingFormula)) { //闈㈢Н*鍗曚环+闄勫姞璐�
+                //feePrice = Double.parseDouble(feeDto.getSquarePrice()) * Double.parseDouble(roomDtos.get(0).getBuiltUpArea()) + Double.parseDouble(feeDto.getAdditionalAmount());
+                BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
+                BigDecimal builtUpArea = new BigDecimal(Double.parseDouble(roomDto.getBuiltUpArea()));
+                BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+                feePrice = squarePrice.multiply(builtUpArea).add(additionalAmount).setScale(3, BigDecimal.ROUND_HALF_EVEN);
+            } else if ("2002".equals(computingFormula)) { // 鍥哄畾璐圭敤
+                //feePrice = Double.parseDouble(feeDto.getAdditionalAmount());
+                BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+                feePrice = additionalAmount.setScale(3, BigDecimal.ROUND_HALF_EVEN);
+            } else if ("4004".equals(computingFormula)) {  //鍔ㄦ�佽垂鐢�
+                feePrice = new BigDecimal(Double.parseDouble(feeDto.getAmount()));
+            } else if ("5005".equals(computingFormula)) {  //(鏈湡搴︽暟-涓婃湡搴︽暟)*鍗曚环+闄勫姞璐�
                 if (StringUtil.isEmpty(feeDto.getCurDegrees())) {
                     //throw new IllegalArgumentException("鎶勮〃鏁版嵁寮傚父");
                 } else {
                     BigDecimal curDegree = new BigDecimal(Double.parseDouble(feeDto.getCurDegrees()));
                     BigDecimal preDegree = new BigDecimal(Double.parseDouble(feeDto.getPreDegrees()));
                     BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
+                    BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+                    BigDecimal sub = curDegree.subtract(preDegree);
+                    feePrice = sub.multiply(squarePrice)
+                            .add(additionalAmount)
+                            .setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                }
+            } else if ("6006".equals(computingFormula)) {
+                feePrice = new BigDecimal(Double.parseDouble(feeDto.getAmount()));
+            } else if ("7007".equals(computingFormula)) { //鑷畾涔夊叕寮�
+                feePrice = computeRoomCustomizeFormula(feeDto, roomDto);
+            } else if ("8008".equals(computingFormula)) {  //鎵嬪姩鍔ㄦ�佽垂鐢�
+                feePrice = new BigDecimal(Double.parseDouble(feeDto.getAmount()));
+            } else if ("9009".equals(computingFormula)) {  //(鏈湡搴︽暟-涓婃湡搴︽暟)*鍔ㄦ�佸崟浠�+闄勫姞璐�
+                if (StringUtil.isEmpty(feeDto.getCurDegrees())) {
+                    //throw new IllegalArgumentException("鎶勮〃鏁版嵁寮傚父");
+                } else {
+                    BigDecimal curDegree = new BigDecimal(Double.parseDouble(feeDto.getCurDegrees()));
+                    BigDecimal preDegree = new BigDecimal(Double.parseDouble(feeDto.getPreDegrees()));
+                    BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getMwPrice()));
                     BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
                     BigDecimal sub = curDegree.subtract(preDegree);
                     feePrice = sub.multiply(squarePrice)
@@ -546,15 +887,227 @@
                             .add(additionalAmount)
                             .setScale(2, BigDecimal.ROUND_HALF_EVEN);
                 }
+            } else if ("6006".equals(computingFormula)) {
+                feePrice = new BigDecimal(Double.parseDouble(feeDto.getAmount()));
+            } else if ("7007".equals(computingFormula)) { //鑷畾涔夊叕寮�
+                feePrice = computeCarCustomizeFormula(feeDto, ownerCarDtos.get(0));
+            } else if ("9009".equals(computingFormula)) {  //(鏈湡搴︽暟-涓婃湡搴︽暟)*鍔ㄦ�佸崟浠�+闄勫姞璐�
+                if (StringUtil.isEmpty(feeDto.getCurDegrees())) {
+                    //throw new IllegalArgumentException("鎶勮〃鏁版嵁寮傚父");
+                } else {
+                    BigDecimal curDegree = new BigDecimal(Double.parseDouble(feeDto.getCurDegrees()));
+                    BigDecimal preDegree = new BigDecimal(Double.parseDouble(feeDto.getPreDegrees()));
+                    BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getMwPrice()));
+                    BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+                    BigDecimal sub = curDegree.subtract(preDegree);
+                    feePrice = sub.multiply(squarePrice)
+                            .add(additionalAmount)
+                            .setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                }
+            } else {
+                throw new IllegalArgumentException("鏆備笉鏀寔璇ョ被鍏紡");
+            }
+        } else if (FeeDto.PAYER_OBJ_TYPE_CONTRACT.equals(feeDto.getPayerObjType())) { //鍚堝悓鐩稿叧
+            String computingFormula = feeDto.getComputingFormula();
+
+            //鏌ヨ鍚堝悓鍏宠仈鎴垮眿
+            ContractRoomDto contractRoomDto = new ContractRoomDto();
+            contractRoomDto.setContractId(feeDto.getPayerObjId());
+            contractRoomDto.setCommunityId(feeDto.getCommunityId());
+            List<ContractRoomDto> contractRoomDtos = contractRoomInnerServiceSMOImpl.queryContractRooms(contractRoomDto);
+
+            if ("1001".equals(computingFormula)) { //闈㈢Н*鍗曚环+闄勫姞璐�
+                //feePrice = Double.parseDouble(feeDto.getSquarePrice()) * Double.parseDouble(roomDtos.get(0).getBuiltUpArea()) + Double.parseDouble(feeDto.getAdditionalAmount());
+                BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
+                BigDecimal builtUpArea = new BigDecimal(0);
+                for (ContractRoomDto tmpContractRoomDto : contractRoomDtos) {
+                    builtUpArea = builtUpArea.add(new BigDecimal(Double.parseDouble(tmpContractRoomDto.getBuiltUpArea())));
+                }
+                feeDto.setBuiltUpArea(builtUpArea.doubleValue() + "");
+                BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+                feePrice = squarePrice.multiply(builtUpArea).add(additionalAmount).setScale(3, BigDecimal.ROUND_HALF_EVEN);
+            } else if ("2002".equals(computingFormula)) { // 鍥哄畾璐圭敤
+                //feePrice = Double.parseDouble(feeDto.getAdditionalAmount());
+                BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+//                BigDecimal roomDount = new BigDecimal(contractRoomDtos.size());
+//                additionalAmount = additionalAmount.multiply(roomDount);
+                feePrice = additionalAmount.setScale(3, BigDecimal.ROUND_HALF_EVEN);
+            } else if ("4004".equals(computingFormula)) {  //鍔ㄦ�佽垂鐢�
+                feePrice = new BigDecimal(Double.parseDouble(feeDto.getAmount()));
+            } else if ("5005".equals(computingFormula)) {  //(鏈湡搴︽暟-涓婃湡搴︽暟)*鍗曚环+闄勫姞璐�
+                if (StringUtil.isEmpty(feeDto.getCurDegrees())) {
+                    //throw new IllegalArgumentException("鎶勮〃鏁版嵁寮傚父");
+                } else {
+                    BigDecimal curDegree = new BigDecimal(Double.parseDouble(feeDto.getCurDegrees()));
+                    BigDecimal preDegree = new BigDecimal(Double.parseDouble(feeDto.getPreDegrees()));
+                    BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
+                    BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+                    BigDecimal sub = curDegree.subtract(preDegree);
+                    feePrice = sub.multiply(squarePrice)
+                            .add(additionalAmount)
+                            .setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                }
+            } else if ("6006".equals(computingFormula)) {
+                feePrice = new BigDecimal(Double.parseDouble(feeDto.getAmount()));
+            } else if ("7007".equals(computingFormula)) { //鑷畾涔夊叕寮�
+                feePrice = computeContractCustomizeFormula(feeDto, contractRoomDtos);
+            } else if ("8008".equals(computingFormula)) {  //鎵嬪姩鍔ㄦ�佽垂鐢�
+                feePrice = new BigDecimal(Double.parseDouble(feeDto.getAmount()));
+            } else if ("9009".equals(computingFormula)) {  //(鏈湡搴︽暟-涓婃湡搴︽暟)*鍔ㄦ�佸崟浠�+闄勫姞璐�
+                if (StringUtil.isEmpty(feeDto.getCurDegrees())) {
+                    //throw new IllegalArgumentException("鎶勮〃鏁版嵁寮傚父");
+                } else {
+                    BigDecimal curDegree = new BigDecimal(Double.parseDouble(feeDto.getCurDegrees()));
+                    BigDecimal preDegree = new BigDecimal(Double.parseDouble(feeDto.getPreDegrees()));
+                    BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getMwPrice()));
+                    BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+                    BigDecimal sub = curDegree.subtract(preDegree);
+                    feePrice = sub.multiply(squarePrice)
+                            .add(additionalAmount)
+                            .setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                }
             } else {
                 throw new IllegalArgumentException("鏆備笉鏀寔璇ョ被鍏紡");
             }
         }
-        return feePrice.setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
+        return feePrice.setScale(3, BigDecimal.ROUND_HALF_EVEN).doubleValue();
     }
 
+    /**
+     * C 浠h〃鎴垮眿瀵瑰簲灏忓尯闈㈢Н
+     * <p>
+     * R 浠h〃鎴垮眿闈㈢Н
+     *
+     * @param feeDto
+     * @param ownerCarDto
+     * @return
+     */
+    private BigDecimal computeCarCustomizeFormula(FeeDto feeDto, OwnerCarDto ownerCarDto) {
+        String value = feeDto.getComputingFormulaText();
+        value = value.replace("\n", "")
+                .replace("\r", "")
+                .trim();
 
-    public Map getTargetEndDateAndOweMonth(FeeDto feeDto) {
+        if (value.contains("C")) { //澶勭悊灏忓尯闈㈢Н
+            CommunityDto communityDto = new CommunityDto();
+            communityDto.setCommunityId(feeDto.getCommunityId());
+            List<CommunityDto> communityDtos = communityInnerServiceSMOImpl.queryCommunitys(communityDto);
+            if (communityDtos == null || communityDtos.size() < 1) {
+                value = value.replace("C", "0");
+            } else {
+                value = value.replace("C", communityDtos.get(0).getCommunityArea());
+            }
+        } else if (value.contains("R")) { //澶勭悊 鎴垮眿闈㈢Н
+            ParkingSpaceDto parkingSpaceDto = new ParkingSpaceDto();
+            parkingSpaceDto.setCommunityId(feeDto.getCommunityId());
+            parkingSpaceDto.setPsId(ownerCarDto.getPsId());
+            List<ParkingSpaceDto> parkingSpaceDtos = parkingSpaceInnerServiceSMOImpl.queryParkingSpaces(parkingSpaceDto);
+            if (parkingSpaceDtos == null || parkingSpaceDtos.size() < 1) { //鏁版嵁鏈夐棶棰�
+                //throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "鏈煡鍒板仠杞︿綅淇℃伅锛屾煡璇㈠鏉℃暟鎹�");
+                value = value.replace("R", "0");
+            } else {
+                value = value.replace("R", parkingSpaceDtos.get(0).getArea());
+            }
+        }
+
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("JavaScript");
+        BigDecimal valueObj = null;
+        try {
+            value = engine.eval(value).toString();
+            valueObj = new BigDecimal(Double.parseDouble(value));
+        } catch (Exception e) {
+            //throw new IllegalArgumentException("鍏紡璁$畻寮傚父锛屽叕寮忎负銆�" + feeDto.getComputingFormulaText() + "銆�,璁$畻 銆�" + value + "銆戝紓甯�");
+            valueObj = new BigDecimal(0);
+        }
+
+        if (valueObj.doubleValue() < 0) {
+            return new BigDecimal(0);
+        }
+
+        return valueObj;
+    }
+
+    /**
+     * 鑷畾涔夊叕寮忚绠�
+     *
+     * @param feeDto
+     * @return C 浠h〃鎴垮眿瀵瑰簲灏忓尯闈㈢Н
+     * F 浠h〃鎴垮眿瀵瑰簲妤兼爧闈㈢Н
+     * U 浠h〃鎴垮眿瀵瑰簲鍗曞厓闈㈢Н
+     * R 浠h〃鎴垮眿闈㈢Н
+     * X 浠h〃鎴垮眿鏀惰垂绯绘暟锛堟埧灞嬬鐞嗕腑閰嶇疆锛�
+     * L 浠h〃鎴垮眿灞傛暟
+     */
+    private BigDecimal computeContractCustomizeFormula(FeeDto feeDto, List<ContractRoomDto> contractRoomDtos) {
+
+        BigDecimal total = new BigDecimal(0.0);
+        for (ContractRoomDto contractRoomDto : contractRoomDtos) {
+            total = total.add(computeRoomCustomizeFormula(feeDto, contractRoomDto));
+        }
+        return total;
+    }
+
+    /**
+     * 鑷畾涔夊叕寮忚绠�
+     *
+     * @param feeDto
+     * @param roomDto
+     * @return C 浠h〃鎴垮眿瀵瑰簲灏忓尯闈㈢Н
+     * F 浠h〃鎴垮眿瀵瑰簲妤兼爧闈㈢Н
+     * U 浠h〃鎴垮眿瀵瑰簲鍗曞厓闈㈢Н
+     * R 浠h〃鎴垮眿闈㈢Н
+     * X 浠h〃鎴垮眿鏀惰垂绯绘暟锛堟埧灞嬬鐞嗕腑閰嶇疆锛�
+     * L 浠h〃鎴垮眿灞傛暟
+     */
+    private BigDecimal computeRoomCustomizeFormula(FeeDto feeDto, RoomDto roomDto) {
+
+        String value = feeDto.getComputingFormulaText();
+        value = value.replace("\n", "")
+                .replace("\r", "")
+                .trim();
+
+        if (value.contains("C")) { //澶勭悊灏忓尯闈㈢Н
+            CommunityDto communityDto = new CommunityDto();
+            communityDto.setCommunityId(feeDto.getCommunityId());
+            List<CommunityDto> communityDtos = communityInnerServiceSMOImpl.queryCommunitys(communityDto);
+            if (communityDtos == null || communityDtos.size() < 1) {
+                value = value.replace("C", "0");
+            } else {
+                value = value.replace("C", communityDtos.get(0).getCommunityArea());
+            }
+        } else if (value.contains("F")) { //澶勭悊妤兼爧
+            value = value.replace("F", roomDto.getFloorArea());
+        } else if (value.contains("U")) { //澶勭悊鍗曞厓
+            value = value.replace("U", roomDto.getUnitArea());
+        } else if (value.contains("R")) { //澶勭悊 鎴垮眿闈㈢Н
+            value = value.replace("R", roomDto.getBuiltUpArea());
+        } else if (value.contains("X")) {// 澶勭悊 鎴垮眿绯绘暟
+            value = value.replace("X", roomDto.getFeeCoefficient());
+        } else if (value.contains("L")) {//澶勭悊鎴垮眿灞傛暟
+            value = value.replace("L", roomDto.getLayer());
+        }
+
+        ScriptEngineManager manager = new ScriptEngineManager();
+        ScriptEngine engine = manager.getEngineByName("JavaScript");
+        BigDecimal valueObj = null;
+        try {
+            value = engine.eval(value).toString();
+            valueObj = new BigDecimal(Double.parseDouble(value));
+        } catch (Exception e) {
+            //throw new IllegalArgumentException("鍏紡璁$畻寮傚父锛屽叕寮忎负銆�" + feeDto.getComputingFormulaText() + "銆�,璁$畻 銆�" + value + "銆戝紓甯�");
+            valueObj = new BigDecimal(0);
+        }
+
+        if (valueObj.doubleValue() < 0) {
+            return new BigDecimal(0);
+        }
+
+        return valueObj;
+
+    }
+
+    public Map getTargetEndDateAndOweMonth(FeeDto feeDto, OwnerCarDto ownerCarDto) {
         Date targetEndDate = null;
         double oweMonth = 0.0;
 
@@ -567,7 +1120,10 @@
             return targetEndDateAndOweMonth;
         }
         if (FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())) {
-            if (!StringUtil.isEmpty(feeDto.getCurDegrees())) {
+            //鍏堝彇 deadlineTime
+            if (feeDto.getDeadlineTime() != null) {
+                targetEndDate = feeDto.getDeadlineTime();
+            } else if (!StringUtil.isEmpty(feeDto.getCurDegrees())) {
                 targetEndDate = feeDto.getCurReadingTime();
             } else if (feeDto.getImportFeeEndTime() == null) {
                 targetEndDate = feeDto.getConfigEndTime();
@@ -585,18 +1141,12 @@
             //鍒版湡鏃堕棿
             Date endDate = feeDto.getEndTime();
             if (FeeDto.PAYER_OBJ_TYPE_CAR.equals(feeDto.getPayerObjType())) {
-                OwnerCarDto ownerCarDto = new OwnerCarDto();
-                ownerCarDto.setCommunityId(feeDto.getCommunityId());
-                ownerCarDto.setCarId(feeDto.getPayerObjId());
-                List<OwnerCarDto> ownerCarDtos = ownerCarInnerServiceSMOImpl.queryOwnerCars(ownerCarDto);
-
-                if (ownerCarDtos == null || ownerCarDtos.size() != 1) {
+                if (ownerCarDto == null) {
                     targetEndDateAndOweMonth.put("oweMonth", 0);
                     targetEndDateAndOweMonth.put("targetEndDate", "");
                     return targetEndDateAndOweMonth;
                 }
-
-                targetEndDate = ownerCarDtos.get(0).getEndTime();
+                targetEndDate = ownerCarDto.getEndTime();
                 //璇存槑娌℃湁娆犺垂
                 if (endDate.getTime() >= targetEndDate.getTime()) {
                     // 鐩爣鍒版湡鏃堕棿 - 鍒版湡鏃堕棿 = 娆犺垂鏈堜唤
@@ -642,8 +1192,21 @@
         return targetEndDateAndOweMonth;
     }
 
+    public Map getTargetEndDateAndOweMonth(FeeDto feeDto) {
+
+        if (FeeDto.PAYER_OBJ_TYPE_CAR.equals(feeDto.getPayerObjType())) {
+            OwnerCarDto ownerCarDto = new OwnerCarDto();
+            ownerCarDto.setCommunityId(feeDto.getCommunityId());
+            ownerCarDto.setCarId(feeDto.getPayerObjId());
+            List<OwnerCarDto> ownerCarDtos = ownerCarInnerServiceSMOImpl.queryOwnerCars(ownerCarDto);
+            return getTargetEndDateAndOweMonth(feeDto, ownerCarDtos == null || ownerCarDtos.size() < 1 ? null : ownerCarDtos.get(0));
+        }
+        return getTargetEndDateAndOweMonth(feeDto, null);
+    }
+
     @Override
     public double dayCompare(Date fromDate, Date toDate) {
+        double resMonth = 0.0;
         Calendar from = Calendar.getInstance();
         from.setTime(fromDate);
         Calendar to = Calendar.getInstance();
@@ -655,22 +1218,86 @@
         Calendar newFrom = Calendar.getInstance();
         newFrom.setTime(fromDate);
         newFrom.add(Calendar.MONTH, result);
+        //濡傛灉鍔犳湀浠藉悗 澶т簬浜嗗埌鏈熸椂闂� 榛樿鍔� 鏈堜唤 -1 鎯呭喌 12-19  21-01-10
+        if (newFrom.getTime().getTime() > toDate.getTime()) {
+            newFrom.setTime(fromDate);
+            result = result - 1;
+            newFrom.add(Calendar.MONTH, result);
+        }
 
-        long t1 = newFrom.getTimeInMillis();
-        long t2 = to.getTimeInMillis();
-        long days = (t2 - t1) / (24 * 60 * 60 * 1000);
-
+        long t1 = newFrom.getTime().getTime();
+        long t2 = to.getTime().getTime();
+        double days = (t2 - t1) * 1.00 / (24 * 60 * 60 * 1000);
         BigDecimal tmpDays = new BigDecimal(days);
-        BigDecimal monthDay = new BigDecimal(30);
+        BigDecimal monthDay = null;
+        Calendar newFromMaxDay = Calendar.getInstance();
+        newFromMaxDay.set(newFrom.get(Calendar.YEAR), newFrom.get(Calendar.MONTH), 1, 0, 0, 0);
+        newFromMaxDay.add(Calendar.MONTH, 1);
+        //鍦ㄥ綋鍓嶆湀涓�
+        if (toDate.getTime() < newFromMaxDay.getTime().getTime()) {
+            monthDay = new BigDecimal(newFromMaxDay.getActualMaximum(Calendar.DAY_OF_MONTH));
+            return tmpDays.divide(monthDay, 2, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).doubleValue();
+        }
+        // 涓婃湀澶╂暟
+        days = (newFromMaxDay.getTimeInMillis() - t1) * 1.00 / (24 * 60 * 60 * 1000);
+        tmpDays = new BigDecimal(days);
+        monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH));
+        BigDecimal preRresMonth = tmpDays.divide(monthDay, 2, BigDecimal.ROUND_HALF_UP);
 
-        return tmpDays.divide(monthDay, 2, RoundingMode.HALF_UP).doubleValue() + result;
+        //涓嬫湀澶╂暟
+        days = (t2 - newFromMaxDay.getTimeInMillis()) * 1.00 / (24 * 60 * 60 * 1000);
+        tmpDays = new BigDecimal(days);
+        monthDay = new BigDecimal(newFromMaxDay.getActualMaximum(Calendar.DAY_OF_MONTH));
+        resMonth = tmpDays.divide(monthDay, 2, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).add(preRresMonth).doubleValue();
+        return resMonth;
     }
 
     @Override
     public Date getTargetEndTime(double month, Date startDate) {
         Calendar endDate = Calendar.getInstance();
         endDate.setTime(startDate);
-        endDate.add(Calendar.MONTH, (int) month);
+
+        Double intMonth = Math.floor(month);
+        endDate.add(Calendar.MONTH, intMonth.intValue());
+        double doubleMonth = month - intMonth;
+        if (doubleMonth <= 0) {
+            return endDate.getTime();
+        }
+//        Calendar futureDate = Calendar.getInstance();
+//        futureDate.setTime(endDate.getTime());
+//        futureDate.add(Calendar.MONTH, 1);
+        int futureDay = endDate.getActualMaximum(Calendar.DAY_OF_MONTH);
+        Double hour = doubleMonth * futureDay * 24;
+        endDate.add(Calendar.HOUR_OF_DAY, hour.intValue());
         return endDate.getTime();
     }
+
+    public static void main(String[] args) {
+        ComputeFeeSMOImpl computeFeeSMO = new ComputeFeeSMOImpl();
+        try {
+            double month = computeFeeSMO.dayCompare(
+
+                    DateUtil.getDateFromString("2020-12-19 00:00:00", DateUtil.DATE_FORMATE_STRING_A),
+                    DateUtil.getDateFromString("2021-1-10 00:00:00", DateUtil.DATE_FORMATE_STRING_A)
+            );
+
+            System.out.println(month);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+    }
+
+//    public static void main(String[] args) {
+//        ComputeFeeSMOImpl computeFeeSMO = new ComputeFeeSMOImpl();
+//        try {
+//            Date startTime = DateUtil.getDateFromString("2020-12-31 00:00:00", DateUtil.DATE_FORMATE_STRING_A);
+//            Date endTime = DateUtil.getDateFromString("2021-1-2 00:00:00", DateUtil.DATE_FORMATE_STRING_A);
+//            double day = (endTime.getTime() - startTime.getTime()) * 1.00 / (24 * 60 * 60 * 1000);
+//
+//            System.out.println(day);
+//
+//        } catch (ParseException e) {
+//            e.printStackTrace();
+//        }
+//    }
 }

--
Gitblit v1.8.0