package com.iformall.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.*;
import com.iformall.domain.po.base.BaseEntity;
import com.iformall.domain.vo.BillTimeVo;
import com.iformall.enums.*;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.*;
import com.iformall.service.*;
import com.iformall.utils.DateUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author gongbiao
 */
@Service
public class WxPropertyContractServiceImpl implements WxPropertyContractService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private String fmUploadDir;

    @Autowired
    WxPropertyContractMapper wxPropertyContractMapper;

    @Autowired
    WxShopMapper wxShopMapper;

    @Autowired
    WxBillPropertyMapper wxBillPropertyMapper;

    @Autowired
    WxBillPropertyDepositMapper wxBillPropertyDepositMapper;

    @Autowired
    WxMerchantMapper wxMerchantMapper;

    @Autowired
    WxRentContractMapper wxRentContractMapper;

    @Autowired
    WxFlowService wxFlowService;

    @Autowired
    WxFlowRecordService wxFlowRecordService;

    @Autowired
    WxRentContractService wxRentContractService;

    @Autowired
    WxPayAccountBillService wxPayAccountBillService;

    @Override
    public Map<String, Object> listAsPage(WxPropertyContract record, Integer pageIndex, Integer pageSize) {
        //Object rentContractStatusInfo = getRentContractStatusInfo(record);
        PageHelper.startPage(pageIndex, pageSize);
        List<Map<String, Object>> rentContractData = wxPropertyContractMapper.queryPropertyContractData(record);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(rentContractData);
        Map<String, Object> result = new HashMap<>();
        //result.put("rentContractStatusInfo", rentContractStatusInfo);
        result.put("pageInfo", pageInfo);
        return result;

    }

    @Override
    public Map<String, Object> getById(Long id) {

        Map<String, Object> result = new HashMap<>();
        WxPropertyContract wxPropertyContract = wxPropertyContractMapper.selectById(id);
        if (wxPropertyContract == null) {
            throw new MallinkException(ErrorCode.PROPERTY_CONTRACT_IS_NOT_FOUND);
        }

        //init dateDiff
        if(wxPropertyContract.getRentalStartDate() != null && wxPropertyContract.getRentalEndDate() != null){
            //加1天
            Date newEndDate = DateUtils.getDaySet(wxPropertyContract.getRentalEndDate(),Calendar.DATE,1);
            int[] array = DateUtils.getDiff(wxPropertyContract.getRentalStartDate(),newEndDate);
            result.put("totalPeriodMonth",array[0]);
            result.put("totalPeriodDay",array[1]);
        }

        //init 租赁单价
        String rentInfo = wxPropertyContract.getRentInfo();
        if(StringUtils.isNotBlank(rentInfo)){
            JSONArray rentInfoArray = JSONArray.parseArray(rentInfo);
            int size = rentInfoArray.size();
            //查询rent_info 包括shopId
            for (int i = 0; i < size; i++) {
                JSONObject rentInfoObject = rentInfoArray.getJSONObject(i);
                Double rentPrice = rentInfoObject.getDouble("rentPrice");
                Long price = wxPropertyContract.getPrice()/100;
                if(rentPrice == null){
                    if(StringUtils.isNotBlank(wxPropertyContract.getRentArea()) && !"0".equals(wxPropertyContract.getRentArea()) && !"0.00".equals(wxPropertyContract.getRentArea())&& !"0.0".equals(wxPropertyContract.getRentArea()) ) {
                        Double rentArea = Double.parseDouble(wxPropertyContract.getRentArea());
                        rentPrice = new BigDecimal((double) price / rentArea).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                        rentInfoObject.put("rentPrice", rentPrice);
                    }
                }
            }
            wxPropertyContract.setRentInfo(rentInfoArray.toJSONString());
        }else{
            if(StringUtils.isNotBlank(wxPropertyContract.getRentArea()) && !"0".equals(wxPropertyContract.getRentArea()) && !"0.00".equals(wxPropertyContract.getRentArea())&& !"0.0".equals(wxPropertyContract.getRentArea()) ) {
                if(StringUtils.isNotBlank(wxPropertyContract.getRentArea()) && !"0".equals(wxPropertyContract.getRentArea()) && !"0.00".equals(wxPropertyContract.getRentArea())) {
                    Long price = wxPropertyContract.getPrice();
                    Double rentArea = Double.parseDouble(wxPropertyContract.getRentArea()) * 100;
                    Double rentPrice = new BigDecimal((double) price / rentArea).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    rentPrice = rentPrice * 100;
                    if (rentPrice > 0) {
                        wxPropertyContract.setRentPrice(rentPrice.toString());
                    } else {
                        wxPropertyContract.setRentPrice("0");
                    }
                }
            }
        }
        if(wxPropertyContract.getPriceUnit() == null){
            wxPropertyContract.setPriceUnit(EnumPriceUnit.M.getCode());
        }
        if(wxPropertyContract.getAdjustPeriod().equals(EnumRentContractAdjustPeriod.ADJUST_PERIOD_DAY.getCode())){
            wxPropertyContract.setAdjustPeriod(EnumRentContractAdjustPeriod.ADJUST_PERIOD_MONTH.getCode());
            wxPropertyContract.setPriceUnit(EnumPriceUnit.D.getCode());
        }

        wxPropertyContract.setPrice(wxPropertyContract.getPrice() != null ? wxPropertyContract.getPrice() : 0);
        wxPropertyContract.setDeposit(wxPropertyContract.getDeposit() != null ? wxPropertyContract.getDeposit() : 0);

        result.put("wxPropertyContract", wxPropertyContract);
        //关联的商户
        if (wxPropertyContract.getMerchantId() != null) {
            WxMerchant wxMerchant = wxMerchantMapper.selectById(wxPropertyContract.getMerchantId());
            result.put("wxMerchant", wxMerchant);
        } else {
            result.put("wxMerchant", null);
        }
        //关联的店铺
        if (wxPropertyContract.getShopId() != null) {
            WxShop record = new WxShop();
            record.setId(wxPropertyContract.getShopId());
            List<Map<String, Object>> list = wxShopMapper.findListMap(record);
            result.put("wxShops", list);
        } else {
            result.put("wxShops", Collections.EMPTY_LIST);
        }

        //租赁费用欠缴
        WxRentContract wxRentContract = new WxRentContract();
        wxRentContract.setId(wxPropertyContract.getRentContractId());
        result.put("rentOweCount",wxRentContractMapper.queryOweCount(wxRentContract));
        //物业费用欠缴
        WxPropertyContract propertyContract = new WxPropertyContract();
        propertyContract.setId(id);
        result.put("propertyOweCount",wxPropertyContractMapper.queryOweCount(propertyContract));
        //押金欠缴
        result.put("depositOweCount",wxBillPropertyDepositMapper.queryOweCount(propertyContract));
        //押金状态
        WxBillPropertyDeposit wxBillPropertyDeposit = new WxBillPropertyDeposit();
        wxBillPropertyDeposit.setPropertyContractId(id);
        List<WxBillPropertyDeposit> select = wxBillPropertyDepositMapper.selectList(new QueryWrapper(wxBillPropertyDeposit));
        if (!select.isEmpty()) {
            result.put("depositStatus", select.get(0).getStatus());
        }
        //发起人备注
        WxFlowRecord wxFlowRecord = new WxFlowRecord();
        wxFlowRecord.setBusinessId(id);
        wxFlowRecord.setStatus(EnumFlowRecordStatus.NEW.getCode());
        List<WxFlowRecord> flowRecordList = wxFlowRecordService.findList(wxFlowRecord);
        if(!CollectionUtils.isEmpty(flowRecordList)){
            result.put("remark",flowRecordList.get(0).getRemark());
        }

        //查询预账单用于展示
        List<WxBillProperty> resultList = getWxBillPropertyPreview(id);
        result.put("previewBillRentList", resultList);

        return result;
    }

    @Override
    public List<WxBillProperty> getWxBillPropertyPreview(Long id) {
        WxBillProperty wxBillRent = new WxBillProperty();
        wxBillRent.setPropertyContractId(id);
        wxBillRent.setSortColumns(BaseEntity.SortField.Period_ASC);
        return wxBillPropertyMapper.findList(wxBillRent);
    }

    /**
     * 重新生成账单（预账单调整）
     */
    public void savePreviewBill(WxPropertyContract record){
        if(CollectionUtils.isEmpty(record.getPreviewBillRentList())){
            return;
        }
        wxBillPropertyMapper.deletePreviewBill(record);
        final IdWorker idWorker = IdWorker.get();
        int count = 1;
        for (WxBillProperty bill:record.getPreviewBillRentList()) {
            bill.setId(idWorker.nextId());
            Date date = new Date();
            bill.setPropertyContractId(record.getId());
            bill.setCreatetime(date);
            bill.setTenantId(record.getTenantId());
            bill.setOwe(bill.getReceivePay());
            bill.setNeedPay(bill.getNeedPay());
            bill.setUpdatetime(date);
            bill.setRentShopType(record.getRentShopType());
            bill.setPeriod(count);
            bill.setIsPreview(EnumIsPreview.YES.getCode());
            bill.setShopInfo(getShopInfoStr(record));
            bill.setRevenue(0L);
            bill.setLatePayRatio(0);
            bill.setPay(0L);
            bill.setIsDel(EnumDelStatus.NOT_DEL.getCode());
            bill.setShopId(record.getShopId());
            bill.setExpiredDay(0L);
            setExpiredDay(bill,Calendar.MONTH,record.getReceivePeriod());
            if (bill.getReceivePay().equals(0L)) {
                bill.setStatus(EnumBillRentStatus.PAID.getCode());
                bill.setPayDate(date);
            }
            count++;
        }
        wxBillPropertyMapper.insertBills(record.getPreviewBillRentList());
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public ResultData saveOrUpdate(WxPropertyContract record, Long userId, String userName) {
        // 保存调整金额（预账单调整）
        boolean haspreview = false;
        if(!CollectionUtils.isEmpty(record.getPreviewBillRentList())){
            savePreviewBill(record);
            haspreview = true;
        }

        if (record.getRentShopType().equals(EnumRentShopType.POINT.getCode()) && null == record.getShopId()) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "shopId不能为空");
        }

        WxRentContract wxRentContract = wxRentContractMapper.selectById(record.getRentContractId());
        if (wxRentContract != null) {
            if (wxRentContract.getStatus().equals(EnumRentContractStatus.CONTRACT_END.getCode()) ||
                    wxRentContract.getStatus().equals(EnumRentContractStatus.CONTRACT_TERMINATE.getCode()) ||
                    wxRentContract.getStatus().equals(EnumRentContractStatus.INVALID.getCode())) {
                return new ResultData(ErrorCode.RENT_CONTRACT_IS_TERMINATED);
            }
        } else {
            return new ResultData(ErrorCode.RENT_CONTRACT_IS_NOT_FOUND);
        }
        if (null == record.getMerchantId() && record.getOperationType().equals(EnumContractOperationType.PART.getCode())) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "merchantId不能为空");
        }
        if (record.getOperationType().equals(EnumContractOperationType.PART.getCode())) {
            WxMerchant merchant = wxMerchantMapper.selectById(record.getMerchantId());
            if (merchant == null) {
                return new ResultData(ErrorCode.MERCHANT_INFO_NOT_FOUND);
            }
        }
        if (null == record.getReceivePeriod()) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "付款周期不能为空");
        }
        if (null == record.getLease()) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "租期不能为空");
        }
        if (null == record.getPrice()) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "物业费不能为空");
        }
        if (null == record.getDeposit()) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "押金不能为空");
        }
        if (record.getPrice().longValue() <= 0) {
            return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(), "物业费要大于0");
        }

        WxPropertyContract propertyContract = new WxPropertyContract();
        propertyContract.setTenantId(record.getTenantId());
        propertyContract.setRentContractId(record.getRentContractId());
        long count = wxPropertyContractMapper.findList(propertyContract)
                .stream().filter(p -> p.getStatus().equals(EnumRentContractStatus.SIGNED_RENT_UNPAID.getCode()) ||
                        p.getStatus().equals(EnumRentContractStatus.RENT_PAID.getCode()) ||
                        p.getStatus().equals(EnumRentContractStatus.CONTRACT_END_SOON.getCode())).count();
        if (count > 0) {
            return new ResultData(ErrorCode.RENT_CONTRACT_WITH_SHOP_IS_FOUND);
        }
        //保存物业合同信息
        String message;
        boolean hasFlow = true;
        if (record.getId() == null) {
            if (record.getOperationType().equals(EnumContractOperationType.WHOLE.getCode())) {
                WxPropertyContract propertyContractQuery = new WxPropertyContract();
                propertyContractQuery.setRentContractId(record.getRentContractId());
                int propertyContractCount = wxPropertyContractMapper.selectCount(new QueryWrapper(propertyContractQuery));
                if (propertyContractCount > 0) {
                    throw new MallinkException(ErrorCode.SYS_SERVER_ERROR);
                }
            }
            hasFlow = false;
            final IdWorker idWorker = IdWorker.get();
            record.setId(idWorker.nextId());
            record.setRentalStartDate(wxRentContract.getRentalStartDate());
            record.setRentalEndDate(wxRentContract.getRentalEndDate());
            record.setStartDate(wxRentContract.getStartDate());
            record.setEndDate(wxRentContract.getEndDate());
            Date date = new Date();
            record.setCreatetime(date);
            record.setUpdatetime(date);
            if (record.getOperationType().equals(EnumContractOperationType.WHOLE.getCode())) {
                record.setStatus(EnumRentContractStatus.INTENTION.getCode());
            } else {
                record.setStatus(EnumRentContractStatus.WAIT_SIGN.getCode());
            }
            record.setApplyStatus(EnumRentContractAppStatus.DEFAULT.getCode());
            try {
                wxPropertyContractMapper.insert(record);
            } catch (Exception e) {
                logger.error("保存物业合同信息失败,e:" + e.getMessage());
                throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
            }

            //生成预览账单
            wxBillPropertyMapper.deletePreviewBill(record);
            //重新生成
            List<WxBillProperty> billList = buildProperty(new WxMerchant(),userId,record,EnumIsPreview.YES.getCode(),true);
            record.setPreviewBillRentList(billList);

            message = "保存物业合同信息成功";
        } else {//更新物业合同信息
            //查询预账单用于展示
            WxBillProperty wxBillRent = new WxBillProperty();
            wxBillRent.setPropertyContractId(record.getId());
            wxBillRent.setSortColumns(BaseEntity.SortField.Period_ASC);
            wxBillRent.setIsPreview(EnumIsPreview.YES.getCode());
            List<WxBillProperty> billList = wxBillPropertyMapper.findList(wxBillRent);
            record.setPreviewBillRentList(billList);

            if(!haspreview){
                if (record.getReceivePeriod() != null && record.getLease() != null && record.getPrice() != null
                        && !record.getReceivePeriod().equals(0) && !record.getLease().equals(0) && !record.getPrice().equals(0l)) {
                    //删除预账单，重新生成
                    wxBillPropertyMapper.deletePreviewBill(record);
                    //重新生成
                    billList = buildProperty(new WxMerchant(),userId,record,EnumIsPreview.YES.getCode(),true);
                    record.setPreviewBillRentList(billList);
                }
            }

            WxPropertyContract wxPropertyContract = wxPropertyContractMapper.selectById(record.getId());
            if (wxPropertyContract == null) {
                return new ResultData(ErrorCode.PROPERTY_CONTRACT_IS_NOT_FOUND);
            }

            record.setRentalStartDate(wxRentContract.getRentalStartDate());
            record.setRentalEndDate(wxRentContract.getRentalEndDate());
            record.setStartDate(wxRentContract.getStartDate());
            record.setEndDate(wxRentContract.getEndDate());
            record.setPrice(record.getPrice() != null ? record.getPrice() : 0);
            record.setDeposit(record.getDeposit() != null ? record.getDeposit() : 0);
            record.setUpdatetime(new Date());
            if (CollectionUtils.isEmpty(record.getFlowParams())) {
                hasFlow = false;
                record.setApplyStatus(EnumRentContractAppStatus.DEFAULT.getCode());
            }
            try {
                wxPropertyContractMapper.updateById(record);
            } catch (Exception e) {
                logger.error("更新物业合同信息失败,e:" + e.getMessage());
                throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
            }

            message = "更新物业合同信息成功";
        }

        if (hasFlow) {
            if (record.getOperationType().equals(EnumContractOperationType.PART.getCode())) {
                if (wxFlowService.getModelByType((Integer) record.getFlowParams().get("businessType"), record.getTenantId()) == null) {
                    updatePropertyContractStatus(record.getId());
                } else {
                    record.getFlowParams().put("businessId", record.getId().toString());
                    wxFlowService.start(record.getFlowParams(), userId, userName, record.getTenantId());

                    // 合同状态改成待签约
                    WxPropertyContract updateRentContract = new WxPropertyContract();
                    updateRentContract.setId(record.getId());
                    updateRentContract.setStatus(EnumRentContractStatus.WAIT_SIGN.getCode());
                    wxPropertyContractMapper.updateStatus(updateRentContract);
                    logger.info("id:{},启动审批流成功", record.getId().toString());
                }
            } else {
                if (wxFlowService.getModelByType((Integer) record.getFlowParams().get("businessType"), record.getTenantId()) == null
                        && record.getMerchantId() != null) {
                    wxRentContractService.updateRentContractStatus(record.getId());
                } else {
                    record.getFlowParams().put("businessId", record.getRentContractId().toString());
                    if (record.getMerchantId() != null) {
                        record.getFlowParams().put("supplement", true);  //设置补录
                    }
                    wxFlowService.start(record.getFlowParams(), userId, userName, record.getTenantId());

                    // 合同状态改成待签约
                    WxRentContract updateRentContract = new WxRentContract();
                    updateRentContract.setId(record.getRentContractId());
                    updateRentContract.setStatus(EnumRentContractStatus.WAIT_SIGN.getCode());
                    wxRentContractMapper.updateStatus(updateRentContract);
                    logger.info("id:{},启动审批流成功,是否补录:{}", record.getRentContractId().toString(), record.getMerchantId() != null);
                }
            }
        }else{
            //审批状态重置
            WxPropertyContract updateRentContract = new WxPropertyContract();
            updateRentContract.setId(record.getId());
            updateRentContract.setApplyStatus(EnumRentContractAppStatus.DEFAULT.getCode());
            wxPropertyContractMapper.updateById(updateRentContract);
        }

        return new ResultData(Result.SUCCESS, message, record);
    }

    @Override
    public ResultData updatePropertyContractStatus(Long id) {
        if (id == null) {
            return new ResultData(ErrorCode.SYS_PARAMETER_ERROR);
        }
        WxPropertyContract record = wxPropertyContractMapper.selectById(id);
        //更新合同状态为签约
        WxPropertyContract wxPropertyContract = new WxPropertyContract();
        wxPropertyContract.setId(id);
        if (record.getRentalStartDate().before(new Date())) {
            wxPropertyContract.setStatus(EnumRentContractStatus.RENT_PAID.getCode());
        } else {
            wxPropertyContract.setStatus(EnumRentContractStatus.SIGNED_RENT_UNPAID.getCode());
        }
        wxPropertyContractMapper.updateById(wxPropertyContract);
        //建立账单
        if (record.getMerchantId() != null
                && record.getReceivePeriod() != null &&
                record.getPrice() > 0) {
            //预览账单改为正式,并写入商户id
            updatePropertyPreviewBill(record);
        }
        return new ResultData(Result.SUCCESS, "操作成功");
    }

    @Override
    public void updatePropertyPreviewBill(WxPropertyContract record) {
        WxBillProperty billProperty = new WxBillProperty();
        billProperty.setPropertyContractId(record.getId());
        billProperty.setIsPreview(EnumIsPreview.NO.getCode());
        billProperty.setMerchantId(record.getMerchantId());
        wxBillPropertyMapper.updatePreviewStatus(billProperty);
        if(record.getDeposit() > 0) {
            buildDeposit(record);
        }
    }

    @Transactional(rollbackFor = {Exception.class})
    public void buildDeposit(WxPropertyContract record) {
        Long propertyContractId = record.getId();
        WxPropertyContract wxPropertyContract = wxPropertyContractMapper.selectById(propertyContractId);
        if (wxPropertyContract != null && wxPropertyContract.getDeposit() > 0) {
            //找到计租方式
            int dayType = wxPropertyContract.getAdjustPeriod().equals(EnumRentContractAdjustPeriod.ADJUST_PERIOD_DAY.getCode()) ? Calendar.DAY_OF_MONTH : Calendar.MONTH;
            final IdWorker idWorker = IdWorker.get();
            WxBillPropertyDeposit wxBillDeposit = new WxBillPropertyDeposit();
            wxBillDeposit.setId(idWorker.nextId());
            wxBillDeposit.setPropertyContractId(wxPropertyContract.getId());
            wxBillDeposit.setPay(0L);
            Long needpay = wxPropertyContract.getDeposit();
            wxBillDeposit.setNeedPay(needpay);
            wxBillDeposit.setReceivePay(needpay);
            wxBillDeposit.setOwe(needpay);
            Date date = new Date();
            Calendar instance = Calendar.getInstance();
            instance.setTime(wxPropertyContract.getRentalStartDate());
            instance.add(Calendar.DAY_OF_MONTH, -1);
            Date time = instance.getTime();
            wxBillDeposit.setReceiveDate(time);
            //账单开始时间
            instance.clear();
            instance.setTime(wxBillDeposit.getReceiveDate());
            instance.add(Calendar.DAY_OF_MONTH, 1);
            wxBillDeposit.setStarttime(instance.getTime());
            //账单结束时间
            instance.clear();
            instance.setTime(wxBillDeposit.getReceiveDate());
            instance.add(dayType, wxPropertyContract.getLease());
            wxBillDeposit.setEndtime(instance.getTime());
            wxBillDeposit.setStatus(EnumBillRentStatus.WAIT_PAY.getCode());
            wxBillDeposit.setExpiredDay(0L);
            wxBillDeposit.setTenantId(record.getTenantId());
            wxBillDeposit.setIsDel(0);
            wxBillDeposit.setMerchantId(record.getMerchantId());
            wxBillDeposit.setShopId(wxPropertyContract.getShopId());
            wxBillDeposit.setCreatetime(date);
            wxBillDeposit.setUpdatetime(date);
            wxBillDeposit.setIsDel(EnumDelStatus.NOT_DEL.getCode());
            wxBillDeposit.setRentShopType(wxPropertyContract.getRentShopType());
            wxBillDeposit.setShopInfo(getShopInfoStr(wxPropertyContract));
            try {
                wxBillPropertyDepositMapper.insert(wxBillDeposit);
            } catch (Exception e) {
                logger.error("添加物业押金账单失败,e:" + e.getMessage());
                throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
            }
        }
    }

    public String getShopInfoStr(WxPropertyContract wxPropertyContract){
        String rentInfo = wxPropertyContract.getRentInfo();
        Map<String, Object> shopInfo = new HashMap<>();
        if (rentInfo != null) {
            JSONArray rentInfoArray = JSONArray.parseArray(rentInfo);
            for (int i = 0, size = rentInfoArray.size(); i < size; i++) {
                JSONObject rentInfoObject = rentInfoArray.getJSONObject(i);
                shopInfo.put(rentInfoObject.getString("shopNumber"), rentInfoObject.get("buildArea"));
            }
        }
        return JSONObject.toJSONString(shopInfo);
    }

    public List<WxBillProperty> buildRentMonth(WxMerchant wxMerchant, Long userId, WxPropertyContract wxPropertyContract, int receivePeriod, Integer lease, Date rentalStartDate, Long price, Integer isPreview,boolean saveDb) {
        String adjustRatio = wxPropertyContract.getAdjustRatio();
        String rentInfo = wxPropertyContract.getRentInfo();
        Map<String, Object> shopInfo = new HashMap<>();
        if (rentInfo != null) {
            JSONArray rentInfoArray = JSONArray.parseArray(rentInfo);
            for (int i = 0, size = rentInfoArray.size(); i < size; i++) {
                JSONObject rentInfoObject = rentInfoArray.getJSONObject(i);
                shopInfo.put(rentInfoObject.getString("shopNumber"), rentInfoObject.get("buildArea"));
            }
        }

        List<Integer> integers = JSONArray.parseArray(adjustRatio, Integer.class);
        integers.add(0, 0);
        int size = integers.size();
        long[] priceArr = new long[size];
        priceArr[0] = price;
        //判断年租金调整方式
        if (wxPropertyContract.getAdjustRatioWay().equals(EnumRentContractAdjustRatioWay.RATIO.getCode())) {
            double priceD = price;
            for (int i = 1; i < size; i++) {
                priceD = priceD + priceD * integers.get(i) / 10000.0;
                priceArr[i] = new BigDecimal(priceD).setScale(0, RoundingMode.HALF_EVEN).longValue();
            }
        } else if (wxPropertyContract.getAdjustRatioWay().equals(EnumRentContractAdjustRatioWay.MONEY.getCode())) {
            long priceD = price;
            for (int i = 1; i < size; i++) {
                priceD = priceD + integers.get(i);
                priceArr[i] = new BigDecimal(priceD).setScale(0, RoundingMode.HALF_EVEN).longValue();
            }
        } else {
            for (int i = 1; i < size; i++) {
                priceArr[i] = new BigDecimal(integers.get(i)).setScale(0, RoundingMode.HALF_EVEN).longValue();
            }
        }

        int month = 12;
        int divide = lease / month;
        int mod = lease % month;
        int[] leaseArr = new int[size];
        for (int i = 0; i < divide; i++) {
            leaseArr[i] = month;
        }
        if (mod > 0) {
            leaseArr[divide] = mod;
        }

        int billcount = 0;
        List<WxBillProperty> resultList = new ArrayList<>();

        List<Date> yearList = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            Calendar instance = Calendar.getInstance();
            Date startDate;
            //自然月
            if(wxPropertyContract.getAdjustPeriod().equals(EnumRentContractAdjustPeriod.ADJUST_PERIOD_NAR_MONTH.getCode())){
                if(i == 0){ //第一期
                    startDate = rentalStartDate;
                }else{
                    instance.setTime(rentalStartDate);
                    instance.add(Calendar.MONTH, month * i);
                    startDate = DateUtils.getFirstDayForCurrMonth(instance.getTime());
                }
            }else{
                instance.setTime(rentalStartDate);
                instance.add(Calendar.MONTH, month * i);
                startDate = instance.getTime();
            }
            yearList.add(startDate);
        }
        Map<String, Object> resultMap = buildRent(receivePeriod, priceArr, yearList, Calendar.MONTH, wxPropertyContract, userId, wxMerchant, billcount, isPreview, shopInfo,saveDb);
        List<WxBillProperty> billRentList = (List<WxBillProperty>)resultMap.get("billList");
        resultList.addAll(billRentList);
        return resultList;
    }

    public Map<String, Object> buildRent(int receivePeriod,long[] priceArrs, List<Date> yearList,int dayType, WxPropertyContract wxPropertyContract, Long userId, WxMerchant wxMerchant, int billcount, Integer isPreview,Map<String, Object> shopInfo,boolean saveDb) {
        WxPayAccountBill wxPayAccountBill = wxPayAccountBillService.getByTenantId(wxPropertyContract.getTenantId());
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
        Map<String,Object> resultMap = new HashedMap();
        List<WxBillProperty> resultList = new ArrayList<>();
        final IdWorker idWorker = IdWorker.get();

        Date endDate = null;
        if(yearList.size() > 1){
            endDate = yearList.get(1);
        }

        List<BillTimeVo> billTimeVoList = new ArrayList<>();
        if(saveDb){
            billTimeVoList = WxRentContractServiceImpl.initBillTimeList(wxPropertyContract.getRentalStartDate(),wxPropertyContract.getRentalEndDate(),wxPropertyContract.getAdjustPeriod(),dayType,receivePeriod);
        }else{
            //预账单编辑账期，生成金额
            for (WxBillProperty rent:wxPropertyContract.getPreviewBillRentList()) {
                BillTimeVo billTimeVo = new BillTimeVo();
                billTimeVo.setStartDate(rent.getStarttime());
                billTimeVo.setEndDate(rent.getEndtime());
                billTimeVo.setReceiveDate(DateUtils.getDaySet(rent.getStarttime(),Calendar.DATE,-1));
                billTimeVoList.add(billTimeVo);
            }
        }

        int index = 0;
        for (int i = 0; i < billTimeVoList.size(); i++) {
            BillTimeVo billTimeVo =  billTimeVoList.get(i);
            //计算金额
            long needpay = 0;

            boolean flag = false;
            if(yearList.size() > 1) {
                if (endDate!=null && (sd.format(billTimeVo.getStartDate()).equals(sd.format(endDate)) || billTimeVo.getStartDate().after(endDate) || billTimeVo.getEndDate().after(endDate) )) {
                    if(yearList.size() > 1) {
                        if (endDate!=null && (sd.format(billTimeVo.getStartDate()).equals(sd.format(endDate)) || billTimeVo.getStartDate().after(endDate) || billTimeVo.getEndDate().after(endDate) )) {
                            //logger.info("=====billTimeVo.getStartDate():"+sd.format(billTimeVo.getStartDate())+" endDate:"+sd.format(endDate));

                            index++;

                            //如果是计算账单金额&cross 拆分日期进行计算
                            if(!saveDb && billTimeVo.getEndDate().after(endDate)) {
                                long needpayFront = 0;
                                long needpayAfter = 0;
                                //同一天，算一天
                                if(sd.format(billTimeVo.getStartDate()).equals(sd.format(billTimeVo.getEndDate()))){
                                    needpayFront = getNeedPayMoney(wxPropertyContract,priceArrs[index-1],billTimeVo.getStartDate(),endDate,i,billTimeVoList.size(),saveDb,dayType,receivePeriod);
                                }else{
                                    if(billTimeVo.getStartDate().before(endDate)){
                                        needpayFront = getNeedPayMoney(wxPropertyContract, priceArrs[index - 1], billTimeVo.getStartDate(), DateUtils.getDaySet(endDate,Calendar.DATE,-1), i, billTimeVoList.size(), saveDb,dayType,receivePeriod);
                                        needpayAfter = getNeedPayMoney(wxPropertyContract, priceArrs[index], endDate, billTimeVo.getEndDate(), i, billTimeVoList.size(), saveDb,dayType,receivePeriod);
                                    }else{
                                        needpayFront = getNeedPayMoney(wxPropertyContract, priceArrs[index], billTimeVo.getStartDate(), billTimeVo.getEndDate(), i, billTimeVoList.size(), saveDb,dayType,receivePeriod);
                                    }
                                }
                                needpay = needpayFront+needpayAfter;
                                flag = true;
                            }
                            if(index >= yearList.size()-1){
                                endDate = null;
                            }else{
                                endDate = yearList.get(index+1);//price index 0开始，year.end 从第二年开始
                                //logger.info("==========cross:"+sd.format(endDate));
                            }
                        }
                    }
                }
            }

            //计算金额
            if(!flag){
                needpay = getNeedPayMoney(wxPropertyContract, priceArrs[index], billTimeVo.getStartDate(), billTimeVo.getEndDate(), i, billTimeVoList.size(),saveDb,dayType,receivePeriod);
            }

            WxBillProperty wxBillProperty = new WxBillProperty();
            wxBillProperty.setIsPreview(isPreview);
            wxBillProperty.setId(idWorker.nextId());
            wxBillProperty.setPropertyContractId(wxPropertyContract.getId());
            wxBillProperty.setPay(0L);
            wxBillProperty.setStarttime(billTimeVo.getStartDate());
            wxBillProperty.setEndtime(billTimeVo.getEndDate());
            wxBillProperty.setReceiveDate(billTimeVo.getReceiveDate());

            wxBillProperty.setNeedPay(needpay);
            wxBillProperty.setOwe(needpay);
            wxBillProperty.setReceivePay(needpay);

            //截止收租日在当前时间之前
            Date date = new Date();
            setExpiredDay(wxBillProperty,dayType,receivePeriod);
            wxBillProperty.setTenantId(wxPropertyContract.getTenantId());
            wxBillProperty.setIsDel(0);
            wxBillProperty.setMerchantId(wxPropertyContract.getMerchantId());
            wxBillProperty.setUserId(userId);
            wxBillProperty.setShopId(wxPropertyContract.getShopId());
            wxBillProperty.setCreatetime(date);
            wxBillProperty.setUpdatetime(date);
            wxBillProperty.setIsDel(EnumDelStatus.NOT_DEL.getCode());
            wxBillProperty.setRentShopType(wxPropertyContract.getRentShopType());
            wxBillProperty.setPeriod(++billcount);
            if (shopInfo != null) {
                wxBillProperty.setShopInfo(JSONObject.toJSONString(shopInfo));
            }
            wxBillProperty.setLatePayRatio(0);

            //计算手续费
            BigDecimal servicePay = new BigDecimal(wxBillProperty.getReceivePay()).multiply(new BigDecimal(wxPayAccountBill.getServiceChargeRate())).divide(new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP);
            wxBillProperty.setServiceChargePay(servicePay.intValue());

            resultList.add(wxBillProperty);
        }
        //批量生成预账单
        if(saveDb) {
            wxBillPropertyMapper.insertBills(resultList);
        }
        resultMap.put("billcount",billcount);
        resultMap.put("billList",resultList);
        return resultMap;
    }

    public long getNeedPayMoney(WxPropertyContract wxRentContract,long price,Date startDate,Date endDate,int i,int billTimeVoListSize,boolean saveDb,int dayType,int receivePeriod){
        long needpay;
        //按日
        if (wxRentContract.getPriceUnit().equals(EnumPriceUnit.D.getCode())){
            Double priceD = new Double(price);
            double needpayD = WxRentContractServiceImpl.getNeedPay(0,priceD,startDate,endDate);
            needpay = new Double(needpayD).longValue();
        }else{
            //年 需要除12
            Double priceD = new Double(price);
            if(EnumPriceUnit.Y.getCode().equals(wxRentContract.getPriceUnit())){
                priceD = new Double(price)/12;
            }

            //生成金额直接计算
            if(!saveDb){
                needpay = new Double(WxRentContractServiceImpl.getMonthNeedPay(priceD, startDate, endDate,dayType,receivePeriod,false)).longValue();
                return needpay;
            }

            SimpleDateFormat sdM = new SimpleDateFormat("yyyy-MM");
            SimpleDateFormat sdD = new SimpleDateFormat("d");
            SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat sdMR = new SimpleDateFormat("MM-dd");

            if(i == billTimeVoListSize - 1){//最后
                if(sdMR.format(startDate).equals(sdMR.format(wxRentContract.getStartDate())) && sdMR.format(endDate).equals(sdMR.format(wxRentContract.getEndDate())) ){
                    int months = WxRentContractServiceImpl.getMonths(sdM.format(startDate)+"-01",sdM.format(endDate)+"-01");
                    months++;
                    needpay = new Double(months * priceD).longValue();
                }else {
                    needpay = new Double(WxRentContractServiceImpl.getMonthNeedPay(priceD, startDate, endDate,dayType,receivePeriod,false)).longValue();
                }
            }else if(i == 0){//第一期
                if(wxRentContract.getAdjustPeriod().equals(EnumRentContractAdjustPeriod.ADJUST_PERIOD_NAR_MONTH.getCode())){
                    if(isFirstDay(startDate)){
                        int months = WxRentContractServiceImpl.getMonths(sdM.format(startDate)+"-01",sdM.format(endDate)+"-01");
                        months++;
                        needpay = new Double(months * priceD).longValue();
                    }else{
                        needpay = new Double(WxRentContractServiceImpl.getMonthNeedPay(priceD, startDate, endDate,dayType,receivePeriod,false)).longValue();
                    }
                }else{
                    if(isFirstDay(startDate)){
                        int months = WxRentContractServiceImpl.getMonths(sdM.format(startDate)+"-01",sdM.format(endDate)+"-01");
                        if(isFirstDay(startDate)){
                            months++;
                        }
                        needpay = new Double(months * priceD).longValue();
                    }else{
                        needpay = new Double(WxRentContractServiceImpl.getMonthNeedPay(priceD, startDate, endDate,dayType,receivePeriod,false)).longValue();
                    }
                }
            }else{//中间
                int months = WxRentContractServiceImpl.getMonths(sdM.format(startDate)+"-01",sdM.format(endDate)+"-01");
                if(isFirstDay(startDate)){
                    months++;
                }
                needpay = new Double(months * priceD).longValue();
            }
        }
        return needpay;
    }

    public void setExpiredDay(WxBillProperty wxBillProperty,int dayType, int receivePeriod){
        Date date = new Date();
        wxBillProperty.setExpiredDay(0L);
        if (wxBillProperty.getReceiveDate().before(date)) {
            long day = (date.getTime() - wxBillProperty.getReceiveDate().getTime()) / (24 * 60 * 60 * 1000);
            wxBillProperty.setStatus(EnumBillRentStatus.NOT_PAID.getCode());
            if (day > 0) {
                wxBillProperty.setExpiredDay(day);
            }
        } else {//截止收租日在当前时间之后
            Calendar now = Calendar.getInstance();
            now.add(dayType, receivePeriod);
            Date currenttime = now.getTime();
            //当前日期加上周期后小于截止收租日就是没有到期，否则当前待缴
            if (currenttime.before(wxBillProperty.getReceiveDate())) {
                wxBillProperty.setStatus(EnumBillRentStatus.NOT_EXPIRED.getCode());
            } else {
                wxBillProperty.setStatus(EnumBillRentStatus.WAIT_PAY.getCode());
            }
        }
    }

    public boolean isFirstDay(Date date){
        int dateInt = Integer.parseInt(new SimpleDateFormat("d").format(date));
        if(dateInt == 1){
            return true;
        }
        return false;
    }

    /**
     * 根据商户/指定物业合同生成物业账单
     * @param wxMerchant
     * @param propertyContract
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public List<WxBillProperty> buildProperty(WxMerchant wxMerchant,Long userId,WxPropertyContract propertyContract,Integer isPreview,boolean saveDb) {
        List<WxBillProperty> result = new ArrayList<>();

        WxPropertyContract wxPropertyContract;
        if(propertyContract == null){
            //根据商户ID找出合同
            wxPropertyContract = new WxPropertyContract();
            wxPropertyContract.setMerchantId(wxMerchant.getId());
            List<WxPropertyContract> list = wxPropertyContractMapper.findList(wxPropertyContract);
            if (list.size() > 0) {
                wxPropertyContract = list.get(0);
            }
        }else{
            wxPropertyContract = propertyContract;
        }

        if (wxPropertyContract != null) {
            int receivePeriod = wxPropertyContract.getReceivePeriod().intValue();
            Integer lease = wxPropertyContract.getLease();
            Date rentalStartDate = wxPropertyContract.getRentalStartDate();
            if (EnumRentStartType.STARTTIME.getCode().equals(wxPropertyContract.getRentStartType())) {
                rentalStartDate = wxPropertyContract.getStartDate();
            }
            propertyContract.setRentalStartDate(rentalStartDate);
            Long price = propertyContract.getPrice();

            //按月计租
            result = buildRentMonth(wxMerchant, userId, propertyContract, receivePeriod, lease, rentalStartDate, price,isPreview,saveDb);
        }
        for (int i = 0; i < result.size(); i++) {
            result.get(i).setPeriod(i+1);
        }
        return result;
    }

    @Override
    public void deleteById(Long id) {
        wxPropertyContractMapper.deleteById(id);
    }


    @Override
    public void download(HttpServletRequest request, HttpServletResponse response, String tenantId) {
        String id = request.getParameter("id");
        WxPropertyContract wxPropertyContract = wxPropertyContractMapper.selectById(id);

        String filesuffix = wxPropertyContract.getFilepath().substring(wxPropertyContract.getFilepath().lastIndexOf("."));
        String filename = UUID.randomUUID() + filesuffix;
        String filepath = fmUploadDir;
        String destPath = filepath + filename;
        File dest = new File(destPath);
        File pDest = dest.getParentFile();
        if (!pDest.exists()) {
            pDest.mkdirs();
        }
        try {
            String exportFileName = wxPropertyContract.getFilename();
            downLoadFromUrl(wxPropertyContract.getFilepath(), filename, filepath);
            downFile(destPath, wxPropertyContract.getFilename(), exportFileName,response, request);
            org.apache.commons.io.FileUtils.forceDelete(dest);
        } catch (IOException e) {
            logger.info("创建本地文件失败" + e.getMessage());
        }
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Object getRentContractStatusInfo(WxPropertyContract record) {

        Map<String, Object> resultData = new HashMap();
        //商铺信息
        WxShop wxShop = new WxShop();
        wxShop.setTenantId(record.getTenantId());
        wxShop.setType(record.getRentShopType());
        wxShop.setStatus(EnumShopStatus.RENT.getCode());
        List<WxShop> rentedList = wxShopMapper.findList(wxShop);
        wxShop.setStatus(EnumShopStatus.NOT_RENT.getCode());
        List<WxShop> unrentedList = wxShopMapper.findList(wxShop);

        HashMap<String, Object> shopMap = new HashMap<>(3);
        int rentedCount = rentedList.size();
        int unrentedCount = unrentedList.size();
        shopMap.put("rentedCount",rentedCount);
        shopMap.put("unrentedCount",unrentedCount);
        shopMap.put("allCount",rentedCount+unrentedCount);
        resultData.put("shopCountInfo", shopMap);

        //需要更新的状态
        resultData.putAll(updateStatus(record));
        return resultData;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public ResultData endRentContract(Long id) {

        WxPropertyContract wxPropertyContract = wxPropertyContractMapper.selectById(id);
        if (wxPropertyContract == null) {
            return new ResultData(ErrorCode.PROPERTY_CONTRACT_IS_NOT_FOUND);
        }
        wxPropertyContract.setStatus(EnumRentContractStatus.CONTRACT_TERMINATE.getCode());
        try {
            wxPropertyContract.setUpdatetime(new Date());
            wxPropertyContractMapper.updateById(wxPropertyContract);
        } catch (MallinkException e) {
            logger.info("终止合同失败:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        return new ResultData(Result.SUCCESS, "操作成功");
    }


    @Override
    public Object getRentContractList(WxPropertyContract record) {
        Map<String, Object> params = new HashMap<>();
        params.put("tenantId", record.getTenantId());
        params.put("rentShopType", record.getRentShopType());
        List<WxRentContract> contractList;
        if (record.getRentShopType().equals(EnumRentShopType.SHOP.getCode())) {
            contractList = wxPropertyContractMapper.getRentContractListByShop(params);
        } else {
            contractList = wxPropertyContractMapper.getRentContractListByPoint(params);
        }
        return contractList;
    }

    @Override
    public ResultData endPropertyContractByRentContractId(Long rentContractId) {
        WxPropertyContract wxPropertyContractParam = new WxPropertyContract();
        wxPropertyContractParam.setRentContractId(rentContractId);
        List<Map<String, Object>> contractData = wxPropertyContractMapper.queryPropertyContractData(wxPropertyContractParam);
        if (contractData.size() == 0) {
            return new ResultData(ErrorCode.PROPERTY_CONTRACT_IS_NOT_FOUND);
        }
        Map<String, Object> contractMap = contractData.get(0);
        WxPropertyContract wxPropertyContract = wxPropertyContractMapper.selectById((Long) contractMap.get("id"));
        wxPropertyContract.setStatus(EnumRentContractStatus.CONTRACT_TERMINATE.getCode());
        try {
            wxPropertyContractMapper.updateById(wxPropertyContract);
        } catch (MallinkException e) {
            logger.info("终止合同失败:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        return new ResultData(Result.SUCCESS, "操作成功");
    }

    @Override
    public ResultData hasRentContract(Long rentContractId) {
        if (null == rentContractId) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL, "rentContractId不能为空");
        }

        WxRentContract wxRentContract = wxRentContractMapper.selectById(rentContractId);
        if (wxRentContract != null) {
            WxPropertyContract wxPropertyContract = new WxPropertyContract();
            wxPropertyContract.setTenantId(wxRentContract.getTenantId());
            if (wxRentContract.getRentShopType().equals(EnumRentShopType.SHOP.getCode())) {
                wxPropertyContract.setMerchantId(wxRentContract.getMerchantId());
            } else {
                wxPropertyContract.setShopId(wxRentContract.getShopId());
            }
            List<WxPropertyContract> select = wxPropertyContractMapper.selectList(new QueryWrapper(wxPropertyContract));
            if (select.size() > 0) {
                long count = select.stream().filter(propertyContract -> propertyContract.getStatus().equals(EnumRentContractStatus.SIGNED_RENT_UNPAID.getCode()) ||
                        propertyContract.getStatus().equals(EnumRentContractStatus.RENT_PAID.getCode()) ||
                        propertyContract.getStatus().equals(EnumRentContractStatus.CONTRACT_END_SOON.getCode())).count();
                if (count > 0) {
                    return new ResultData(true);
                }
            }
        }
        return new ResultData(false);
    }

    @Override
    public Map<String, Object> updateStatus(WxPropertyContract record) {
        Map<String, Object> resultData = new HashMap();
        WxPropertyContract wxPropertyContract = new WxPropertyContract();
        wxPropertyContract.setTenantId(record.getTenantId());
        wxPropertyContract.setRentShopType(record.getRentShopType());

        int allCount = wxPropertyContractMapper.selectCount(new QueryWrapper(wxPropertyContract));
        resultData.put("allCount", allCount);

        //作废合同
        wxPropertyContract.setStatus(EnumRentContractStatus.INVALID.getCode());
        wxPropertyContractMapper.updateRentInvalidStatus(wxPropertyContract);

        //待签约
        wxPropertyContract.setStatus(EnumRentContractStatus.WAIT_SIGN.getCode());
        wxPropertyContractMapper.updateRentWaitSignStatus(wxPropertyContract);
        int waitSignCount = wxPropertyContractMapper.queryRentContractWaitSignStatus(wxPropertyContract);
        resultData.put("waitSignCount", waitSignCount);

        //计租中
        wxPropertyContract.setStatus(EnumRentContractStatus.RENT_PAID.getCode());
        wxPropertyContractMapper.updateRentContractPaidStatus(wxPropertyContract);
        int rendPaidCount = wxPropertyContractMapper.queryRentContractPaidStatus(wxPropertyContract);
        resultData.put("rendPaidCount", rendPaidCount);

        //将到期
        wxPropertyContract.setStatus(EnumRentContractStatus.CONTRACT_END_SOON.getCode());
        wxPropertyContractMapper.updateRentContractEndSoonStatus(wxPropertyContract);
        int endSoonCount = wxPropertyContractMapper.queryRentContractEndSoonStatus(wxPropertyContract);
        resultData.put("endSoonCount", endSoonCount);

        //到期
        wxPropertyContract.setStatus(EnumRentContractStatus.CONTRACT_END.getCode());
        int endCount = wxPropertyContractMapper.queryRentContractEndStatus(wxPropertyContract);
        wxPropertyContractMapper.updateRentContractEndStatus(wxPropertyContract);
        resultData.put("endCount", endCount);

        return resultData;
    }

    public static void downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置超时间为3秒
        conn.setConnectTimeout(3 * 1000);
        //防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

        //得到输入流
        InputStream inputStream = conn.getInputStream();
        //获取自己数组
        byte[] getData = readInputStream(inputStream);

        //文件保存位置
        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdir();
        }
        File file = new File(saveDir + File.separator + fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        if (fos != null) {
            fos.close();
        }
        if (inputStream != null) {
            inputStream.close();
        }


        System.out.println("info:" + url + " download success");

    }

    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    public void downFile(String filePath, String filename, String exportFileName, HttpServletResponse response,
                         HttpServletRequest req) {
        try {
            response.reset();
            response.setContentType("bin");
            String agent = req.getHeader("user-agent");
            if (agent.contains("Firefox")) {
                response.setHeader("Content-disposition", "attachment; filename=" + new String(exportFileName.getBytes("GB2312"), "ISO-8859-1"));
            } else {
                response.setHeader("Content-disposition", "attachment; filename=" + java.net.URLEncoder.encode(exportFileName, "UTF-8"));
            }
            // 循环取出流中的数据
            byte[] b = new byte[1024];
            int len;
            InputStream inStream = new FileInputStream(filePath);
            while ((len = inStream.read(b)) > 0)
                response.getOutputStream().write(b, 0, len);
            inStream.close();
        } catch (Exception e) {
            logger.info("下载合同失败" + e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public void endContract(WxPropertyContract wxPropertyContract) {
        wxPropertyContract.setStatus(EnumRentContractStatus.CONTRACT_TERMINATE.getCode());
        wxPropertyContractMapper.updateStatus(wxPropertyContract);

        WxBillProperty wxBillProperty = new WxBillProperty();
        wxBillProperty.setPropertyContractId(wxPropertyContract.getId());
        wxBillPropertyMapper.updateInvalidStatus(wxBillProperty);
    }

    @Override
    public WxPropertyContract getByBill(WxBillProperty billRent) {
        return wxPropertyContractMapper.getByBill(billRent);
    }

}




