// 每一次批量提交的投标审核一定是针对同一个产品,因此不会出现一批投标购买针对不同产品的情况
  // 审核提交给第三方后,对第三方返回的执行结果参数的后续处理
  @Override
  public void buyAuditSuccessHandle(List<String> loanNos) throws Exception {
    if (loanNos == null || loanNos.isEmpty()) {
      throw new Exception("审核返回列表为空");
    }

    // 每一次批量提交的投标审核一定是针对同一个产品,因此取出第一条投标对应的产品,判断其状态,如果已经为还款中,则说明已经执行成功
    String eLoanNo = loanNos.get(0);
    List<CashStream> eCashStreams = cashStreamDao.findSuccessByActionAndLoanNo(-1, eLoanNo);
    CashStream eCashStream = eCashStreams.get(0);
    Submit eSubmit = submitDao.find(eCashStream.getSubmitId());
    Product product = productDao.find(eSubmit.getProductId());
    GovermentOrder order = orderDao.find(product.getGovermentorderId());

    Borrower borrower = borrowerDao.find(order.getBorrowerId());
    if (Product.STATE_REPAYING == product.getState()) {
      // 产品已经处于还款状态,说明针对本产品的购买审核已经执行完毕
      return;
    }

    for (String loanNo : loanNos) {
      List<CashStream> cashStreams = cashStreamDao.findSuccessByActionAndLoanNo(-1, loanNo);
      CashStream cashStream = cashStreams.get(0);

      if (cashStreams.size() == 2) {
        // 针对本个LoanNo,在平台上有两条执行成功的现金流与之对应,那肯定说明这次购买已经处理成功,一条冻结,一条转账
        continue; // 重复的命令
      }

      try {
        Integer cashStreamId = null;
        cashStreamId =
            accountService.pay(
                cashStream.getLenderAccountId(),
                borrower.getAccountId(),
                cashStream.getChiefamount().negate(),
                cashStream.getSubmitId(),
                "支付");
        cashStreamDao.updateLoanNo(cashStreamId, loanNo, null);
      } catch (IllegalConvertException e) {
        e.printStackTrace();
      }
    }

    // 校验 Product实际支付额=所有Lender的支付资金流之和
    CashStreamSum sum = cashStreamDao.sumProduct(product.getId(), CashStream.ACTION_PAY);
    if (sum.getChiefAmount().negate().compareTo(product.getRealAmount()) != 0)
      throw new CheckException("投标购买审核完成总金额与产品实际融资金额不符,查看是否有尚未审核完毕的投标");

    // 根据产品实际融资额度重新计算并更新还款计划
    innerPayBackService.refreshPayBack(product.getId(), true);

    // 状态转换为还款中,及一系列后续操作
    innerProductService.startRepaying(product.getId());
  }
  private void buyAuditReturnHandle(List<String> loanNos) throws Exception {
    if (loanNos == null || loanNos.isEmpty()) {
      throw new Exception("审核返回列表为空");
    }

    // 每一次批量提交的投标审核一定是针对同一个产品,因此取出第一条投标对应的产品,判断其状态,如果已经为还款中,则说明已经执行成功
    String eLoanNo = loanNos.get(0);
    List<CashStream> eCashStreams = cashStreamDao.findSuccessByActionAndLoanNo(-1, eLoanNo);
    CashStream eCashStream = eCashStreams.get(0);
    Submit eSubmit = submitDao.find(eCashStream.getSubmitId());
    Product product = productDao.find(eSubmit.getProductId());
    GovermentOrder order = orderDao.find(product.getGovermentorderId());

    if (Product.STATE_QUITFINANCING == product.getState()) {
      // 产品已经处于流标状态,说明针对本产品的购买审核已经执行完毕
      return;
    }

    for (String loanNo : loanNos) {
      List<CashStream> cashStreams = cashStreamDao.findSuccessByActionAndLoanNo(-1, loanNo);
      CashStream cashStream = cashStreams.get(0);

      if (cashStreams.size() == 2) {
        // 针对本个LoanNo,在平台上有两条执行成功的现金流与之对应,那肯定说明这次购买已经处理成功,一条冻结,一条流标解冻
        continue; // 重复的命令
      }

      try {
        Integer cashStreamId = null;
        cashStreamId =
            accountService.unfreezeLenderAccount(
                cashStream.getLenderAccountId(),
                cashStream.getChiefamount().negate(),
                cashStream.getSubmitId(),
                "流标");
        cashStreamDao.updateLoanNo(cashStreamId, loanNo, null);
      } catch (IllegalConvertException e) {
        e.printStackTrace();
      }
    }

    // 校验 Product实际流标解冻额=所有Lender的支付资金流之和
    CashStreamSum sum = cashStreamDao.sumProduct(product.getId(), CashStream.ACTION_UNFREEZE);
    if (sum.getChiefAmount().compareTo(product.getRealAmount()) != 0)
      throw new CheckException("流标解冻总金额与产品实际融资金额不符,查看是否有尚未审核完毕的投标");

    // 状态转换为流标,及一系列后续操作
    innerProductService.quitFinancing(product.getId());
  }
  public static void main(String args[]) throws Exception {
    //		withdrawSingleCashStream("LN19029242014122113491557888");

    Date datestart = new Date(2015 - 1900, 9 - 1, 8, 8, 0, 0);
    Date dateend = new Date(2015 - 1900, 9 - 1, 15, 8, 0, 0);

    long start = DateCalculateUtils.getStartTime(datestart.getTime());
    long end = DateCalculateUtils.getEndTime(dateend.getTime()) + 1000;

    List<CashStream> css = cashStreamDao.findByActionAndTime(-1, start, end);
    //		List<CashStream> css = cashStreamDao.findByActionAndTime(-1, -1, -1);

    //		List<CashStream> css = new ArrayList<CashStream>();
    //		css.add(cashStreamDao.find(56));
    //		css.add(cashStreamDao.find(57));

    int total = 0;
    int success = 0;
    int wrong = 0;

    StringBuilder errorlog = new StringBuilder();

    Set<Integer> lenderIds = new HashSet<Integer>();
    Set<Integer> borrowerIds = new HashSet<Integer>();

    for (CashStream cs : css) {

      if (cs.getLenderAccountId() != null) {
        lenderIds.add(cs.getLenderAccountId());
      }

      if (cs.getBorrowerAccountId() != null) {
        borrowerIds.add(cs.getBorrowerAccountId());
      }

      total++;
      try {
        checkSingleCashStream(cs.getId());
        success++;
      } catch (Exception e) {
        System.err.println(e.getMessage());
        errorlog.append(e.getMessage()).append("\n");
        wrong++;
      }
    }

    System.out.println(errorlog.toString());
    System.out.println("现金流审核执行完毕:总共" + total + "条,成功" + success + "条,失败" + wrong + "条!");

    System.out.println("lenderIds: " + lenderIds);
    System.out.println("borrowerIds: " + borrowerIds);

    System.exit(0);
  }
  public static boolean checkFreezeResult(CashStream cashStream, String body) throws Exception {
    boolean flag = true;
    Gson gson = new Gson();
    List<Map<String, String>> res = (List<Map<String, String>>) gson.fromJson(body, List.class);

    if ((res == null || res.isEmpty()) && cashStream.getState() == cashStream.STATE_INIT) {
      return true;
    } else if ((res == null || res.isEmpty())
        && cashStream.getLenderAccountId() == null
        && cashStream.getBorrowerAccountId() != null) {
      return true;
    } else if (cashStream.getState() == cashStream.STATE_INIT) {
      List<CashStream> cash =
          cashStreamDao.findBySubmitAndActionAndState(
              cashStream.getSubmitId(), cashStream.getAction(), CashStream.STATE_SUCCESS);
      if (cash != null && !cash.isEmpty()) {
        return true;
      } else {
        Map<String, String> result = res.get(0);
        if ("支付超时".equals(cashStream.getDescription())) {
          return true;
        } else if ("0".equals(result.get("TransferState")) && "0".equals(result.get("ActState"))) {
          return true;
        } else {
          throw new Exception("现金流[ID:" + cashStream.getId() + "]有问题: 平台未处理的现金流在第三方上有对应的记录!");
        }
      }
    } else if ((res == null || res.isEmpty())) {
      throw new Exception("现金流[ID:" + cashStream.getId() + "]有问题: 投标冻结找不到第三方上对应的记录!");
    }

    String laccount = "";

    Lender lender = lenderDao.findByAccountID(cashStream.getLenderAccountId());

    if (lender != null) {
      laccount = lender.getThirdPartyAccount();
    } else {
      laccount =
          borrowerDao.findByAccountID(cashStream.getBorrowerAccountId()).getThirdPartyAccount();
    }

    Map<String, String> result = res.get(0);

    // 付款人乾多多标识
    String LoanOutMoneymoremore = result.get("LoanOutMoneymoremore");

    // 收款人乾多多标识
    String LoanInMoneymoremore = result.get("LoanInMoneymoremore");

    // 额度
    String Amount = result.get("Amount");
    // 乾多多流水号
    String LoanNo = result.get("LoanNo");

    // 转账类型
    String TransferAction = result.get("TransferAction");

    boolean accountflag = laccount.equals(LoanOutMoneymoremore);

    boolean loanflag =
        cashStream.getLoanNo() == null ? false : cashStream.getLoanNo().equals(LoanNo);

    // 投标
    boolean actionflag = lender == null ? TransferAction.equals("2") : TransferAction.equals("1");

    boolean totalflag =
        cashStream
                .getChiefamount()
                .add(cashStream.getInterest())
                .negate()
                .compareTo(new BigDecimal(Amount))
            == 0;

    flag = flag && loanflag && totalflag && accountflag && actionflag;

    StringBuilder message = new StringBuilder();

    message.append("现金流[ID:" + cashStream.getId() + "]: ");

    if (loanflag == false) {
      message.append(" 乾多多流水号不一致:[平台" + cashStream.getLoanNo() + "][钱多多" + LoanNo + "] ");
    }

    if (totalflag == false) {
      message.append(
          " 金额不一致:[平台" + cashStream.getChiefamount().negate().toString() + "][钱多多" + Amount + "] ");
    }

    if (accountflag == false) {
      message.append(" 账户不一致:[平台:" + laccount + "][钱多多 :" + LoanOutMoneymoremore + "] ");
    }

    if (actionflag == false) {
      message.append(" 行为不一致:[平台 投标][钱多多 还款] ");
    }

    if (!flag) {
      throw new Exception(message.toString());
    }

    return flag;
  }
  public static boolean checkSingleCashStream(Integer cashStreamId) throws Exception {
    CashStream cashStream = cashStreamDao.find(cashStreamId);
    if (cashStream == null) return true;

    if (cashStream.getChiefamount().add(cashStream.getInterest()).compareTo(new BigDecimal(0))
        == 0) {
      return true;
    }

    String baseUrl = innerService.getBaseUrl(IInnerThirdPaySupportService.ACTION_ORDERQUERY);
    Map<String, String> params = new HashMap<String, String>();
    params.put("PlatformMoneymoremore", platformMoneymoremore);
    if (cashStream.getAction() == CashStream.ACTION_CASH
        || (cashStream.getAction() == CashStream.ACTION_RECHARGE
            && "提现退回".equals(cashStream.getDescription()))) params.put("Action", "2");
    else if (cashStream.getAction() == CashStream.ACTION_RECHARGE) params.put("Action", "1");

    StringBuilder sBuilder = new StringBuilder();
    sBuilder.append(StringUtil.strFormat(params.get("PlatformMoneymoremore")));
    sBuilder.append(StringUtil.strFormat(params.get("Action")));

    String body = "";
    //		if(cashStream.getAction()==CashStream.ACTION_PAY ||
    // cashStream.getAction()==CashStream.ACTION_UNFREEZE)
    //		{
    if (cashStream.getLoanNo() != null) {
      params.put("LoanNo", cashStream.getLoanNo());
      sBuilder.append(StringUtil.strFormat(params.get("LoanNo")));
      RsaHelper rsa = RsaHelper.getInstance();
      params.put("SignInfo", rsa.signData(sBuilder.toString(), privateKey));
      body = httpClientService.post(baseUrl, params);
    } else {
      params.put("OrderNo", String.valueOf(cashStream.getId()));
      sBuilder.append(StringUtil.strFormat(params.get("OrderNo")));
      RsaHelper rsa = RsaHelper.getInstance();
      params.put("SignInfo", rsa.signData(sBuilder.toString(), privateKey));
      body = httpClientService.post(baseUrl, params);
    }

    try {
      boolean flag = false;

      if (cashStream.getAction() == CashStream.ACTION_RECHARGE) {
        flag = checkRechargeResult(cashStream, body);
      } else if (cashStream.getAction() == CashStream.ACTION_AWARD) {
        flag = checkAwardResult(cashStream, body);
      } else if (cashStream.getAction() == CashStream.ACTION_CASH) {
        flag = checkWithDrawResult(cashStream, body);
      } else if (cashStream.getAction() == CashStream.ACTION_REPAY
          || cashStream.getAction() == CashStream.ACTION_PURCHASEBACK
          || cashStream.getAction() == CashStream.ACTION_TEMPDEBT) {
        flag = checkPayBackResult(cashStream, body);
      } else if (cashStream.getAction() == CashStream.ACTION_SYNCHRONIZE) {
        flag = checkSynchronizeResult(cashStream, body);
      } else if (cashStream.getAction() == CashStream.ACTION_PAY
          || cashStream.getAction() == CashStream.ACTION_PURCHASE) {
        flag = checkPayResult(cashStream, body);
      } else if (cashStream.getAction() == CashStream.ACTION_FREEZE) {
        flag = checkFreezeResult(cashStream, body);
      } else if (cashStream.getAction() == CashStream.ACTION_UNFREEZE) {
        flag = checkUnFreezeResult(cashStream, body);
      } else if (cashStream.getAction() == CashStream.ACTION_STORECHANGE) {
        flag = checkStoreResult(cashStream, body);
      } else {
        throw new Exception("现金流[ID:" + cashStream.getId() + "]有问题: 未知状态!");
      }
      return flag;
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
  }