Просмотр исходного кода

optimize pay fee detail to month

java110 лет назад: 2
Родитель
Сommit
402d54b051

+ 42 - 0
java110-bean/src/main/java/com/java110/dto/fee/MonthFeeDetailDto.java

@@ -0,0 +1,42 @@
+package com.java110.dto.fee;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 缴费记录转换为
+ */
+public class MonthFeeDetailDto implements Serializable {
+
+
+    public MonthFeeDetailDto(double receivedAmount, FeeDetailDto feeDetailDto) {
+        this.receivedAmount = receivedAmount;
+
+        this.feeDetailDtos = new ArrayList<>();
+        this.feeDetailDtos.add(feeDetailDto);
+    }
+
+    public MonthFeeDetailDto() {
+    }
+
+    private double receivedAmount;
+
+    private List<FeeDetailDto> feeDetailDtos;
+
+    public double getReceivedAmount() {
+        return receivedAmount;
+    }
+
+    public void setReceivedAmount(double receivedAmount) {
+        this.receivedAmount = receivedAmount;
+    }
+
+    public List<FeeDetailDto> getFeeDetailDtos() {
+        return feeDetailDtos;
+    }
+
+    public void setFeeDetailDtos(List<FeeDetailDto> feeDetailDtos) {
+        this.feeDetailDtos = feeDetailDtos;
+    }
+}

+ 54 - 8
java110-utils/src/main/java/com/java110/utils/util/DateUtil.java

@@ -5,10 +5,7 @@ import java.sql.Timestamp;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 /**
  * Created by wuxw on 2017/7/24.
@@ -130,6 +127,7 @@ public class DateUtil {
             return sDateFormat.format(date);
         }
     }
+
     public static String getFormatTimeStringB(Date date) {
         SimpleDateFormat sDateFormat = getDateFormat(DateUtil.DATE_FORMATE_STRING_B);
 
@@ -620,7 +618,6 @@ public class DateUtil {
 
     /**
      *    *字符串的日期格式的计算
-     *
      */
     public static int daysBetween(String smdate, String bdate) {
         long between_days = 0;
@@ -696,14 +693,63 @@ public class DateUtil {
 
     /**
      * 通过时间秒毫秒数判断两个时间的间隔
+     *
      * @param date1
      * @param date2
      * @return
      */
-    public static int differentDaysUp(Date date1,Date date2)
-    {
-        double days = ((date2.getTime() - date1.getTime()) / (1000*3600*24*1.00));
+    public static int differentDaysUp(Date date1, Date date2) {
+        double days = ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24 * 1.00));
         return new Double(Math.ceil(days)).intValue();
     }
 
+    /**
+     * 获取两个日期之间的所有月份 (年月)
+     *
+     * @param startTime
+     * @param endTime
+     * @return:list
+     */
+    public static List<String> getMonthBetweenDate(Date startTime, Date endTime) {
+        return getMonthBetweenDate(DateUtil.getFormatTimeStringA(startTime), DateUtil.getFormatTimeStringA(endTime));
+    }
+
+    /**
+     * 获取两个日期之间的所有月份 (年月)
+     *
+     * @param startTime
+     * @param endTime
+     * @return:list
+     */
+    public static List<String> getMonthBetweenDate(String startTime, String endTime) {
+        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMATE_STRING_M);
+        // 声明保存日期集合
+        List<String> list = new ArrayList<>();
+        try {
+            // 转化成日期类型
+            Date startDate = sdf.parse(startTime);
+            Date endDate = sdf.parse(endTime);
+
+            //用Calendar 进行日期比较判断
+            Calendar calendar = Calendar.getInstance();
+            while (startDate.getTime() <= endDate.getTime()) {
+
+                // 把日期添加到集合
+                list.add(sdf.format(startDate));
+
+                // 设置日期
+                calendar.setTime(startDate);
+
+                //把月数增加 1
+                calendar.add(Calendar.MONTH, 1);
+
+                // 获取增加后的日期
+                startDate = calendar.getTime();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return list;
+    }
+
 }

+ 11 - 2
service-fee/src/main/java/com/java110/fee/feeMonth/IPayFeeMonthHelp.java

@@ -2,10 +2,12 @@ package com.java110.fee.feeMonth;
 
 import com.java110.dto.fee.FeeDetailDto;
 import com.java110.dto.fee.FeeDto;
+import com.java110.dto.fee.MonthFeeDetailDto;
 import com.java110.dto.payFeeDetailMonth.PayFeeMonthOwnerDto;
 
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 public interface IPayFeeMonthHelp {
 
@@ -14,7 +16,7 @@ public interface IPayFeeMonthHelp {
     Double getMonthFeePrice(FeeDto feeDto);
 
 
-    Double getReceivableAmount(List<FeeDetailDto> feeDetailDtos, Double feePrice, Date curDate, FeeDto feeDto);
+    Double getReceivableAmount(List<FeeDetailDto> feeDetailDtos,Map<String, MonthFeeDetailDto> monthFeeDetailDtos, Double feePrice, Date curDate, FeeDto feeDto);
 
     /**
      * 计算实收
@@ -22,7 +24,7 @@ public interface IPayFeeMonthHelp {
      * @param feePrice
      * @return
      */
-    Double getReceivedAmount(List<FeeDetailDto> feeDetailDtos, Double feePrice, Date curDate, FeeDto feeDto);
+    Double getReceivedAmount(List<FeeDetailDto> feeDetailDtos,Map<String ,MonthFeeDetailDto> monthFeeDetailDtos, Double feePrice, Date curDate, FeeDto feeDto);
 
     Double getDiscountAmount(Double feePrice, double receivedAmount, Date curDate, FeeDto feeDto);
 
@@ -41,4 +43,11 @@ public interface IPayFeeMonthHelp {
      * @return
      */
     String getFeeFeeTime(List<FeeDetailDto> feeDetailDtos, String detailId);
+
+    /**
+     * 缴费记录转换为月缴费记录,金额 除以 缴费时间段内所包含的月个数
+     * @param feeDetailDtos
+     * @return
+     */
+    Map<String ,MonthFeeDetailDto> analysisMonthFeeDetail(List<FeeDetailDto> feeDetailDtos);
 }

+ 98 - 42
service-fee/src/main/java/com/java110/fee/feeMonth/PayFeeMonthHelp.java

@@ -4,6 +4,7 @@ import com.java110.core.smo.IComputeFeeSMO;
 import com.java110.dto.fee.FeeAttrDto;
 import com.java110.dto.fee.FeeDetailDto;
 import com.java110.dto.fee.FeeDto;
+import com.java110.dto.fee.MonthFeeDetailDto;
 import com.java110.dto.payFeeDetailMonth.PayFeeMonthOwnerDto;
 import com.java110.intf.community.IRoomInnerServiceSMO;
 import com.java110.utils.util.BeanConvertUtil;
@@ -13,10 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 @Service
 public class PayFeeMonthHelp implements IPayFeeMonthHelp {
@@ -53,58 +51,34 @@ public class PayFeeMonthHelp implements IPayFeeMonthHelp {
         if (!FeeDto.FEE_FLAG_ONCE.equals(feeDto.getPayerObjType())) {
             return feePrice;
         }
-        double maxMonth = Math.ceil(computeFeeSMOImpl.dayCompare(feeDto.getStartTime(), feeDto.getEndTime()));
-        if (maxMonth <= 0) {
+        List<String> months = DateUtil.getMonthBetweenDate(feeDto.getStartTime(), feeDto.getEndTime());
+        //double maxMonth = Math.ceil(computeFeeSMOImpl.dayCompare(feeDto.getStartTime(), feeDto.getEndTime()));
+        if (months == null || months.size() <= 0) {
             return feePrice;
 
         }
-        BigDecimal feePriceDec = new BigDecimal(feePrice).divide(new BigDecimal(maxMonth), 2, BigDecimal.ROUND_HALF_UP);
+        BigDecimal feePriceDec = new BigDecimal(feePrice).divide(new BigDecimal(months.size()), 4, BigDecimal.ROUND_HALF_UP);
         feePrice = feePriceDec.doubleValue();
         return feePrice;
     }
 
 
-    public Double getReceivableAmount(List<FeeDetailDto> feeDetailDtos, Double feePrice, Date curDate, FeeDto feeDto) {
-        FeeDetailDto feeDetailDto = getCurFeeDetail(feeDetailDtos, curDate);
-
-        if (feeDetailDto == null && curDate.getTime() < feeDto.getEndTime().getTime()) {
+    public Double getReceivableAmount(List<FeeDetailDto> feeDetailDtos, Map<String, MonthFeeDetailDto> monthFeeDetailDtos, Double feePrice, Date curDate, FeeDto feeDto) {
+        MonthFeeDetailDto monthFeeDetailDto = getCurMonthFeeDetail(monthFeeDetailDtos, curDate);
+        if (monthFeeDetailDto == null && curDate.getTime() < feeDto.getEndTime().getTime()) {
             return 0.00;
         }
-
         return feePrice;
     }
 
-    @Override
-    public Double getReceivedAmount(List<FeeDetailDto> feeDetailDtos, Double feePrice, Date curDate, FeeDto feeDto) {
-        //todo 这种情况下应该 实收为0
-        if (curDate.getTime() >= feeDto.getEndTime().getTime()) {
-            return 0.00;
-        }
-        //todo 如果 fee 为空
-        if (feeDetailDtos == null) {
-            return feePrice;
-        }
-        FeeDetailDto feeDetailDto = getCurFeeDetail(feeDetailDtos, curDate);
-
-        if (feeDetailDto == null && curDate.getTime() < feeDto.getEndTime().getTime()) {
-            return 0.00;
-        }
-
-        if (feeDetailDto == null) {
-            return feePrice;
-        }
-
-        double maxMonth = Math.ceil(computeFeeSMOImpl.dayCompare(feeDetailDto.getStartTime(), feeDetailDto.getEndTime()));
 
-        if (maxMonth < 1) {
-            return Double.parseDouble(feeDetailDto.getReceivedAmount());
+    @Override
+    public Double getReceivedAmount(List<FeeDetailDto> feeDetailDtos, Map<String, MonthFeeDetailDto> monthFeeDetailDtos, Double feePrice, Date curDate, FeeDto feeDto) {
+        MonthFeeDetailDto monthFeeDetailDto = getCurMonthFeeDetail(monthFeeDetailDtos, curDate);
+        if (monthFeeDetailDto == null) {
+            return 0.0;
         }
-
-        BigDecimal totalRecDec = new BigDecimal(feeDetailDto.getReceivedAmount());
-        //每月平均值
-        BigDecimal priRecDec = totalRecDec.divide(new BigDecimal(maxMonth), 4, BigDecimal.ROUND_HALF_UP);
-
-        return priRecDec.doubleValue();
+        return monthFeeDetailDto.getReceivedAmount();
     }
 
     @Override
@@ -143,6 +117,7 @@ public class PayFeeMonthHelp implements IPayFeeMonthHelp {
         return null;
     }
 
+
     /**
      * 获取当前缴费记录
      *
@@ -157,7 +132,7 @@ public class PayFeeMonthHelp implements IPayFeeMonthHelp {
         List<FeeDetailDto> tFeeDetailDtos = new ArrayList<>();
         for (FeeDetailDto feeDetailDto : feeDetailDtos) {
             if (feeDetailDto.getStartTime().getTime() <= curDate.getTime() && feeDetailDto.getEndTime().getTime() > curDate.getTime()) {
-                tFeeDetailDtos.add(BeanConvertUtil.covertBean(feeDetailDto,FeeDetailDto.class));
+                tFeeDetailDtos.add(BeanConvertUtil.covertBean(feeDetailDto, FeeDetailDto.class));
             }
         }
 
@@ -179,4 +154,85 @@ public class PayFeeMonthHelp implements IPayFeeMonthHelp {
     }
 
 
+    @Override
+    public Map<String, MonthFeeDetailDto> analysisMonthFeeDetail(List<FeeDetailDto> feeDetailDtos) {
+
+        if (feeDetailDtos == null || feeDetailDtos.size() < 1) {
+            return null;
+        }
+
+        Map<String, MonthFeeDetailDto> monthFeeDetailDtos = new HashMap<>();
+
+        for (FeeDetailDto feeDetailDto : feeDetailDtos) {
+            //计算两个日期包含的月份
+            List<String> months = DateUtil.getMonthBetweenDate(feeDetailDto.getStartTime(), feeDetailDto.getEndTime());
+
+            if (months == null || months.size() < 1) {
+                putReceivedAmountToMonthFeeDetailDtos(monthFeeDetailDtos,
+                        DateUtil.getFormatTimeString(feeDetailDto.getStartTime(), DateUtil.DATE_FORMATE_STRING_M),
+                        Double.parseDouble(feeDetailDto.getReceivedAmount()),
+                        feeDetailDto);
+                continue;
+            }
+
+            BigDecimal totalRecDec = new BigDecimal(feeDetailDto.getReceivedAmount());
+            //每月平均值
+            BigDecimal priRecDec = totalRecDec.divide(new BigDecimal(months.size()), 4, BigDecimal.ROUND_HALF_UP);
+
+            for (String month : months) {
+                putReceivedAmountToMonthFeeDetailDtos(monthFeeDetailDtos,
+                        month,
+                        priRecDec.doubleValue(),
+                        feeDetailDto);
+            }
+
+        }
+        return null;
+    }
+
+
+    /**
+     * 月份存放起来
+     *
+     * @param monthFeeDetailDtos
+     * @param month
+     * @param receivedAmount
+     */
+    private void putReceivedAmountToMonthFeeDetailDtos(Map<String, MonthFeeDetailDto> monthFeeDetailDtos,
+                                                       String month,
+                                                       double receivedAmount,
+                                                       FeeDetailDto feeDetailDto) {
+
+        if (!monthFeeDetailDtos.containsKey(month)) {
+            monthFeeDetailDtos.put(month, new MonthFeeDetailDto(receivedAmount, feeDetailDto));
+            return;
+        }
+
+        MonthFeeDetailDto monthFeeDetailDto = monthFeeDetailDtos.get(month);
+        BigDecimal recDec = new BigDecimal(monthFeeDetailDto.getReceivedAmount()).add(new BigDecimal(receivedAmount)).setScale(4, BigDecimal.ROUND_HALF_UP);
+        monthFeeDetailDto.setReceivedAmount(recDec.doubleValue());
+        monthFeeDetailDto.getFeeDetailDtos().add(feeDetailDto);
+        monthFeeDetailDtos.put(month, monthFeeDetailDto);
+    }
+
+    /**
+     * 月离散数据
+     *
+     * @param monthFeeDetailDtos
+     * @param curDate
+     * @return
+     */
+    private MonthFeeDetailDto getCurMonthFeeDetail(Map<String, MonthFeeDetailDto> monthFeeDetailDtos, Date curDate) {
+        String month = DateUtil.getFormatTimeString(curDate, DateUtil.DATE_FORMATE_STRING_M);
+        if (monthFeeDetailDtos == null) {
+            return null;
+        }
+        if (!monthFeeDetailDtos.containsKey(month)) {
+            return null;
+        }
+        MonthFeeDetailDto monthFeeDetailDto = monthFeeDetailDtos.get(month);
+        return monthFeeDetailDto;
+    }
+
+
 }

+ 13 - 3
service-fee/src/main/java/com/java110/fee/feeMonth/PayFeeMonthImpl.java

@@ -6,6 +6,7 @@ import com.java110.core.log.LoggerFactory;
 import com.java110.core.smo.IComputeFeeSMO;
 import com.java110.dto.fee.FeeDetailDto;
 import com.java110.dto.fee.FeeDto;
+import com.java110.dto.fee.MonthFeeDetailDto;
 import com.java110.dto.payFeeDetailMonth.PayFeeDetailMonthDto;
 import com.java110.dto.payFeeDetailMonth.PayFeeMonthOwnerDto;
 import com.java110.intf.fee.*;
@@ -99,9 +100,14 @@ public class PayFeeMonthImpl implements IPayFeeMonth {
         if (payFeeDetailMonthDtos == null || payFeeDetailMonthDtos.size() < 1) {
             startTime = feeDto.getStartTime();
         } else {
+
+            //todo 删除最大月 从最大月开始离散,主要担心缴费时间不是1号导致 最大月收入不对
+            PayFeeDetailMonthPo payFeeDetailMonthPo = new PayFeeDetailMonthPo();
+            payFeeDetailMonthPo.setMonthId(payFeeDetailMonthDtos.get(0).getMonthId());
+            payFeeDetailMonthInnerServiceSMOImpl.deletePayFeeDetailMonth(payFeeDetailMonthPo);
             Calendar calendar = Calendar.getInstance();
             calendar.setTime(DateUtil.getDateFromStringA(payFeeDetailMonthDtos.get(0).getCurMonthTime()));
-            calendar.add(Calendar.MONTH, 1);
+            //calendar.add(Calendar.MONTH, 1);
             startTime = calendar.getTime();
         }
 
@@ -123,6 +129,10 @@ public class PayFeeMonthImpl implements IPayFeeMonth {
         feeDetailDto.setStates(new String[]{FeeDetailDto.STATE_NORMAL,FeeDetailDto.STATE_RETURNING});
         List<FeeDetailDto> feeDetailDtos = feeDetailInnerServiceSMOImpl.queryFeeDetails(feeDetailDto);
 
+
+        //todo 将缴费记录转换为月的方式
+        Map<String ,MonthFeeDetailDto> monthFeeDetailDtos = payFeeMonthHelp.analysisMonthFeeDetail(feeDetailDtos);
+
         //todo 生成 月离散数据
         PayFeeDetailMonthPo tmpPayFeeDetailMonthPo;
         List<PayFeeDetailMonthPo> payFeeDetailMonthPos = new ArrayList<>();
@@ -138,13 +148,13 @@ public class PayFeeMonthImpl implements IPayFeeMonth {
             tmpPayFeeDetailMonthPo.setDetailId(payFeeMonthHelp.getFeeDetailId(feeDetailDtos, calendar.getTime()));
             tmpPayFeeDetailMonthPo.setDetailYear(calendar.get(Calendar.YEAR) + "");
             tmpPayFeeDetailMonthPo.setDetailMonth((calendar.get(Calendar.MONTH) + 1) + "");
-            receivableAmount = payFeeMonthHelp.getReceivableAmount(feeDetailDtos, feePrice, calendar.getTime(), feeDto);
+            receivableAmount = payFeeMonthHelp.getReceivableAmount(feeDetailDtos,monthFeeDetailDtos, feePrice, calendar.getTime(), feeDto);
             //todo 应收小于等于0 不统计
             if(receivableAmount <=0){
                 continue;
             }
             tmpPayFeeDetailMonthPo.setReceivableAmount( receivableAmount + "");
-            tmpPayFeeDetailMonthPo.setReceivedAmount(payFeeMonthHelp.getReceivedAmount(feeDetailDtos, feePrice, calendar.getTime(), feeDto) + "");
+            tmpPayFeeDetailMonthPo.setReceivedAmount(payFeeMonthHelp.getReceivedAmount(feeDetailDtos,monthFeeDetailDtos, feePrice, calendar.getTime(), feeDto) + "");
             tmpPayFeeDetailMonthPo.setDiscountAmount(
                     payFeeMonthHelp.getDiscountAmount(Double.parseDouble(tmpPayFeeDetailMonthPo.getReceivableAmount()),
                             Double.parseDouble(tmpPayFeeDetailMonthPo.getReceivedAmount()),