package common.service.impl;

import adi.model.ADIUser;
import adi.service.ADIAccountService;
import common.model.*;
import common.repository.*;
import common.service.*;
import dic.ContractStatusEnum;
import dic.ContractTypeEnum;
import dic.RoleEnum;
import net.sf.json.JSONArray;
import org.apache.poi.ss.usermodel.*;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.format.DateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import tkio.model.Account;
import tkio.model.IncrementFlow;
import tkio.model.PackageType;
import tkio.repository.AccountRepository;
import tkio.repository.IncrementFlowRepository;
import tkio.repository.PackageTypeRepository;
import tkio.service.AccountService;
import tkio.service.TkioAccountService;
import userio.service.AccountIOService;
import userio.service.IOAccountService;
import util.DateUtil;
import util.*;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by mxq on 2018/1/16.
 */
@Service
public class ContractServiceImpl implements ContractService {


    private static final Map<String, String> CONTRACT_TYPE = new HashMap() {{
        put("0", "首次签约");
        put("1", "续约");
        put("2", "合同变更");
    }};
    private static final Map<String, String> CONTRACT_TYPE_NAME = new HashMap() {{
        put("首次签约", "0");
        put("续签", "1");
        put("补充协议", "2");
    }};

    public static final Map<String, String> FUNCTION_TYPE = new HashMap() {{
        put("1", "流量赠送");
        put("2", "合同变更记录");
        put("3", "收款/开票记录");
        put("4", "合同管理");
    }};

    private static final Map<String, String> SHEET_TITLE = new HashMap() {{
        put("我方签约主体", "my_body_name");
        put("客户签约主体", "customer_body");
        put("行业分类", "trade_type");
        put("合同金额", "money");
        put("客户主账号", "email");
        put("合同编号", "contract_code");
        put("签约类型", "contract_type");
        put("套餐", "price_level");
        put("合同类型", "type_id");
        put("合同开始日期", "start_date");
        put("合同结束日期", "end_date");
        put("签约销售", "sale");
    }};

    private static final Map<String, String> SHEET_TITLE_RESERVE = new HashMap() {{
        put("my_body_name", "我方签约主体");
        put("customer_body", "客户签约主体");
        put("trade_type", "行业分类");
        put("money", "合同金额");
        put("email", "客户主账号");
        put("contract_code", "合同编号");
        put("contract_type", "签约类型");
        put("price_level", "套餐");
        put("type_id", "合同类型");
        put("start_date", "合同开始日期");
        put("end_date", "合同结束日期");
        put("sale", "签约销售");
    }};

    public static final String UPLOAD_TITLE = "我方签约主体,客户签约主体,行业分类,合同开始日期,合同结束日期," +
            "签约销售,客户主账号,合同编号,签约类型,套餐,合同金额";

    public static final Map<String, String> SHEET_NAMES = new HashMap() {{
        put("TrackingIO", "tkio");
        put("DMP", "dmp");
        put("防作弊卫士", "fake");
        put("ADI", "adi");
        put("ADS", "ads");
        put("ABTEST", "abtest");
    }};

    public static final Map<String, String> SHEET_NAMES_RESERVE = new HashMap() {{
        put("tkio", "TrackingIO");
        put("dmp", "DMP");
        put("fake", "防作弊卫士");
        put("adi", "ADI");
        put("ads", "ADS");
        put("abtest", "ABTEST");
    }};

    Logger logger = LoggerFactory.getLogger(ContractServiceImpl.class);

    @Autowired
    ContractRepository contractRepository;
    @Autowired
    ContractBodyRepository contractBodyRepository;
    @Autowired
    Account4WebRepository account4WebRepository;
    @Autowired
    PackageTypeRepository packageTypeRepository;
    @Autowired
    PriceLevelMoneyRepository priceLevelMoneyRepository;
    @Autowired
    UserRepository userRepository;
    @Autowired
    ContractChangeRepository contractChangeRepository;
    @Autowired
    ContractMoneyRepository contractMoneyRepository;
    @Autowired
    AccountService accountService;
    @Autowired
    AccountIOService accountIOService;
    @Autowired
    IOAccount4WebRepository ioAccount4WebRepository;
    @Autowired
    ContractIncrementRepository contractIncrementRepository;
    @Autowired
    TkioAccountService tkioAccountService;
    @Autowired
    IOAccountService ioAccountService;
    @Autowired
    AccountRepository accountRepository;
    @Autowired
    UserService userService;
    @Autowired
    IncrementFlowRepository incrementFlowRepository;
    @Autowired
    BPUContractRepository bpuContractRepository;
    @Autowired
    ADIAccountService adiAccountService;

    @Autowired
    TradeTypeRepsitory tradeTypeRepsitory;

    @Autowired
    ContractRelationRepository contractRelationRepository;

    @Autowired
    FlowChangeRepository flowChangeRepository;

    @Autowired
    ChangeDelDetailRepository changeDelDetailRepository;

    @Autowired
    ChangeDelInfoRepository changeDelInfoRepository;

    @Autowired
    SalesRepository salesRepository;

    @Autowired
    PackageBaseRepository packageBaseRepository;

    @Autowired
    AuthRepository authRepository;

    @Autowired
    AuthService authService;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    TransactionUtils transactionUtils;

    @Autowired
    ShareIncomeService shareIncomeService;


    @Override
    public Map<String, Object> checkAccount(String email, String platfrom) {
        Map<String, Object> map = new HashMap<>();
        Account4Web account4Web = null;
        IOAccount4Web ioAccount4Web = null;
        ADIUser adiUser = null;
        platfrom = "tkio";

        if ("tkio".equals(platfrom)) {
            account4Web = account4WebRepository.findByEmail(email);
        } else if ("io".equals(platfrom)) {
            ioAccount4Web = ioAccount4WebRepository.findByEmail(email);
        } else if ("adi".equals(platfrom)) {
            adiUser = adiAccountService.findOne(email);
        }
        if (null == account4Web && null == ioAccount4Web && null == adiUser) {
            map.put("result", 0);
        } else {
            BigInteger integer = contractRepository.countNumByEmail(email, platfrom);
            map.put("result", 1);
            if (platfrom.equals("adi")) {
                map.put("company", adiUser.getCompany());
            } else {
                map.put("company", null == account4Web ? ioAccount4Web.getCompany() : account4Web.getCompany());
            }

            map.put("num", integer.intValue());
            Contract contract = contractRepository.findByPlatformAndEmailLimitVaild(platfrom, email);
            if (null == contract) {
                map.put("status", false);
            } else {
                map.put("status", true);
            }
        }

        return map;
    }

    @Override
    public Boolean checkTime(String email, String platfrom, String type, String product) {
        Boolean flag = false;
        if (ContractTypeEnum.MAIN.getKey().equals(type)) {
            Contract contract = contractRepository.findByPlatformAndEmailLimit1(platfrom, email, type);
            if (null == contract) {
                flag = true;
            } else {
                String beforeDay = DateUtil.getBeforeDays(180);
                if (beforeDay.compareTo(contract.getEndDate()) > 0) {
                    flag = true;
                }
            }
        } else {
            ContractIncrement increment = contractIncrementRepository.findByCode(product);
            Contract contract = contractRepository.findByPlatformAndEmailAndPricelevelLimit1(platfrom, email, type, increment.getId());
            if (null == contract) {
                flag = true;
            } else {
                String beforeDay = DateUtil.getBeforeDays(180);
                String endDate = contract.getEndDate() == null ? contract.getDs() : contract.getEndDate();
                if (beforeDay.compareTo(endDate) > 0) {
                    flag = true;
                }
            }
        }
        return flag;
    }

    @Override
    public List<ContractBody> findBody(String platform, User loginAccount) {

        if ("all".equals(platform)) {
            List<ContractBody> all = contractBodyRepository.findAllCodeDis();
            return all;
        } else {

            List<ContractBody> common = null;
            if (!"abtest".equals(platform) && !"ads".equals(platform)) {
                common = contractBodyRepository.findByPlatform("common");
            }

            List<ContractBody> byPlatform = contractBodyRepository.findByPlatform(platform);
            if (common == null) {
                common = new ArrayList<>();
            }
            common.addAll(byPlatform);

            if (RoleEnum.FINANCE.getKey().equals(loginAccount.getRole())) {
                Map<String, Object> filter = authService.getAuthExtends(loginAccount);
                common = common.stream().filter(t -> filter.get(t.getCode()) != null).collect(Collectors.toList());
            }

            return common;
        }

    }

    @Override
    public String getContractCode(String code) {
        BigInteger integer = contractRepository.countNumByDs(DateUtil.getBeforeDays(0));
        String lastCode = "";
        if (integer.intValue() < 9) {
            lastCode = "0" + (integer.intValue() + 1);
        } else {
            lastCode = "" + (integer.intValue() + 1);
        }
        String re = code + "-" + DateUtil.getDays2(0) + lastCode;
        return re;
    }

    @Override
    public String getContractCode(String code, String platform, String company) {

//        BigInteger countContract = contractRepository.findcountContract(code);
//
//        String lastCode;
//
//        if("fake".equals(platform)){
//            platform = "FZBWS";
//        }
//
//        int codeInt = countContract.intValue();
//
//        if (codeInt < 9) {
//            lastCode = "0" + (codeInt + 1);
//        } else {
//            lastCode = "" + (codeInt + 1);
//        }
//        return  code + "-" + platform.toUpperCase() + "-" + DateUtil.getDays2(0) + "-" + lastCode;


        String codeName = contractRepository.findLastCode(code);
        if ("fake".equals(platform)) {
            platform = "FZBWS";
        }

        int codeInt = 0;

        if (!StringUtils.isEmpty(codeName)) {

            String[] codeformat = codeName.split("-");

            if (codeformat.length == 4) {
                codeInt = Integer.parseInt(codeformat[3]);
            }

        }

        String lastCode;

        if (codeInt < 9) {
            lastCode = "0" + (codeInt + 1);
        } else {
            lastCode = "" + (codeInt + 1);
        }

        return code + "-" + platform.toUpperCase() + "-" + DateUtil.getDays2(0) + "-" + lastCode;


    }

    @Override
    public List findSetmeal(String platform) {

//        platform = "tkio";
//
//        List list = new ArrayList();
//        if ("adi".equals(platform)) {
//            for (int i = 1; i < 3; i++) {
//                Map<String, String> packageMap = new HashMap<>();
//                packageMap.put("id", i + "");
//                if (i == 1) {
//                    packageMap.put("packageName", PackageEnum.PROBATION.getValue());
//                } else {
//                    packageMap.put("packageName", PackageEnum.FORMAL.getValue());
//                }
//                list.add(packageMap);
//            }
//        } else {
//            if ("tkio".equals(platform) || "io".equals(platform)) {
////            List<PackageType> packageTypeList = packageTypeRepository.findAll();
//                List<PackageType> packageTypeList = packageTypeRepository.findIsNewAll();
//                for (PackageType p : packageTypeList) {
//                    p.setType("main");
//                    list.add(p);
//                }
//                // 增值套餐
////                List<ContractIncrement> increments = contractIncrementRepository.findAll();
////                list.addAll(increments);
//            } else if ("userdesk".equals(platform) || "dmp".equals(platform) || "fake".equals(platform)) {
//                list = bpuContractRepository.findByProduct(platform);
//            }
//        }

        List list = new ArrayList();

        if ("tkio".equals(platform) || "io".equals(platform)) {
            List<PackageType> packageTypeList = packageTypeRepository.findIsNewAll();
            for (PackageType p : packageTypeList) {
                p.setType("main");
                list.add(p);
            }

            return list;
        } else {
            List<PackageBase> packageBases = packageBaseRepository.findByPlatAndStatus(platform, 1);
            return packageBases;
        }


    }

    @Override
    public List<ContractIncrement> findIncrement() {
        return null;
    }

    @Override
    public Double getRebat(String product, Integer level, Double money) {
        Double rebat = 1d;
        try {
            PriceLevelMoney levelMoney = priceLevelMoneyRepository.getOne(product, level);
            rebat = money * 1.0 / levelMoney.getMoney();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rebat;
    }

    @Override
    public List<Sales> getSales() {
        return salesRepository.findAllByStatusOn();
    }

    @Override
    public Contract build(Contract contract) {
        User user = userRepository.findByEmail(contract.getSaleName());
        if (null != user) {
            contract.setSale(user.getId());
        }
        contract.setVirtual(true);
        Account account = accountRepository.findByEmail(contract.getEmail());
        contract.setCustomerBody(account.getCompany());
        contract.setType("increment");
        contract.setPlatform("tkio");
        contract.setStartDate(DateUtil.getBeforeDays(0));
        ContractIncrement contractIncrement = contractIncrementRepository.findByCode(contract.getPriceLevelName());
        contract.setPriceLevel(contractIncrement.getId());
        Contract contract1 = create(null, contract);
        return contract1;
    }

    @Override
    public Contract create(User loginUser, Contract resource) {

        if (resource == null) {
            return null;
        }

        if (!StringUtils.isEmpty(resource.getContractCode())
                && !ContractStatusEnum.MONEY_BACK_FIRST.getKey().equals(resource.getStatus())) {
            Contract contractExist = contractRepository.findByCode(resource.getContractCode().trim());
            if (contractExist != null) {
                contractExist = new Contract();
                // 合同编号已存在
                contractExist.setId(-100L);
                contractExist.setErroMessage("合同编号已存在");
                return contractExist;
            }
        }


        resource.setInvoice(0L);
        Long extraFlow = resource.getExtraFlow();
        if (extraFlow == null) {
            extraFlow = 0L;
        }
        if (resource.getPayMoney() == null) {
            resource.setPayMoney(0d);
        }

        resource.setDs(DateUtil.getBeforeDays(0));

        this.saveIncrementFlow(resource, extraFlow);

        this.dealContractStatus(resource, loginUser, "save");

        if (ContractStatusEnum.MONEY_BACK_FIRST.getKey().equals(resource.getStatus())) {
            resource.setStartDate(new DateTime().toString("yyyy-MM-dd"));
        } else {
            resource.setStatus(ContractStatusEnum.NFORMAL.getKey());
        }

        DateTime[] datePoints = new DateTime[]{
                new DateTime(resource.getStartDate()),
                new DateTime(new DateTime().toString("yyyy-MM-dd"))
        };

        if (shareIncomeService.checkLateContract(new DateTime(resource.getStartDate()),
                new DateTime(new DateTime().toString("yyyy-MM-dd")))) {
            resource.setStatus(ContractStatusEnum.LATE.getKey());
        }


        if (resource.getRelationContract() == null) {
            resource.setRelationContract(-1L);
        }

        if (null != loginUser) {
            resource.setCreateAccount(loginUser.getId());
            resource.setCreateName(loginUser.getName());
        }

        resource.setCreateTime(new Date());

        //同步修改trackingio的数据
//        if (resource.getPlatform().equals("tkio") && resource.getType().equals("main")) {
//            accountService.update(resource);
//        }
//        if (resource.getPlatform().equals("io") && resource.getType().equals("main")) {
//            accountIOService.update(resource);
//        }
//        if (resource.getPlatform().equals("adi")) {
//            adiAccountService.updateAccount(resource);
//        }


        //this.calculateShareIncome(resource);//判断是否计算调整金


        resource = contractRepository.save(resource);

        this.saveContractRelations(resource, resource.getId());

        List<String> codes = contractRepository.findContractBodyNames(resource.getCustomerBody(), resource.getContractCode());
        if (!codes.isEmpty()) {
            // 合同编号已存在
            resource.setCustomBodyNames(codes);
            return resource;
        }

        return resource;
    }

    public void calculateShareIncome(Contract resource) {


        if (!StringUtils.isEmpty(resource.getAdjustmentFundForm())) {
            //表单有输入值 则优先保存该值
            resource.setAdjustmentFund(Long.parseLong(resource.getAdjustmentFundForm()));
            return;
        }

        DateTime formStart = new DateTime(resource.getStartDate());
        DateTime contractStart = new DateTime(resource.getStartDate());
        DateTime contractEnd = new DateTime(resource.getEndDate());
        if (formStart.getMonthOfYear() != new DateTime().getMonthOfYear()) {
            // 自动计算分摊调整金
            //当录入时间与合同开始时间不在一个月时。自动生成调分摊输入调整金。
            //分摊收入调整金 =  合同金额 * 6% / 合同总天数  *[录入日期前一月最后一日（含） - 合同开始日期]
            int day1 = Days.daysBetween(contractStart, contractEnd).getDays() + 1;
            int day2 = Days.daysBetween(contractStart, new DateTime().plusMonths(-1).dayOfMonth().withMaximumValue()).getDays() + 1;
            long resultValue = new BigDecimal(resource.getMoney() * (1 - 0.06) / day1 * day2)
                    .setScale(2, BigDecimal.ROUND_HALF_UP)
                    .multiply(new BigDecimal(100)).longValue();
            resource.setAdjustmentFund(resultValue); // 此处为 *100的结果
        } else {
            resource.setAdjustmentFund(0L);
        }
    }


    private void saveIncrementFlow(Contract resource, Long extraFlow) {
        if ("main".equals(resource.getType())) {
            if (resource.getPlatform().equals("tkio")) {
                if (!(extraFlow.longValue() == 0)) {
                    if (resource.getPlatform().equals("tkio")) {
                        IncrementFlow flow = new IncrementFlow();
                        Account account = accountRepository.findByEmail(resource.getEmail());
                        flow.setAccount(account.getId());
                        flow.setFlow(extraFlow);
                        flow.setEndDate(resource.getEndDate());
                        flow.setStartDate(resource.getStartDate());
                        flow.setContractCode(resource.getContractCode());
                        incrementFlowRepository.save(flow);
                    }
                }
            }
        }
    }


    private void saveContractRelations(Contract resource, Long contractId) {
        if (resource.getRelationContract() != null && resource.getRelationContract() > 0) {
            //保存关联合同信息
            ContractRelation relation = new ContractRelation();
            relation.setCreateTime(new Date());
            relation.setMainContract(contractId);
            relation.setRelationId(resource.getRelationContract());
            relation.setPlatform(resource.getPlatform());

            ContractRelation relationOrig = contractRelationRepository.findByRelationData(relation.getMainContract(), relation.getRelationId(), resource.getPlatform());
            if (relationOrig == null) {
                contractRelationRepository.save(relation);
            }

            //处理被关联 合同
            Contract contract = contractRepository.findOne(resource.getRelationContract());
            if (contract.getRelationContract() == null || contract.getRelationContract() == -1) {
                contract.setRelationContract(contractId);
                contract.setRelationCode(resource.getContractCode());
                contractRepository.save(contract);
            }

            //设置关联编号
            resource.setRelationCode(contract.getContractCode());

        }
    }


    public Contract create_bak(User loginUser, Contract resource) {

        if (resource == null) {
            return null;
        }

        Contract contractExist = contractRepository.findByCodePlatform(resource.getContractCode(), resource.getPlatform());

        if (contractExist != null) {
            // 合同编号已存在
            return null;
        }

        // 老的逻辑
        String contractCode = getContractCode(resource.getMyBodyCode());

        if (!contractCode.equals(resource.getContractCode())) {
            resource.setContractCode(contractCode);
        }

        resource.setPayMoney(0d);
        resource.setInvoice(0L);
        Long extraFlow = resource.getExtraFlow();
        resource.setDs(DateUtil.getBeforeDays(0));

        if (resource.getType().equals("main")) {
            if (resource.getPlatform().equals("tkio")) {
                if (!(extraFlow.longValue() == 0)) {
                    if (resource.getPlatform().equals("tkio")) {
                        IncrementFlow flow = new IncrementFlow();
                        Account account = accountRepository.findByEmail(resource.getEmail());
                        flow.setAccount(account.getId());
                        flow.setFlow(extraFlow);
                        flow.setEndDate(resource.getEndDate());
                        flow.setStartDate(resource.getStartDate());
                        flow.setContractCode(resource.getContractCode());
                        incrementFlowRepository.save(flow);
                    }
                }
            }
            if (DateUtil.getBeforeDays(0).compareTo(resource.getStartDate()) < 0) {
                resource.setDs(DateUtil.getBeforeDays(0));
                resource.setStatus("wait");
            } else {
                resource.setDs(DateUtil.getBeforeDays(0));
                resource.setStatus("executing");
            }
        } else {
//            resource.setDs(DateUtil.getBeforeDays(0));
//            resource.setStatus("wait");
        }

//        if (resource.getRebateMoney() != null) {
//            if (resource.getMoney() == null) {
//                resource.setMoney(0L);
//            }
//
//            if (resource.getRebateMoney().compareTo(BigDecimal.ZERO) < 0) {
//                //未回款
//                resource.setStatus(ContractStatusEnum.MONEY_BACK_NONE.getKey());
//
//            }else if(resource.getRebateMoney().compareTo(new BigDecimal(resource.getMoney()+""))< 0){
//                // 部分回款
//                resource.setStatus(ContractStatusEnum.MONEY_BACK_PART.getKey());
//            }else{
//                // 已回款
//                resource.setStatus(ContractStatusEnum.MONEY_BACK_ALL.getKey());
//            }
//
//        } else {
//            //未回款
//            resource.setStatus(ContractStatusEnum.MONEY_BACK_NONE.getKey());
//        }

        Double rebat = null;
        if (null != resource.getPriceLevel()) {
            rebat = getRebat(resource.getProduct(), resource.getPriceLevel().intValue(), resource.getMoney());
        } else {
            rebat = getRebat(resource.getProduct(), 0, resource.getMoney());
        }

        BigDecimal bg = new BigDecimal(rebat);
        double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        resource.setRebate(f1);

        if (null != loginUser) {
            resource.setCreateAccount(loginUser.getId());
            resource.setCreateName(loginUser.getName());
        }
        resource.setCreateTime(new Date());

        //同步修改trackingio的数据
        if (resource.getPlatform().equals("tkio") && resource.getType().equals("main")) {
            accountService.update(resource);
        }
        if (resource.getPlatform().equals("io") && resource.getType().equals("main")) {
            accountIOService.update(resource);
        }
        if (resource.getPlatform().equals("adi")) {
            adiAccountService.updateAccount(resource);
        }

        if (resource.getType().equals(ContractTypeEnum.MAIN.getKey())
                || (resource.getType().equals(ContractTypeEnum.INCREMENT.getKey()) && resource.getPriceLevel().equals(1L))) {
            List<Contract> contractList = contractRepository.findByPlatformAndEmail(resource.getPlatform(), resource.getEmail(), resource.getType());
            if (ValidateUtil.isValid(contractList)) {
                List<Contract> list = new ArrayList<>();
                for (Contract contract : contractList) {
                    if (contract.getType().equals(ContractTypeEnum.MAIN.getKey())
                            || (contract.getType().equals(ContractTypeEnum.INCREMENT.getKey()) && contract.getPriceLevel().equals(1L))) {
                        if (contract.getStatus().equals(ContractStatusEnum.EXECUTING.getKey())
                                || contract.getStatus().equals(ContractStatusEnum.WAIT.getKey())) {
                            contract.setStatus(ContractStatusEnum.CANCEL.getKey());
                        }
                        list.add(contract);
                    }

                }
                contractRepository.save(contractList);
            }
        }

        resource = contractRepository.save(resource);


        if (resource.getRelationContract() != null && resource.getRelationContract() > 0) {
            //保存关联合同信息
            ContractRelation relation = new ContractRelation();
            relation.setCreateTime(new Date());
            relation.setMainContract(resource.getId());
            relation.setRelationId(resource.getRelationContract());
            relation.setPlatform(resource.getPlatform());
            contractRelationRepository.save(relation);

        }

        return resource;
    }

    @Override
    public Contract update(User loginUser, Contract resource, String ip) {

        Contract contract = contractRepository.findOne(resource.getId());

        if (resource.getContractCode() != null && !resource.getContractCode().equals(contract.getContractCode())) {
            Contract contractExist = contractRepository.findByCode(resource.getContractCode().trim());
            if (contractExist != null) {
                // 合同编号已存在
                contractExist = new Contract();
                contractExist.setId(-100L);
                contractExist.setErroMessage("合同编号已存在");
                return contractExist;
            }
        }

        this.dealContractStatus(resource, loginUser, "update");

        this.saveContractRelations(resource, contract.getId());

        ChangeDelInfo delInfo = new ChangeDelInfo();

        delInfo.setModifyId(loginUser.getId());
        delInfo.setModifyAccount(loginUser.getName());
        delInfo.setEmail(contract.getEmail());
        delInfo.setDs(new DateTime().toString("yyyy-MM-dd"));
        delInfo.setModifyType(2);
        delInfo.setContractCode(contract.getContractCode());
        delInfo.setCreatTime(new Date());
        delInfo.setFunction(4);
        delInfo.setDetail("修改详情");
        delInfo.setIp(ip);


        List<ChangeDelDetail> updateFields = this.changeDelInfoForContract(contract, resource, delInfo.getId(), "");

        if (updateFields != null && updateFields.size() > 0) {
            changeDelInfoRepository.save(delInfo);

            for (ChangeDelDetail delDetail : updateFields) {
                delDetail.setParentId(delInfo.getId());
            }

            changeDelDetailRepository.save(updateFields);
        }

        resource.setCreateName(contract.getCreateName());
        resource.setCreateAccount(contract.getCreateAccount());
        resource.setCreateTime(contract.getCreateTime());
        resource.setModifyTime(new Date());
        resource.setDs(contract.getDs());
        resource.setProduct(contract.getProduct());

        if (null != loginUser) {
            resource.setModifyAccount(loginUser.getId());
        }

        if (ContractStatusEnum.MONEY_BACK_FIRST.getKey().equals(contract.getStatus())) {
            ContractMoney contractMoney = contractMoneyRepository.findOne(contract.getFirstBackId());
            if (contractMoney != null) {
                contractMoney.setContractCode(resource.getContractCode());
                contractMoneyRepository.save(contractMoney);
            }
        }

        resource.setStatus(contract.getStatus());

        //this.calculateShareIncome(resource);

        resource.setId(contract.getId());

        return contractRepository.save(resource);

    }

    private List<ChangeDelDetail> changeDelInfoForContract(Contract byfind, Contract resource, Long pid, String ip) {

        List<ChangeDelDetail> delDetailsList = new ArrayList<>();
        String contractCode = byfind.getContractCode();
        this.dealChangeInfoDetail(byfind.getCustomerBody(), resource.getCustomerBody(),
                "客户签约主体", "customerBody", pid, delDetailsList, byfind);
        this.dealChangeInfoDetail(byfind.getCustomerShort(), resource.getCustomerShort(),
                "客户简称", "customerShort", pid, delDetailsList, byfind);
        this.dealChangeInfoDetail(byfind.getCustomerThird(), resource.getCustomerThird(),
                "第三方签约主体", "customerThird", pid, delDetailsList, byfind);

        if (byfind.getTradeType() != resource.getTradeType()) {
            List<TradeType> types = tradeTypeRepsitory.findByTwoId(byfind.getTradeType(), resource.getTradeType());
            Map<String, String> dataDic = new HashMap();
            for (TradeType tradeType : types) {
                dataDic.put(tradeType.getId().toString(), tradeType.getName());
            }
            String nameFind = dataDic.get(byfind.getTradeType() + "");
            String nameResource = dataDic.get(resource.getTradeType() + "");
            this.dealChangeInfoDetail(nameFind == null ? "无" : nameFind, nameResource == null ? "无" : nameResource,
                    "行业分类", "tradeType", pid, delDetailsList, byfind);
        }

        this.dealChangeInfoDetail(byfind.getStartDate(), resource.getStartDate(),
                "合同开始日期", "startDate", pid, delDetailsList, byfind);

        this.dealChangeInfoDetail(byfind.getEndDate(), resource.getEndDate(),
                "合同结束日期", "startDate", pid, delDetailsList, byfind);


        if (byfind.getSale() != resource.getSale()) {
            List<Sales> sales = salesRepository.findByTwoId(byfind.getSale(), resource.getSale());
            this.dealChangeInfoDetail(sales.get(0).getName(), sales.get(1).getName(),
                    "签约销售", "sale", pid, delDetailsList, byfind);
        }

        this.dealChangeInfoDetail(byfind.getExtraFlow() == null ? "" : byfind.getExtraFlow().toString(),
                resource.getExtraFlow() == null ? "" : resource.getExtraFlow().toString(),
                "赠送流量", "extraFlow", pid, delDetailsList, byfind);

        this.dealChangeInfoDetail(byfind.getEmail(), resource.getEmail(),
                "客户主账号", "startDate", pid, delDetailsList, byfind);

        this.dealChangeInfoDetail(CONTRACT_TYPE.get(byfind.getContractType()),
                CONTRACT_TYPE.get(resource.getContractType()),
                "签约类型", "startDate", pid, delDetailsList, byfind);

        this.dealChangeInfoDetail(byfind.getDiscountTimeLong() == null ? "" : byfind.getDiscountTimeLong().toString(),
                resource.getDiscountTimeLong() == null ? "" : resource.getDiscountTimeLong().toString(),
                "赠送时长", "discountTimeLong", pid, delDetailsList, byfind);

        this.dealChangeInfoDetail(byfind.getRelationCode() == null ? "无" : byfind.getRelationCode(),
                resource.getRelationCode() == null ? "无" : resource.getRelationCode(),
                "关联合同", "relationCode", pid, delDetailsList, byfind);

        return delDetailsList;


    }

    private void dealChangeInfoDetail(String before, String now, String delDetailinfo, String fildeName,
                                      Long pid, List<ChangeDelDetail> delDetails, Contract contract) {

        ChangeDelDetail delDetail = new ChangeDelDetail();
        delDetail.setFiledName(fildeName);
        delDetail.setDetail(delDetailinfo);
        delDetail.setCreatTime(new Date());
        delDetail.setItem("合同修改");
        delDetail.setParentId(pid);
        delDetail.setContractCode(contract.getContractCode());
        delDetail.setEmail(contract.getEmail());

        if (before != null && !before.equals(now)) {
            delDetail.setBeforeValue(before);
            delDetail.setAfterValue(now == null ? "" : now);
            delDetails.add(delDetail);
        } else {
            if (now != null && !now.equals(before)) {
                delDetail.setBeforeValue(before == null ? "" : before);
                delDetail.setAfterValue(now);
                delDetails.add(delDetail);
            }
        }
    }


    public Contract update_bak(User loginUser, Contract resource) {
//        Map<Long, String> packageMap = getPackageMap();
//        Map<Long, String> saleMap = getSaleMap();
//        Contract contract = contractRepository.findOne(resource.getId());
//
//        ContractChange cc = new ContractChange();
//        cc.setType("update");
//        cc.setUser(loginUser.getId());
//        cc.setDs(DateUtil.getBeforeDays(0));
//        cc.setContent("");
//        cc.setEmail(contract.getEmail());
//        cc.setCompany(contract.getCustomerBody());
//        cc.setContractCode(contract.getContractCode());
//        this.dealContractStatus(resource,loginUser,"update");


//        if (!resource.getStartDate().equals(contract.getStartDate())) {
//            cc.setContent(cc.getContent() + "开始时间变更 : " + contract.getStartDate() + "-->" + resource.getStartDate());
//            contract.setStartDate(resource.getStartDate());
////            if(DateUtil.getBeforeDays(0).compareTo(resource.getStartDate()) < 0){
////                contract.setStatus("wait");
////            }else{
////                contract.setStatus("executing");
////            }
//        }
//        if (!resource.getEndDate().equals(contract.getEndDate())) {
//            cc.setContent(cc.getContent() + "   结束时间变更 : " + contract.getEndDate() + "-->" + resource.getEndDate());
//            contract.setEndDate(resource.getEndDate());
//        }
//
//        boolean newRebat = false;
//        if (contract.getType().equals(ContractTypeEnum.MAIN.getKey()) && null != resource.getPriceLevel()) {
//            if (!resource.getPriceLevel().equals(contract.getPriceLevel())) {
//                cc.setContent(cc.getContent() + "  套餐变更：" + packageMap.get(contract.getPriceLevel()) + "-->" + packageMap.get(resource.getPriceLevel()));
//                newRebat = true;
//                contract.setPriceLevel(resource.getPriceLevel());
//            }
//        }
//
//        if (!resource.getMoney().equals(contract.getMoney())) {
//            cc.setContent(cc.getContent() + "   金额变更： " + contract.getMoney() + "-->" + resource.getMoney());
//            newRebat = true;
//            contract.setMoney(resource.getMoney());
//        }
//
//        if (!resource.getRebateMoney().equals(contract.getRebateMoney())) {
//            cc.setContent(cc.getContent() + "  回款金额变更： " + contract.getMoney() + "-->" + resource.getMoney());
//            newRebat = true;
//            contract.setMoney(resource.getMoney());
//        }
//
//        if (!resource.getSale().equals(contract.getSale())) {
//            cc.setContent(cc.getContent() + "销售变更：" + saleMap.get(contract.getSale()) + "-->" + saleMap.get(resource.getSale()));
//            contract.setSale(resource.getSale());
//        }
//
////        if (newRebat && !"adi".equals(contract.getPlatform())) {
////            Double rebat = getRebat(contract.getProduct(), contract.getPriceLevel().intValue(), contract.getMoney());
////            BigDecimal bg = new BigDecimal(rebat);
////            double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
//////            contract.setRebate(f1);
////        }
//
//        if (!resource.getSale().equals(contract.getSale())) {
//            cc.setContent(cc.getContent() + "销售变更：" + saleMap.get(contract.getSale()) + "-->" + saleMap.get(resource.getSale()));
//            contract.setSale(resource.getSale());
//        }

//        cc.setPlatform(contract.getPlatform());
//        contractChangeRepository.save(cc);

        //同步修改trackingio的数据
//        if (contract.getPlatform().equals("tkio") && resource.getType().equals("main")) {
//            accountService.update(contract);
//        }
//        if (contract.getPlatform().equals("io") && resource.getType().equals("main")) {
//            accountIOService.update(contract);
//        }
//        if (contract.getPlatform().equals("adi")) {
//            adiAccountService.updateAccount(contract);
//        }

//        if (contract.getPlatform().equals("tkio")) {
//            if (contract.getType().equals("main")) {
//                IncrementFlow flow = incrementFlowRepository.findOne(resource.getContractCode());
//                if (null != flow) {
//                    flow.setEndDate(resource.getEndDate());
//                    flow.setStartDate(resource.getStartDate());
//                    if (contract.getExtraFlow() != resource.getExtraFlow()) {
//                        flow.setFlow(resource.getExtraFlow());
//                        incrementFlowRepository.save(flow);
//                    }
//                } else if (resource.getExtraFlow().longValue() > 0) {
//                    IncrementFlow flow1 = new IncrementFlow();
//                    Account account = accountRepository.findByEmail(contract.getEmail());
//                    flow1.setAccount(account.getId());
//                    flow1.setFlow(resource.getExtraFlow());
//                    flow1.setEndDate(resource.getEndDate());
//                    flow1.setStartDate(resource.getStartDate());
//                    flow1.setContractCode(resource.getContractCode());
//                    incrementFlowRepository.save(flow1);
//                }
//            }
//
//        }

//        contract.setStatus(resource.getStatus());
//        contract.setExtraFlow(resource.getExtraFlow());
//        contract.setTradeType(resource.getTradeType());
//        contract.setInvoiceMoney(resource.getInvoiceMoney());
//        contract.setRelationContract(resource.getRelationContract());
//        contract.setRebateMoney(resource.getRebateMoney());
//        contract.setDiscountTimeLong(resource.getDiscountTimeLong());
//
//        contract.setModifyTime(new Date());
//        if (null != loginUser) {
//            resource.setModifyAccount(loginUser.getId());
//        }
//
//
//        this.saveContractRelations(resource,contract.getId());
//
//        return contractRepository.save(contract);
        return null;
    }


    private void dealContractStatus(Contract resource, User loginUser, String type) {


        ContractMoney money = new ContractMoney();

        if (resource.getPayMoney() != null) {

            if (resource.getMoney() == null) {
                resource.setMoney(0d);
            }

            if (ContractStatusEnum.MONEY_BACK_FIRST.getKey().equals(resource.getStatus())) {

                resource.setStatus(ContractStatusEnum.MONEY_BACK_FIRST.getKey());
                //记录收款记录

                money.setType("pay");
                money = saveContractMoney(money, loginUser, resource, type);

            } else if (resource.getPayMoney().longValue() <= 0) {
                //未回款
//                resource.setStatus(ContractStatusEnum.MONEY_BACK_NONE.getKey());
                resource.setBackStatus(1);

            } else if (resource.getPayMoney().longValue() < resource.getMoney().longValue()) {
                // 部分回款
//                resource.setStatus(ContractStatusEnum.MONEY_BACK_PART.getKey());
                resource.setBackStatus(2);

                //记录收款记录
                money.setType("pay");
                money = saveContractMoney(money, loginUser, resource, type);


            } else {
                // 已回款
//                resource.setStatus(ContractStatusEnum.MONEY_BACK_ALL.getKey());
                resource.setBackStatus(3);
                money.setType("pay");
                money = saveContractMoney(money, loginUser, resource, type);
            }


        } else {
            //未回款
            resource.setBackStatus(1);
//            resource.setStatus(ContractStatusEnum.MONEY_BACK_NONE.getKey());
        }

        if (money.getId() != null) {
            resource.setFirstBackId(money.getId());
        } else {
            resource.setFirstBackId(0L);
        }

        if (resource.getPayMoney() == null) {
            resource.setPayMoney(0d);
        }

        if (resource.getInvoiceMoney() == null) {
            resource.setInvoiceMoney(new BigDecimal(0));
        } else {
            // 记录发票记录
            money.setType("invoice");
            saveContractMoney(money, loginUser, resource, type);
        }

        if (resource.getDiscountTimeLong() == null) {
            resource.setDiscountTimeLong(0L);
        }

        if (resource.getExtraFlow() == null) {
            resource.setExtraFlow(0L);
        }

        if (resource.getDiscountTimeLong() > 0 || resource.getExtraFlow() > 0) {
            //记录优惠信息
            saveFlowChange(resource, loginUser, type, resource.getDiscountTimeLong(), resource.getExtraFlow());
        }

        if (!ContractStatusEnum.MONEY_BACK_FIRST.getKey().equals(resource.getStatus())) {
            //处理合同编号
            resource.setCodeNum(Integer.parseInt(resource.getContractCode().split("-")[3]));

        }

    }


    //保存开票收款记录
    private ContractMoney saveContractMoney(ContractMoney money, User loginUser, Contract contract, String type) {

        if (!"save".equals(type)) {
            return money;
        }

        if (ContractStatusEnum.MONEY_BACK_FIRST.getKey().equals(contract.getStatus())) {
            money.setMoney(contract.getPayMoney());
        } else if (money.getType().equals("pay")) {
            money.setMoney(contract.getMoney());
        } else {
            money.setMoney(contract.getInvoiceMoney().doubleValue());
        }


        money.setSalse(contract.getSale());
        money.setPriceLevel(contract.getPriceLevel());

//        if(ContractStatusEnum.MONEY_BACK_FIRST.getKey().equals(contract.getStatus())){
//            money.setCompany(contract.getMyBodyName());
//        }else{
//            money.setCompany(contract.getCustomerBody());
//        }

        money.setCompany(contract.getCustomerBody());

        money.setContractCode(contract.getContractCode());
        money.setPlatform(contract.getPlatform());
        money.setEmail(contract.getEmail());

        money.setPlatform(contract.getPlatform());
        money.setCreateAccount(loginUser.getId());
        money.setCreateTime(new Date());
        money.setUser(loginUser.getId());
        money.setCreateName(loginUser.getName());
        money.setDs(new DateTime().toString("yyyy-MM-dd"));
        money = contractMoneyRepository.save(money);
        return money;
    }

    // 保存优惠流量 优惠时长 记录
    private void saveFlowChange(Contract contract, User loginUser, String type, Long discountTimeLong, Long extraFlow) {

        if (!"save".equals(type)) {
            return;
        }

        FlowChange change = new FlowChange();
        change.setDiscountFlow(extraFlow);
        change.setDiscountTimeLong(discountTimeLong);
        change.setAddDate(new DateTime().toString("yyyy-MM-dd"));
        change.setAddTime(new Date());
        change.setCompany(contract.getMyBodyName());
        change.setContractCode(contract.getContractCode());
        change.setDelFlag(0);
        change.setEmail(contract.getEmail());
        change.setModifyUname(loginUser.getName());
        change.setModifyUser(loginUser.getId());
        flowChangeRepository.save(change);

    }


    /**
     * @param loginAccount
     * @param startDate
     * @param endDate
     * @param platform
     * @param contractId   用于 获取关联合同列表
     * @return
     */
    @Override
    public List<Contract> findAll(User loginAccount, String startDate, String endDate, String platform, String contractId) {
        List<Contract> result = new ArrayList<>();

        List<String> platforms = new ArrayList<>();
        Map<String, String> idsDic = new HashMap<>();
        platforms.add(platform);

        if (!StringUtils.isEmpty(contractId)) {
            //获取 关联合同列表
            List<String> conIds = new ArrayList<>();
            conIds.add(contractId);
            this.getContractRelationIds(conIds, idsDic);
            idsDic.remove(contractId);
            if ("fake".equals(platform)) {
                platforms.add("tkio");
            }
        }

        List<Contract> contractList = new ArrayList<>();

        List<String> ids = new ArrayList<>(idsDic.keySet());

        Auth auth = authRepository.findByUser(loginAccount.getId());

        if (RoleEnum.FINANCE.getKey().equals(loginAccount.getRole())) {
            //财务  按签约主体查看
            List bodyids = JSONArray.fromObject(auth.getAuthExtend());

            if (!StringUtils.isEmpty(contractId)) {

                if (ids != null && ids.size() > 0) {
                    contractList = contractRepository.findByDsContractBody(startDate, endDate, platforms, bodyids, ids);
                }
            } else {
                contractList = contractRepository.findByDsContractBody(startDate, endDate, platform, bodyids);
            }

        } else if (RoleEnum.SALSEMAN.getKey().equals(loginAccount.getRole())) {
            //销售 按签约合同人查看

//            List salseid =  Arrays.asList(loginAccount.getAuthExtend().split(","));
            List salseid = JSONArray.fromObject(auth.getAuthExtend());

            if (!StringUtils.isEmpty(contractId)) {

                if (ids != null && ids.size() > 0) {
                    contractList = contractRepository.findByDsContractSalse(startDate, endDate, platforms, salseid, ids);
                }
            } else {
                contractList = contractRepository.findByDsContractSalse(startDate, endDate, platform, salseid);
            }

        } else {
            if (!StringUtils.isEmpty(contractId)) {

                if (ids != null && ids.size() > 0) {
                    contractList = contractRepository.findByDsRelation(startDate, endDate, platforms, ids);
                }
            } else {
                contractList = contractRepository.findByDs(startDate, endDate, platform);
            }
        }


//        if (loginAccount.getRole().equals(RoleEnum.SOUTH_BUSSINUSS.getKey()) || loginAccount.getRole().equals(RoleEnum.NORTH_BUSSINUSS.getKey())) {
//
//            List<User> userList = userService.findAllSons(loginAccount.getId());
//            List<Long> idList = new ArrayList<>();
//            idList.add(loginAccount.getId());
//            for (User u : userList) {
//                idList.add(u.getId());
//            }
//
////            contractList = contractRepository.findByDsAndRoile(startDate, endDate, platfrom, idList);
//
//
//            if (!StringUtils.isEmpty(contractId)) {
//                //查看关联合同
//                if (ids != null && ids.size() > 0) {
//                    contractList = contractRepository.findByDsAndRoileRelation(startDate, endDate, platforms, idList, ids);
//                }
//
//            } else {
//                contractList = contractRepository.findByDsAndRoile(startDate, endDate, platform, idList);
//            }
//
//
//        } else {
////            contractList = contractRepository.findByDs(startDate, endDate, platform);
//
//            if (!StringUtils.isEmpty(contractId)) {
//                if (ids != null && ids.size() > 0) {
//                    contractList = contractRepository.findByDsRelation(startDate, endDate, platforms, ids);
//                }
//            } else {
//                contractList = contractRepository.findByDs(startDate, endDate, platform);
//            }
//
//        }

        Map<String, String> saleMap = new HashMap();

        Map<String, PackageType> typeMap = new HashMap();

        Map<String, PackageBase> packageBaseMap = new HashMap<>();

        // 获取字典数据
        this.getDicMapDatas(saleMap, typeMap, null, null, packageBaseMap, platform);

        Map<String, String> bodyMap = contractBodyRepository.findAllCodeDis().stream().collect(Collectors.toMap(ContractBody::getCode, ContractBody::getName));

        Map<String, String> tradeTypeMap = tradeTypeRepsitory.findAll().stream().collect(Collectors.toMap(v -> v.getId().toString(), v -> v.getName()));

        if (ValidateUtil.isValid(contractList)) {
            for (Contract c : contractList) {
                c.setMyBodyName(bodyMap.get(c.getMyBodyCode()));
                c.setTradeName(tradeTypeMap.get(c.getTradeType() + ""));
                c.setDs(new DateTime(c.getCreateTime()).toString("yyyy-MM-dd"));

                if ((c.getExtraFlow() != null && c.getExtraFlow() > 0) ||
                        (c.getDiscountTimeLong() != null && c.getDiscountTimeLong() > 0)) {

                    c.setHasDiscount("有");

                } else {
                    c.setHasDiscount("无");
                }

                if (c.getRelationContract() == null) {
                    c.setRelationContract(-1L);
                }

                if (ContractStatusEnum.MONEY_BACK_FIRST.getKey().equals(c.getStatus())) {
                    c.setStartDate(null);
                }


//                if (c.getType().equals(ContractTypeEnum.MAIN.getKey()) && platform.contains("io")) {
//
//                } else if (c.getType().equals(ContractTypeEnum.MAIN.getKey())) {
//                    c.setPriceLevelName(bpuMap.containsKey(c.getPriceLevel()) ? bpuMap.get(c.getPriceLevel()) : "");
//                } else {
//                    c.setPriceLevelName(incremenMap.containsKey(c.getPriceLevel()) ? incremenMap.get(c.getPriceLevel()) : "");
//                }

                c.setSaleName(saleMap.containsKey(c.getSale()) ? saleMap.get(c.getSale()) : "");

                if ("tkio".equals(platform)) {
                    c.setPriceLevelName(typeMap.containsKey(c.getPriceLevel()) ? typeMap.get(c.getPriceLevel()).getPackageName() : "");
                } else {

                    c.setPriceLevelName(packageBaseMap.get(c.getPriceLevel()) == null ? "" : packageBaseMap.get(c.getPriceLevel()).getPackageName());
                }

//                c.setCreateName(saleMap.containsKey(c.getCreateAccount()) ? saleMap.get(c.getCreateAccount()) : "");

                result.add(c);
            }
        }
        return result;
    }


    public void getDicMapDatas(Map saleMap, Map typeMap, Map incremenMap, Map bpuMap, Map packageBaseMap, String platform) {


        if (saleMap != null) {
            List<Sales> salesList = salesRepository.findAllByStatusOn();
            if (ValidateUtil.isValid(salesList)) {
                for (Sales s : salesList) {
                    saleMap.put(s.getId(), s.getName());
                }
            }
        }

        if (typeMap != null) {
            List<PackageType> typeList = packageTypeRepository.findAll();
            if (ValidateUtil.isValid(typeList)) {
                for (PackageType s : typeList) {
                    typeMap.put(s.getId(), s);
                }
            }
        }

        if (incremenMap != null) {
            List<ContractIncrement> incrementList = contractIncrementRepository.findAll();
            if (ValidateUtil.isValid(incrementList)) {
                for (ContractIncrement s : incrementList) {
                    incremenMap.put(s.getId(), s.getPackageName());
                }
            }
        }


        if (bpuMap != null) {
            List<BPUContract> bpuContractList = bpuContractRepository.findAll();
            if (ValidateUtil.isValid(bpuContractList)) {
                for (BPUContract s : bpuContractList) {
                    bpuMap.put(s.getId(), s.getPackageName());
                }
            }
        }

        if (packageBaseMap != null) {

            List<PackageBase> packageBases = packageBaseRepository.findByPlatAndStatus(platform, 1);
            for (PackageBase base : packageBases) {
                packageBaseMap.put(base.getId(), base);
            }
        }


    }


    @Override
    public Contract findOne(User loginAccount, String startDate, String endDate, String platform, String contractId) {

        Contract contract = contractRepository.findOneByCode(platform, contractId);

        Map<String, String> saleMap = new HashMap();

        Map<String, PackageType> typeMap = new HashMap();

        Map<String, PackageBase> packageBaseMap = new HashMap<>();

        // 获取字典数据
        this.getDicMapDatas(saleMap, typeMap, null, null, packageBaseMap, platform);

        contract.setSaleName(saleMap.containsKey(contract.getSale()) ? saleMap.get(contract.getSale()) : "");
        if ("tkio".equals(platform)) {
            contract.setPriceLevelName(typeMap.containsKey(contract.getPriceLevel()) ? typeMap.get(contract.getPriceLevel()).getPackageName() : "");
        } else {

            contract.setPriceLevelName(packageBaseMap.get(contract.getPriceLevel()) == null ? "" : packageBaseMap.get(contract.getPriceLevel()).getPackageName());
        }

        contract.setCreateName(saleMap.containsKey(contract.getCreateAccount()) ? saleMap.get(contract.getCreateAccount()) : "");

        return contract;
    }

    private void getContractRelationIds(List<String> contractId, Map<String, String> idsDic) {

        //获取 关联合同 id
        List<String> contractIds = new ArrayList<>();

        List<BigInteger> ids = contractRelationRepository.findRelationIds(contractId);

        if (ids != null && ids.size() > 0) {
            for (BigInteger id : ids) {

                String idss = id.toString();
                if (idsDic.get(idss) == null) {
                    contractIds.add(idss);
                    idsDic.put(idss, "0");
                }
            }

            if (contractIds.size() > 0) {
                //递归 查询 id  查询所有相关联的合同
                this.getContractRelationIds(contractIds, idsDic);
            }
        }
    }


    @Override
    public Contract contractStatusUpdate(String platform, String contractId, String status, String ip, User loginUser) {

        if (StringUtils.isEmpty(contractId)) {
            return null;
        }

        Contract contract = contractRepository.findOne(Long.parseLong(contractId));

        ChangeDelInfo changeDelInfo = new ChangeDelInfo();
        changeDelInfo.setContractCode(contract.getContractCode());
        changeDelInfo.setEmail(contract.getEmail());

        changeDelInfo.setEmail(contract.getEmail());

        if (ContractStatusEnum.CANCEL.getKey().equals(status)) {
            contract.setStatus(status);
            changeDelInfo.setDetail("废弃合同");
            changeDelInfo.setSourceId(contract.getId());
            this.saveChangeDelInfo(changeDelInfo, 4, 2, ip, loginUser); // type 2 修改

        } else {
            changeDelInfo.setDetail("删除合同");
            changeDelInfo.setOriginal(contract.getStatus());
            changeDelInfo.setSourceId(contract.getId());
            this.saveChangeDelInfo(changeDelInfo, 4, 1, ip, loginUser);
            contract.setStatus(ContractStatusEnum.DELETE.getKey());

        }

        return contractRepository.save(contract);
    }

    @Override
    public Contract findOne(String code) {

        List<Contract> result = new ArrayList<>();
        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }
        List<PackageType> typeList = packageTypeRepository.findAll();
        Map<Long, String> typeMap = new HashMap<>();
        if (ValidateUtil.isValid(typeList)) {
            for (PackageType s : typeList) {
                typeMap.put(s.getId(), s.getPackageName());
            }
        }
        List<ContractIncrement> incrementList = contractIncrementRepository.findAll();
        Map<Long, String> incremenMap = new HashMap<>();
        if (ValidateUtil.isValid(incrementList)) {
            for (ContractIncrement s : incrementList) {
                incremenMap.put(s.getId(), s.getPackageName());
            }
        }
        Contract contract = contractRepository.findByCode(code);
        contract.setSaleName(saleMap.containsKey(contract.getSale()) ? saleMap.get(contract.getSale()) : "");
        if (contract.getType().equals(ContractTypeEnum.MAIN.getKey())) {
            contract.setPriceLevelName(typeMap.containsKey(contract.getPriceLevel()) ? typeMap.get(contract.getPriceLevel()) : "");
        } else {
            contract.setPriceLevelName(incremenMap.containsKey(contract.getPriceLevel()) ? incremenMap.get(contract.getPriceLevel()) : "");
        }
        contract.setCreateName(saleMap.containsKey(contract.getCreateAccount()) ? saleMap.get(contract.getCreateAccount()) : "");

        Boolean flag = null;
        if (!contract.getType().equals(ContractTypeEnum.MAIN.getKey())) {
            //人群分析
            if (null == contract.getEndDate()) {
                flag = checkTime(contract.getEmail(), contract.getPlatform(), contract.getType(), "black");
            } else {
                flag = checkTime(contract.getEmail(), contract.getPlatform(), contract.getType(), "analysis");
            }

            if (flag) {
                contract.setContractType("0");
            } else {
                contract.setContractType("1");
            }
        }
        return contract;
    }

    @Override
    public ContractMoney pay(User loginUser, ContractMoney resource) {
//        Contract contract = contractRepository.findByCode(resource.getContractCode());

        Contract contract = contractRepository.findOne(resource.getId());

        if (resource.getType().equals("pay")) {
            contract.setPayMoney(contract.getPayMoney() + resource.getMoney());
            //判断回款状态
            this.dealContractStatus(contract, loginUser, "update");
        } else {
            contract.setInvoiceMoney(contract.getInvoiceMoney().add(new BigDecimal(resource.getMoney().toString())));
        }

        if (ContractTypeEnum.INCREMENT.getKey().equals(contract.getType())) {
            contract.setStatus("end");
        }
        contractRepository.save(contract);

        resource.setPriceLevel(contract.getPriceLevel());
        resource.setSalse(contract.getSale());
        resource.setCompany(contract.getCustomerBody());
        resource.setCreateName(loginUser.getName());
        resource.setPlatform(contract.getPlatform());
        resource.setCreateAccount(loginUser.getId());
        resource.setCreateTime(new Date());
        resource.setUser(loginUser.getId());
        resource.setContractCode(contract.getContractCode());
        resource.setEmail(contract.getEmail());

//        if (resource.getType().equals("pay") && contract.getPlatform().equals("tkio")) {
//            tkioAccountService.contractPay(loginUser, resource);
//        } else if (resource.getType().equals("pay") && contract.getPlatform().equals("io")) {
//            ioAccountService.contractPay(loginUser, resource);
//        }
        return contractMoneyRepository.save(resource);
    }

    @Override
    public Contract change(User loginUser, ContractChange resource, FlowChange flowChange) {

        Contract contract = contractRepository.findByCode(resource.getContractCode());
        Map<Long, String> packageMap = getPackageMap(contract);

        boolean showTip = false;
        if (resource.getType().equals("price")) {

            resource.setContent(packageMap.get(contract.getPriceLevel()) + "改为" + packageMap.get(resource.getLevel()));
            resource.setMarke(contract.getMoney() + "元改为" + resource.getMoney() + "元");
            contract.setMoney(resource.getMoney());
            contract.setPriceLevel(resource.getLevel());

            // 处理回款状态
            this.dealContractStatus(contract, loginUser, "update");


        } else if ("give".equals(resource.getType())) {
            //变更优惠记录
            this.saveFlowChange(contract, loginUser, "save", resource.getDiscountTimeLong(), resource.getExtraFlow());
            // 累加 合同表中数据
            if (resource.getExtraFlow() != null) {
                contract.setExtraFlow(contract.getExtraFlow() + resource.getExtraFlow());
            }
            if (resource.getDiscountTimeLong() != null) {
                contract.setDiscountTimeLong(contract.getDiscountTimeLong() + resource.getDiscountTimeLong());
            }

        } else {

            if (ContractStatusEnum.CANCEL.getKey().equals(resource.getStatus())) {
                //合同作废
                resource.setContent(ContractStatusEnum.CANCEL.getValue());
                contract.setStatus(ContractStatusEnum.CANCEL.getKey());
                showTip = true;
            } else if (ContractStatusEnum.SUSPEND.getKey().equals(resource.getStatus())) {
                //合同中止
                resource.setContent(ContractStatusEnum.SUSPEND.getValue());
                contract.setStatus(ContractStatusEnum.SUSPEND.getKey());
                showTip = true;
            }

        }
        resource.setPlatform(contract.getPlatform());
        resource.setCreateAccount(loginUser.getId());
        resource.setUser(loginUser.getId());


        if (ContractStatusEnum.SUSPEND.getKey().equals(resource.getStatus())) {
            resource.setCreateTime(new Date());
        } else {
            resource.setCreateTime(new Date());
            resource.setDs(DateUtil.getBeforeDays(0));
        }


        if (!"give".equals(resource.getType())) {
            contractChangeRepository.save(resource);
        }

        contractRepository.save(contract);

        if (showTip) {
            //获取相关执行合同名称
            List<String> codes = contractRepository.findContractBodyNames(contract.getCustomerBody(), contract.getContractCode());
            contract.setCustomBodyNames(codes);
        } else {
            contract.setCustomBodyNames(new ArrayList<>());
        }

        return contract;
    }


    @Override
    public Object changesDel(String platform, String id, String type, String ip, User loginUser) {


        if ("give".equals(type)) {
            // 优惠流量
            FlowChange change = flowChangeRepository.findOne(Long.parseLong(id));
            change.setDelFlag(1);
            flowChangeRepository.save(change);

            ChangeDelInfo changeDelInfo = new ChangeDelInfo();
            changeDelInfo.setContractCode(change.getContractCode());
            changeDelInfo.setEmail(change.getEmail());
            changeDelInfo.setSourceId(change.getId());
            changeDelInfo.setDetail("赠送时长:" + change.getDiscountTimeLong() + "天 — 赠送流量" + change.getDiscountFlow());

            this.saveChangeDelInfo(changeDelInfo, 1, 1, ip, loginUser);

            return change;
        } else if ("change".equals(type)) {
            //套餐变更
            ContractChange contractChange = contractChangeRepository.findOne(Long.parseLong(id));
            contractChange.setDelFlag(1);
            contractChangeRepository.save(contractChange);

            ChangeDelInfo changeDelInfo = new ChangeDelInfo();
            changeDelInfo.setContractCode(contractChange.getContractCode());
            changeDelInfo.setDetail("套餐变更");
            changeDelInfo.setEmail(contractChange.getEmail());
            changeDelInfo.setSourceId(contractChange.getId());
            this.saveChangeDelInfo(changeDelInfo, 2, 1, ip, loginUser);

            return contractChange;
        } else {

            ContractMoney contractMoney = contractMoneyRepository.findOne(Long.parseLong(id));
            contractMoney.setDelFlag(1);
            contractMoneyRepository.save(contractMoney);

            ChangeDelInfo changeDelInfo = new ChangeDelInfo();
            changeDelInfo.setContractCode(contractMoney.getContractCode());
            changeDelInfo.setEmail(contractMoney.getEmail());
            changeDelInfo.setSourceId(contractMoney.getId());

            if ("pay".equals(contractMoney.getType())) {

                this.dealPayMoneyByContractMoney(contractMoney, -1);
                changeDelInfo.setDetail("收款记录-金额:" + contractMoney.getMoney());

            } else {
                changeDelInfo.setDetail("开票记录-金额:" + contractMoney.getMoney());
            }

            this.saveChangeDelInfo(changeDelInfo, 3, 1, ip, loginUser);

            return contractMoney;
        }

    }

    private void dealPayMoneyByContractMoney(ContractMoney contractMoney, int addOr) {
        // 删除收款记录 修改相应收款金额
        // 恢复收款记录 修改相应合同收款金额
        Contract contract = contractRepository.findByCode(contractMoney.getContractCode());
        contract.setPayMoney(contract.getPayMoney() + contractMoney.getMoney() * addOr);
        contractRepository.save(contract);
    }


    @Override
    public List<ChangeDelInfo> getChangeDelData(User loginAccount, String contranctCode, String startDate, String
            endDate) {

        List<ChangeDelInfo> datas = changeDelInfoRepository.findOnStartDate(startDate, endDate);
        return datas;
    }


    @Override
    public List<ChangeDelDetail> getChangeDelDetailData(User loginAccount, String pid) {

        List<ChangeDelDetail> datas = changeDelDetailRepository.findByPid(pid);
        return datas;
    }


    @Override
    public ChangeDelInfo changesDelRecover(String id, String type, User loginAccount) {
        // 恢复删除

        ChangeDelInfo changeDelInfo = changeDelInfoRepository.findOne(Long.parseLong(id));
        if (changeDelInfo.getModifyType() == 1) {
//            put("1","流量赠送");
//            put("2","合同变更记录");
//            put("3","收款/开票记录");
//            put("4","合同管理");
            if (changeDelInfo.getFunction() == 1) {
                FlowChange change = flowChangeRepository.findOne(changeDelInfo.getSourceId());
                change.setDelFlag(0);
                flowChangeRepository.save(change);
            } else if (changeDelInfo.getFunction() == 2) {
                ContractChange contractChange = contractChangeRepository.findOne(changeDelInfo.getSourceId());
                contractChange.setDelFlag(0);
                contractChangeRepository.save(contractChange);
            } else if (changeDelInfo.getFunction() == 3) {
                //
                ContractMoney money = contractMoneyRepository.findOne(changeDelInfo.getSourceId());
                String detail = changeDelInfo.getDetail();
                if (detail != null && detail.startsWith("收款")) {
                    //恢复收款记录 修改相应合同收款金额
                    dealPayMoneyByContractMoney(money, 1);
                }
                money.setDelFlag(0);
                contractMoneyRepository.save(money);
            } else if (changeDelInfo.getFunction() == 4) {
                // 合同恢复
                Contract contract = contractRepository.findOne(changeDelInfo.getSourceId());
                contract.setStatus(changeDelInfo.getOriginal());
                contractRepository.save(contract);

            }

            changeDelInfoRepository.delete(changeDelInfo);
        }

        return null;
    }

    public void saveChangeDelInfo(ChangeDelInfo changeDelInfo, int function, int type, String ip, User loginUser) {

        changeDelInfo.setCreatTime(new Date());
        changeDelInfo.setFunction(function);// 1 赠送记录
        changeDelInfo.setModifyType(type);// 1 删除
        changeDelInfo.setIp(ip);
        changeDelInfo.setDs(new DateTime().toString("yyyy-MM-dd"));
        changeDelInfo.setModifyAccount(loginUser.getName());
        changeDelInfo.setModifyId(loginUser.getId());
        changeDelInfoRepository.save(changeDelInfo);

    }

    @Override
    public List<ContractMoney> findPay(String startDate, String endDate, String code) {
        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }

        List<ContractMoney> result = new ArrayList<>();
        List<ContractMoney> list = contractMoneyRepository.findByDs(startDate, endDate, code);
        if (ValidateUtil.isValid(list)) {
            for (ContractMoney cm : list) {
                cm.setCreateName(saleMap.containsKey(cm.getUser()) ? saleMap.get(cm.getUser()) : "");
                result.add(cm);
            }
        }
        return result;
    }

    @Override
    public List<ContractChange> findChange(String startDate, String endDate, String code) {

        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }

        List<ContractChange> result = new ArrayList<>();
        List<ContractChange> list = contractChangeRepository.findByDs(startDate, endDate, code);
        if (ValidateUtil.isValid(list)) {
            for (ContractChange cm : list) {
                cm.setCreateName(saleMap.containsKey(cm.getUser()) ? saleMap.get(cm.getUser()) : "");
                result.add(cm);
            }
        }

        return result;
    }

    @Override
    public List<FlowChange> findflowChange(String startDate, String endDate, String code) {
        return flowChangeRepository.findByAddDate(startDate, endDate, code);
    }

    @Override
    public Contract updatePay(User loginUser, ContractMoney resource, String ip) {
        ContractMoney contractMoney = contractMoneyRepository.findOne(resource.getId());
        Contract contract = contractRepository.findByCode(resource.getContractCode());

        ChangeDelInfo changeDelInfo = new ChangeDelInfo();

        ChangeDelDetail delDetail = new ChangeDelDetail();
        delDetail.setBeforeValue(contractMoney.getMoney().toString());
        delDetail.setAfterValue(resource.getMoney().toString());

        if (contractMoney.getType().equals("pay")) {
            contract.setPayMoney(contract.getPayMoney() + resource.getMoney() - contractMoney.getMoney());

            delDetail.setItem("收款");
            delDetail.setDetail("收款金额");

        } else {
//            contract.setInvoice(contract.getInvoice() + resource.getMoney() - contractMoney.getMoney());
            contract.setInvoiceMoney(contract.getInvoiceMoney().add(new BigDecimal(resource.getMoney())).subtract(new BigDecimal(contractMoney.getMoney())));
            delDetail.setItem("开票");
            delDetail.setDetail("开票金额");
        }

        changeDelInfo.setDetail("修改详情");//
        changeDelInfo.setContractCode(contractMoney.getContractCode());
        changeDelInfo.setEmail(contractMoney.getEmail());
        this.saveChangeDelInfo(changeDelInfo, 3, 2, ip, loginUser);

        delDetail.setCreatTime(new Date());
        delDetail.setContractCode(contractMoney.getContractCode());
        delDetail.setEmail(contractMoney.getEmail());
        delDetail.setParentId(changeDelInfo.getId());

        changeDelDetailRepository.save(delDetail);

        Contract save = contractRepository.save(contract);

        contractMoney.setModifyAccount(loginUser.getId());
        contractMoney.setModifyTime(new Date());
        contractMoney.setMoney(resource.getMoney());
//        contractMoney.setDs(resource.getDs());
        contractMoneyRepository.save(contractMoney);

        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }

        Map<Long, String> typeMap = this.getPackageMap(contract);
        save.setSaleName(saleMap.containsKey(save.getSale()) ? saleMap.get(save.getSale()) : "");
        save.setPriceLevelName(typeMap.containsKey(save.getPriceLevel()) ? typeMap.get(save.getPriceLevel()) : "");
        save.setCreateName(saleMap.containsKey(save.getSale()) ? saleMap.get(save.getSale()) : "");
        return save;
    }


//    public List<ContractMoney> findPayAll(String startDate, String endDate, String platfrom) {
//
//        return this.findPayAll(startDate,endDate,platfrom,"all","all", null);
//    }


    @Override
    public List<ContractMoney> findPayAll(User loginAccount, String startDate, String endDate, String
            platfrom, String moneyType, String packageTypeSearch, String money_ids) {

        Map<Long, PackageType> packageTypeMap = new HashMap<>();
        Map<Long, String> saleMap = new HashMap<>();
        Map<Long, PackageBase> packageBaseMap = new HashMap<>();

        this.getDicMapDatas(saleMap, packageTypeMap, null, null, packageBaseMap, platfrom);

        List<ContractMoney> result = new ArrayList<>();

        List<ContractMoney> list;

        if ("-1".equals(money_ids)) {

            list = new ArrayList<>();

        } else if (!StringUtil.isEmpty(money_ids)) {
            list = contractMoneyRepository.findByDsAllContractMoneyIds(startDate, endDate, platfrom, Arrays.asList(money_ids.split(",")));
        } else if (!"all".equals(moneyType) && !"all".equals(packageTypeSearch)) {
            list = contractMoneyRepository.findByDsAllContractAll(startDate, endDate, platfrom, moneyType, packageTypeSearch);
        } else if (!"all".equals(moneyType)) {
            list = contractMoneyRepository.findByDsAllContractMoneyType(startDate, endDate, platfrom, moneyType);
        } else if (!"all".equals(packageTypeSearch)) {
            list = contractMoneyRepository.findByDsAllContractPkSearch(startDate, endDate, platfrom, packageTypeSearch);
        } else {
            list = contractMoneyRepository.findByDsAllContract(startDate, endDate, platfrom);
        }

        // 权限过滤

        Map<String, Object> authdata = authService.getAuthExtends(loginAccount);

        if (authdata.get("needcheck") != null) {

            List<String> codesList = list.stream().map(p -> p.getContractCode()).collect(Collectors.toList());

//            contract_code,my_body_code,sale,platform

            if (RoleEnum.FINANCE.getKey().equals(loginAccount.getRole())) {

                list = filterContractMoney(codesList, authdata, list, 1);

            } else if (RoleEnum.SALSEMAN.getKey().equals(loginAccount.getRole())) {

                list = filterContractMoney(codesList, authdata, list, 2);
            } else if (RoleEnum.PM.getKey().equals(loginAccount.getRole())) {

                list = filterContractMoney(codesList, authdata, list, 3);
            }

        }

        if (ValidateUtil.isValid(list)) {
            for (ContractMoney cm : list) {

                cm.setSalseName(saleMap.get(cm.getSalse()));

                if ("tkio".equals(platfrom)) {

                    PackageType packageType = packageTypeMap.get(cm.getPriceLevel());

                    if (packageType != null) {
                        String flow = packageType.getTrackFlow().intValue() < 0 ? "无限制" : packageType.getTrackFlow().intValue() / 10000 + "万/年";

                        cm.setPackageName(packageType.getPackageName() + ": 流量" + flow + " APP" + packageType.getAppNum() + "个");

                    } else {
                        cm.setPackageName("");
                    }

                } else {
                    cm.setPackageName(packageBaseMap.get(cm.getPriceLevel()) == null ? "" : packageBaseMap.get(cm.getPriceLevel()).getPackageName());
                }

            }
        }
        return list;
    }

    private List<ContractMoney> filterContractMoney
            (List<String> codesList, Map<String, Object> authdata, List<ContractMoney> list, int nextIndex) {

        if (codesList == null || codesList.size() == 0) {
            return list;
        }

        List<Object[]> contactdata = contractRepository.findByContractCode(codesList);

        if (contactdata != null) {
            Map<String, String> dicdata = contactdata.stream().
                    collect(Collectors.toMap(p -> p[0].toString(), p -> p[nextIndex] == null ? "all" : p[nextIndex].toString(), (key1, key2) -> key1));

            return list.stream().filter(p ->
                    authdata.get(dicdata.get(p.getContractCode())) == null ? false : true
                            || "all".equals(authdata.get(dicdata.get(p.getContractCode())))).collect(Collectors.toList());

        } else {

            return list;

        }


    }

    @Override
    public List<TradeType> getTradeData(String platform) {
        return tradeTypeRepsitory.findAll();
    }

    @Override
    public List<Map> contractCodeAll(String platform, String contractId) {

        Map<String, String> data = new HashMap<>();
        data.put("id", "-1");
        data.put("contractCode", "无");

        List result = new ArrayList();
        result.add(data);

        List<String> plats = new ArrayList<>();

        plats.add(platform);

        if ("fake".equals(platform)) {
            plats.add("tkio");
        }

        List<ContractRelation> ids = null;
        Contract contract = null;
        if (!StringUtils.isEmpty(contractId) && !contractId.equals("null")) {
            ids = contractRelationRepository.findRelationIdsMain(contractId);
            contract = contractRepository.findOne(Long.parseLong(contractId));
        }

        if (ids != null) {

            // 已关联合同 字典
            Map<String, String> filterMap = new HashMap();
            for (ContractRelation relation : ids) {

                if (contract != null && !relation.getRelationId().equals(contract.getRelationContract())) {
                    filterMap.put(relation.getRelationId() + "_", "");
                }

            }

            // 所有可关联合同
            List<Map> resultBefore = contractRepository.contractCodePlatform(plats);
            for (Map m : resultBefore) {

                String m_id = m.get("id").toString() + "_";
                if (filterMap.get(m_id) == null && !m_id.equals(contractId + "_")) {
                    result.add(m);
                }
            }
        } else {
            result.addAll(contractRepository.contractCodePlatform(plats));
        }

        return result;
    }

    @Override
    public Map contractCodeCheck(String platform, String contractCode) {

        Contract contractExist = contractRepository.findByCodePlatform(contractCode, platform);

        Map<String, String> data = new HashMap<>();

        if (contractExist != null) {
            data.put("exist", "true");
        } else {
            data.put("exist", "false");
        }
        return data;
    }

    public Map<Long, String> getPackageMap(Contract contract) {
//        List<PackageType> typeList = packageTypeRepository.findAll();

        String platform = contract.getPlatform();

        if ("trackio".equals(platform)) {
            List<PackageType> typeList = packageTypeRepository.findIsNewAll();
            Map<Long, String> typeMap = new HashMap<>();
            if (ValidateUtil.isValid(typeList)) {
                for (PackageType s : typeList) {
                    typeMap.put(s.getId(), s.getPackageName());
                }
            }

            return typeMap;
        } else {

            List<PackageBase> packageBases = packageBaseRepository.findByPlatAndStatus(platform, 1);

            Map<Long, String> typeMap = new HashMap<>();
            for (PackageBase packageBase : packageBases) {
                typeMap.put(packageBase.getId(), packageBase.getPackageName());

            }

            return typeMap;
        }

    }

    public Map<Long, String> getSaleMap() {
        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }
        return saleMap;
    }


    public static Map<String, String> convertBean(Object bean) throws
            IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Class type = bean.getClass();
        Map<String, String> returnMap = new HashMap<String, String>();
        BeanInfo beanInfo = Introspector.getBeanInfo(type);

        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (int i = 0; i < propertyDescriptors.length; i++) {
            PropertyDescriptor descriptor = propertyDescriptors[i];
            String propertyName = descriptor.getName();
            if (!propertyName.equals("class")) {
                Method readMethod = descriptor.getReadMethod();

                Object invoke = readMethod.invoke(bean, new Object[0]);
                String result = (null == invoke ? null : invoke.toString());

                if (result != null) {
                    returnMap.put(propertyName, result);
                } else {
                    returnMap.put(propertyName, null);
                }


            }
        }
        return returnMap;
    }


    @Override
    public ResultModel uploadBatchInfo(MultipartFile file, String platform) {
        InputStream stream = null;
        try {
            int row_length = 11;
            stream = file.getInputStream();
            Workbook workbook = WorkbookFactory.create(stream);
//            Iterator<Sheet> sheetIter = workbook.sheetIterator();
//            while (sheetIter.hasNext()) {
//                Sheet sheet = sheetIter.next();
//            }
            return saveDataBySheet(workbook.getSheetAt(0), row_length, platform);

        } catch (Exception ex) {
            logger.error("批量上传合同错误", ex);
            return ResultModel.ERROR(ResultStatus.UPLOAD_ERRO);
        }
    }


    public ResultModel saveDataBySheet(Sheet sheet, int row_length, String platformexcl) {
        String sheetName = sheet.getSheetName();
        if (!SHEET_NAMES.containsKey(sheetName)) {
            return ResultModel.ERROR("模板标签页名称错误");
        }

        if (!sheetName.equalsIgnoreCase(SHEET_NAMES_RESERVE.get(platformexcl))) {
            return ResultModel.ERROR("请上传对应项目模板处理的数据");
        }

        String platform = SHEET_NAMES.get(sheetName);
        Map<String, Long> tradTypeMap = tradeTypeRepsitory.findAll()
                .stream().collect(Collectors.toMap(TradeType::getName, TradeType::getId));
        Map<String, Long> salseMap = salesRepository.findSaleByStatus(0)
                .stream().collect(Collectors.toMap(Sales::getName, Sales::getId));
        Map<String, Long> packageMap = null;

        if ("tkio".equals(platform) || "io".equals(platform)) {
            packageMap = packageTypeRepository.findIsNewAll()
                    .stream().collect(Collectors.toMap(PackageType::getPackageName, PackageType::getId));
        } else {
            packageMap = packageBaseRepository.findByPlatAndStatus(platform, 1)
                    .stream().collect(Collectors.toMap(PackageBase::getPackageName, PackageBase::getId));
        }

        Map<String, String> cBodyMap = null;
        if ("abtest".equals(platform) || "ads".equals(platform)) {
            cBodyMap = contractBodyRepository.findByPlatform(platform)
                    .stream().collect(Collectors.toMap(ContractBody::getName, ContractBody::getCode));
        } else {
            cBodyMap = contractBodyRepository.findAllDis()
                    .stream().collect(Collectors.toMap(ContractBody::getName, ContractBody::getCode, (v1, v2) -> v1));
        }

        Row row = sheet.getRow(0);
        List<String> titleKey = new ArrayList<>();
        if (!parseRowData(row, row_length, null, titleKey)) {
            return ResultModel.ERROR(ResultStatus.FORMAT_FILE_ERRO);
        }

        int row_already = titleKey.size();
        String extend_row_sql = "platform,product,my_body_code,create_time,code_num,type,status,back_status,ds," +
                "create_account,create_name,extra_flow,relation_contract,invoice_money,first_back_id";

        int extend_size = extend_row_sql.split(",").length;

        DataFormatter formatter = new DataFormatter();
        int rowNumber = sheet.getLastRowNum();
        List<Object[]> args_data = new ArrayList<>();

        Map<String, String> codeUniqueDic = new HashMap<>();
        for (int j = 1; j <= rowNumber; j++) {
            Row row_data = sheet.getRow(j);
            Object[] s_data = new Object[titleKey.size() + extend_size];
            String bodyCode = null;
            String ds = null;
            if (row_data == null) {
                continue;
            }

            for (int w = 0; w < titleKey.size(); w++) {
                String sheetTitle = titleKey.get(w);
                Cell cell = row_data.getCell(w);
                int line_num = j + 1;
                if (null == cell || cell.getCellTypeEnum().equals(CellType.BLANK)) {
                    return ResultModel.ERROR("第" + line_num + "行【" +
                            SHEET_TITLE_RESERVE.get(sheetTitle) + "】不能为空,请重新上传");
                } else {
                    String dataSTR = formatter.formatCellValue(cell).trim();
                    //校验合同编号
                    if ("contract_code".equals(sheetTitle)) {
                        if (!codeUniqueDic.containsKey(dataSTR)) {
                            codeUniqueDic.put(dataSTR, "1");
                        } else {
                            return ResultModel.ERROR(ResultStatus.CCODE_EXITS.getCode(),
                                    "合同编号【" + dataSTR + "】已存在,请重新上传");
                        }

                        Contract contractExist = contractRepository.checkByCode(dataSTR);
                        if (contractExist != null) {
                            return ResultModel.ERROR(ResultStatus.CCODE_EXITS.getCode(),
                                    "合同编号【" + dataSTR + "】已存在,请重新上传");
                        }
                    }

                    if ("my_body_name".equals(sheetTitle)) {
                        if (!cBodyMap.containsKey(dataSTR)) {
                            return ResultModel.ERROR("第" + line_num + "行【我方签约主体】错误");
                        } else {
                            s_data[w] = dataSTR;
                            bodyCode = cBodyMap.get(dataSTR);
                        }

                    } else if ("trade_type".equals(sheetTitle)) {
                        if (!tradTypeMap.containsKey(dataSTR)) {
                            return ResultModel.ERROR("第" + line_num + "行【行业分类】错误");
                        } else {
                            s_data[w] = tradTypeMap.get(dataSTR);
                        }
                    } else if ("sale".equals(sheetTitle)) {
                        if (!salseMap.containsKey(dataSTR)) {
                            return ResultModel.ERROR("第" + line_num + "行【签约销售】错误");
                        } else {
                            s_data[w] = salseMap.get(dataSTR);
                        }
                    } else if ("contract_type".equals(sheetTitle)) {
                        if (!CONTRACT_TYPE_NAME.containsKey(dataSTR)) {
                            return ResultModel.ERROR("第" + line_num + "行【签约类型】错误");
                        } else {
                            s_data[w] = CONTRACT_TYPE_NAME.get(dataSTR);
                        }
                    } else if ("price_level".equals(sheetTitle)) {
                        if (packageMap != null && !packageMap.containsKey(dataSTR)) {
                            return ResultModel.ERROR("第" + line_num + "行【套餐】错误");
                        } else {
                            s_data[w] = packageMap.get(dataSTR);
                        }
                    } else if ("start_date".equals(sheetTitle) || "end_date".equals(sheetTitle)) {
                        String dfmate = cell.getCellStyle().getDataFormatString();

                        if (!"yyyy/mm;@".equals(dfmate)
                                && !"m/d/yy".equals(dfmate)
                                && !"yy/m/d".equals(dfmate)
                                && !"mm/dd/yy".equals(dfmate)
                                && !"dd-mmm-yy".equals(dfmate)
                                && !"yyyy/m/d".equals(dfmate)
                        ) {
                            return ResultModel.ERROR("第" + line_num + "行【日期单元格】错误");
                        }

                        if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) {
                            // 用于转化为日期格式
                            Date d = cell.getDateCellValue();
                            DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
                            s_data[w] = formater.format(d);
                        } else {
                            s_data[w] = cell.toString();
                        }

                        if ("start_date".equals(sheetTitle)) {
                            ds = s_data[w].toString();
                        }

                    } else if ("money".equals(sheetTitle)) {

                        s_data[w] = dataSTR.replace(",", "");
                    } else {
                        s_data[w] = dataSTR;
                    }
                }
            }


            //platform,product,my_body_code,create_time,code_num,type,status,back_status,ds,
            s_data[row_already] = platform;
            s_data[row_already + 1] = platform;
            s_data[row_already + 2] = bodyCode;
            s_data[row_already + 3] = new Date();
            s_data[row_already + 4] = 0;
            s_data[row_already + 5] = "main";
            s_data[row_already + 6] = ContractStatusEnum.NFORMAL.getKey(); //常规合同
            s_data[row_already + 7] = 1; //未回款
            s_data[row_already + 8] = ds;
//            create_account,create_name,extra_flow,relation_contract,invoice_money,first_back_id
            s_data[row_already + 9] = 0;
            s_data[row_already + 10] = "导入";
            s_data[row_already + 11] = 0;
            s_data[row_already + 12] = -1;
            s_data[row_already + 13] = 0;
            s_data[row_already + 14] = 0;
            //批量添加数据
            args_data.add(s_data);
        }

        StringBuffer sql = new StringBuffer("insert into contract (");
        titleKey.forEach(v -> sql.append(v + ","));
        sql.append(extend_row_sql);
        sql.append(") values (");

        for (int ed = 0, s = row_already + extend_size; ed < s; ed++) {
            if (ed == 0) {
                sql.append("?");
            } else {
                sql.append(",?");
            }
        }
        sql.append(")");
        logger.info("sql[{}]", sql.toString());

//        TransactionStatus transactionStatus = transactionUtils.begin();
        jdbcTemplate.batchUpdate(sql.toString(), args_data);
//        transactionUtils.commit(transactionStatus);

        return ResultModel.OK();

    }


    private boolean parseRowData(Row row, int length, StringBuffer content, List<String> titleKey) {

        if (row == null) {
            return false;
        }
        if (content == null) {
            content = new StringBuffer();
        }
        DataFormatter formatter = new DataFormatter();
        for (int i = 0; i < length; i++) {
            Cell cell = row.getCell(i);
            if (null != cell && !cell.getCellTypeEnum().equals(CellType.BLANK)) {
                String cnValue = formatter.formatCellValue(cell).trim();
                if (content.length() == 0) {
                    content.append(cnValue);
                } else {
                    content.append("," + cnValue);
                }

                if (!SHEET_TITLE.containsKey(cnValue)) {
                    return false;
                }
                titleKey.add(SHEET_TITLE.get(cnValue));
            }
        }

        return true;
    }



    public static void main(String[] args) {
//        String dateStr1 = "2019-04-30";
//        String dateStr2 = "2019-04-01";
//
//        System.out.println(new DateTime(dateStr2).compareTo(new DateTime(dateStr1)));
//        System.out.println(Days.daysBetween(new DateTime(dateStr2), new DateTime(dateStr1)).getDays());

        System.out.println(10023L * 1.0 / 100);
        System.out.println((129 * 100 / 111) * 1.0 / 100);
        System.out.println();

    }
}
