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.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.IOException;
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.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 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("行政区域", "barrio_id");
		put("隶属集团", "belong_group");
		put("行业分类", "trade_type");
		put("合同金额", "money");
		put("合同流量", "track_flow");
		put("赠送流量", "extra_flow");
		put("客户主账号", "email");
		put("合同编号", "contract_code");
		put("签约类型", "contract_type");
		put("套餐", "price_level");
		put("合同类型", "type_id");
		put("合同开始日期", "start_date");
		put("合同结束日期", "end_date");
		put("签约销售", "sale");
		put("关联合同编号", "relation_code");
		put("补充协议签订日期", "signed_date");
		put("是否计算一次性收入", "one_time");
		put("业务类型", "business_type");
		put("协议类型", "agreement_type");
	}};

	private static final Map<String, String> SHEET_TITLE_RESERVE = new HashMap() {{
		put("my_body_name", "我方签约主体");
		put("customer_body", "客户签约主体");
		put("barrio_id", "行政区域");
		put("belong_group", "隶属集团");
		put("trade_type", "行业分类");
		put("money", "合同金额");
		put("track_flow", "合同流量");
		put("extra_flow", "赠送流量");
		put("email", "客户主账号");
		put("contract_code", "合同编号");
		put("contract_type", "签约类型");
		put("price_level", "套餐");
		put("type_id", "合同类型");
		put("start_date", "合同开始日期");
		put("end_date", "合同结束日期");
		put("sale", "签约销售");
		put("relation_code", "关联合同编号");
		put("signed_date", "补充协议签订日期");
		put("one_time", "是否计算一次性收入");
		put("business_type", "业务类型");
		put("agreement_type", "协议类型");
	}};

	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");
		put("CAS", "cas");
	}};

	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");
		put("cas", "CAS");
	}};

	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;

	@Autowired
	QcloudAccountRepository qcloudAccountRepository;

	@Autowired
	private BarrioCityRepository barrioCityRepository;

	@Autowired
	private CalculationFlowRepository calculationFlowRepository;

	@Autowired
	private DmpIncomeService dmpIncomeService;

	@Autowired
	private PdIncomeRepository pdIncomeRepository;


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

		if ("tkio".equals(platfrom)) {
			//account4Web = account4WebRepository.findByEmail(email);
			account = accountRepository.findByEmail(email);

			if (account == null) {
				QcloudAccount qcloudAccount = qcloudAccountRepository.findByEmail(email);

				if (qcloudAccount != null) {
					account = new Account();
					account.setId(qcloudAccount.getId());
					account.setCompany(qcloudAccount.getCompany());
					account.setEmail(qcloudAccount.getEmail());
				}
			}

		} else if ("io".equals(platfrom)) {
			ioAccount4Web = ioAccount4WebRepository.findByEmail(email);
		} else if ("adi".equals(platfrom) || "cas".equals(platfrom)) {
			adiUser = adiAccountService.findOne(email, "国内");
		}
		if (null == account && 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 if (platfrom.equals("cas")) {
				map.put("company", adiUser.getCompany());
				map.put("validStartDate", adiUser.getSendTime());
			} else {
				// map.put("company", null == account4Web ? ioAccount4Web.getCompany() : account4Web.getCompany());
				map.put("company", account.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, platform);
		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 ("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;
		}
		resource.setOneTime(true);
		//补充协议
		if ("2".equals(resource.getContractType()) && "tkio".equals(resource.getPlatform())) {
			//关联合同不能为空
			if (null == resource.getRelationContract() || "".equals(resource.getRelationContract()) || -1L == resource.getRelationContract()) {
				Contract contractExist = new Contract();
				contractExist.setId(-100L);
				contractExist.setErroMessage("关联合同为必填项");
				return contractExist;
			}
			//补充协议开始日期不能晚于原始合同的结束日期
			Contract relationContract = contractRepository.findOne(resource.getRelationContract());
			if (relationContract.getEndDate().compareTo(resource.getSignedDate()) < 0) {
				Contract contractExist = new Contract();
				contractExist.setId(-100L);
				contractExist.setErroMessage("补充协议开始日期不能晚于原始合同的结束日期");
				return contractExist;
			}
		}

		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);//判断是否计算调整金


		//判断库里是否已有合同的主账号
		if ("tkio".equals(resource.getPlatform())) {
			List<Contract> contracts = contractRepository.findByPlatformAndEmail(resource.getPlatform(), resource.getEmail());
			CalculationFlow calculationFlow = new CalculationFlow();
			calculationFlow.setEmail(resource.getEmail());
			calculationFlow.setContractCode(resource.getContractCode());
			calculationFlow.setStatus(0);
			calculationFlow.setTriggerType("新建");
			calculationFlow.setCreateTime(DateUtil.getCurrentDateStr());
			calculationFlow.setIsAll(false);
			if (contracts == null || contracts.size() > 0) {
				for (Contract contract : contracts) {
					if (intersection(contract, resource)) {//有交集
						calculationFlow.setIsAll(true);
						break;
					}
				}
			}
			calculationFlowRepository.save(calculationFlow);

			//补充协议:后端逻辑顺序绑定
			if ("2".equals(resource.getContractType())) {
				DateTime dateTime = new DateTime(resource.getSignedDate());//补充协议晚录判断
				if (shareIncomeService.checkLateContract(dateTime,
						new DateTime(new DateTime().toString("yyyy-MM-dd")))) {
					resource.setStatus(ContractStatusEnum.LATE.getKey());
				} else {
					resource.setStatus(ContractStatusEnum.NFORMAL.getKey());
				}
				Long relationContract = resource.getRelationContract();
				Contract one = contractRepository.findOne(relationContract);
				resource.setRelationCode(one.getContractCode());
				String relationCode = resource.getRelationCode();
				resource.setStartDate(one.getStartDate());
				String platform = resource.getPlatform();
				while (true) {
					Contract contract = contractRepository.findByCodePlatform(relationCode, platform);
					if (StringUtils.isEmpty(contract.getNextSignedDate())) {

						if (ContractStatusEnum.LATE.getKey().equals(resource.getStatus())) {//如果晚录则设置绑定下一份合同的日期为签订月的最后一天
							contract.setNextSignedDate(dateTime.dayOfMonth().withMaximumValue().toString("yyyy-MM-dd"));
						} else {
							contract.setNextSignedDate(dateTime.plusDays(-1).toString("yyyy-MM-dd"));//签订日的前一天
						}
						contract.setNextSignedContractCode(resource.getContractCode());
						contractRepository.save(contract);
						break;
					} else {
						relationCode = contract.getNextSignedContractCode();
					}
				}

			}
		} else if ("cas".equals(resource.getPlatform())) {
			PackageBase one = packageBaseRepository.findOne(resource.getPriceLevel());
			ADIUser adiUser = adiAccountService.findOne(resource.getEmail(), one.getPackageName());
			if (adiUser == null || StringUtils.isEmpty(adiUser.getSendTime())) {
				resource.setShareSign(0);
			} else {
				resource.setShareSign(1);
				DateTime sendTime = new DateTime(DateUtil.parseDate(DateUtil.C_TIME_PATTON_DEFAULT, adiUser.getSendTime()));

				DateTime startDate = new DateTime(resource.getStartDate());
				if (sendTime.isBefore(startDate)) {
					sendTime = startDate;
				}
				DateTime endDate = new DateTime(resource.getEndDate());
				String validStartDateStr = sendTime.toString(DateUtil.C_DATE_PATTON_DEFAULT);
				int contractAllDay = Days.daysBetween(startDate, endDate).getDays();//合同总天数-1 ,用于计算结束日期
				String validEndDateStr = sendTime.plusDays(contractAllDay).toString("yyyy-MM-dd");
				resource.setValidStartDate(validStartDateStr);
				resource.setValidEndDate(validEndDateStr);
				if (shareIncomeService.checkLateContract(new DateTime(validStartDateStr),
						new DateTime(new DateTime().toString("yyyy-MM-dd")))) {
					resource.setStatus(ContractStatusEnum.LATE.getKey());
				} else {
					resource.setStatus(ContractStatusEnum.NFORMAL.getKey());
				}
			}
		}


		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 * 10000);
						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 * 10000);
						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 ("2".equals(resource.getContractType()) && "tkio".equals(resource.getPlatform())) {
			//关联合同不能为空
			if (null == resource.getRelationContract() || "".equals(resource.getRelationContract()) || -1L == resource.getRelationContract()) {
				Contract contractExist = new Contract();
				contractExist.setId(-100L);
				contractExist.setErroMessage("关联合同为必填项");
				return contractExist;
			}
			//补充协议开始日期不能晚于原始合同的结束日期
			Contract relationContract = contractRepository.findOne(resource.getRelationContract());
			if (relationContract.getEndDate().compareTo(resource.getSignedDate()) < 0) {
				Contract contractExist = new Contract();
				contractExist.setId(-100L);
				contractExist.setErroMessage("补充协议开始日期不能晚于原始合同的结束日期");
				return contractExist;
			}
		}

		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());
		if (ContractStatusEnum.NFORMAL.getKey().equals(contract.getStatus()) || ContractStatusEnum.LATE.getKey().equals(contract.getStatus())) {
			if (shareIncomeService.checkLateContract(new DateTime(resource.getStartDate()),
					new DateTime(new DateTime(resource.getCreateTime()).toString("yyyy-MM-dd")))) {
				resource.setStatus(ContractStatusEnum.LATE.getKey());
			} else {
				resource.setStatus(ContractStatusEnum.NFORMAL.getKey());
			}
		}


		//this.calculateShareIncome(resource);

		resource.setId(contract.getId());

		//判断库里是否已有合同的主账号
		if ("tkio".equals(resource.getPlatform())) {
			if (contract.getStartDate() != resource.getStartDate() && contract.getEndDate() != resource.getEndDate()) {
				List<Contract> contracts = contractRepository.findByPlatformAndEmail(resource.getPlatform(), resource.getEmail());
				CalculationFlow calculationFlow = new CalculationFlow();
				calculationFlow.setEmail(resource.getEmail());
				calculationFlow.setContractCode(resource.getContractCode());
				calculationFlow.setStatus(0);
				calculationFlow.setTriggerType("编辑");
				calculationFlow.setCreateTime(DateUtil.getCurrentDateStr(DateUtil.C_TIME_PATTON_DEFAULT));
				calculationFlow.setIsAll(false);
				if (contracts == null || contracts.size() > 0) {
					for (Contract contract1 : contracts) {
						if (contract1.getId() != contract.getId()) {
							if (intersection(contract1, resource) || intersection(contract1, contract)) {//有交集
								calculationFlow.setIsAll(true);
								break;
							}
						}
					}
				}
				calculationFlowRepository.save(calculationFlow);
			}
			//补充协议
			if ("2".equals(resource.getContractType())) {
				DateTime dateTime = new DateTime(resource.getSignedDate());//补充协议晚录判断
				if (ContractStatusEnum.NFORMAL.getKey().equals(contract.getStatus()) || ContractStatusEnum.LATE.getKey().equals(contract.getStatus())) {
					if (shareIncomeService.checkLateContract(dateTime,
							new DateTime(new DateTime(resource.getCreateTime()).toString("yyyy-MM-dd")))) {
						resource.setStatus(ContractStatusEnum.LATE.getKey());
					} else {
						resource.setStatus(ContractStatusEnum.NFORMAL.getKey());
					}
				}
				Contract bindContract = contractRepository.findByNextSignedContractCode(resource.getContractCode());
				if (ContractStatusEnum.LATE.getKey().equals(resource.getStatus())) {//如果晚录则设置绑定下一份合同的日期为签订月的最后一天
					bindContract.setNextSignedDate(dateTime.dayOfMonth().withMaximumValue().toString("yyyy-MM-dd"));
				} else {
					bindContract.setNextSignedDate(dateTime.plusDays(-1).toString("yyyy-MM-dd"));//签订日的前一天
				}
				contractRepository.save(bindContract);
			}
		} else if ("cas".equals(resource.getPlatform())) {
			PackageBase one = packageBaseRepository.findOne(resource.getPriceLevel());
			ADIUser adiUser = adiAccountService.findOne(resource.getEmail(), one.getPackageName());
			if (adiUser == null || StringUtils.isEmpty(adiUser.getSendTime())) {
				resource.setShareSign(0);
			} else {
				resource.setShareSign(1);
				DateTime sendTime = new DateTime(DateUtil.parseDate(DateUtil.C_TIME_PATTON_DEFAULT, adiUser.getSendTime()));

				DateTime startDate = new DateTime(resource.getStartDate());
				if (sendTime.isBefore(startDate)) {
					sendTime = startDate;
				}
				DateTime endDate = new DateTime(resource.getEndDate());
				String validStartDateStr = sendTime.toString(DateUtil.C_DATE_PATTON_DEFAULT);
				int contractAllDay = Days.daysBetween(startDate, endDate).getDays();//合同总天数-1 ,用于计算结束日期
				String validEndDateStr = sendTime.plusDays(contractAllDay).toString("yyyy-MM-dd");
				resource.setValidStartDate(validStartDateStr);
				resource.setValidEndDate(validEndDateStr);
				if (shareIncomeService.checkLateContract(new DateTime(validStartDateStr),
						new DateTime(new DateTime().toString("yyyy-MM-dd")))) {
					resource.setStatus(ContractStatusEnum.LATE.getKey());
				} else {
					resource.setStatus(ContractStatusEnum.NFORMAL.getKey());
				}
			}
		}

		return contractRepository.save(resource);

	}

	public Boolean intersection(Contract contract1, Contract contract2) {
		return (DateUtil.getDate(contract1.getStartDate()).getTime() <= DateUtil.getDate(contract2.getStartDate()).getTime() &&
				DateUtil.getDate(contract1.getEndDate()).getTime() >= DateUtil.getDate(contract2.getStartDate()).getTime()) ||
				(DateUtil.getDate(contract1.getStartDate()).getTime() <= DateUtil.getDate(contract2.getEndDate()).getTime() &&
						DateUtil.getDate(contract1.getEndDate()).getTime() >= DateUtil.getDate(contract2.getEndDate()).getTime()) ||
				(DateUtil.getDate(contract2.getStartDate()).getTime() <= DateUtil.getDate(contract1.getStartDate()).getTime() &&
						DateUtil.getDate(contract2.getEndDate()).getTime() >= DateUtil.getDate(contract1.getEndDate()).getTime());
	}

	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)) {

			List<String> coedIds = contractList.stream().map(v -> v.getContractCode()).collect(Collectors.toList());

			Map<String, String> acceptanceAmountMap = new HashMap<>();
			if ("pd".equals(platform)) {
				//私有化合同关联 验收收入
				List<Object[]> objects = pdIncomeRepository.findGroupWithCode(coedIds);
				acceptanceAmountMap = objects.stream().collect(Collectors.toMap(v -> v[0] + "", v -> v[1] + "", (v1, v2) -> v1));
			}

			//处理收款开票金额
			List<Object[]> codeMoneyList = contractMoneyRepository.findGroupCode(platform, coedIds);

			Map<String, Object[]> codeMoneyMap = codeMoneyList.stream().collect(Collectors.toMap(v -> v[0] + "", v -> v, (v1, v2) -> v1));


			List<BarrioCity> barrioCities = barrioCityRepository.findAll();
			Map<Long, BarrioCity> barrioCitiesNameMap = barrioCities.stream().collect(Collectors.toMap(BarrioCity::getId, Function.identity(), (v1, v2) -> v1));

			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.getBarrioId() != null)
					c.setBarrioName(barrioCitiesNameMap.get(barrioCitiesNameMap.get(c.getBarrioId()).getParentId()).getName());
				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);
				}

				//验收金额
				c.setAcceptanceAmount(acceptanceAmountMap.containsKey(c.getContractCode())
						? acceptanceAmountMap.get(c.getContractCode()) : "0");

				//收款开票金额


				if (codeMoneyMap == null || codeMoneyMap.isEmpty() || !codeMoneyMap.containsKey(c.getContractCode())) {
					c.setAmountCollected("0");
					c.setInvoiceAmount("0");
				} else {
					Object[] value = codeMoneyMap.get(c.getContractCode());
					c.setAmountCollected(value[1] + "");
					c.setInvoiceAmount(value[2] + "");
				}

               /* 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);
			}
		}

		//对结果二次加工
		if ("tkio".equals(platform)) {
			List<Long> relationContracts = contractRepository.findRelationContractBySideAgre();//查询被补充协议关联的合同
			for (Contract contract : result) {
				if (null == contract.getContractType() || !"2".equals(contract.getContractType())) { //非补充协议
					if (relationContracts.contains(BigInteger.valueOf(contract.getId()))) {
						contract.setOperate(false);//如果合同 被补充协议关联
					}
				} else {
					if (contract.getRelationContract() != null && contract.getRelationContract() > 0) { //补充协议
						contract.setOperate(false);//如果补充协议被关联
					}
				}
			}
		}
		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()) : "");

		//处理收款开票金额
		List<Object[]> codeMoneyList = contractMoneyRepository.findGroupCode(platform, Arrays.asList(contract.getContractCode() + ""));

		if (codeMoneyList != null && codeMoneyList.size() > 0) {
			Object[] value = codeMoneyList.get(0);
			contract.setAmountCollected(value[1] + "");
			contract.setInvoiceAmount(value[2] + "");
		} else {
			contract.setAmountCollected("0");
			contract.setInvoiceAmount("0");
		}

		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());
		Contract contract = contractRepository.findByCodeAndNotDel(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;
				//判断库里是否已有合同的主账号
				if ("tkio".equals(resource.getPlatform())) {
					List<Contract> contracts = contractRepository.findByPlatformAndEmail(resource.getPlatform(), resource.getEmail());
					CalculationFlow calculationFlow = new CalculationFlow();
					calculationFlow.setEmail(resource.getEmail());
					calculationFlow.setContractCode(resource.getContractCode());
					calculationFlow.setStatus(0);
					calculationFlow.setTriggerType("中止");
					calculationFlow.setCreateTime(DateUtil.getCurrentDateStr());
					calculationFlow.setIsAll(false);
					if (contracts == null || contracts.size() > 0) {
						for (Contract contract1 : contracts) {
							if (contract1.getId() != contract.getId()) {
								if (intersection(contract1, contract)) {//有交集
									calculationFlow.setIsAll(true);
									break;
								}
							}
						}
					}
					calculationFlowRepository.save(calculationFlow);
				}
			}

		}
		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()
					.filter(p -> p.getContractCode() != null).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, User loginAccount) {

		if ("dmp".equals(platform)) {
			return dmpIncomeService.contractUploadFile(file, platform, loginAccount);
		}


		InputStream stream = null;
		try {
			int row_length;
			if (platform.equals("tkio")) {
				row_length = 17;
			} else if (platform.equals("dmp")) {
				row_length = 17;
			} else if (platform.equals("cas")) {
				row_length = 14;
			} else {
				row_length = 13;
			}
			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, loginAccount);

		} catch (Exception ex) {
			logger.error("批量上传合同错误", ex);
			return ResultModel.ERROR(ResultStatus.UPLOAD_ERRO);
		} finally {
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e) {
					logger.error("", e);
				}
			}
		}
	}

	@Override
	public Object getBarrioCities() {
		List<BarrioCity> barrioCities = barrioCityRepository.findByParentId(0L);
		ArrayList<BarrioCityVO> objects = new ArrayList<>();
		for (BarrioCity barrioCity : barrioCities) {
			BarrioCityVO barrioCityVO = new BarrioCityVO();
			barrioCityVO.setParentCity(barrioCity);
			barrioCityVO.setCitys(barrioCityRepository.findByParentId(barrioCity.getId()));
			objects.add(barrioCityVO);
		}
		return objects;
	}


	public ResultModel saveDataBySheet(Sheet sheet, int row_length, String platformexcl, User loginAccount) {
		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 = packageBaseRepository.findByPlatAndStatus(platform, 1)
				.stream().collect(Collectors.toMap(PackageBase::getPackageName, PackageBase::getId));

		Map<Long, BarrioCity> barrioCityMap = barrioCityRepository.findAll()
				.stream().collect(Collectors.toMap(BarrioCity::getId, Function.identity()));
        /*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);
		}
		if (!platform.equals("tkio")) {
			titleKey.remove("合同流量");
			titleKey.remove("track_flow");
			titleKey.remove("赠送流量");
			titleKey.remove("extra_flow");
			titleKey.remove("补充协议签订日期");
			titleKey.remove("signed_date");
			titleKey.remove("关联合同编号");
			titleKey.remove("relation_code");
		} else if (!platform.equals("cas")) {
			titleKey.remove("有效开始日");
			titleKey.remove("valid_start_date");
			titleKey.remove("有效结束日");
			titleKey.remove("valid_end_date");
		}

		int row_already = titleKey.size();
		String extend_row_sql = null;

		if ("tkio".equals(platform)) {
			extend_row_sql = "platform,product,my_body_code,create_time,code_num,type,status,back_status,ds," +
					"create_account,create_name,relation_contract,invoice_money,first_back_id";
		} else if ("cas".equals(platform)) {
			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,valid_start_date,valid_end_date";
		} else {
			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<>();
		List<Contract> masterContracts = new ArrayList<>();

		Map<String, String> codeUniqueDic = new HashMap<>();
		List<String> accountsEmail = new ArrayList<>();
		List<String> moreEmail = new ArrayList<>();
		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;
			Date createTime = null;
			if (row_data == null) {
				continue;
			}

			Map<String, String> filter = new HashMap<>();
			filter.put("rowIndex", j + "");

			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) || "null".equalsIgnoreCase(formatter.formatCellValue(cell).trim())) {
					//主账号为空,额外处理
					if ("email".equals(sheetTitle) && "tkio".equals(platformexcl) && "null".equalsIgnoreCase(formatter.formatCellValue(cell).trim())) {
						String dataSTR = "null";
						s_data[w] = dataSTR;
						moreEmail.add(dataSTR.trim());
						accountsEmail.add(dataSTR.trim());
					} else {
						//非主账号 按照之前逻辑不变
						//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");
							filter.put("contractCode", dataSTR);
						} 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);
							filter.put("contractType", CONTRACT_TYPE_NAME.get(dataSTR));
						}
					} else if ("price_level".equals(sheetTitle)) {
						if (packageMap != null && !packageMap.containsKey(dataSTR) && !(platform.equals("tkio") && packageMap.containsValue(Long.parseLong(dataSTR)))) {
							return ResultModel.ERROR("第" + line_num + "行【套餐】错误");
						} else {
							if (platform.equals("tkio")) {
								s_data[w] = dataSTR;
							} else {
								s_data[w] = packageMap.get(dataSTR);
							}
						}
					} else if ("start_date".equals(sheetTitle) || "end_date".equals(sheetTitle) || "signed_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)
								&& !"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);
							if ("tkio".equals(platform)) {
								if ("signed_date".equals(sheetTitle)) {
									createTime = d;
									filter.put("signedDate", formater.format(d));
								}
								if ("start_date".equals(sheetTitle)) {
									filter.put("w", String.valueOf(w));
								}
							} else if ("cas".equals(platform)) {
								if ("start_date".equals(sheetTitle) || "end_date".equals(sheetTitle)) {
									filter.put(sheetTitle, String.valueOf(s_data[w]));
								}
							} else {
								if ("start_date".equals(sheetTitle)) {
									createTime = 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 if ("barrio_id".equals(sheetTitle)) {
						if (barrioCityMap.containsKey(Long.parseLong(dataSTR))) {
							s_data[w] = dataSTR;
						} else {
							return ResultModel.ERROR("第" + line_num + "行【行政区域】code错误");
						}
					} else if ("barrio_id".equals(sheetTitle)) {
						if (barrioCityMap.containsKey(Long.parseLong(dataSTR))) {
							s_data[w] = dataSTR;
						} else {
							return ResultModel.ERROR("第" + line_num + "行【行政区域】code错误");
						}
					} else if ("relation_code".equals(sheetTitle)) {
						s_data[w] = dataSTR;
						filter.put("relation_code", dataSTR);
					} else if ("one_time".equals(sheetTitle)) {
						if (dataSTR.equals("否")) {
							s_data[w] = false;
						} else {
							s_data[w] = true;
						}
						filter.put("validStartDate", formatter.formatCellValue(row_data.getCell(14)).trim());
						filter.put("one_time", dataSTR);
					} else {
						//主账号不为空,按照之前逻辑不变
						s_data[w] = dataSTR;
						if ("email".equals(sheetTitle) && !StringUtils.isEmpty(dataSTR) && "tkio".equals(platformexcl)) {
							if (!accountsEmail.contains(dataSTR.trim())) {
								moreEmail.add(dataSTR.trim());
							}
							accountsEmail.add(dataSTR.trim());
						} else if ("email".equals(sheetTitle) && "cas".equals(platform)) {
							filter.put(sheetTitle, dataSTR.trim());
						}
					}
				}
			}


			if ("tkio".equals(platform) && "2".equals(filter.get("contractType"))) {
				if (filter.get("relation_code") == null) {
					return ResultModel.ERROR("第" + filter.get("rowIndex") + "行【关联合同编号】为空");
				} else {
					String relation_code = filter.get("relation_code");
					Contract masterContract = contractRepository.findByCodePlatform(relation_code, "tkio");
					if (masterContract == null) {
						return ResultModel.ERROR("第" + filter.get("rowIndex") + "行【关联合同编号】不存在");
					} else {
						String endDate = masterContract.getEndDate();
						String signedDate = filter.get("signedDate");
						if (signedDate == null) {
							return ResultModel.ERROR("第" + filter.get("rowIndex") + "行【补充协议签订日期】为空");
						} else {
							s_data[Integer.valueOf(filter.get("w"))] = masterContract.getStartDate();
							if (endDate.compareTo(signedDate) < 0) {
								return ResultModel.ERROR("第" + filter.get("rowIndex") + "行【补充协议签订日期】不能晚于关联合同的结束日期");
							}

							DateTime dateTime = new DateTime(signedDate);//补充协议晚录判断
							String relationCode = relation_code;
							while (true) {
								Contract contract = contractRepository.findByCodePlatform(relationCode, platform);
								if (StringUtils.isEmpty(contract.getNextSignedDate())) {
									contract.setNextSignedDate(dateTime.plusDays(-1).toString("yyyy-MM-dd"));//签订日的前一天
									contract.setNextSignedContractCode(filter.get("contractCode"));
									masterContracts.add(contract);
									break;
								} else {
									relationCode = contract.getNextSignedContractCode();
								}
							}

						}
					}
				}
			} else if ("cas".equals(platform)) {
				String email = filter.get("email");
				String start_date = filter.get("start_date");
				String end_date = filter.get("end_date");
				String rowIndex = filter.get("rowIndex");
				String validStartDateStr = filter.get("validStartDate");

				//if(filter.get("one_time").equals("否")){
				if (!StringUtils.isEmpty(validStartDateStr)) {
					DateTime dateTime = new DateTime(validStartDateStr);
					DateTime startDate = new DateTime(start_date);
					if (dateTime.isBefore(startDate)) {
						dateTime = startDate;
					}
					DateTime endDate = new DateTime(end_date);
					filter.put("valid_start_date", dateTime.toString("yyyy-MM-dd"));
					if (filter.get("one_time").equals("否")) {
						filter.put("valid_end_date", end_date);
					} else {
						int contractAllDay = Days.daysBetween(startDate, endDate).getDays();//合同总天数-1 ,用于计算结束日期
						filter.put("valid_end_date", dateTime.plusDays(contractAllDay).toString("yyyy-MM-dd"));
					}
				} else {
					return ResultModel.ERROR("第" + rowIndex + "行主账号【" + email + "】未填写IP发送");
				}
				// }
                /*else{
                    Map<String, Object> adiAccount = checkAccount( email,platform);
                    if(adiAccount!=null){
                        Object result = adiAccount.get("result");
                        if(result.equals(1)){
                            Object validStartDate = adiAccount.get("validStartDate");
                            if(validStartDate==null||StringUtils.isEmpty(validStartDate) || validStartDate.equals("null")){
                                return ResultModel.ERROR("第" + rowIndex + "行主账号【" + email + "】未进行IP发送");
                            }else{
                                String validStartDateStr = validStartDate.toString().split(" ")[0];
                                DateTime dateTime = new DateTime(validStartDateStr);
                                DateTime startDate = new DateTime(start_date);
                                DateTime endDate = new DateTime(end_date);
                                int contractAllDay = Days.daysBetween(startDate, endDate).getDays();//合同总天数
                                filter.put("valid_start_date",dateTime.toString("yyyy-MM-dd"));
                                filter.put("valid_end_date",dateTime.plusDays(contractAllDay).toString("yyyy-MM-dd"));
                            }
                        }else{
                            return ResultModel.ERROR("第" + rowIndex + "行主账号【" + email + "】不存在");
                        }
                    }else{
                        return ResultModel.ERROR("第" + rowIndex + "行ADI主账号校验URL失效");
                    }
                }*/


			}

			if (!accountsEmail.isEmpty()) {
				List<String> emails = accountRepository.findEmailByEmails(accountsEmail);
				Map<String, String> emailDic;
				try (Stream<String> emailStream = emails.stream()) {
					emailDic = emailStream.collect(Collectors.toMap(v -> v, v -> v, (v1, v2) -> v1));
				}

                /*//查询腾讯云 服务器上的账号
                String emailQ = String.join(",", accountsEmail).replace(",", "','");
                jdbcTemplateqCloud.query("select email from account where is_super_user is true and  email in (?) ", new String[]{"'" + emailQ + "'"}, new RowMapper<Map>() {
                    @Override
                    public Map mapRow(ResultSet resultSet, int i) throws SQLException {
                        emailDic.put(resultSet.getString("email"), resultSet.getString("email"));
                        return null;
                    }
                });*/

				List<QcloudAccount> qcloudAccounts = qcloudAccountRepository.findAll();
				qcloudAccounts.forEach(v -> emailDic.put(v.getEmail(), ""));

				for (int i = 0; i < accountsEmail.size(); i++) {
					String e = accountsEmail.get(i);
					if ("tkio".equals(platformexcl) && "null".equals(e)) {
						// tiko允许主账号email是空
					} else {
						//按照之前逻辑
						if (!emailDic.containsKey(e)) {
							return ResultModel.ERROR("第" + (i + 1) + "行 客户主账号【" + e + "】在Office运营后台未找到,请重新上传");
						}
					}
				}
			}

			//platform,product,my_body_code,create_time,code_num,type,status,back_status,ds,
			s_data[row_already] = platform;
			s_data[row_already + 1] = "tkio".equals(platform) ? "trackingio" : platform;
			s_data[row_already + 2] = bodyCode;
			s_data[row_already + 3] = DateUtil.getCurrentDateStr(DateUtil.C_TIME_PATTON_DEFAULT);
			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] = "导入-" + loginAccount.getName();
			if ("tkio".equals(platform)) {
				s_data[row_already + 11] = -1;
				s_data[row_already + 12] = 0;
				s_data[row_already + 13] = 0;
			} else {
				s_data[row_already + 11] = 0;
				s_data[row_already + 12] = -1;
				s_data[row_already + 13] = 0;
				s_data[row_already + 14] = 0;
				if ("cas".equals(platform)) {
					s_data[row_already + 15] = filter.get("valid_start_date");
					s_data[row_already + 16] = filter.get("valid_end_date");
				}
			}

			//批量添加数据
			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);
		contractRepository.save(masterContracts);
//        transactionUtils.commit(transactionStatus);
		if ("tkio".equals(platform)) {
			for (String email : moreEmail) {
				CalculationFlow calculationFlow = new CalculationFlow();
				calculationFlow.setEmail(email);
				calculationFlow.setStatus(0);
				calculationFlow.setTriggerType("导入");
				calculationFlow.setCreateTime(DateUtil.getCurrentDateStr(DateUtil.C_TIME_PATTON_DEFAULT));
				calculationFlow.setIsAll(true);
				calculationFlowRepository.save(calculationFlow);
			}
		}
		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) {
		DateTime startDate = new DateTime("2020-01-01");
		DateTime endDate = new DateTime("2020-01-20");
		int contractAllDay = Days.daysBetween(startDate, endDate).getDays();//合同总天数
		System.out.println(contractAllDay + " | " + startDate.plusDays(contractAllDay).toString("yyyy-MM-dd"));

	}
}