@Override
  public Response<Boolean> updateSolution(RequirementSolution solution) {
    Response<Boolean> result = new Response<Boolean>();

    if (solution.getId() == null) {
      log.error("update requirement solution need solutionId");
      result.setError("solution.id.null");
      return result;
    }

    // 需要保证该方案处于3:方案交互 or 4:方案综投.需求才能被更改
    RequirementStatus[] statuses = {RequirementStatus.SOL_INTERACTIVE, RequirementStatus.SOL_END};
    Response<Boolean> statusRes = checkRequirementStatus(solution.getRequirementId(), statuses);
    if (!statusRes.isSuccess()) {
      log.error("check requirement status failed, error code={}", statusRes.getError());
      result.setError(statusRes.getError());
      return result;
    }
    if (!statusRes.getResult()) {
      log.error("requirement status can't allow suppler update solution.");
      result.setError("solution.status.notUpdate");
      return result;
    }

    try {
      result.setResult(requirementSolutionDao.update(solution));
    } catch (Exception e) {
      log.error(
          "update requirement solution failed, solutionId={}, error code={}",
          solution.getId(),
          Throwables.getStackTraceAsString(e));
      result.setError("solution.update.failed");
    }

    return result;
  }
  @Override
  public Response<Boolean> updateBatchTechnology(String solutions) {
    Response<Boolean> result = new Response<Boolean>();
    List<RequirementSolution> solutionList =
        JSON_MAPPER.fromJson(
            solutions, JSON_MAPPER.createCollectionType(List.class, RequirementSolution.class));

    if (solutionList == null || solutionList.isEmpty()) {
      log.error("requirement solutions is empty.");
      result.setError("requirement.solution.empty");
      return result;
    }

    try {
      RequirementSolution newSolution;
      for (RequirementSolution solution : solutionList) {
        if (solution.getTechnology() == null) {
          log.error("create module solution need technology");
          result.setError("solution.technology.null");
          return result;
        }

        if (solution.getTechnology() < 0 || solution.getTechnology() > 10000) {
          log.error("requirement solution technology score is in 0~100.");
          result.setError("solution.technology.scope");
          return result;
        }

        newSolution = new RequirementSolution();
        newSolution.setId(solution.getId());
        newSolution.setTechnology(solution.getTechnology());
        // 采购商对方案的技术进行评分
        requirementSolutionDao.update(newSolution);
      }

      result.setResult(true);
    } catch (Exception e) {
      log.error(
          "update requirement solution technology is failed, error code={}.",
          Throwables.getStackTraceAsString(e));
      result.setError("solution.technology.failed");
    }

    return result;
  }
  @Override
  public Response<Boolean> updateSolutionFile(
      Long requirementId, String solutionFile, BaseUser user) {
    Response<Boolean> result = new Response<Boolean>();

    if (requirementId == null) {
      log.error("update requirement solution need requirementId");
      result.setError("requirement.id.null");
      return result;
    }

    if (Strings.isNullOrEmpty(solutionFile)) {
      log.error("update requirement solution file can't be null.");
      result.setError("solution.file.null");
      return result;
    }

    // 验证用户是否已登入
    if (user == null) {
      log.error("create requirement solution, user must login.");
      result.setError("user.not.login");
      return result;
    }

    try {
      RequirementSolution solution =
          requirementSolutionDao.findByUserId(requirementId, user.getId());

      // 处理历史文档
      requirementSolutionDao.updateSolutionFile(solution.getId(), solutionFile);
      // 记录提交方案的供应商数量
      requirementCountService.setReqCountInfo(
          solution.getRequirementId(), RequirementCountType.SEND_SO, 1);
      result.setResult(true);
    } catch (Exception e) {
      log.error(
          "update requirement solution failed, requirementId={}, solutionFile={}, error code={}.",
          requirementId,
          solutionFile,
          Throwables.getStackTraceAsString(e));
    }

    return result;
  }
  @Override
  public Response<CheckSolEndDto> solutionEnd(Long requirementId, BaseUser user) {
    Response<CheckSolEndDto> result = new Response<CheckSolEndDto>();

    // 验证用户是否已登入
    if (user == null) {
      log.error("create requirement solution, user must login.");
      result.setError("user.not.login");
      return result;
    }

    if (requirementId == null) {
      log.error("update requirement solution need requirementId");
      result.setError("requirementId.id.null");
      return result;
    }

    try {
      // 获取用户的需求方案信息
      RequirementSolution requirementSolution =
          requirementSolutionDao.findByUserId(requirementId, user.getId());

      // 获取需求信息
      Requirement requirement = requirementDao.findById(requirementSolution.getRequirementId());

      Response<Boolean> checkSupplier = checkSupplierInfo(requirementId, user);
      if (!checkSupplier.isSuccess()) {
        log.error(
            "check supplier info for requirement failed, error code={}", checkSupplier.getError());
        result.setError(checkSupplier.getError());
        return result;
      }

      Response<Boolean> checkRes = checkReqStatusWithSol(requirement, requirementSolution);
      if (!checkRes.isSuccess()) {
        log.error("check requirement & solution info failed, error code={}", checkRes.getError());
        result.setError(checkRes.getError());
        return result;
      } else {
        CheckSolEndDto checkSolEndDto = new CheckSolEndDto();

        // 获取全部报价信息
        List<ModuleQuotation> quotations =
            moduleQuotationDao.findAllQuotations(requirementSolution.getId());

        // 获取全部的TQRDC信息
        List<ModuleSolution> solutions =
            moduleSolutionDao.findAllSolutions(requirementSolution.getId());
        Map<Long, ModuleSolution> solutionMap = Maps.newHashMap();

        for (ModuleSolution solution : solutions) {
          solutionMap.put(solution.getModuleId(), solution);
        }

        // 计算整个需求的Q&R数据用于显示
        Integer qualityValue = 0;
        Date maxReaction = null;
        Date cpmDate;

        List<Module> moduleList = moduleDao.findModules(requirementId);

        // 计算总的模块报价总权值
        int error = 0;
        Integer totalValue = 0;
        for (ModuleQuotation quotation : quotations) {
          for (Module module : moduleList) {
            // 校验报价不能低于模块的价格(统计数量)
            if (Objects.equal(quotation.getModuleId(), quotation.getModuleId())
                && quotation.getPrice() > module.getCost()) {
              log.error("module quotation cost price can't more than module default price");
              error++;
            }
          }

          // 计算总报价
          totalValue += quotation.getTotal() * quotation.getPrice();

          // 计算总Q
          qualityValue +=
              quotation.getTotal() * solutionMap.get(quotation.getModuleId()).getQuality();

          // 计算最大R
          cpmDate = solutionMap.get(quotation.getModuleId()).getReaction();
          maxReaction =
              maxReaction == null ? cpmDate : (maxReaction.after(cpmDate) ? maxReaction : cpmDate);
        }

        if (error == 0) {
          // 方案终投阶段只允许提交一次
          RequirementSolution solution = new RequirementSolution();
          solution.setId(requirementSolution.getId());
          solution.setQuality(qualityValue); // 整体的Q
          solution.setReaction(maxReaction); // 整体的R
          solution.setCost(totalValue); // 整体的C
          solution.setStatus(RequirementSolution.Status.SEND_END.value());
          requirementSolutionDao.update(solution);
        }

        // 判断采购商是否已经提交了保证金
        Response<Integer> paidRes =
            depositService.checkPaid(requirement.getId(), requirementSolution.getSupplierId());
        if (!paidRes.isSuccess()) {
          log.error(
              "check supplier send deposit fee result failed, error code={}", result.getError());
          result.setError(paidRes.getError());
          return result;
        }

        checkSolEndDto.setPaidResult(paidRes.getResult());
        checkSolEndDto.setCostResult(error == 0);

        result.setResult(checkSolEndDto);
      }
    } catch (Exception e) {
      log.error(
          "change requirement solution status failed, requirementId={}, userId={}, error code={}",
          requirementId,
          user.getId(),
          Throwables.getStackTraceAsString(e));
      result.setError("solution.update.failed");
    }

    return result;
  }
  @Override
  public Response<Boolean> updateSolutionAccept(
      Long requirementId, String acceptInfo, BaseUser user) {
    Response<Boolean> result = new Response<Boolean>();

    if (requirementId == null) {
      log.error("update requirement solution accept need requirementId");
      result.setError("solution.requirementId.null");
      return result;
    }

    // 验证用户是否已登入
    if (user == null) {
      log.error("create requirement solution, user must login.");
      result.setError("user.not.login");
      return result;
    }

    // 需要保证该方案处于3:方案交互 or 4:方案综投.需求才能被更改
    RequirementStatus[] statuses = {RequirementStatus.SOL_INTERACTIVE, RequirementStatus.SOL_END};
    Response<Boolean> statusRes = checkRequirementStatus(requirementId, statuses);
    if (!statusRes.isSuccess()) {
      log.error("check requirement status failed, error code={}", statusRes.getError());
      result.setError(statusRes.getError());
      return result;
    }
    if (!statusRes.getResult()) {
      log.error("requirement status can't allow suppler update solution.");
      result.setError("solution.status.notUpdate");
      return result;
    }

    try {
      // 获取供应商提交的需求信息
      RequirementSolution solution =
          requirementSolutionDao.findByUserId(requirementId, user.getId());
      RequirementSolution newSolution = new RequirementSolution();
      newSolution.setId(solution.getId());
      newSolution.setNotAccept(acceptInfo);
      // 写入更改方案承诺后需求方案的状态
      if (acceptInfo == null) {
        // 全部承诺
        newSolution.setStatus(RequirementSolution.Status.ALL_ACCEPT.value());

        // 记录提交方案的供应商数量
        requirementCountService.setReqCountInfo(requirementId, RequirementCountType.SEND_SO, 1);

        // 记录供应商承诺目标的数量
        solutionCountService.setSolCountInfo(user.getId(), SolutionCountType.ACCEPT_SOL, 1);
      } else {
        if (acceptInfo.length() > 2048) {
          log.error("accept info is to long");
          result.setError("solution.accept.toLong");
          return result;
        }
        newSolution.setStatus(RequirementSolution.Status.LITTLE_ACCEPT.value());
      }

      // 更新需求的承诺信息
      result.setResult(requirementSolutionDao.update(newSolution));
    } catch (Exception e) {
      log.error(
          "update requirement solution accept failed, requirementId={}, error code={}",
          requirementId,
          Throwables.getStackTraceAsString(e));
      result.setError("solution.update.failed");
    }

    return result;
  }
  /**
   * 根据需求信息查询需求对应的阶段下的方案是否符合最终的提交要求
   *
   * @param requirement 需求信息
   * @param requirementSolution 用户的方案信息
   * @return Boolean 返回检验信息
   */
  private Response<Boolean> checkReqStatusWithSol(
      Requirement requirement, RequirementSolution requirementSolution) {
    Response<Boolean> result = new Response<Boolean>();

    // 是否是方案终投阶段
    if (Objects.equal(RequirementStatus.SOL_END, RequirementStatus.from(requirement.getStatus()))) {
      // 技术领先、差异化必须要提交方案(solutionFile:上传的详细的方案文档)其它场景不需要
      if (Objects.equal(Tactics.from(requirement.getTacticsId()), Tactics.TECHNOLOGY_NEW)
          || Objects.equal(Tactics.from(requirement.getTacticsId()), Tactics.DIFFERENTIATION)) {
        if (requirementSolution.getSolutionFile() == null
            || requirementSolution.getSolutionFile().isEmpty()) {
          log.error("jump to requirement solution end need send solution file.");
          result.setError("solution.file.null");
          return result;
        }
      }

      // todo 添加判断用户是否已经提交报价单文档

      // 模块方案信息
      List<ModuleSolution> solutions =
          moduleSolutionDao.findAllSolutions(requirementSolution.getId());

      // 模块报价信息
      List<ModuleQuotation> quotations =
          moduleQuotationDao.findAllQuotations(requirementSolution.getId());

      // 获取需求详细的模块数量
      Integer actualModuleNum = requirement.getModuleNum();

      // 判断模块的TQRD信息是否填写完整
      if (!Objects.equal(actualModuleNum, solutions.size())) {
        log.error("send solution to end status, the module solution info must be enter.");
        result.setError("moduleSol.info.null");
        return result;
      }

      // 判断是否填写完整的模块报价信息
      if (!Objects.equal(actualModuleNum, quotations.size())) {
        log.error("send solution to end status, the module quotation info must be enter.");
        result.setError("moduleQuo.info.null");
        return result;
      }

      // 验证TQRD数据是否已全部填写
      for (ModuleSolution solution : solutions) {
        if (solution.getTechnology() == null
            || solution.getQuality() == null
            || solution.getReaction() == null
            || solution.getDelivery() == null) {
          log.error("send solution to end status, the module solution info must be enter.");
          result.setError("moduleSol.info.null");
          return result;
        }
      }

      // 验证报价数据是否填写完整
      for (ModuleQuotation quotation : quotations) {
        if (quotation.getSolutionId() == null
            || quotation.getModuleId() == null
            || quotation.getPrice() == null
            || Strings.isNullOrEmpty(quotation.getCoinType())
            || quotation.getExchangeRate() == null) {
          log.error("send solution to end status, the module quotation info must be enter.");
          result.setError("moduleQuo.info.null");
          return result;
        }
      }

      result.setResult(true);
    } else {
      log.error("requirement status don't allow requirement solution end.");
      result.setError("solution.status.not.end");
      return result;
    }

    return result;
  }