package com.yuchen.saas.park.service.service.property.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.thinkunion.park.service.common.cache.CacheNames;
import com.yuchen.saas.manage.system.api.entity.NestOrgUser;
import com.yuchen.saas.manage.system.api.feign.ISysClient;
import com.yuchen.saas.park.api.dto.property.*;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.property.*;
import com.yuchen.saas.park.api.enums.property.PayStatusEnum;
import com.yuchen.saas.park.api.enums.property.SourceTypeEnum;
import com.yuchen.saas.park.api.vo.property.*;
import com.yuchen.saas.park.service.mapper.property.PropertyPayReductionMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.property.*;
import com.yuchen.saas.park.service.service.property.bill.PropertyBillService;
import com.yuchen.saas.parking.charge.api.po.ParkingChargingRecord;
import lombok.extern.slf4j.Slf4j;
import org.nest.springwrap.core.log.exception.ServiceException;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.Condition;
import org.nest.springwrap.core.mp.support.NestPage;
import org.nest.springwrap.core.redis.lock.RedisLock;
import org.nest.springwrap.core.secure.ContextUser;
import org.nest.springwrap.core.secure.utils.AuthUtil;
import org.nest.springwrap.core.tool.api.R;
import org.nest.springwrap.core.tool.utils.DateUtil;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 减免活动-缴费减免 服务实现类
 * </p>
 *
 * @author cxj
 * @since 2023-12-22
 */
@Service
@Slf4j
public class PropertyPayReductionServiceImpl extends BaseServiceImpl<PropertyPayReductionMapper, PropertyPayReduction> implements IPropertyPayReductionService {
    @Resource
    private ISysClient sysClient;

    @Resource
    private IPropertyPayReductionDetailService iPropertyPayReductionDetailService;

    @Resource
    private IPropertyPayReductionHouseLogService iPropertyPayReductionHouseLogService;

    @Resource
    private IPropertyPayReductionHouseService iPropertyPayReductionHouseService;

    @Resource
    private PmgBatParkInfoService parkInfoService;

    @Resource
    private PropertyFeeStandardService propertyFeeStandardService;

    @Resource
    private PropertyHousesService propertyHousesService;

    @Resource
    private PropertyBuildingsService propertyBuildingsService;

    @Autowired
    private PropertyBuildingUnitService propertyBuildingUnitService;

    @Resource
    private PropertyBillService propertyBillService;


    @Override
    public NestPage<PropertyPayReductionPageVo> getPage(PropertyPayReductionQueryDto dto) {
        LambdaQueryWrapper<PropertyPayReduction> queryWrapper = Wrappers.lambdaQuery();
        List<Long> ids = new ArrayList<>();
        if (Func.isNotEmpty(dto.getFeeStandardId()) || Func.isNotEmpty(dto.getFeeItemId())) {
            List<PropertyPayReductionDetail> payReductionDetails = iPropertyPayReductionDetailService.listByQuery(dto.getFeeStandardId(), dto.getFeeItemId());
            ids.addAll(payReductionDetails.stream().map(a -> a.getPayReductionId()).collect(Collectors.toList()));
        }
        if (Func.isNotEmpty(dto.getBuildingId()) || Func.isNotEmpty(dto.getHouseId())) {
            List<PropertyPayReductionHouse> payReductionHouses = iPropertyPayReductionHouseService.listByQuery(dto.getBuildingId(), dto.getHouseId());
            if (Func.isNotEmpty(payReductionHouses)) {
                ids.addAll(payReductionHouses.stream().map(a -> a.getPayReductionId()).collect(Collectors.toList()));
            }
        }
        if (Func.isNotEmpty(ids)) {
            queryWrapper.in(PropertyPayReduction::getId, ids);
        }
        queryWrapper.eq(PropertyPayReduction::getParkId, dto.getParkId())
                .like(Func.isNotEmpty(dto.getCustomerName()), PropertyPayReduction::getCustomerName, dto.getCustomerName());
        IPage<PropertyPayReduction> page = this.page(Condition.getPage(dto), queryWrapper);
        IPage<PropertyPayReductionPageVo> result = new Page<>();
        Func.copy(page, result);
        List<PropertyPayReduction> list = page.getRecords();
        if (Func.isEmpty(list)) {
            return NestPage.of(result);
        }
        result.setRecords(list.stream().map(a -> {
            PropertyPayReductionPageVo vo = Func.copy(a, PropertyPayReductionPageVo.class);
            PmgBatParkInfo parkInfo = parkInfoService.getById(a.getParkId());
            if (Func.isNotEmpty(parkInfo)) {
                vo.setParkName(parkInfo.getParkName());
            }
            List<PropertyPayReductionDetail> detailList = iPropertyPayReductionDetailService.listByPayReductionId(a.getId());

            vo.setReductionDetail(detailList.stream().map(b -> {
                PropertyPayReductionPageVo.PropertyPayReductionDetailItemVo detailVo = Func.copy(b, PropertyPayReductionPageVo.PropertyPayReductionDetailItemVo.class);
                PropertyFeeStandard feeStandard = propertyFeeStandardService.getById(b.getPayFeeStandardId());
                if (Func.isNotEmpty(feeStandard)) {
                    detailVo.setPayFeeStandardName(feeStandard.getFeeName());
                }
                PropertyFeeStandard feeStandard2 = propertyFeeStandardService.getById(b.getReductionFeeStandardId());
                if (Func.isNotEmpty(feeStandard2)) {
                    detailVo.setReductionFeeStandardName(feeStandard2.getFeeName());
                }
                return detailVo;
            }).collect(Collectors.toList()));
            vo.setScope(iPropertyPayReductionHouseService.countByPayReductionId(a.getId()));
            return vo;
        }).collect(Collectors.toList()));
        return NestPage.of(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addOrUpdate(PropertyPayReductionAddDto dto) {
        PropertyPayReduction reduction = Func.copy(dto, PropertyPayReduction.class);
        LambdaQueryWrapper<PropertyPayReduction> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.ne(Func.isNotEmpty(dto.getId()), PropertyPayReduction::getId, dto.getId())
                .eq(PropertyPayReduction::getParkId, dto.getParkId())
                .eq(PropertyPayReduction::getReductionName, dto.getReductionName());
        if (count(queryWrapper) > 0) {
            throw new ServiceException("同一管理区不能出现减免名称同名");
        }
        if (Func.isNotEmpty(dto.getId())) {
            PropertyPayReduction oldDto = getById(dto.getId());
            if (Func.isEmpty(oldDto)) {
                throw new ServiceException("修改的数据不存在");
            }
            if (Func.isEmpty(oldDto.getReviewState()) || oldDto.getReviewState() != 0) {
                throw new ServiceException("只有状态'待审核'才能进行编辑");
            }

            reduction.setId(dto.getId());
            iPropertyPayReductionDetailService.removeByPayReductionId(dto.getId());
            iPropertyPayReductionHouseLogService.removeByPayReductionId(dto.getId());
            iPropertyPayReductionHouseService.removeByPayReductionId(dto.getId());
        }

        ContextUser user = AuthUtil.getUser();
        if (Func.isNotEmpty(user)) {
            if (Func.isNotEmpty(user.getCustomerManageId()) && user.getCustomerManageId() > 0) {
                reduction.setCustomerId(user.getCustomerManageId());
                //todo 设置客户名称
            }
            if (Func.isNotEmpty(user.getOrgUserId()) && user.getOrgUserId() > 0) {
                R<NestOrgUser> orgUserById = sysClient.getOrgUserById(user.getOrgUserId());
                if (Func.isEmpty(dto.getId()) && orgUserById.isSuccess() && Func.isNotEmpty(orgUserById.getData())) {
                    reduction.setOrgUserName(orgUserById.getData().getName());
                }
            }

        }
        if (Func.isNotEmpty(dto.getReductionTimeStart()) && Func.isNotEmpty(dto.getReductionTimeEnd())) {
            reduction.setIsOnTime(1);
        } else {
            reduction.setIsOnTime(0);
        }
        saveOrUpdate(reduction);
        List<PropertyHouses> allHouses = new ArrayList<>();

        for (PropertyPayReductionHouseLog item : dto.getPayReductionHouseList()) {
            item.setPayReductionId(reduction.getId());
            switch (SourceTypeEnum.matchCode(item.getType())) {
                case PARK:
                    List<PropertyHouses> houses1 = propertyHousesService.listByParkId(item.getSourceId());
                    if (Func.isNotEmpty(houses1)) {
                        allHouses.addAll(houses1);
                    }
                    break;
                case BUILDING:
                    List<PropertyHouses> houses2 = propertyHousesService.listByBuildingId(item.getSourceId());
                    if (Func.isNotEmpty(houses2)) {
                        allHouses.addAll(houses2);
                    }
                    break;
                case FLOOR:
                    List<PropertyHouses> houses3 = propertyHousesService.listByFoolNum(Func.toInt(item.getSourceId()));
                    if (Func.isNotEmpty(houses3)) {
                        allHouses.addAll(houses3);
                    }
                    break;
                case UNIT:
                    List<PropertyHouses> houses4 = propertyHousesService.listByUnitNum(Func.toStr(item.getSourceId()));
                    if (Func.isNotEmpty(houses4)) {
                        allHouses.addAll(houses4);
                    }
                    break;
                case HOUSE:
                    PropertyHouses byId = propertyHousesService.getById(item.getSourceId());
                    if (Func.isNotEmpty(byId)) {
                        allHouses.add(byId);
                    }
                    break;
                default:
                    break;
            }
        }
        if (Func.isNotEmpty(dto.getPayReductionHouseList())) {
            iPropertyPayReductionHouseLogService.saveBatch(dto.getPayReductionHouseList());
        }
        if (Func.isNotEmpty(allHouses)) {
            List<PropertyPayReductionHouse> pauReductionHouseList = allHouses.stream().map(a -> {
                PropertyPayReductionHouse payReductionHouse = Func.copy(a, PropertyPayReductionHouse.class);
                payReductionHouse.setId(null);
                payReductionHouse.setPayReductionId(reduction.getId());
                payReductionHouse.setHouseId(a.getId());
                if (Func.isNotEmpty(user)) {
                    if (Func.isNotEmpty(user.getCustomerManageId()) && user.getCustomerManageId() > 0) {
                        payReductionHouse.setCustomerId(user.getCustomerManageId());
                    }
                }
                return payReductionHouse;
            }).collect(Collectors.toList());
            if (Func.isNotEmpty(pauReductionHouseList)) {
                iPropertyPayReductionHouseService.saveBatch(pauReductionHouseList);
            }
        }
        for (PropertyPayReductionDetail item : dto.getPayReductionDetailList()) {
            item.setId(null);
            item.setParkId(dto.getParkId());
            if (Func.isNotEmpty(user)) {
                if (Func.isNotEmpty(user.getCustomerManageId()) && user.getCustomerManageId() > 0) {
                    item.setCustomerId(user.getCustomerManageId());
                }
            }
            item.setPayReductionId(reduction.getId());
            PropertyFeeStandard feeStandard1 = propertyFeeStandardService.getById(item.getPayFeeStandardId());
            if (Func.isNotEmpty(feeStandard1)) {
                item.setPayFeeItemId(feeStandard1.getFeeItemId());
            }
            PropertyFeeStandard feeStandard2 = propertyFeeStandardService.getById(item.getReductionFeeStandardId());
            if (Func.isNotEmpty(feeStandard2)) {
                item.setReductionFeeItemId(feeStandard2.getFeeItemId());
            }
        }
        if (Func.isNotEmpty(dto.getPayReductionDetailList())) {
            iPropertyPayReductionDetailService.saveBatch(dto.getPayReductionDetailList());
        }
        return true;
    }

    @Override
    public Boolean del(Long id) {
        PropertyPayReduction byId = getById(id);
        if (Func.isEmpty(byId)) {
            throw new ServiceException("数据已不存在!");
        }
        if (Func.isNotEmpty(byId.getReviewState())) {
            if (byId.getReviewState() == 1) {
                if (byId.getIsOnTime() == 0) {
                    throw new ServiceException("执行中的活动不能删除!");
                } else {
                    if (Func.isNotEmpty(byId.getReductionTimeEnd()) && byId.getReductionTimeEnd().getTime() > System.currentTimeMillis()) {
                        throw new ServiceException("活动时间未结束不能删除!");
                    }
                }
            } else if (byId.getReviewState() == 0) {
                throw new ServiceException(" 待审核数据不能删除!");
            }
        }
        return deleteLogic(Arrays.asList(id));
    }

    @Override
    public Boolean stop(Long id) {
        PropertyPayReduction byId = getById(id);
        if (Func.isEmpty(byId)) {
            throw new ServiceException("数据已不存在!");
        }
        if (Func.isEmpty(byId.getReviewState()) || byId.getReviewState() != 1) {
            throw new ServiceException("只有执行中的数据才能进行停用!");
        }
        byId.setReviewState(3);
        return updateById(byId);
    }

    @Override
    public Boolean audit(PropertyPayReductionAuditDto param) {
        PropertyPayReduction byId = getById(param.getId());
        if (Func.isEmpty(byId)) {
            throw new ServiceException("数据已不存在!");
        }
        if (Func.isNotEmpty(byId.getReviewState()) && byId.getReviewState() != 0) {
            throw new ServiceException("只有待审核的数据才能进行审核!");
        }
        byId.setReviewState(param.getReviewState());
        byId.setReviewRemark(param.getReviewRemark());
        byId.setReviewTime(new Date());
        ContextUser user = AuthUtil.getUser();
        if (Func.isNotEmpty(user)) {
            byId.setReviewUserId(user.getUserId());
            R<NestOrgUser> orgUserById = sysClient.getOrgUserById(user.getOrgUserId());
            if (orgUserById.isSuccess() && Func.isNotEmpty(orgUserById.getData())) {
                byId.setReviewUserName(orgUserById.getData().getName());
            }
        }
        return updateById(byId);
    }

    @Override
    public PropertyPayReductionDetailVo getDetailById(Long id) {
        PropertyPayReduction byId = getById(id);
        if (Func.isEmpty(byId)) {
            throw new ServiceException("数据已不存在!");
        }
        PropertyPayReductionDetailVo vo = Func.copy(byId, PropertyPayReductionDetailVo.class);
        PmgBatParkInfo parkInfo = parkInfoService.getById(byId.getParkId());
        if (Func.isNotEmpty(parkInfo)) {
            vo.setParkName(parkInfo.getParkName());
        }
        vo.setPayReductionHouseList(iPropertyPayReductionHouseLogService.listByPayReductionId(id).stream().map(a -> {
            PropertyPayReductionDetailVo.PropertyPayReductionHouseLogItemVo houseLogItemVo = Func.copy(a, PropertyPayReductionDetailVo.PropertyPayReductionHouseLogItemVo.class);
            switch (SourceTypeEnum.matchCode(houseLogItemVo.getType())) {
                case PARK:
                    PmgBatParkInfo parkInfo1 = parkInfoService.getById(houseLogItemVo.getSourceId());
                    if (Func.isNotEmpty(parkInfo1)) {
                        houseLogItemVo.setSourceName(parkInfo1.getParkName());
                    }
                    break;
                case BUILDING:
                    PropertyBuildings buildings = propertyBuildingsService.getById(houseLogItemVo.getSourceId());
                    if (Func.isNotEmpty(buildings)) {
                        houseLogItemVo.setSourceName(buildings.getBuildingName());
                    }
                    break;
                case FLOOR:
                    //todo 楼层有问题,楼层没建立数据id
                    break;
                case UNIT:
                    PropertyBuildingUnit buildingUnit = propertyBuildingUnitService.getById(houseLogItemVo.getSourceId());
                    if (Func.isNotEmpty(buildingUnit)) {
                        houseLogItemVo.setSourceName(buildingUnit.getUnitNum());
                    }
                    break;
                case HOUSE:
                    PropertyHouses houses = propertyHousesService.getById(houseLogItemVo.getSourceId());
                    if (Func.isNotEmpty(houses)) {
                        houseLogItemVo.setSourceName(houses.getHouseName());
                    }
                    break;
                default:
                    break;
            }
            return houseLogItemVo;
        }).collect(Collectors.toList()));
        vo.setPayReductionDetailList(iPropertyPayReductionDetailService.listByPayReductionId(id).stream().map(a -> {
            PropertyPayReductionDetailVo.PropertyPayReductionDetailItemVo detailItemVo = Func.copy(a, PropertyPayReductionDetailVo.PropertyPayReductionDetailItemVo.class);
            PropertyFeeStandard feeStandard1 = propertyFeeStandardService.getById(a.getPayFeeStandardId());
            if (Func.isNotEmpty(feeStandard1)) {
                detailItemVo.setPayFeeStandardName(feeStandard1.getFeeName());
            }
            PropertyFeeStandard feeStandard2 = propertyFeeStandardService.getById(a.getReductionFeeStandardId());
            if (Func.isNotEmpty(feeStandard2)) {
                detailItemVo.setReductionFeeStandardName(feeStandard2.getFeeName());
            }
            return detailItemVo;
        }).collect(Collectors.toList()));
        return vo;
    }

    @Override
    public PropertyPayReductionAuditVo getAuditById(Long id) {
        PropertyPayReduction byId = getById(id);
        if (Func.isEmpty(byId)) {
            throw new ServiceException("数据已不存在!");
        }
        PropertyPayReductionAuditVo vo = Func.copy(byId, PropertyPayReductionAuditVo.class);
        PmgBatParkInfo parkInfo = parkInfoService.getById(byId.getParkId());
        if (Func.isNotEmpty(parkInfo)) {
            vo.setParkName(parkInfo.getParkName());
        }
        List<PropertyPayReductionHouse> propertyPayReductionHouses = iPropertyPayReductionHouseService.listByPayReductionId(id);
        vo.setPayReductionHouseItem(propertyPayReductionHouses.stream().map(a -> {
            PropertyPayReductionAuditVo.PropertyPayReductionHouseItem houseItem = new PropertyPayReductionAuditVo.PropertyPayReductionHouseItem();
            PropertyHouses houses = propertyHousesService.getById(a.getHouseId());
            if (Func.isNotEmpty(houses)) {
                Func.copy(houses, houseItem);
                PropertyBuildings buildings = propertyBuildingsService.getById(houses.getBuildingId());
                if (Func.isNotEmpty(buildings)) {
                    houseItem.setBuildingName(buildings.getBuildingName());
                }
            }
            return houseItem;
        }).collect(Collectors.toList()));

        List<PropertyPayReductionDetail> propertyPayReductionDetails = iPropertyPayReductionDetailService.listByPayReductionId(id);
        vo.setPayReductionDetailItem(propertyPayReductionDetails.stream().map(a -> {
                    PropertyPayReductionAuditVo.PropertyPayReductionDetailItem detailItem = Func.copy(a, PropertyPayReductionAuditVo.PropertyPayReductionDetailItem.class);
                    PropertyFeeStandard feeStandard1 = propertyFeeStandardService.getById(a.getPayFeeStandardId());
                    if (Func.isNotEmpty(feeStandard1)) {
                        detailItem.setPayFeeStandardName(feeStandard1.getFeeName());
                    }
                    PropertyFeeStandard feeStandard2 = propertyFeeStandardService.getById(a.getReductionFeeStandardId());
                    if (Func.isNotEmpty(feeStandard2)) {
                        detailItem.setReductionFeeStandardName(feeStandard2.getFeeName());
                    }
                    return detailItem;
                }).collect(Collectors.toList())
        );
        return vo;
    }

    @Override
    public Boolean extendTime(PropertyPayReductionExtendTimeDto param) {
        PropertyPayReduction byId = getById(param.getId());
        if (Func.isEmpty(byId)) {
            throw new ServiceException("数据已不存在!");
        }
        if(byId.getReviewState()!=1){
            throw new ServiceException("执行中的活动才能延长活动时间!");
        }
        if(param.getReductionTimeEnd().getTime()<=byId.getReductionTimeEnd().getTime()){
            throw new ServiceException("选择的结束时间需大于原先已设置的活动结束时间!");
        }
        byId.setReductionTimeEnd(param.getReductionTimeEnd());
        return updateById(byId);
    }

    @Override
    public List<PropertyPayReduction> listByParkId(Long parkId) {
        LambdaQueryWrapper<PropertyPayReduction> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PropertyPayReduction::getParkId,parkId)
                .eq(PropertyPayReduction::getReviewState,1)
                .orderByDesc(PropertyPayReduction::getSeq);
        return list(queryWrapper);
    }

    @Override
    @RedisLock(value = CacheNames.LOCK_PAY_REDUCTION_SORT,param ="#param.parkId",leaseTime=-1)
    @Transactional(rollbackFor = Exception.class)
    public Boolean sort(PropertyPayReductionSortDto param) {
        List<PropertyPayReduction> upDateList=new ArrayList<>();
        int seq=0;
        for (Long id:param.getIds()) {
            PropertyPayReduction byId = getById(id);
            if(Func.isNotEmpty(byId)){
                if(!Func.equalsSafe(param.getParkId(),byId.getParkId())){
                    throw new ServiceException("请选择相同的园区数据排序!");
                }
                if(byId.getReviewState()!=1){
                    continue;
                }
                byId.setSeq(seq);
                seq++;
                upDateList.add(byId);
            }
        }
        if(Func.isEmpty(upDateList)){
            return false;
        }
        return  updateBatchById(upDateList);
    }

    @Override
    public PropertyPayReductionVo getPayReduction(Long houseId, Long unitPrice, Long totalPrice, Long feeStandardId, Date paymentTime, Integer monthNum, Date billStartTime, Date billEndTime, boolean isArrears) {
        PropertyPayReductionVo vo=new PropertyPayReductionVo();
        List<PropertyPayReductionHouse> payReductionHouses = iPropertyPayReductionHouseService.listByHouseId(houseId);
        if(Func.isEmpty(payReductionHouses)){
            return vo;
        }
        LambdaQueryWrapper<PropertyPayReduction> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PropertyPayReduction::getReviewState,1)
                .in(PropertyPayReduction::getId,payReductionHouses.stream().map(a->a.getPayReductionId()).collect(Collectors.toList()))
                .and(Func.isNotEmpty(paymentTime),wrapper -> wrapper
                        .or(item -> item
                                .eq(PropertyPayReduction::getIsOnTime,1)
                                .ge(PropertyPayReduction::getReductionTimeEnd, paymentTime)
                                .le(PropertyPayReduction::getReductionTimeStart,paymentTime))
                        .or(item -> item
                                .eq(PropertyPayReduction::getIsOnTime,0)))
                .orderByDesc(PropertyPayReduction::getSeq);
        List<PropertyPayReduction> list = list(queryWrapper);
        for (PropertyPayReduction item:list) {
            //需要缴清费,但是欠费
            if(Func.isNotEmpty(item.getIsPaidFee())&&item.getIsPaidFee()==1&&isArrears){
                continue;
                /*//查询房源是否有未结清的账单,有的话就不满足
                if(propertyBillService.countByPayStatusAndHouseId(PayStatusEnum.ARREARS,houseId)>0){
                    continue;
                }*/

            }
            if(buildPropertyPayReductionVo( vo, item, houseId,  unitPrice,  totalPrice,  feeStandardId,  monthNum,  billStartTime,  billEndTime)){
                break;
            }
        }
        log.info("缴费减免活动,房源id:{},单价{},总价{},收费标准id{},支付时间{},月数{},账单开始时间{},账单结算时间{},账单减免详情{}"
                ,houseId,unitPrice,totalPrice,feeStandardId,paymentTime,monthNum,billStartTime,billEndTime,vo);
        return vo;
    }

    @Override
    public List<PropertyReductionListVo> listByHouseId(Long houseId) {
        List<PropertyPayReductionHouse> payReductionHouses = iPropertyPayReductionHouseService.listByHouseId(houseId);
        if(Func.isNotEmpty(payReductionHouses)){
            Date now = new Date();
            LambdaQueryWrapper<PropertyPayReduction> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(PropertyPayReduction::getReviewState,1)
                    .in(PropertyPayReduction::getId,payReductionHouses.stream().map(a->a.getPayReductionId()).collect(Collectors.toList()))
                    .and(Func.isNotEmpty(now),wrapper -> wrapper
                            .or(item -> item
                                    .eq(PropertyPayReduction::getIsOnTime,1)
                                    .ge(PropertyPayReduction::getReductionTimeEnd, now)
                                    .le(PropertyPayReduction::getReductionTimeStart,now))
                            .or(item -> item
                                    .eq(PropertyPayReduction::getIsOnTime,0)))
                    .orderByDesc(PropertyPayReduction::getSeq);
            List<PropertyPayReduction> list = list(queryWrapper);
            return Func.copy(list,PropertyReductionListVo.class);
        }
        return Collections.emptyList();
    }

    private boolean  buildPropertyPayReductionVo(PropertyPayReductionVo vo,PropertyPayReduction payReduction,Long houseId, Long unitPrice, Long totalPrice, Long feeStandardId, Integer monthNum, Date billStartTime, Date billEndTime){
        List<PropertyPayReductionVo.FeeStandardDetail> feeStandardDetailLis=new ArrayList<>();
        Long totalReductionPrice=0L;
        boolean flag=false;
        List<PropertyPayReductionVo.ReductionPriceDetail> reductionPriceDetailList=new ArrayList<>();
        List<PropertyPayReductionDetail> payReductionDetails = iPropertyPayReductionDetailService.listByPayReductionId(payReduction.getId());
        if(Func.isEmpty(payReductionDetails)){
            return false;
        }
        if(Func.isEmpty(payReduction.getReductionType())){
            return false;
        }
        if(Func.isEmpty(payReduction.getReductionDetailType())){
            return false;
        }

        for (PropertyPayReductionDetail item:payReductionDetails) {
            if(Func.isEmpty(item.getItemType())||Func.isEmpty(item.getReductionAmt())||Func.isEmpty(item.getPayFeeStandardId())){
                log.info("减免活动配置错误PropertyPayReductionDetail->id{}",item.getId());
                continue;
            }
            //交满指定月数费用
            if(payReduction.getReductionType()==1){
                //缴的月份跟收费标准符合才继续
                if(Func.isEmpty(item.getPayMonthNum())&&
                        item.getPayMonthNum()<=monthNum&&Func.equalsSafe(feeStandardId,item.getPayFeeStandardId())){
                    //指定减免月数
                    if(payReduction.getReductionDetailType()==1){
                        if(Func.isNotEmpty(item.getReductionFeeStandardId())&&item.getItemType()==3){
                            PropertyPayReductionVo.FeeStandardDetail feeStandardDetail=new PropertyPayReductionVo.FeeStandardDetail();
                            feeStandardDetail.setMonthNum(item.getReductionAmt());
                            feeStandardDetail.setFeeStandardId(item.getReductionFeeStandardId());
                            feeStandardDetail.setDetail(item);
                            feeStandardDetailLis.add(feeStandardDetail);
                            flag=true;
                        }else{
                            log.info("减免活动配置错误PropertyPayReductionDetail->id{}",item.getId());
                        }
                        //2减免单价
                    }else if(payReduction.getReductionDetailType()==2&&Func.isNotEmpty(unitPrice)){
                        if(item.getItemType()==1){
                            Long reductionPrice=totalPrice*item.getReductionAmt()/unitPrice;
                            //减免掉的总金额
                            totalReductionPrice=totalReductionPrice+reductionPrice;
                            PropertyPayReductionVo.ReductionPriceDetail reductionPriceDetail=new PropertyPayReductionVo.ReductionPriceDetail();
                            reductionPriceDetail.setReductionPrice(reductionPrice);
                            reductionPriceDetail.setDetail(item);
                            reductionPriceDetailList.add(reductionPriceDetail);
                            flag=true;
                        }else if(item.getItemType()==2){
                            if(item.getReductionAmt()<=100){
                                Long reductionPrice=totalPrice-(item.getReductionAmt()*totalPrice/100);
                                totalReductionPrice=totalReductionPrice+reductionPrice;
                                PropertyPayReductionVo.ReductionPriceDetail reductionPriceDetail=new PropertyPayReductionVo.ReductionPriceDetail();
                                reductionPriceDetail.setReductionPrice(reductionPrice);
                                reductionPriceDetail.setDetail(item);
                                reductionPriceDetailList.add(reductionPriceDetail);
                                flag=true;
                            }else {
                                log.info("减免活动配置错误PropertyPayReductionDetail->id{}",item.getId());
                            }
                        }
                    }

                }else{
                    continue;
                }
            }
            if(payReduction.getReductionType()==2){
                //缴的区间在减免的区间内跟收费标准符合才继续
                if(Func.isNotEmpty(item.getPayTimeEnd())&&Func.isNotEmpty(item.getPayTimeStart())&&
                        Func.isNotEmpty(billStartTime)&&billStartTime.getTime()<=item.getPayTimeEnd().getTime()&&billStartTime.getTime()>=item.getPayTimeStart().getTime()&&
                        Func.isNotEmpty(billEndTime)&&billEndTime.getTime()<=item.getPayTimeEnd().getTime()&&billEndTime.getTime()>=item.getPayTimeStart().getTime()&&
                        Func.equalsSafe(feeStandardId,item.getPayFeeStandardId())){

                    //指定减免月数
                    if(payReduction.getReductionDetailType()==1){
                        if(Func.isNotEmpty(item.getReductionFeeStandardId())&&item.getItemType()==3){
                            PropertyPayReductionVo.FeeStandardDetail feeStandardDetail=new PropertyPayReductionVo.FeeStandardDetail();
                            feeStandardDetail.setMonthNum(item.getReductionAmt());
                            feeStandardDetail.setFeeStandardId(item.getReductionFeeStandardId());
                            feeStandardDetail.setDetail(item);
                            feeStandardDetailLis.add(feeStandardDetail);
                            flag=true;
                        }else{
                            log.info("减免活动配置错误PropertyPayReductionDetail->id{}",item.getId());
                        }
                        //2减免单价
                    }else if(payReduction.getReductionDetailType()==2&&Func.isNotEmpty(unitPrice)){
                        if(item.getItemType()==1){
                            //减免的单价如果大于单价就
                            Long reductionPrice=item.getReductionAmt()>unitPrice?totalPrice:totalPrice*item.getReductionAmt()/unitPrice;
                            //减免掉的总金额
                            totalReductionPrice=totalReductionPrice+reductionPrice;
                            PropertyPayReductionVo.ReductionPriceDetail reductionPriceDetail=new PropertyPayReductionVo.ReductionPriceDetail();
                            reductionPriceDetail.setReductionPrice(reductionPrice);
                            reductionPriceDetail.setDetail(item);
                            reductionPriceDetailList.add(reductionPriceDetail);
                            flag=true;
                        }else if(item.getItemType()==2){
                            if(item.getReductionAmt()<=100){
                                Long reductionPrice=totalPrice-(item.getReductionAmt()*totalPrice/100);
                                totalReductionPrice=totalReductionPrice+reductionPrice;
                                PropertyPayReductionVo.ReductionPriceDetail reductionPriceDetail=new PropertyPayReductionVo.ReductionPriceDetail();
                                reductionPriceDetail.setReductionPrice(reductionPrice);
                                reductionPriceDetail.setDetail(item);
                                reductionPriceDetailList.add(reductionPriceDetail);
                                flag=true;
                            }else {
                                log.info("减免活动配置错误PropertyPayReductionDetail->id{}",item.getId());
                            }
                        }
                    }

                }else{
                    continue;
                }
            }
        }
        vo.setPayReduction(payReduction);
        vo.setFeeStandardDetailList(feeStandardDetailLis);
        vo.setTotalReductionPrice(totalReductionPrice);
        vo.setReductionPriceDetailList(reductionPriceDetailList);

        return flag;
    }
}
