Your Name
2023-08-26 7958f1dddb8a7f4e70d232b07a7703955ecedae0
service-fee/src/main/java/com/java110/fee/feeMonth/PayFeeMonthImpl.java
@@ -1,28 +1,27 @@
package com.java110.fee.feeMonth;
import com.alibaba.fastjson.JSONObject;
import com.java110.core.factory.GenerateCodeFactory;
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.payFeeDetailMonth.PayFeeDetailMonthDto;
import com.java110.dto.payFeeDetailMonth.PayFeeMonthOwnerDto;
import com.java110.dto.report.ReportRoomDto;
import com.java110.intf.fee.IFeeInnerServiceSMO;
import com.java110.intf.fee.IPayFeeConfigV1InnerServiceSMO;
import com.java110.intf.fee.IPayFeeDetailMonthInnerServiceSMO;
import com.java110.po.payFeeDetailMonth.PayFeeDetailMonthPo;
import com.java110.dto.payFee.PayFeeMonthOwnerDto;
import com.java110.intf.fee.*;
import com.java110.po.payFee.PayFeeDetailMonthPo;
import com.java110.utils.util.Assert;
import com.java110.utils.util.DateUtil;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
/**
 * 费用离散为月 实现类
 * V2
 * <p>
 * case 1 定时任务 调用
 */
@Service
public class PayFeeMonthImpl implements IPayFeeMonth {
@@ -38,6 +37,9 @@
    private IPayFeeDetailMonthInnerServiceSMO payFeeDetailMonthInnerServiceSMOImpl;
    @Autowired
    private IFeeDetailInnerServiceSMO feeDetailInnerServiceSMOImpl;
    @Autowired
    private IPayFeeMonthHelp payFeeMonthHelp;
    @Autowired
@@ -45,107 +47,19 @@
    public static final int DEFAULT_DEAL_COUNT = 200;
    /**
     * 生成单个费用 并 离散到月
     * @param feeId
     * 1.0 定时任务离散 小区数据 离散为 月数据
     *
     * @param communityId
     */
    @Override
    public void doGeneratorOrRefreshFeeMonth(String feeId, String communityId) {
        // todo 查询费用
        FeeDto feeDto = new FeeDto();
        feeDto.setCommunityId(communityId);
        feeDto.setFeeId(feeId);
        List<FeeDto> tmpFeeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
        Assert.listOnlyOne(tmpFeeDtos, "费用不存在");
        doGeneratorOrRefreshFeeMonth(tmpFeeDtos.get(0), communityId);
    }
    public void doGeneratorOrRefreshFeeMonth(FeeDto feeDto, String communityId) {
        //todo 计算每月单价
        Double feePrice = payFeeMonthHelp.getMonthFeePrice(feeDto);
        // 准备离散的基础数据
        PayFeeMonthOwnerDto payFeeMonthOwnerDto = payFeeMonthHelp.generatorOwnerRoom(feeDto);
        //todo 检查费用是否离散过,如果没有离散过,先离散 start_time 到 end_time 的数据
        ifHasNoMonthData(feeDto,payFeeMonthOwnerDto,feePrice);
    }
    /**
     * 如果费用没有month 数据,则直接离散 start_time 到end_time 数据
     * @param feeDto
     */
    private void ifHasNoMonthData(FeeDto feeDto,PayFeeMonthOwnerDto payFeeMonthOwnerDto,Double feePrice) {
        //todo 分析建账时间 和开始时间
        Date startTime = feeDto.getStartTime();
        if(startTime == null){
            throw new IllegalArgumentException("数据错误,未包含开始时间");
        }
        Calendar calendar = Calendar.getInstance();
        int startYear = calendar.get(Calendar.YEAR);
        int startMonth = calendar.get(Calendar.MONTH)+1;
        PayFeeDetailMonthDto payFeeDetailMonthDto = new PayFeeDetailMonthDto();
        payFeeDetailMonthDto.setCommunityId(feeDto.getCommunityId());
        payFeeDetailMonthDto.setFeeId(feeDto.getFeeId());
        payFeeDetailMonthDto.setDetailYear(startYear+"");
        payFeeDetailMonthDto.setDetailMonth(startMonth+"");
        int count = payFeeDetailMonthInnerServiceSMOImpl.queryPayFeeDetailMonthsCount(payFeeDetailMonthDto);
        // todo 说明这个费用已经第一次离散过
        if(count > 0){
            return ;
        }
        double maxMonth = Math.ceil(computeFeeSMOImpl.dayCompare(startTime, feeDto.getEndTime()));
        if (maxMonth < 1) {
            return;
        }
        PayFeeDetailMonthPo tmpPayFeeDetailMonthPo;
        String detailId = "";
        String discountAmount = "";
        String receivedAmount = "";
        List<PayFeeDetailMonthPo> payFeeDetailMonthPos = new ArrayList<>();
        for (int month = 0; month < maxMonth; month++) {
            calendar.setTime(startTime);
            calendar.add(Calendar.MONTH, month);
            tmpPayFeeDetailMonthPo = new PayFeeDetailMonthPo();
            tmpPayFeeDetailMonthPo.setFeeId(feeDto.getFeeId());
            tmpPayFeeDetailMonthPo.setCommunityId(feeDto.getCommunityId());
            tmpPayFeeDetailMonthPo.setDetailId(detailId);
            tmpPayFeeDetailMonthPo.setDetailMonth((calendar.get(Calendar.MONTH) + 1) + "");
            tmpPayFeeDetailMonthPo.setDetailYear(calendar.get(Calendar.YEAR) + "");
            tmpPayFeeDetailMonthPo.setDiscountAmount(discountAmount);
            tmpPayFeeDetailMonthPo.setMonthId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_monthId));
            tmpPayFeeDetailMonthPo.setReceivableAmount(feePrice + "");
            tmpPayFeeDetailMonthPo.setReceivedAmount(receivedAmount);
            tmpPayFeeDetailMonthPo.setRemark("程序计算生成");
            tmpPayFeeDetailMonthPo.setObjName(payFeeMonthOwnerDto.getObjName());
            tmpPayFeeDetailMonthPo.setObjId(payFeeMonthOwnerDto.getObjId());
            tmpPayFeeDetailMonthPo.setOwnerId(payFeeMonthOwnerDto.getOwnerId());
            tmpPayFeeDetailMonthPo.setOwnerName(payFeeMonthOwnerDto.getOwnerName());
            payFeeDetailMonthPos.add(tmpPayFeeDetailMonthPo);
        }
        payFeeDetailMonthInnerServiceSMOImpl.savePayFeeDetailMonths(payFeeDetailMonthPos);
    }
    @Async
    @Override
    public void doGeneratorOrRefreshAllFeeMonth(String communityId) {
        //todo 清理 pay_fee_detail_month
        PayFeeDetailMonthPo payFeeDetailMonthPo = new PayFeeDetailMonthPo();
        payFeeDetailMonthPo.setCommunityId(communityId);
        payFeeDetailMonthInnerServiceSMOImpl.deletePayFeeDetailMonth(payFeeDetailMonthPo);
        FeeDto feeDto = new FeeDto();
@@ -164,13 +78,158 @@
        //todo  每次按200条处理
        for (int pageIndex = 0; pageIndex < page; pageIndex++) {
            feeDto.setPage(pageIndex * max);
            feeDto.setPage(pageIndex + 1);
            feeDto.setRow(max);
            List<FeeDto> tmpFeeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
            // 离散费用
            doTmpFeeDtoMonths(communityId, tmpFeeDtos);
        }
    }
    /**
     * 2.0 物业缴费时离散 报表数据
     *
     * @param feeId
     * @param detailId
     * @param communityId
     */
    @Async
    @Override
    public void payFeeDetailRefreshFeeMonth(String feeId, String detailId, String communityId) {
        // todo 查询费用
        FeeDto feeDto = new FeeDto();
        feeDto.setCommunityId(communityId);
        feeDto.setFeeId(feeId);
        List<FeeDto> tmpFeeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
        Assert.listOnlyOne(tmpFeeDtos, "费用不存在");
        feeDto = tmpFeeDtos.get(0);
        //todo 查询 缴费明细
        FeeDetailDto feeDetailDto = new FeeDetailDto();
        feeDetailDto.setCommunityId(feeDto.getCommunityId());
        feeDetailDto.setFeeId(feeDto.getFeeId());
        feeDetailDto.setDetailId(detailId);
        List<FeeDetailDto> feeDetailDtos = feeDetailInnerServiceSMOImpl.queryFeeDetails(feeDetailDto);
        Assert.listOnlyOne(feeDetailDtos, "缴费记录不存在");
        //todo 计算每月单价
        Double feePrice = payFeeMonthHelp.getMonthFeePrice(feeDto);
        // todo 准备离散的基础数据
        PayFeeMonthOwnerDto payFeeMonthOwnerDto = payFeeMonthHelp.generatorOwnerRoom(feeDto);
        // todo 删除缴费时间范围内的数据
        doDeletePayFeeDetailInMonth(feeDto, feeDetailDtos.get(0));
        // todo 生成一段时间内的数据
        maxMonthDateToDeadlineTimeData(feeDto, payFeeMonthOwnerDto, feePrice);
    }
    /**
     * 生成单个费用 并 离散到月
     *
     * @param feeId
     * @param communityId
     */
    @Override
    public void doGeneratorOrRefreshFeeMonth(String feeId, String communityId) {
        // todo 查询费用
        FeeDto feeDto = new FeeDto();
        feeDto.setCommunityId(communityId);
        feeDto.setFeeId(feeId);
        List<FeeDto> tmpFeeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
        Assert.listOnlyOne(tmpFeeDtos, "费用不存在");
        doGeneratorOrRefreshFeeMonth(tmpFeeDtos.get(0), communityId);
    }
    /**
     * 生成多个费用 并 离散到月
     *
     * @param feeIds
     * @param communityId
     */
    @Override
    @Async
    public void doGeneratorFeeMonths(List<String> feeIds, String communityId) {
        for (String feeId : feeIds) {
            doGeneratorOrRefreshFeeMonth(feeId, communityId);
        }
    }
    /**
     * 删除月费用
     *
     * @param feeId
     * @param communityId
     */
    @Override
    public void deleteFeeMonth(String feeId, String communityId) {
        PayFeeDetailMonthPo payFeeDetailMonthPo = new PayFeeDetailMonthPo();
        payFeeDetailMonthPo.setFeeId(feeId);
        payFeeDetailMonthPo.setCommunityId(communityId);
        payFeeDetailMonthInnerServiceSMOImpl.deletePayFeeDetailMonth(payFeeDetailMonthPo);
    }
    private void doGeneratorOrRefreshFeeMonth(FeeDto feeDto, String communityId) {
        // todo 计算每月单价
        Double feePrice = payFeeMonthHelp.getMonthFeePrice(feeDto);
        // todo 准备离散的基础数据
        PayFeeMonthOwnerDto payFeeMonthOwnerDto = payFeeMonthHelp.generatorOwnerRoom(feeDto);
        //todo 离散start_time 或者 pay_fee_detail_month 最大月份 到  deadlineTime 的数据
        maxMonthDateToDeadlineTimeData(feeDto, payFeeMonthOwnerDto, feePrice);
    }
    /**
     * 离散最大 离散月到 deadlineTime 的数据
     * <p>
     * 核心方法处理
     *
     * @param feeDto
     * @param payFeeMonthOwnerDto
     * @param feePrice
     */
    private void maxMonthDateToDeadlineTimeData(FeeDto feeDto, PayFeeMonthOwnerDto payFeeMonthOwnerDto, Double feePrice) {
        //todo 处理已经交过费的记录处理
        payFeeMonthHelp.waitDispersedFeeDetail(feeDto, payFeeMonthOwnerDto);
        //todo 处理 endTime 到 deadlineTime 的费用
        Date deadlineTime = computeFeeSMOImpl.getDeadlineTime(feeDto);
        payFeeMonthHelp.waitDispersedOweFee(feeDto, payFeeMonthOwnerDto, feePrice, deadlineTime);
    }
    /**
     * 删除缴费范围内的数据
     *
     * @param feeDto
     * @param feeDetailDto
     */
    private void doDeletePayFeeDetailInMonth(FeeDto feeDto, FeeDetailDto feeDetailDto) {
        PayFeeDetailMonthPo payFeeDetailMonthPo = new PayFeeDetailMonthPo();
        payFeeDetailMonthPo.setFeeId(feeDto.getFeeId());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(feeDetailDto.getStartTime());
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        payFeeDetailMonthPo.setCurMonthTime(DateUtil.getFormatTimeStringB(calendar.getTime()));
        payFeeDetailMonthPo.setCurMonthEndTime(DateUtil.getFormatTimeStringB(feeDetailDto.getEndTime()));
        payFeeDetailMonthInnerServiceSMOImpl.deletePayFeeDetailMonth(payFeeDetailMonthPo);
    }
    private void doTmpFeeDtoMonths(String communityId, List<FeeDto> tmpFeeDtos) {