@Override
  public CashOutByOperatorPassDto cashoutOperatorByPass(
      Context respCtx, Context responseCtx, CashOutByOperatorPassDto cashoutDto)
      throws ApplicationException {
    // tried times add 1
    this.cashoutPassDao.increaseTriedTimes(cashoutDto.getBarcode());

    // lookup the 'CASHOUT_PASS' according to field 'BARCODE' & 'password'
    CashoutPass cashoutpass = this.cashoutPassDao.findByBarcode(cashoutDto.getBarcode());
    if (cashoutpass == null || cashoutpass.getId() == null || "".equals(cashoutpass.getId())) {
      // throw new ApplicationException(SystemException.CODE_CASHOUTPASS_NO_EXIST_BARCODE,
      // "[CashoutByPassword](barcode="
      // + cashoutDto.getBarcode() + ") not exist the barcode].");
      responseCtx.setResponseCode(SystemException.CODE_CASHOUTPASS_NO_EXIST_BARCODE);
      logger.error("======================================");
      logger.error(
          "[CashoutByPassword](barcode=" + cashoutDto.getBarcode() + ") not exist the barcode].");
      logger.error("======================================");
      return null;
    }

    // check whether or not used
    if (cashoutpass.getCashoutTeTransactionId() != null
        && !"".equals(cashoutpass.getCashoutTeTransactionId())) {
      // throw new ApplicationException(SystemException.CODE_CASHOUTPASS_ALREADY_USED,
      // "[CashoutByPassword](barcode="
      // + cashoutDto.getBarcode() + ") is already used].");
      responseCtx.setResponseCode(SystemException.CODE_CASHOUTPASS_ALREADY_USED);
      logger.error("======================================");
      logger.error(
          "[CashoutByPassword](barcode=" + cashoutDto.getBarcode() + ") is already used].");
      logger.error("======================================");
      return null;
    }

    // check expired time
    if (new Date().compareTo(cashoutpass.getExpireTime()) > 0) {
      // throw new ApplicationException(SystemException.CODE_CASHOUTPASS_EXPIRETIME,
      // "[CashoutByPassword] The cashout password is expiry !");
      responseCtx.setResponseCode(SystemException.CODE_CASHOUTPASS_EXPIRETIME);
      logger.error("======================================");
      logger.error("[CashoutByPassword] The cashout password is expiry !");
      logger.error("======================================");
      return null;
    }

    // check max tried times
    SysConfiguration sysConf = this.getSysConfigurationDao().getSysConfiguration();
    int maxiumtimes = sysConf.getMaxiumTimesOfCashoutPass();
    if ((cashoutpass.getTriedTimes()) > maxiumtimes) {
      // throw new ApplicationException(SystemException.CODE_CASHOUTPASS_EXCEED_MAXTIMES,
      // "[CashoutByPassword] The cashout by password is exceed max tried times !");
      responseCtx.setResponseCode(SystemException.CODE_CASHOUTPASS_EXCEED_MAXTIMES);
      logger.error("======================================");
      logger.error("[CashoutByPassword] The cashout by password is exceed max tried times !");
      logger.error("======================================");
      return null;
    }

    // check password whether or not correct
    if (!cashoutpass.getCashoutPassword().equals(cashoutDto.getPassword())) {
      // throw new ApplicationException(SystemException.CODE_CASHOUTPASS_INCORRECT,
      // "[CashoutByPassword](barcode="
      // + cashoutDto.getBarcode() + ") password is incorrect].");
      responseCtx.setResponseCode(SystemException.CODE_CASHOUTPASS_INCORRECT);
      logger.error("======================================");
      logger.error(
          "[CashoutByPassword](barcode=" + cashoutDto.getBarcode() + ") password is incorrect].");
      logger.error("======================================");
      return null;
    }

    // main logic for cash out
    cashoutLogic(
        respCtx,
        cashoutpass,
        cashoutpass.getOperatorId(),
        cashoutpass.getCashoutAmount(),
        TransactionType.CASH_OUT_OPERATOR_PASS.getRequestType());

    // ==========================

    // assemble response bean
    CashOutByOperatorPassDto respCashoutPassDto = new CashOutByOperatorPassDto();
    respCashoutPassDto.setAmount(cashoutpass.getCashoutAmount());
    respCashoutPassDto.setOperatorId(cashoutpass.getOperatorId());

    return respCashoutPassDto;
  }
  @Override
  public CashOutPassDto getCashoutPass(Context respCtx, CashOutPassDto cashoutDto)
      throws ApplicationException {
    String cashoutOperatorid = respCtx.getOperatorId();
    Operator operator = this.operatorDao.findById(Operator.class, cashoutOperatorid);
    if (operator == null) {
      throw new ApplicationException(
          SystemException.CODE_NO_OPERATOR,
          "operator(id=" + cashoutOperatorid + ") doesn't exist.");
    }

    // cashout amount must greater than 0
    if (cashoutDto.getAmount().doubleValue() <= 0) {
      throw new ApplicationException(
          SystemException.CODE_CASHOUT_AMOUNT_LESSTHAN_ZERO,
          "GetCashoutPass,OPERATOR(id="
              + operator.getId()
              + ") can't accept cashout amount less or equal 0");
    }

    if (operator.getCreditType() == Merchant.CREDIT_TYPE_DEFINITIVEVALUE) {
      // check operator balance
      BigDecimal totalBalance = new BigDecimal("0");
      totalBalance = totalBalance.add(operator.getCommisionBalance());
      totalBalance = totalBalance.add(operator.getCashoutBalance());
      totalBalance = totalBalance.add(operator.getPayoutCreditLevel());

      if (logger.isDebugEnabled()) {
        logger.debug(
            "current operator :operator_id:"
                + operator.getId()
                + ",totalbalance="
                + totalBalance.toPlainString());
      }

      // judge the balance whether or not sufficient
      if (totalBalance.compareTo(cashoutDto.getAmount()) < 0) {
        throw new ApplicationException(
            SystemException.CODE_INSUFFICIENT_BALANCE,
            "OPERATOR(id="
                + operator.getId()
                + ") insufficient balance[commission balance,cashout balance,payout balance].");
      }

    } else if (operator.getCreditType() == Merchant.CREDIT_TYPE_USE_PARENT) {
      // lookup the merchant
      Merchant originmerchant = getMerchantByOperator(cashoutOperatorid, false);
      Merchant finalMerchant =
          this.merchantDao.findDistributeMerchantByMerchantId(originmerchant.getId());
      if (finalMerchant == null) {
        throw new ApplicationException(
            SystemException.CODE_NO_MERCHANT,
            "operator(id=" + cashoutOperatorid + ") doesn't exist parent merchant.");
      }
      // check merchant balance
      BigDecimal totalBalance = new BigDecimal("0");
      totalBalance = totalBalance.add(finalMerchant.getCommisionBalance());
      totalBalance = totalBalance.add(finalMerchant.getCashoutBalance());
      totalBalance = totalBalance.add(finalMerchant.getPayoutCreditLevel());

      if (logger.isDebugEnabled()) {
        logger.debug(
            "current merchant :final_merchant_id:"
                + finalMerchant.getId()
                + ",totalbalance="
                + totalBalance.toPlainString());
      }

      // judge the balance whether or not sufficient
      if (totalBalance.compareTo(cashoutDto.getAmount()) < 0) {
        throw new ApplicationException(
            SystemException.CODE_INSUFFICIENT_BALANCE,
            "MERCHANT(id="
                + finalMerchant.getId()
                + ") insufficient balance[commission balance,cashout balance,payout balance].");
      }
    }

    // Get sys_configuration
    SysConfiguration sysConf = this.getSysConfigurationDao().getSysConfiguration();

    // successful record the data to 'CASHOUT_PASS'
    // MAX_EXPIRE_TIME_CASHOUT_PASS (unit: minute)
    String teTransactionID = respCtx.getTransaction().getId();

    CashoutPass cashoutpass = new CashoutPass();
    String generalid = this.getUuidManager().getGeneralID();
    cashoutpass.setId(generalid);
    cashoutpass.setOperatorId(cashoutOperatorid);
    cashoutpass.setCashoutAmount(cashoutDto.getAmount());
    cashoutpass.setCashoutPassword(cashoutDto.getPassword());
    cashoutpass.setExpireTime(
        DateUtils.addMinute(new Date(), sysConf.getMaxExpireTimeCashoutPass()));
    cashoutpass.setTriedTimes(0);
    cashoutpass.setTeTransactionId(teTransactionID);
    cashoutpass.setCashoutBarCode(new Barcoder(0, generalid).getBarcode()); // barcode
    cashoutpass.setCreateBy(respCtx.getOperatorId());
    cashoutpass.setCreateTime(net.mpos.fk.util.DateUtils.getCurrentDate());

    this.cashoutPassDao.insert(cashoutpass);

    // assemble the response bean
    CashOutPassDto respCashoutDto = new CashOutPassDto();
    respCashoutDto.setAmount(cashoutDto.getAmount());
    respCashoutDto.setExpireTime(
        net.mpos.fk.util.DateUtils.convertTimestampToString(cashoutpass.getExpireTime()));
    respCashoutDto.setBarcode(cashoutpass.getCashoutBarCode());

    return respCashoutDto;
  }