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.manage.user.api.entity.User;
import com.yuchen.saas.manage.user.api.feign.IUserClient;
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.CreateBillTypeEnum;
import com.yuchen.saas.park.api.vo.property.*;
import com.yuchen.saas.park.service.mapper.property.PropertyHouseMeterReadingMapper;
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.PropertyBillFactoryService;
import com.yuchen.saas.park.service.util.BigdecimalUtil;
import com.yuchen.saas.parking.api.util.DateUtils;
import com.yuchen.saas.parking.charge.api.po.ParkingChargingRecord;
import com.yuchen.saas.payment.api.enums.SaasPaymentErrorEnums;
import io.swagger.annotations.ApiModelProperty;
import org.nest.springwrap.core.excel.util.ExcelUtil;
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.nest.springwrap.core.tool.utils.SpringUtil;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 房源仪表抄表 服务实现类
 * </p>
 *
 * @author cxj
 * @since 2023-11-27
 */
@Service
public class PropertyHouseMeterReadingServiceImpl extends BaseServiceImpl<PropertyHouseMeterReadingMapper, PropertyHouseMeterReading> implements IPropertyHouseMeterReadingService {

    @Lazy
    @Resource
    private IPropertyHouseMeterService iPropertyHouseMeterService;

    @Resource
    private IPropertyHouseMeterReadingLogService iPropertyHouseMeterReadingLogService;

    @Resource
    private PropertyBuildingsService propertyBuildingsService;

    @Resource
    private PmgBatParkInfoService pmgBatParkInfoService;

    @Resource
    private IPropertyMeterService iPropertyMeterService;

    @Resource
    private PropertyHousesService propertyHousesService;

    @Resource
    private ISysClient sysClient;

    @Resource
    private IUserClient iUserClient;

    @Resource
    private PropertyFeeStandardService propertyFeeStandardService;

    @Resource
    private PropertyBillFactoryService propertyBillFactoryService;

    @Resource
    private PropertyBillingSettingsService propertyBillingSettingsService;


    @Override
    public NestPage<PropertyHouseMeterReadingByHousePageVo> getPageByHouse(PropertyHouseMeterReadingQueryDto dto) {
        IPage<PropertyHouseMeter> page = iPropertyHouseMeterService.getPageByHouse(dto);
        IPage<PropertyHouseMeterReadingByHousePageVo> result = new Page<>();
        Func.copy(page, result);
        List<PropertyHouseMeter> list = page.getRecords();
        if (Func.isEmpty(list)) {
            return NestPage.of(result);
        }
        List<PropertyHouseMeterReadingByHousePageVo> resultList = page.getRecords().stream().map(a -> buildVo(a, dto.getMeterReadingTime())).collect(Collectors.toList());
        result.setRecords(resultList);
        return NestPage.of(result);
    }

    @Override
    public void exportTemplate(PropertyHouseMeterReadingQueryDto param, HttpServletResponse response) {
        param.setCurrent(-1).setSize(-1);
        NestPage<PropertyHouseMeterReadingByHousePageVo> page=getPageByHouse(param);
        if(Func.isNotEmpty(page.getRecords())){
            List<PropertyHouseMeterReadingByHouseExcelVo> list=Func.copy(page.getRecords(),PropertyHouseMeterReadingByHouseExcelVo.class);
            ExcelUtil.excelLockExport( response,"房源抄表数据模板", "房源抄表数据模板", list,PropertyHouseMeterReadingByHouseExcelVo.class);
        }
    }

    //批量添加,允许部分成功
    @Override
    public Boolean addList(List<PropertyHouseMeterReadingAddDto> list) {
        StringBuilder stringBuilder = new StringBuilder();
        for (PropertyHouseMeterReadingAddDto item : list) {
            try {
                SpringUtil.getBean(IPropertyHouseMeterReadingService.class).add(item.getId(), item.getMeterReadingNum(), item.getMeterReadingTime(),false);
            } catch (ServiceException e) {
                stringBuilder.append(e.getMessage());
            }
        }
        if (stringBuilder.length() > 0) {
            throw new ServiceException(stringBuilder.toString());
        }
        return true;
    }

    @Override
    public Boolean updateList(List<PropertyHouseMeterReadingUpdateDto> list) {
        if(Func.isEmpty(list)){
            throw new ServiceException("请提交修改的数据!");
        }
        List<PropertyHouseMeterReadingAddDto> updateList=new ArrayList<>(list.size());
        for (PropertyHouseMeterReadingUpdateDto item:list) {
            PropertyHouseMeterReading meterReading = getById(item.getId());
            if (Func.isNotEmpty(meterReading)) {
                //不是初始记录跟未计费才能进行修改时间
                if(Func.isNotEmpty(meterReading.getIsInit())&&meterReading.getIsInit()==0&&Func.isNotEmpty(meterReading.getIsCharging())&&meterReading.getIsCharging()==0){
                    if(meterReading.getLastMeterReadingTime().getTime()>item.getMeterReadingTime().getTime()){
                        throw new ServiceException("资源代码{" + meterReading.getResourceCode() + "}抄表时间不能小于上期抄表时间!");
                    }
                    PropertyHouseMeterReadingAddDto dto= new PropertyHouseMeterReadingAddDto();
                    dto.setId(item.getId());
                    dto.setMeterReadingNum(meterReading.getMeterReadingNum());
                    dto.setMeterReadingTime(item.getMeterReadingTime());
                    updateList.add(dto);
                }
            }
        }
        if(Func.isNotEmpty(updateList)){
            return addList(updateList);
        }else {
            return false;
        }
    }


    @Override
    @RedisLock(value = CacheNames.LOCK_HOUSE_METER_READING, param = "#houseMeterId", leaseTime = -1)
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(Long houseMeterId, BigDecimal meterReadingNum, Date meterReadingTime,Boolean isUpdate) {
        PropertyHouseMeter houseMeter = iPropertyHouseMeterService.getById(houseMeterId);
        if (Func.isEmpty(houseMeter)) {
            return false;
        }

        if(Func.isNotEmpty(houseMeter.getIsSealed())&&houseMeter.getIsSealed()==1){
            throw new ServiceException("资源代码{" + houseMeter.getMeterFullName() + "}已经封存无法进行抄表!");
        }
        if(Func.isNotEmpty(houseMeter.getIsMeterReading())&&houseMeter.getIsMeterReading()==0){
            throw new ServiceException("资源代码{" + houseMeter.getMeterFullName() + "}已设置不进行抄表!");
        }
        //把最新的抄表日期跟抄表读数记录在仪表上
        houseMeter.setFinallyMeterReadingTime(meterReadingTime);
        houseMeter.setFinallyMeterReadingNum(meterReadingNum);
        iPropertyHouseMeterService.updateById(houseMeter);

        //获取最新一条抄表记录
        PropertyHouseMeterReading houseMeterReading = getByHouseMeterIdAndQuery(houseMeterId, null, null, null, null, 1);
        //是不是更改仪表数据
        if(Func.isNotEmpty(isUpdate)&&isUpdate){
            if(Func.isNotEmpty(houseMeterReading)){
                if (Func.isNotEmpty(houseMeterReading.getIsInit()) && houseMeterReading.getIsInit() == 1) {
                    if (BigdecimalUtil.gt(meterReadingNum, houseMeter.getMaxNum())) {
                        throw new ServiceException("资源代码{" + houseMeter.getResourceCode() + "}抄表数据不能大于仪表最大读数!");
                    }
                    houseMeterReading.setMeterReadingNum(meterReadingNum);
                    houseMeterReading.setMeterReadingTime(meterReadingTime);
                    return updateById(houseMeterReading);
                }
            }
        }
        if (Func.isEmpty(houseMeterReading)) {
            //如果为空的话,说明是初始记录,作为初始记录新增
            return addHouseMeterReading(houseMeter, 1, meterReadingTime, meterReadingNum, null, null, null, null);
        }
        //判断最新的一条是不是初始记录
        if (Func.isNotEmpty(houseMeterReading.getIsInit()) && houseMeterReading.getIsInit() == 1) {
            //是初始记录的话,不管是否计费都作为初始记录,
            return addHouseMeterReading(houseMeter, 0, meterReadingTime, meterReadingNum, houseMeterReading.getMeterReadingTime(),
                    houseMeterReading.getMeterReadingNum(), houseMeterReading.getId(), null);
        } else {
            //不是初始记录的话
            //判断是否已经计费
            if (Func.isNotEmpty(houseMeterReading.getIsCharging()) && houseMeterReading.getIsCharging() == 1) {
                //已经计费的话进行新增
                return addHouseMeterReading(houseMeter, 0, meterReadingTime, meterReadingNum, houseMeterReading.getMeterReadingTime(),
                        houseMeterReading.getMeterReadingNum(), houseMeterReading.getId(), null);
            } else {
                return addHouseMeterReading(houseMeter, 0, meterReadingTime, meterReadingNum, houseMeterReading.getLastMeterReadingTime(),
                        houseMeterReading.getLastMeterReadingNum(), houseMeterReading.getLastMeterReadingId(), houseMeterReading.getId());
            }
        }
    }

    @Override
    public PropertyHouseMeterReadingForBuildingVo listForBuilding(PropertyHouseMeterReadingQueryDto dto) {
        PropertyHouseMeterReadingForBuildingVo vo = new PropertyHouseMeterReadingForBuildingVo();
        int totalMeterNum = 0;
        int totalReadNum = 0;
        int totalUnReadNum = 0;
        List<PropertyHouseMeter> list = iPropertyHouseMeterService.listByParkIdAndBuildingIdAndMeterId(dto.getParkId(), dto.getBuildingId(), dto.getMeterId());
        if (Func.isEmpty(list)) {
            vo.setTotalMeterNum(totalMeterNum);
            vo.setTotalReadNum(totalReadNum);
            vo.setTotalUnReadNum(totalUnReadNum);
            vo.setList(new ArrayList<>());
            return vo;
        }
        Date monthFirstDayDate = DateUtils.getMonthFirstDayDate(dto.getMeterReadingTime());
        Date monthLastDayDate = DateUtils.getMonthLastDayDate(dto.getMeterReadingTime());
        Map<Long, PropertyHouseMeterReadingForBuildingVo.PropertyHouseMeterReadingForBuildingItemVo> buildingMap = new HashMap<>();
        for (PropertyHouseMeter item : list) {
            totalMeterNum++;
            PropertyHouseMeterReadingForBuildingVo.PropertyHouseMeterReadingForBuildingItemVo itemVo;
            if (buildingMap.containsKey(item.getBuildingId())) {
                itemVo = buildingMap.get(item.getBuildingId());
            } else {
                itemVo = new PropertyHouseMeterReadingForBuildingVo.PropertyHouseMeterReadingForBuildingItemVo();
                PropertyBuildings building = propertyBuildingsService.getById(item.getBuildingId());
                if (Func.isNotEmpty(building)) {
                    itemVo.setBuildingName(building.getBuildingName());
                }
                itemVo.setMeterNum(0);
                itemVo.setReadNum(0);
                itemVo.setUnReadNum(0);
                buildingMap.put(item.getBuildingId(), itemVo);
            }
            itemVo.setMeterNum(itemVo.getMeterNum() + 1);
            LambdaQueryWrapper<PropertyHouseMeterReading> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(PropertyHouseMeterReading::getHouseMeterId, item.getId())
                    .le(Func.isNotEmpty(monthLastDayDate), PropertyHouseMeterReading::getMeterReadingTime, monthLastDayDate)
                    .ge(Func.isNotEmpty(monthFirstDayDate), PropertyHouseMeterReading::getMeterReadingTime, monthFirstDayDate);
            if (count(queryWrapper) > 0) {
                totalReadNum++;
                itemVo.setReadNum(itemVo.getReadNum() + 1);
            } else {
                totalUnReadNum++;
                itemVo.setUnReadNum(itemVo.getUnReadNum() + 1);
            }
        }
        List<PropertyHouseMeterReadingForBuildingVo.PropertyHouseMeterReadingForBuildingItemVo> listVo = buildingMap.entrySet().stream()
                .map(e -> e.getValue())
                .collect(Collectors.toList());
        vo.setTotalMeterNum(totalMeterNum);
        vo.setTotalReadNum(totalReadNum);
        vo.setTotalUnReadNum(totalUnReadNum);
        vo.setList(listVo);
        return vo;
    }

    private boolean addHouseMeterReading(PropertyHouseMeter houseMeter, Integer isInit, Date meterReadingTime,
                                         BigDecimal meterReadingNum, Date lastMeterReadingTime, BigDecimal lastMeterReadingNum,
                                         Long lastMeterReadingId, Long oldId) {
        if (Func.isNotEmpty(meterReadingTime) && Func.isNotEmpty(lastMeterReadingTime)) {
            if (meterReadingTime.getTime() <= lastMeterReadingTime.getTime()) {
                throw new ServiceException("资源代码{" + houseMeter.getResourceCode() + "}抄表日期不能早于已计费抄表记录的抄表日期!");
            }
        }
        if (Func.isEmpty(meterReadingNum)) {
            throw new ServiceException("资源代码{" + houseMeter.getResourceCode() + "}抄表数据不能为空!");
        }
        if (BigdecimalUtil.gt(meterReadingNum, houseMeter.getMaxNum())) {
            throw new ServiceException("资源代码{" + houseMeter.getResourceCode() + "}抄表数据不能大于仪表最大读数!");
        }
        PropertyHouseMeterReading houseMeterReading = new PropertyHouseMeterReading();
        houseMeterReading.setParkId(houseMeter.getParkId());
        houseMeterReading.setHouseId(houseMeter.getHouseId());
        houseMeterReading.setBuildingId(houseMeter.getBuildingId());
        houseMeterReading.setFloorNum(houseMeter.getFloorNum());
        houseMeterReading.setUnitNum(houseMeter.getUnitNum());
        houseMeterReading.setResourceCode(houseMeter.getResourceCode());
        houseMeterReading.setResourceType(houseMeter.getResourceType());
        houseMeterReading.setHouseMeterId(houseMeter.getId());
        houseMeterReading.setMeterId(houseMeter.getMeterId());
        houseMeterReading.setIsInit(isInit);
        houseMeterReading.setParentId(houseMeter.getParentId());
        //houseMeterReading.setIsCharging() 默认未计费,取数据库默认值
        houseMeterReading.setMeterReadingTime(meterReadingTime);
        houseMeterReading.setMeterReadingNum(meterReadingNum);
        houseMeterReading.setLastMeterReadingTime(lastMeterReadingTime);
        houseMeterReading.setLastMeterReadingNum(lastMeterReadingNum);
        houseMeterReading.setLastMeterReadingId(lastMeterReadingId);
        houseMeterReading.setRate(houseMeter.getRate());//未计费的情况是临时值
        houseMeterReading.setAttritionRate(houseMeter.getAttritionRate());
        houseMeterReading.setResourceId(houseMeter.getResourceId());
        ContextUser contextUser = AuthUtil.getUser();
        if (Func.isNotEmpty(contextUser)) {
            contextUser.getOrgUserId();
            R<NestOrgUser> orgUserR = sysClient.getOrgUserById(contextUser.getOrgUserId());
            if (orgUserR.isSuccess() && Func.isNotEmpty(orgUserR.getData())) {
                houseMeterReading.setOrgUserName(orgUserR.getData().getName());
            }
        }
        if (Func.isNotEmpty(meterReadingNum) && Func.isNotEmpty(lastMeterReadingNum)) {
            if (BigdecimalUtil.lt(meterReadingNum, lastMeterReadingNum)) {
                throw new ServiceException("资源代码{" + houseMeter.getResourceCode() + "}抄表数据不能小于上期读数!");
            }
            houseMeterReading.setDosage(this.getDosage(meterReadingNum, lastMeterReadingNum, houseMeter.getRate(),houseMeter.getAttritionRate(),houseMeter.getParkId()));
        }
        if (Func.isNotEmpty(oldId)) {
            houseMeterReading.setId(oldId);
        }
        Boolean flag = saveOrUpdate(houseMeterReading);
        if (flag) {
            //日志记录,目前没业务需求,抄表被变更记录使用
            PropertyHouseMeterReadingLog readingLog = Func.copy(houseMeterReading, PropertyHouseMeterReadingLog.class);
            readingLog.setHouseMeterReadingId(houseMeterReading.getId());
            readingLog.setId(null);
            iPropertyHouseMeterReadingLogService.save(readingLog);
        }
        return flag;
    }

    private BigDecimal getDosage(BigDecimal meterReadingNum, BigDecimal lastMeterReadingNum, BigDecimal rate,BigDecimal attritionRate,Long parkId) {
        if (Func.isNotEmpty(meterReadingNum) && Func.isNotEmpty(lastMeterReadingNum) && Func.isNotEmpty(rate)) {
            //用量报保留的小数点及取舍方式取账单设置
            int scale = 2;
            PropertyBillingSettings billingSettings = propertyBillingSettingsService.getBillingSettings(parkId);
            if(Func.isNotEmpty(billingSettings)&&Func.isNotEmpty(billingSettings.getMeterDigitsType())
                    &&billingSettings.getMeterDigitsType()>=0&&billingSettings.getMeterDigitsType()<=2){
                scale=billingSettings.getMeterDigitsType();
            }
            return BigdecimalUtil.multiply(BigdecimalUtil.subtract(meterReadingNum, lastMeterReadingNum),
                    Func.isEmpty(attritionRate)?rate:BigdecimalUtil.add(rate,attritionRate), scale, RoundingMode.DOWN);
        } else {
            return BigdecimalUtil.ZERO;
        }
    }

    private PropertyHouseMeterReadingByHousePageVo buildVo(PropertyHouseMeter a, Date date) {
        //todo 用量取舍值保存及返回
        PropertyHouseMeterReadingByHousePageVo vo = new PropertyHouseMeterReadingByHousePageVo();
        Func.copy(a, vo);
        PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(a.getParkId());
        if(Func.isNotEmpty(parkInfo)){
            vo.setParkName(parkInfo.getParkName());
        }
        PropertyBuildings buildings = propertyBuildingsService.getById(a.getBuildingId());
        if(Func.isNotEmpty(buildings)){
            vo.setBuildingName(buildings.getBuildingName());
        }
        //默认设置不置灰
        vo.setIsGreyOut(0);
        Date monthFirstDayDate = DateUtils.getMonthFirstDayDate(date);
        Date monthLastDayDate = DateUtils.getMonthLastDayDate(date);
        //获取该月份的后一条抄表记录
        PropertyHouseMeterReading houseMeterReading = getByHouseMeterIdAndQuery(a.getId(), null, null, monthFirstDayDate, monthLastDayDate, 1);
        if (Func.isNotEmpty(houseMeterReading)) {
            LambdaQueryWrapper<PropertyHouseMeterReading> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(PropertyHouseMeterReading::getHouseMeterId, a.getId())
                    .gt(PropertyHouseMeterReading::getMeterReadingTime, monthLastDayDate)
                    .orderByAsc(PropertyHouseMeterReading::getMeterReadingTime).last("limit 1");
            //晚于本月的最早记录
            PropertyHouseMeterReading gtHouseMeterReading = getOne(queryWrapper);
            //仪表在该月份有抄表数据且无晚于该月份的抄表记录情况
            if (Func.isEmpty(gtHouseMeterReading)) {
                if (Func.isNotEmpty(houseMeterReading.getIsInit()) && houseMeterReading.getIsInit() == 1) {
                    vo.setStatus(0);
                    vo.setLastMeterReadingTime(houseMeterReading.getMeterReadingTime());
                    vo.setLastMeterReadingNum(houseMeterReading.getMeterReadingNum());
                    //初始数据,作为上次抄表数据,用量如果有计费,使用计费的用量
                    if(houseMeterReading.getIsCharging()==1){
                        vo.setLastDosage(houseMeterReading.getDosage());
                    }else{
                        vo.setLastDosage(getDosage(houseMeterReading.getMeterReadingNum(),BigdecimalUtil.ZERO,a.getRate(),a.getAttritionRate(),a.getParkId()));
                    }
                    return vo;
                }
                if (Func.isNotEmpty(houseMeterReading.getIsCharging()) && houseMeterReading.getIsCharging() == 0) {
                    vo.setStatus(1);
                    //vo.setDosage(houseMeterReading.getDosage());
                    vo.setMeterReadingTime(houseMeterReading.getMeterReadingTime());
                    vo.setMeterReadingNum(houseMeterReading.getMeterReadingNum());
                    vo.setLastMeterReadingTime(houseMeterReading.getLastMeterReadingTime());
                    vo.setLastMeterReadingNum(houseMeterReading.getLastMeterReadingNum());
                    vo.setDosage(this.getDosage(vo.getMeterReadingNum(), vo.getLastMeterReadingNum(), a.getRate(),a.getAttritionRate(),a.getParkId()));
                    PropertyHouseMeterReading lastMeterReading = getById(houseMeterReading.getLastMeterReadingId());
                    if(Func.isNotEmpty(lastMeterReading)){
                        vo.setLastDosage(lastMeterReading.getDosage());
                    }
                    return vo;
                }
                if (Func.isNotEmpty(houseMeterReading.getIsCharging()) && houseMeterReading.getIsCharging() == 1) {
                    vo.setStatus(0);
                    vo.setLastMeterReadingTime(houseMeterReading.getMeterReadingTime());
                    vo.setLastMeterReadingNum(houseMeterReading.getMeterReadingNum());
                    vo.setLastDosage(houseMeterReading.getDosage());
                    return vo;
                }
            } else {
                if (Func.isNotEmpty(houseMeterReading.getIsInit()) && houseMeterReading.getIsInit() == 1) {
                    vo.setLastMeterReadingTime(houseMeterReading.getMeterReadingTime());
                    vo.setLastMeterReadingNum(houseMeterReading.getMeterReadingNum());
                    if (Func.isNotEmpty(houseMeterReading.getIsCharging()) && houseMeterReading.getIsCharging() == 0) {
                        vo.setStatus(1);
                        //vo.setDosage(gtHouseMeterReading.getDosage());
                        vo.setMeterReadingTime(gtHouseMeterReading.getMeterReadingTime());
                        vo.setMeterReadingNum(gtHouseMeterReading.getMeterReadingNum());
                        vo.setLastMeterReadingTime(gtHouseMeterReading.getLastMeterReadingTime());
                        vo.setLastMeterReadingNum(gtHouseMeterReading.getLastMeterReadingNum());
                        vo.setDosage(this.getDosage(vo.getMeterReadingNum(), vo.getLastMeterReadingNum(), a.getRate(),a.getAttritionRate(),a.getParkId()));
                        PropertyHouseMeterReading lastMeterReading = getById(gtHouseMeterReading.getLastMeterReadingId());
                        if(Func.isNotEmpty(lastMeterReading)){
                            vo.setLastDosage(lastMeterReading.getDosage());
                        }
                        return vo;
                    }
                    if (Func.isNotEmpty(houseMeterReading.getIsCharging()) && houseMeterReading.getIsCharging() == 1) {
                        vo.setIsGreyOut(1);
                        vo.setLastMeterReadingTime(houseMeterReading.getMeterReadingTime());
                        vo.setLastMeterReadingNum(houseMeterReading.getMeterReadingNum());
                        vo.setLastDosage(houseMeterReading.getDosage());
                    }
                    return vo;
                } else {
                    vo.setStatus(2);
                    vo.setRate(houseMeterReading.getRate());
                    vo.setAttritionRate(houseMeterReading.getAttritionRate());
                    vo.setDosage(houseMeterReading.getDosage());
                    vo.setMeterReadingTime(houseMeterReading.getMeterReadingTime());
                    vo.setMeterReadingNum(houseMeterReading.getMeterReadingNum());
                    vo.setLastMeterReadingTime(houseMeterReading.getLastMeterReadingTime());
                    vo.setLastMeterReadingNum(houseMeterReading.getLastMeterReadingNum());
                    PropertyHouseMeterReading lastMeterReading = getById(houseMeterReading.getLastMeterReadingId());
                    if(Func.isNotEmpty(lastMeterReading)){
                        vo.setLastDosage(lastMeterReading.getDosage());
                    }
                    return vo;
                }
            }
        } else {
            //仪表初始记录如果选择的月份小于初始记录,置灰
            PropertyHouseMeterReading initMeterReading = getByHouseMeterIdAndQuery(a.getId(), 1, null, null, null, 1);
            if (initMeterReading.getMeterReadingTime().getTime() > monthLastDayDate.getTime()) {
                vo.setIsGreyOut(1);
                return vo;
            }
            //获取大于本月的抄表的第一条记录
            PropertyHouseMeterReading nestMeterReading = getByHouseMeterIdAndQuery(a.getId(), null, null, monthLastDayDate, null, 0);
            if (Func.isEmpty(nestMeterReading)) {
                //没有晚于该月份的抄表记录情况
                PropertyHouseMeterReading beforeMeterReading = getByHouseMeterIdAndQuery(a.getId(), null, null, null, monthFirstDayDate, 1);
                if (Func.isNotEmpty(beforeMeterReading)) {
                    if (Func.isNotEmpty(beforeMeterReading.getIsCharging()) && beforeMeterReading.getIsCharging() == 1) {
                        //上一条已计费的话
                        vo.setLastMeterReadingTime(beforeMeterReading.getMeterReadingTime());
                        vo.setLastMeterReadingNum(beforeMeterReading.getMeterReadingNum());
                        vo.setLastDosage(beforeMeterReading.getDosage());
                        vo.setStatus(0);
                        return vo;
                    }
                    if (Func.isNotEmpty(beforeMeterReading.getIsCharging()) && beforeMeterReading.getIsCharging() == 0) {
                        if (Func.isNotEmpty(beforeMeterReading.getIsInit()) && beforeMeterReading.getIsInit() == 1) {
                            vo.setLastMeterReadingTime(beforeMeterReading.getMeterReadingTime());
                            vo.setLastMeterReadingNum(beforeMeterReading.getMeterReadingNum());
                            vo.setStatus(0);
                            //初始数据,作为上次抄表数据,用量如果有计费,使用计费的用量
                            if(beforeMeterReading.getIsCharging()==1){
                                vo.setLastDosage(beforeMeterReading.getDosage());
                            }else{
                                vo.setLastDosage(getDosage(beforeMeterReading.getMeterReadingNum(),BigdecimalUtil.ZERO,a.getRate(),a.getAttritionRate(),a.getParkId()));
                            }
                        } else {
                            vo.setMeterReadingNum(beforeMeterReading.getMeterReadingNum());
                            vo.setStatus(0);
                            //上一条已计费的记录
                            vo.setLastMeterReadingTime(beforeMeterReading.getLastMeterReadingTime());
                            vo.setLastMeterReadingNum(beforeMeterReading.getLastMeterReadingNum());
                            PropertyHouseMeterReading lastMeterReading = getById(beforeMeterReading.getLastMeterReadingId());
                            if(Func.isNotEmpty(lastMeterReading)){
                                vo.setLastDosage(lastMeterReading.getDosage());
                            }
                        }
                        return vo;
                    }
                }
            } else {
                //有晚于该月份的抄表记录情况

                //未计费情况
                if (Func.isNotEmpty(nestMeterReading.getIsCharging()) && nestMeterReading.getIsCharging() == 0) {
                    vo.setMeterReadingNum(nestMeterReading.getMeterReadingNum());
                    vo.setStatus(1);
                    vo.setLastMeterReadingTime(nestMeterReading.getLastMeterReadingTime());
                    vo.setLastMeterReadingNum(nestMeterReading.getLastMeterReadingNum());
                    vo.setDosage(this.getDosage(vo.getMeterReadingNum(), vo.getLastMeterReadingNum(), a.getRate(),a.getAttritionRate(),a.getParkId()));
                    PropertyHouseMeterReading lastMeterReading = getById(nestMeterReading.getLastMeterReadingId());
                    if(Func.isNotEmpty(lastMeterReading)){
                        vo.setLastDosage(lastMeterReading.getDosage());
                    }
                    return vo;
                }
                //已计费情况
                if (Func.isNotEmpty(nestMeterReading.getIsCharging()) && nestMeterReading.getIsCharging() == 1) {
                    vo.setIsGreyOut(1);
                    vo.setLastMeterReadingTime(nestMeterReading.getLastMeterReadingTime());
                    vo.setLastMeterReadingNum(nestMeterReading.getLastMeterReadingNum());
                    PropertyHouseMeterReading lastMeterReading = getById(nestMeterReading.getLastMeterReadingId());
                    if(Func.isNotEmpty(lastMeterReading)){
                        vo.setLastDosage(lastMeterReading.getDosage());
                    }
                    /*PropertyHouseMeterReading beforeChargingMeterReading = getByHouseMeterIdAndQuery(a.getId(),null, null,null,monthFirstDayDate,1);
                    if(Func.isNotEmpty(beforeChargingMeterReading)){
                        vo.setLastMeterReadingTime(beforeChargingMeterReading.getMeterReadingTime());
                        vo.setLastMeterReadingNum(beforeChargingMeterReading.getMeterReadingNum());
                    }*/
                    return vo;
                }
            }
        }
        return vo;
    }

    /**
     * @param houseMeterId
     * @param isInit
     * @param isCharging
     * @param monthFirstDayDate
     * @param monthLastDayDate
     * @param firstOrLast       1按时间倒序第一条,0按时间顺序第一条
     * @return
     */
    @Override
    public PropertyHouseMeterReading getByHouseMeterIdAndQuery(Long houseMeterId, Integer isInit, Integer isCharging, Date monthFirstDayDate, Date monthLastDayDate, int firstOrLast) {
        LambdaQueryWrapper<PropertyHouseMeterReading> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PropertyHouseMeterReading::getHouseMeterId, houseMeterId)
                .eq(Func.isNotEmpty(isInit), PropertyHouseMeterReading::getIsInit, isInit)
                .eq(Func.isNotEmpty(isCharging), PropertyHouseMeterReading::getIsCharging, isCharging)
                .le(Func.isNotEmpty(monthLastDayDate), PropertyHouseMeterReading::getMeterReadingTime, monthLastDayDate)
                .ge(Func.isNotEmpty(monthFirstDayDate), PropertyHouseMeterReading::getMeterReadingTime, monthFirstDayDate);
        //.between(Func.isNotEmpty(monthFirstDayDate)&&Func.isNotEmpty(monthLastDayDate),PropertyHouseMeterReading::getMeterReadingTime,monthFirstDayDate,monthLastDayDate)
        if (firstOrLast == 1) {
            queryWrapper.orderByDesc(PropertyHouseMeterReading::getMeterReadingTime,PropertyHouseMeterReading::getUpdateTime);
        }
        if (firstOrLast == 0) {
            queryWrapper.orderByAsc(PropertyHouseMeterReading::getMeterReadingTime,PropertyHouseMeterReading::getUpdateTime);
        }
        queryWrapper.last("limit 1");
        return getOne(queryWrapper);
    }

    @Override
    public NestPage<PropertyHouseMeterReadingDetailPageVo> getPageForDetail(PropertyHouseMeterReadingDetailQueryDto dto) {
        Page<PropertyHouseMeterReadingDetailPageVo> result = new Page<>();
        List<PropertyHouseMeterReadingDetailPageVo> resultList;
        LambdaQueryWrapper<PropertyHouseMeterReading> queryWrapper = Wrappers.lambdaQuery();
        if (Func.isNotEmpty(dto.getMeterReadingTime())) {
            Date monthFirstDayDate = DateUtils.getMonthFirstDayDate(dto.getMeterReadingTime());
            Date monthLastDayDate = DateUtils.getMonthLastDayDate(dto.getMeterReadingTime());
            queryWrapper.le(Func.isNotEmpty(monthLastDayDate), PropertyHouseMeterReading::getMeterReadingTime, monthLastDayDate)
                    .ge(Func.isNotEmpty(monthFirstDayDate), PropertyHouseMeterReading::getMeterReadingTime, monthFirstDayDate);
        }
        if (Func.isNotEmpty(dto.getStatus())) {
            if (dto.getStatus() == 0) {
                queryWrapper.eq(PropertyHouseMeterReading::getIsInit, 1);
            } else if (dto.getStatus() == 1) {
                queryWrapper.eq(PropertyHouseMeterReading::getIsInit, 0);
                queryWrapper.eq(PropertyHouseMeterReading::getIsCharging, 0);
            } else if (dto.getStatus() == 2) {
                queryWrapper.eq(PropertyHouseMeterReading::getIsCharging, 1);
            }
        }
        queryWrapper.eq(Func.isNotEmpty(dto.getMeterId()), PropertyHouseMeterReading::getMeterId, dto.getMeterId())
                .eq(Func.isNotEmpty(dto.getParkId()), PropertyHouseMeterReading::getParkId, dto.getParkId())
                .eq(Func.isNotEmpty(dto.getBuildingId()), PropertyHouseMeterReading::getBuildingId, dto.getBuildingId())
                .like(Func.isNotEmpty(dto.getResourceCode()), PropertyHouseMeterReading::getResourceCode, dto.getResourceCode())
                .orderByDesc(PropertyHouseMeterReading::getMeterReadingTime);
        //已抄表数据
        if (Func.isNotEmpty(dto.getIsReading()) && dto.getIsReading() == 1) {
            IPage<PropertyHouseMeterReading> page = this.page(Condition.getPage(dto), queryWrapper);
            Func.copy(page, result);
            List<PropertyHouseMeterReading> list = page.getRecords();
            if (Func.isEmpty(list)) {
                return NestPage.of(result);
            }
            resultList = list.stream().map(a -> {
                PropertyHouseMeterReadingDetailPageVo vo = Func.copy(a, PropertyHouseMeterReadingDetailPageVo.class);
                buildDetailPageVo(vo);
                R<User> userR = iUserClient.userInfoById(vo.getCreateUser());
                if (userR.isSuccess() && Func.isNotEmpty(userR.getData())) {
                    vo.setPhone(userR.getData().getPhone());
                }
                if (Func.isNotEmpty(vo.getIsInit()) && vo.getIsInit() == 1) {
                    vo.setStatus(0);
                } else {
                    if (Func.isNotEmpty(vo.getIsCharging()) && vo.getIsCharging() == 1) {
                        vo.setStatus(2);
                    } else {
                        vo.setStatus(1);
                    }
                }


                return vo;
            }).collect(Collectors.toList());
        } else {
            List<PropertyHouseMeterReading> list = list(queryWrapper);
            LambdaQueryWrapper<PropertyHouseMeter> houseMeterQueryWrapper = Wrappers.lambdaQuery();
            if (Func.isNotEmpty(list)) {
                Set<Long> houseMeterIds = list.stream().map(a -> a.getHouseMeterId()).collect(Collectors.toSet());
                houseMeterQueryWrapper.notIn(PropertyHouseMeter::getId, houseMeterIds);
            }
            //初始日期要小于所选月份才进行显示
            if (Func.isNotEmpty(dto.getMeterReadingTime())) {
                Date monthLastDayDate = DateUtils.getMonthLastDayDate(dto.getMeterReadingTime());
                houseMeterQueryWrapper.le(Func.isNotEmpty(monthLastDayDate), PropertyHouseMeter::getInitTime, monthLastDayDate);
            }
            houseMeterQueryWrapper.eq(Func.isNotEmpty(dto.getMeterId()), PropertyHouseMeter::getMeterId, dto.getMeterId())
                    .eq(Func.isNotEmpty(dto.getParkId()), PropertyHouseMeter::getParkId, dto.getParkId())
                    .eq(Func.isNotEmpty(dto.getBuildingId()), PropertyHouseMeter::getBuildingId, dto.getBuildingId())
                    .like(Func.isNotEmpty(dto.getResourceCode()), PropertyHouseMeter::getResourceCode, dto.getResourceCode())
                    .orderByDesc(PropertyHouseMeter::getBuildingId);
            IPage<PropertyHouseMeter> page = iPropertyHouseMeterService.page(Condition.getPage(dto), houseMeterQueryWrapper);
            Func.copy(page, result);
            List<PropertyHouseMeter> houseMeters = page.getRecords();
            if (Func.isEmpty(houseMeters)) {
                return NestPage.of(result);
            }
            resultList = houseMeters.stream().map(a -> {
                PropertyHouseMeterReadingDetailPageVo vo = Func.copy(a, PropertyHouseMeterReadingDetailPageVo.class);
                buildDetailPageVo(vo);
                return vo;
            }).collect(Collectors.toList());
        }
        result.setRecords(resultList);
        return NestPage.of(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteList(List<Long> ids) {
        if (Func.isEmpty(ids)) {
            throw new ServiceException("请选择要操作的记录!");
        }
        LambdaQueryWrapper<PropertyHouseMeterReading> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(PropertyHouseMeterReading::getId, ids)
                .and(wrapper -> wrapper
                        .or(item -> item
                                .eq(PropertyHouseMeterReading::getIsInit,1))
                        .or(item -> item
                                .eq(PropertyHouseMeterReading::getIsCharging, 1)));
        if(count(queryWrapper)>0){
            throw new ServiceException("删除数据存在初始记录或存在已计费的记录,请重新刷新!");
        }
        return removeByIds(ids);
    }

    @Override
    public Integer countByIsCharging(Long houseMeterId) {
        LambdaQueryWrapper<PropertyHouseMeterReading> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PropertyHouseMeterReading::getIsCharging,1)
                .eq(PropertyHouseMeterReading::getHouseMeterId,houseMeterId);
        return count(queryWrapper);
    }

    @Override
    public NestPage<PropertyHouseMeterReadingByResourcePageVo> getPageResource(PropertyHouseMeterReadingResourceQueryDto dto) {
        List<Long> feeStandardIdList=new ArrayList<>();
        if(Func.isNotEmpty(dto.getFeeItemId())){
            feeStandardIdList= propertyFeeStandardService.listFeeByFeeItemId(dto.getFeeItemId()).stream().map(a->a.getId()).collect(Collectors.toList());
        }
        LambdaQueryWrapper<PropertyHouseMeterReading> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PropertyHouseMeterReading::getResourceId,dto.getResourceId())
                .in(Func.isNotEmpty(feeStandardIdList),PropertyHouseMeterReading::getFeeStandardId,feeStandardIdList);
        if(Func.isNotEmpty(dto.getMeterReadingTime())){
            Date monthFirstDayDate = DateUtils.getMonthFirstDayDate(dto.getMeterReadingTime());
            Date monthLastDayDate = DateUtils.getMonthLastDayDate(dto.getMeterReadingTime());
            queryWrapper.le(Func.isNotEmpty(monthLastDayDate), PropertyHouseMeterReading::getMeterReadingTime, monthLastDayDate)
                    .ge(Func.isNotEmpty(monthFirstDayDate), PropertyHouseMeterReading::getMeterReadingTime, monthFirstDayDate);
        }
        queryWrapper.orderByDesc(PropertyHouseMeterReading::getMeterReadingTime);
        IPage<PropertyHouseMeterReading> page = this.page(Condition.getPage(dto), queryWrapper);
        IPage<PropertyHouseMeterReadingByResourcePageVo> result=new Page<>();
        Func.copy(page,result);
        List<PropertyHouseMeterReadingByResourcePageVo> list = page.getRecords().stream().map(a -> {
            PropertyHouseMeterReadingByResourcePageVo vo= Func.copy(a,PropertyHouseMeterReadingByResourcePageVo.class);
            PropertyHouseMeter houseMeter = iPropertyHouseMeterService.getById(vo.getHouseMeterId());
            if(Func.isNotEmpty(houseMeter)){
                vo.setMeterFullName(houseMeter.getMeterFullName());
            }
            return vo;
        }).collect(Collectors.toList());
        result.setRecords(list);
        return NestPage.of(result);
    }

    @Override
    public PropertyHouseMeterReadingByAppVo getDetailByApp(Long id) {

        PropertyHouseMeter byId = iPropertyHouseMeterService.getById(id);
        if(Func.isEmpty(byId)){
            throw new ServiceException("所选数据已不存在!");
        }
        PropertyHouseMeterReadingByAppVo vo=Func.copy(byId,PropertyHouseMeterReadingByAppVo.class);
        PropertyMeter meter = iPropertyMeterService.getById(byId.getMeterId());
        if(Func.isNotEmpty(meter)){
            vo.setMeterName(meter.getMeterName());
        }
        PropertyHouses houses = propertyHousesService.getById(byId.getHouseId());
        if(Func.isNotEmpty(houses)){
            vo.setHouseName(houses.getHouseName());
        }
        LambdaQueryWrapper<PropertyHouseMeterReading> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PropertyHouseMeterReading::getHouseMeterId, id)
                .orderByDesc(PropertyHouseMeterReading::getMeterReadingTime).last("limit 1");
        PropertyHouseMeterReading houseMeterReading = getOne(queryWrapper);
        if(Func.isEmpty(houseMeterReading)){
            return vo;
        }
        Date monthFirstDayDate = DateUtils.getMonthFirstDayDate(new Date());

        if (Func.isNotEmpty(houseMeterReading.getIsInit()) && houseMeterReading.getIsInit() == 1) {
            vo.setLastMeterReadingNum(houseMeterReading.getMeterReadingNum());
            vo.setLastMeterReadingTime(houseMeterReading.getMeterReadingTime());
            if(houseMeterReading.getMeterReadingTime().getTime()>monthFirstDayDate.getTime()){
                vo.setMeterReadingNum(houseMeterReading.getMeterReadingNum());
                vo.setMeterReadingTime(houseMeterReading.getMeterReadingTime());
            }
        }else{
            if (Func.isNotEmpty(houseMeterReading.getIsCharging()) && houseMeterReading.getIsCharging() == 1) {
                vo.setLastMeterReadingNum(houseMeterReading.getMeterReadingNum());
                vo.setLastMeterReadingTime(houseMeterReading.getMeterReadingTime());
            }else{
                if(houseMeterReading.getMeterReadingTime().getTime()>monthFirstDayDate.getTime()){
                    //已抄表
                    vo.setLastMeterReadingNum(houseMeterReading.getLastMeterReadingNum());
                    vo.setLastMeterReadingTime(houseMeterReading.getLastMeterReadingTime());
                    vo.setMeterReadingNum(houseMeterReading.getMeterReadingNum());
                    vo.setMeterReadingTime(houseMeterReading.getMeterReadingTime());
                }else{
                    //未抄表
                    vo.setLastMeterReadingNum(houseMeterReading.getLastMeterReadingNum());
                    vo.setLastMeterReadingTime(houseMeterReading.getLastMeterReadingTime());
                }
            }


        }
        return vo;
    }

    @Override
    public Boolean buildCharge(List<Long> ids) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < ids.size(); i++) {
            Long item =  ids.get(i);
            PropertyHouseMeterReading byId = getById(item);
            if(Func.isEmpty(byId)){
                stringBuilder.append(String.format("第%s条抄表数据已不存在",i+1));
                continue;
            }
            if(Func.isNotEmpty(byId.getIsCharging())&&byId.getIsCharging()==1){
                stringBuilder.append(String.format("第%s条抄表数据已计费",i+1));
                continue;
            }
            try {
                SpringUtil.getBean(IPropertyHouseMeterReadingService.class).buildCharge(byId.getHouseMeterId(),item,i);
            } catch (ServiceException e) {
                stringBuilder.append(e.getMessage());
            }

        }
        if (stringBuilder.length() > 0) {
            throw new ServiceException(stringBuilder.toString());
        }
        return true;
    }

    @Override
    @RedisLock(value = CacheNames.LOCK_HOUSE_METER_READING, param = "#houseMeterId", leaseTime = -1)
    @Transactional(rollbackFor = Exception.class)
    public Boolean buildCharge(Long houseMeterId,Long id,Integer i) {
        if(Func.isEmpty(i)){
            i=0;
        }
        PropertyHouseMeterReading houseMeterReading = getById(id);
        if(Func.isEmpty(houseMeterReading)){
            throw new ServiceException(String.format("第%s条抄表数据已不存在",i+1));
        }
        if(Func.isNotEmpty(houseMeterReading.getIsCharging())&&houseMeterReading.getIsCharging()==1){
            throw new ServiceException(String.format("第%s条抄表数据已计费",i+1));
        }
        PropertyHouseMeter houseMeter = iPropertyHouseMeterService.getById(houseMeterReading.getHouseMeterId());
        if(Func.isEmpty(houseMeter)){
            throw new ServiceException(String.format("第%s条抄表数据绑定的仪表不存在",i+1));
        }
        //抄表数据改为计费状态
        houseMeterReading.setFeeStandardId(houseMeter.getChargingStandardId());
        houseMeterReading.setRate(houseMeter.getRate());
        houseMeterReading.setAttritionRate(houseMeter.getAttritionRate());
        houseMeterReading.setIsCharging(1);
        houseMeterReading.setDosage(getDosage(houseMeterReading.getMeterReadingNum(),houseMeterReading.getLastMeterReadingNum(),houseMeter.getRate(),houseMeter.getAttritionRate(),houseMeter.getParkId()));
        if(Func.isEmpty(houseMeter.getChargingStandardId())){
            throw new ServiceException(String.format("第%s条抄表数据仪表未绑定收费标准无法生成计费",i+1));
        }
        //生成计费
        createBill( houseMeterReading, houseMeter);
        return updateById(houseMeterReading);
    }

    private Boolean createBill(PropertyHouseMeterReading houseMeterReading,PropertyHouseMeter houseMeter) {
        //生成计费
        CreateBillDto createBillDto= new CreateBillDto();
        createBillDto.setCreateBillTypeEnum(CreateBillTypeEnum.METER);
        PropertyMeterCreateBillDto dto=new PropertyMeterCreateBillDto();
        dto.setMeterReadingType(1);
        dto.setMeterReadingId(houseMeterReading.getId());
        dto.setBuildingId(houseMeterReading.getBuildingId());
        dto.setHouseId(houseMeterReading.getHouseId());
        dto.setFeeId(houseMeter.getChargingStandardId());
        PropertyFeeStandard feeStandard = propertyFeeStandardService.getById(houseMeter.getChargingStandardId());
        if(Func.isNotEmpty(feeStandard)){
            dto.setFeeItemId(feeStandard.getFeeItemId());
        }
        dto.setBillableQuantity(houseMeterReading.getDosage());
        dto.setStartDate(houseMeterReading.getLastMeterReadingTime());
        dto.setEndDate(houseMeterReading.getMeterReadingTime());
        dto.setMeterFullName(houseMeter.getMeterFullName());
        dto.setLastMeterReadingNum(houseMeterReading.getLastMeterReadingNum());
        dto.setMeterReadingNum(houseMeterReading.getMeterReadingNum());
        PropertyMeter meter = iPropertyMeterService.getById(houseMeterReading.getMeterId());
        if(Func.isNotEmpty(meter)){
            dto.setMeterUnit(meter.getUnit());
        }
        createBillDto.setMeterCreateBillDtoList(Arrays.asList(dto));
        propertyBillFactoryService.createBill(createBillDto);
        return true;
    }

    private void buildDetailPageVo(PropertyHouseMeterReadingDetailPageVo vo) {
        PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(vo.getParkId());
        if (Func.isNotEmpty(parkInfo)) {
            vo.setParkName(parkInfo.getParkName());
        }
        PropertyBuildings buildings = propertyBuildingsService.getById(vo.getBuildingId());
        if (Func.isNotEmpty(buildings)) {
            vo.setBuildingName(buildings.getBuildingName());
        }
        PropertyHouses houses = propertyHousesService.getById(vo.getHouseId());
        if (Func.isNotEmpty(houses)) {
            vo.setHouseName(houses.getHouseName());
        }
        PropertyMeter meter = iPropertyMeterService.getById(vo.getMeterId());
        if (Func.isNotEmpty(meter)) {
            vo.setMeterName(meter.getMeterName());
        }
        PropertyHouseMeter houseMeter = iPropertyHouseMeterService.getById(vo.getHouseMeterId());
        if(Func.isNotEmpty(houseMeter)){
            vo.setMeterFullName(houseMeter.getMeterFullName());
        }
        //未计费状态倍率取配置的,用量重新算
        if (Func.isNotEmpty(vo.getIsCharging()) && vo.getIsCharging() == 0) {
            if (Func.isNotEmpty(houseMeter)) {
                vo.setRate(houseMeter.getRate());
                vo.setAttritionRate(houseMeter.getAttritionRate());
                vo.setDosage(this.getDosage(vo.getMeterReadingNum(), vo.getLastMeterReadingNum(), vo.getRate(),vo.getAttritionRate(),houseMeter.getParkId()));
            }

        }
    }

}
