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.yuchen.saas.manage.system.api.entity.NestOrgUser;
import com.yuchen.saas.manage.system.api.feign.ISysClient;
import com.yuchen.saas.park.api.dto.property.PropertyDirectReductionAddDto;
import com.yuchen.saas.park.api.dto.property.PropertyDirectReductionAuditDto;
import com.yuchen.saas.park.api.dto.property.PropertyDirectReductionQueryDto;
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.SourceTypeEnum;
import com.yuchen.saas.park.api.vo.property.*;
import com.yuchen.saas.park.service.mapper.property.PropertyDirectReductionMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.property.*;
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.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.nest.springwrap.core.tool.utils.StringPool;
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.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 减免活动-直接减免 服务实现类
 * </p>
 *
 * @author cxj
 * @since 2023-12-19
 */
@Service
@Slf4j
public class PropertyDirectReductionServiceImpl extends BaseServiceImpl<PropertyDirectReductionMapper, PropertyDirectReduction> implements IPropertyDirectReductionService {
    @Resource
    private ISysClient sysClient;

    @Resource
    private IPropertyDirectReductionHouseLogService iPropertyDirectReductionHouseLogService;

    @Resource
    private IPropertyDirectReductionHouseService iPropertyDirectReductionHouseService;

    @Resource
    private IPropertyDirectReductionDetailService iPropertyDirectReductionDetailService;

    @Resource
    private PropertyHousesService propertyHousesService;

    @Resource
    private PropertyFeeStandardService propertyFeeStandardService;

    @Resource
    private PmgBatParkInfoService parkInfoService;

    @Resource
    private PropertyBuildingsService propertyBuildingsService;

    @Resource
    private PropertyBuildingUnitService propertyBuildingUnitService;

    @Resource
    private IPropertyPayReductionService iPropertyPayReductionService;

    @Override
    public NestPage<PropertyDirectReductionPageVo> getPage(PropertyDirectReductionQueryDto dto) {
        IPage<PropertyDirectReductionPageVo> result = new Page<>();
        LambdaQueryWrapper<PropertyDirectReduction> queryWrapper = Wrappers.lambdaQuery();
        List<Long> ids = new ArrayList<>();
        if (Func.isNotEmpty(dto.getFeeStandardId()) || Func.isNotEmpty(dto.getFeeItemId())) {
            List<PropertyDirectReductionDetail> propertyDirectReductionDetails = iPropertyDirectReductionDetailService.listByQuery(dto.getFeeStandardId(), dto.getFeeItemId());
            if(Func.isEmpty(propertyDirectReductionDetails)){
                return NestPage.of(result);
            }
            ids.addAll(propertyDirectReductionDetails.stream().map(a -> a.getDirectReductionId()).collect(Collectors.toList()));
        }
        if (Func.isNotEmpty(dto.getBuildingId()) || Func.isNotEmpty(dto.getHouseId())) {
            List<PropertyDirectReductionHouse> propertyDirectReductionHouses = iPropertyDirectReductionHouseService.listByQuery(dto.getBuildingId(), dto.getHouseId());
            if(Func.isEmpty(propertyDirectReductionHouses)){
                return NestPage.of(result);
            }
            ids.addAll(propertyDirectReductionHouses.stream().map(a -> a.getDirectReductionId()).collect(Collectors.toList()));
        }
        if (Func.isNotEmpty(ids)) {
            queryWrapper.in(PropertyDirectReduction::getId, ids);
        }
        queryWrapper.eq(PropertyDirectReduction::getParkId, dto.getParkId())
                .like(Func.isNotEmpty(dto.getCustomerName()), PropertyDirectReduction::getCustomerName, dto.getCustomerName());
        IPage<PropertyDirectReduction> page = this.page(Condition.getPage(dto), queryWrapper);

        Func.copy(page, result);
        List<PropertyDirectReduction> list = page.getRecords();
        if (Func.isEmpty(list)) {
            return NestPage.of(result);
        }
        result.setRecords(list.stream().map(a -> {
            PropertyDirectReductionPageVo vo = Func.copy(a, PropertyDirectReductionPageVo.class);
            PmgBatParkInfo parkInfo = parkInfoService.getById(a.getParkId());
            if (Func.isNotEmpty(parkInfo)) {
                vo.setParkName(parkInfo.getParkName());
            }
            List<PropertyDirectReductionDetail> detailList = iPropertyDirectReductionDetailService.listByDirectReductionId(a.getId());

            vo.setReductionDetail(detailList.stream().map(b -> {
                PropertyDirectReductionPageVo.PropertyDirectReductionItemVo detailVo = Func.copy(b, PropertyDirectReductionPageVo.PropertyDirectReductionItemVo.class);
                PropertyFeeStandard feeStandard = propertyFeeStandardService.getById(b.getFeeStandardId());
                if (Func.isNotEmpty(feeStandard)) {
                    detailVo.setFeeStandardName(feeStandard.getFeeName());
                }
                return detailVo;
            }).collect(Collectors.toList()));
            vo.setScope(iPropertyDirectReductionHouseService.countByDirectReductionId(a.getId()));

            return vo;
        }).collect(Collectors.toList()));

        return NestPage.of(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addOrUpdate(PropertyDirectReductionAddDto dto) {
        PropertyDirectReduction reduction = Func.copy(dto, PropertyDirectReduction.class);
        LambdaQueryWrapper<PropertyDirectReduction> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.ne(Func.isNotEmpty(dto.getId()), PropertyDirectReduction::getId, dto.getId())
                .eq(PropertyDirectReduction::getParkId, dto.getParkId())
                .eq(PropertyDirectReduction::getReductionName, dto.getReductionName());
        if (count(queryWrapper) > 0) {
            throw new ServiceException("同一管理区不能出现减免名称同名");
        }
        if (Func.isNotEmpty(dto.getId())) {
            PropertyDirectReduction 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());
            iPropertyDirectReductionHouseLogService.removeByDirectReductionId(dto.getId());
            iPropertyDirectReductionDetailService.removeByDirectReductionId(dto.getId());
            iPropertyDirectReductionHouseService.removeByDirectReductionId(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 (PropertyDirectReductionHouseLog item : dto.getDirectReductionHouseList()) {
            item.setDirectReductionId(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:
                    //todo 楼层有问题,楼层没建立数据id
                    List<PropertyHouses> houses3 = propertyHousesService.listByFoolNum(Func.toInt(item.getSourceId()));
                    if (Func.isNotEmpty(houses3)) {
                        allHouses.addAll(houses3);
                    }
                    break;
                case UNIT:
                    PropertyBuildingUnit buildingUnit = propertyBuildingUnitService.getById(item.getSourceId());
                    if (Func.isNotEmpty(buildingUnit)) {
                        List<PropertyHouses> houses4 = propertyHousesService.listByUnitNum(buildingUnit.getUnitNum());
                        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.getDirectReductionHouseList())) {
            iPropertyDirectReductionHouseLogService.saveBatch(dto.getDirectReductionHouseList());
        }
        if (Func.isNotEmpty(allHouses)) {
            List<PropertyDirectReductionHouse> directReductionHouseList = allHouses.stream().map(a -> {
                PropertyDirectReductionHouse directReductionHouse = Func.copy(a, PropertyDirectReductionHouse.class);
                directReductionHouse.setId(null);
                directReductionHouse.setDirectReductionId(reduction.getId());
                directReductionHouse.setHouseId(a.getId());
                if (Func.isNotEmpty(user)) {
                    if (Func.isNotEmpty(user.getCustomerManageId()) && user.getCustomerManageId() > 0) {
                        directReductionHouse.setCustomerId(user.getCustomerManageId());
                    }
                }
                return directReductionHouse;
            }).collect(Collectors.toList());
            if (Func.isNotEmpty(directReductionHouseList)) {
                iPropertyDirectReductionHouseService.saveBatch(directReductionHouseList);
            }
        }
        for (PropertyDirectReductionDetail item : dto.getDirectReductionDetailList()) {
            item.setId(null);
            item.setParkId(dto.getParkId());
            if (Func.isNotEmpty(user)) {
                if (Func.isNotEmpty(user.getCustomerManageId()) && user.getCustomerManageId() > 0) {
                    item.setCustomerId(user.getCustomerManageId());
                }
            }
            item.setDirectReductionId(reduction.getId());
            PropertyFeeStandard feeStandard = propertyFeeStandardService.getById(item.getFeeStandardId());
            if (Func.isNotEmpty(feeStandard)) {
                item.setFeeItemId(feeStandard.getFeeItemId());
            }
        }
        if (Func.isNotEmpty(dto.getDirectReductionDetailList())) {
            iPropertyDirectReductionDetailService.saveBatch(dto.getDirectReductionDetailList());
        }
        return true;
    }

    @Override
    public Boolean del(Long id) {
        PropertyDirectReduction 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) {
        PropertyDirectReduction 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(PropertyDirectReductionAuditDto param) {
        PropertyDirectReduction 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.setReductionName(orgUserById.getData().getName());
            }
        }
        return updateById(byId);
    }

    @Override
    public PropertyDirectReductionDetailVo getDetailById(Long id) {
        PropertyDirectReduction byId = getById(id);
        if (Func.isEmpty(byId)) {
            throw new ServiceException("数据已不存在!");
        }
        PropertyDirectReductionDetailVo vo = Func.copy(byId, PropertyDirectReductionDetailVo.class);
        PmgBatParkInfo parkInfo = parkInfoService.getById(byId.getParkId());
        if (Func.isNotEmpty(parkInfo)) {
            vo.setParkName(parkInfo.getParkName());
        }
        vo.setDirectReductionHouseList(iPropertyDirectReductionHouseLogService.listByDirectReductionId(id).stream().map(a -> {
            PropertyDirectReductionDetailVo.PropertyDirectReductionHouseLogItemVo houseLogItemVo = Func.copy(a, PropertyDirectReductionDetailVo.PropertyDirectReductionHouseLogItemVo.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.setDirectReductionDetailList(iPropertyDirectReductionDetailService.listByDirectReductionId(id).stream().map(a -> {
            PropertyDirectReductionDetailVo.PropertyDirectReductionDetailItemVo detailItemVo = Func.copy(a, PropertyDirectReductionDetailVo.PropertyDirectReductionDetailItemVo.class);
            PropertyFeeStandard feeStandard = propertyFeeStandardService.getById(a.getFeeStandardId());
            if (Func.isNotEmpty(feeStandard)) {
                detailItemVo.setFeeStandardName(feeStandard.getFeeName());
            }
            return detailItemVo;
        }).collect(Collectors.toList()));
        return vo;
    }

    @Override
    public PropertyDirectReductionAuditVo getAuditById(Long id) {
        PropertyDirectReduction byId = getById(id);
        if (Func.isEmpty(byId)) {
            throw new ServiceException("数据已不存在!");
        }
        PropertyDirectReductionAuditVo vo = Func.copy(byId, PropertyDirectReductionAuditVo.class);
        PmgBatParkInfo parkInfo = parkInfoService.getById(byId.getParkId());
        if (Func.isNotEmpty(parkInfo)) {
            vo.setParkName(parkInfo.getParkName());
        }
        List<PropertyDirectReductionHouse> propertyDirectReductionHouses = iPropertyDirectReductionHouseService.listByDirectReductionId(id);
        vo.setDirectReductionHouseItem(propertyDirectReductionHouses.stream().map(a -> {
            PropertyDirectReductionAuditVo.PropertyDirectReductionHouseItem houseItem = new PropertyDirectReductionAuditVo.PropertyDirectReductionHouseItem();
            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<PropertyDirectReductionDetail> propertyDirectReductionDetails = iPropertyDirectReductionDetailService.listByDirectReductionId(id);
        vo.setDirectReductionDetailItem(propertyDirectReductionDetails.stream().map(a -> {
                    PropertyDirectReductionAuditVo.PropertyDirectReductionDetailItem detailItem = Func.copy(a, PropertyDirectReductionAuditVo.PropertyDirectReductionDetailItem.class);
                    PropertyFeeStandard feeStandard = propertyFeeStandardService.getById(a.getFeeStandardId());
                    if (Func.isNotEmpty(feeStandard)) {
                        detailItem.setFeeStandardName(feeStandard.getFeeName());
                    }
                    return detailItem;
                }).collect(Collectors.toList())
        );
        return vo;
    }

    @Override
    public PropertyDirectReductionVo getPayReduction(Long houseId, Long unitPrice, Long totalPrice, Long feeStandardId, Date paymentTime, Integer monthNum, Date billStartTime, Date billEndTime) {
        PropertyDirectReductionVo vo=new PropertyDirectReductionVo();
        List<PropertyDirectReductionHouse> directReductionHouses = iPropertyDirectReductionHouseService.listByHouseId(houseId);
        if(Func.isEmpty(directReductionHouses)){
            return vo;
        }
        LambdaQueryWrapper<PropertyDirectReduction> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PropertyDirectReduction::getReviewState,1)
                .in(PropertyDirectReduction::getId,directReductionHouses.stream().map(a->a.getDirectReductionId()).collect(Collectors.toList()))
                .orderByDesc(PropertyDirectReduction::getCreateTime);
        List<PropertyDirectReduction> list = list(queryWrapper);
        for (PropertyDirectReduction item:list) {
            buildPropertyDirectReductionVo( vo, item, houseId,  unitPrice,  totalPrice,  feeStandardId,  monthNum,  billStartTime,  billEndTime);
        }
        log.info("缴费减免活动,房源id:{},单价{},总价{},收费标准id{},支付时间{},月数{},账单开始时间{},账单结算时间{},账单减免详情{}"
                ,houseId,unitPrice,totalPrice,feeStandardId,paymentTime,monthNum,billStartTime,billEndTime,vo);
        return vo;
    }

    @Override
    public PropertyReductionVo getAllReduction(Long houseId, Long unitPrice, Long totalPrice, Long feeStandardId, Date paymentTime, Integer monthNum, Date billStartTime, Date billEndTime,boolean isArrears) {
        PropertyDirectReductionVo directReductionVo=getPayReduction( houseId,  unitPrice,  totalPrice,  feeStandardId,  paymentTime,  monthNum,  billStartTime,  billEndTime);
        PropertyPayReductionVo payReduction = iPropertyPayReductionService.getPayReduction(houseId, unitPrice, totalPrice,
                feeStandardId, paymentTime, monthNum, billStartTime, billEndTime, isArrears);
        PropertyReductionVo vo=new PropertyReductionVo();
        vo.setTotalReductionPrice(payReduction.getTotalReductionPrice()+directReductionVo.getTotalReductionPrice());
        vo.setDirectReductionVo(directReductionVo);
        vo.setPayReductionVo(payReduction);
        vo.setFeeStandardDetailList(payReduction.getFeeStandardDetailList());
        return vo;
    }

    @Override
    public List<PropertyReductionListVo> listByHouseId(Long houseId) {
        List<PropertyReductionListVo> result=new ArrayList<>();
        List<PropertyDirectReductionHouse> directReductionHouses = iPropertyDirectReductionHouseService.listByHouseId(houseId);
        if(Func.isNotEmpty(directReductionHouses)){
            LambdaQueryWrapper<PropertyDirectReduction> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(PropertyDirectReduction::getReviewState,1)
                    .in(PropertyDirectReduction::getId,directReductionHouses.stream().map(a->a.getDirectReductionId()).collect(Collectors.toList()))
                    .orderByDesc(PropertyDirectReduction::getCreateTime);
            List<PropertyDirectReduction> list = list(queryWrapper);
            List<PropertyReductionListVo> reductionListVos=Func.copy(list,PropertyReductionListVo.class);
            result.addAll(reductionListVos);
        }
        List<PropertyReductionListVo> reductionList = iPropertyPayReductionService.listByHouseId(houseId);
        if(Func.isNotEmpty(reductionList)){
            result.addAll(reductionList);
        }
        return result;
    }

    private boolean  buildPropertyDirectReductionVo(PropertyDirectReductionVo vo,PropertyDirectReduction directReduction,Long houseId, Long unitPrice, Long totalPrice, Long feeStandardId, Integer monthNum, Date billStartTime, Date billEndTime) {
        Long itemReductionPrice = 0L;
        PropertyFeeStandard feeStandard =null;
        if (Func.isEmpty(directReduction.getReductionType())) {
            log.info("减免活动配置错误PropertyDirectReduction->id{}", directReduction.getId());
            return false;
        }
        //前置校验下,按单价减免,有减免时间的话,如果账单不是跟设置的时间一样的话,那就不符合减免活动规则
        if (directReduction.getReductionType() == 1&&Func.isNotEmpty(directReduction.getIsOnTime()) && directReduction.getIsOnTime() == 1) {
            if (Func.isEmpty(directReduction.getReductionTimeStart()) || Func.isEmpty(directReduction.getReductionTimeEnd())) {
                log.info("减免活动配置错误PropertyDirectReduction->id{}", directReduction.getId());
                return false;
            }
            feeStandard = propertyFeeStandardService.getById(feeStandardId);
            if(Func.isEmpty(feeStandard)){
                log.info("收费标准数据错误->id{}", feeStandardId);
                return false;
            }
            if(Func.isNotEmpty(feeStandard.getFeeMark())&&feeStandard.getFeeMark()!=1){
                if(!Func.equalsSafe(DateUtil.format(billStartTime,DateUtil.PATTERN_DATE),DateUtil.format(directReduction.getReductionTimeStart(),DateUtil.PATTERN_DATE))){
                    return false;
                }
            }

        }

        List<PropertyDirectReductionDetail> directReductionDetails = iPropertyDirectReductionDetailService.listByDirectReductionIdAndFeeStandardId(directReduction.getId(), feeStandardId);
        if (Func.isEmpty(directReductionDetails)) {
            //减免活动没匹配的明细
            return false;
        }
        List<PropertyDirectReductionVo.ReductionPriceDetail> reductionPriceDetailList=new ArrayList<>();

        for (PropertyDirectReductionDetail item : directReductionDetails) {
            if (Func.isEmpty(item.getItemType()) || Func.isEmpty(item.getReductionAmt()) || Func.isEmpty(item.getFeeStandardId())) {
                log.info("减免活动配置错误PropertyDirectReductionDetail->id{}", item.getId());
                continue;
            }
            //1按单价减免
            if (directReduction.getReductionType() == 1) {
                if(Func.isEmpty(unitPrice)){
                    log.info("账单没有单价,减免活动配置错误PropertyDirectReductionDetail->id{},feeStandardId->{}", item.getId(),feeStandardId);
                    continue;
                }
                //有设置指定减免时间
                if (Func.isNotEmpty(directReduction.getIsOnTime()) && directReduction.getIsOnTime() == 1) {
                    //减免的天数
                    Long  dayCoincidence = DateUtil.getDayCoincidence(billStartTime, billEndTime, directReduction.getReductionTimeStart(), directReduction.getReductionTimeStart());
                    //减免的单价
                    Long reductionUnitPrice=0L;
                    if(item.getItemType()==1){
                        reductionUnitPrice=item.getReductionAmt()>unitPrice?unitPrice:item.getReductionAmt();
                    }else if(item.getItemType()==2){
                        if(item.getReductionAmt()<=100){
                             reductionUnitPrice=unitPrice-(item.getReductionAmt()*unitPrice/100);
                        }else {
                            log.info("减免活动配置错误PropertyPayReductionDetail->id{}",item.getId());
                        }
                    }
                    Long reductionPrice=dayCoincidence*reductionUnitPrice;
                    itemReductionPrice=itemReductionPrice+reductionPrice;
                    PropertyDirectReductionVo.ReductionPriceDetail reductionPriceDetail=new PropertyDirectReductionVo.ReductionPriceDetail();
                    reductionPriceDetail.setReductionPrice(reductionPrice);
                    reductionPriceDetail.setDetail(item);
                    reductionPriceDetailList.add(reductionPriceDetail);
                }else{
                    Long reductionPrice=0L;
                    if(item.getItemType()==1){
                         reductionPrice=item.getReductionAmt()>unitPrice?totalPrice:totalPrice*item.getReductionAmt()/unitPrice;

                    } else if(item.getItemType()==2){
                         reductionPrice=totalPrice-(item.getReductionAmt()*totalPrice/100);
                    }
                    itemReductionPrice=itemReductionPrice+reductionPrice;
                    PropertyDirectReductionVo.ReductionPriceDetail reductionPriceDetail=new PropertyDirectReductionVo.ReductionPriceDetail();
                    reductionPriceDetail.setReductionPrice(reductionPrice);
                    reductionPriceDetail.setDetail(item);
                    reductionPriceDetailList.add(reductionPriceDetail);
                }
            } else if(directReduction.getReductionType() == 2){
                Long reductionPrice=item.getReductionAmt()>totalPrice?totalPrice:item.getReductionAmt();
                itemReductionPrice=itemReductionPrice+reductionPrice;
                PropertyDirectReductionVo.ReductionPriceDetail reductionPriceDetail=new PropertyDirectReductionVo.ReductionPriceDetail();
                reductionPriceDetail.setReductionPrice(reductionPrice);
                reductionPriceDetail.setDetail(item);
                reductionPriceDetailList.add(reductionPriceDetail);
            }
        }
        if(Func.isEmpty(reductionPriceDetailList)){
            return false;
        }
        PropertyDirectReductionVo.DirectReductionList directReductionItem = new PropertyDirectReductionVo.DirectReductionList();
        directReductionItem.setItemReductionPrice(itemReductionPrice);
        directReductionItem.setDirectReduction(directReduction);
        directReductionItem.setReductionPriceDetailList(reductionPriceDetailList);

        vo.setTotalReductionPrice(vo.getTotalReductionPrice()+itemReductionPrice);
        vo.getDirectReductionList().add(directReductionItem);
        return true;
    }
}
