java110
2023-05-17 402d54b051a96b61a5bab774437e98705b64708d
optimize pay fee detail to month
4个文件已修改
1个文件已添加
273 ■■■■ 已修改文件
java110-bean/src/main/java/com/java110/dto/fee/MonthFeeDetailDto.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-utils/src/main/java/com/java110/utils/util/DateUtil.java 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/feeMonth/IPayFeeMonthHelp.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/feeMonth/PayFeeMonthHelp.java 140 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/feeMonth/PayFeeMonthImpl.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-bean/src/main/java/com/java110/dto/fee/MonthFeeDetailDto.java
New file
@@ -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;
    }
}
java110-utils/src/main/java/com/java110/utils/util/DateUtil.java
@@ -5,10 +5,7 @@
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 @@
            return sDateFormat.format(date);
        }
    }
    public static String getFormatTimeStringB(Date date) {
        SimpleDateFormat sDateFormat = getDateFormat(DateUtil.DATE_FORMATE_STRING_B);
@@ -620,7 +618,6 @@
    /**
     *    *字符串的日期格式的计算
     *
     */
    public static int daysBetween(String smdate, String bdate) {
        long between_days = 0;
@@ -696,14 +693,63 @@
    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @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;
    }
}
service-fee/src/main/java/com/java110/fee/feeMonth/IPayFeeMonthHelp.java
@@ -2,10 +2,12 @@
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 @@
    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 @@
     * @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 @@
     * @return
     */
    String getFeeFeeTime(List<FeeDetailDto> feeDetailDtos, String detailId);
    /**
     * 缴费记录转换为月缴费记录,金额 除以 缴费时间段内所包含的月个数
     * @param feeDetailDtos
     * @return
     */
    Map<String ,MonthFeeDetailDto> analysisMonthFeeDetail(List<FeeDetailDto> feeDetailDtos);
}
service-fee/src/main/java/com/java110/fee/feeMonth/PayFeeMonthHelp.java
@@ -4,6 +4,7 @@
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.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 @@
        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;
    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;
        }
        //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());
        }
        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 @@
        return null;
    }
    /**
     * 获取当前缴费记录
     *
@@ -157,7 +132,7 @@
        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 @@
    }
    @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;
    }
}
service-fee/src/main/java/com/java110/fee/feeMonth/PayFeeMonthImpl.java
@@ -6,6 +6,7 @@
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 @@
        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 @@
        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 @@
            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()),