@Override
  @Transactional(propagation = Propagation.REQUIRED)
  public CustomerOrderTransDto paymentByMemberCashvalue(
      MemberCashValuePaymentDto memberCashValuePaymentDto) throws Exception {
    if (memberCashValuePaymentDto.getCustomerId() == null
        || memberCashValuePaymentDto.getItemNos().length == 0
        || memberCashValuePaymentDto.getTotalAmount() == null)
      throw new GTACommonException(GTAError.MemberError.MEMBER_NOT_FOUND);

    if (memberCashValuePaymentDto.getOrderQty() == null) memberCashValuePaymentDto.setOrderQty(1);
    if (StringUtils.isEmpty(memberCashValuePaymentDto.getPaymentMethod()))
      memberCashValuePaymentDto.setPaymentMethod(Constant.CASH_Value);

    Long customerId = memberCashValuePaymentDto.getCustomerId();
    Member member = memberDao.getMemberByCustomerId(customerId);
    MemberCashvalue memberCashvalue = null;
    if (StringUtils.isEmpty(memberCashValuePaymentDto.getPaymentMethod())
        || memberCashValuePaymentDto.getPaymentMethod().equals(Constant.CASH_Value)) {
      memberCashvalue = updateMemberCashValueData(member, memberCashValuePaymentDto);
    }
    CustomerOrderTransDto customerOrderTransDto =
        saveCustomerOrderTrans(customerId, memberCashValuePaymentDto);
    if (null != memberCashvalue)
      customerOrderTransDto.setAvailableBalance(memberCashvalue.getAvailableBalance());
    return customerOrderTransDto;
  }
  private MemberCashvalue updateMemberCashValueData(
      Member member, MemberCashValuePaymentDto memberCashValuePaymentDto)
      throws GTACommonException {
    MemberCashvalue memberCashvalue = null;
    Long customerId = member.getCustomerId();
    String memberType = member.getMemberType();
    if (!StringUtils.isEmpty(memberType)) {
      if ((Constant.memberType.IDM.toString().equalsIgnoreCase(memberType)
              || Constant.memberType.CDM.toString().equalsIgnoreCase(memberType))
          && (null != member.getSuperiorMemberId() && member.getSuperiorMemberId() > 0)) {
        MemberLimitRule memberLimitRuleTRN =
            memberLimitRuleDao.getMemberLimitRule(customerId, LimitType.TRN.name());
        if (null != memberLimitRuleTRN) {
          BigDecimal numValue = memberLimitRuleTRN.getNumValue();
          if (limitUnit.EACH.name().equals(memberLimitRuleTRN.getLimitUnit())) {
            if (memberCashValuePaymentDto.getTotalAmount().compareTo(numValue) > 0)
              throw new GTACommonException(GTAError.MemberError.PAYMENTAMOUNT_EXCEEDS_PERPAYMENT);
          }
        }
        memberCashvalue = memberCashValueDao.getMemberCashvalueById(member.getSuperiorMemberId());
        customerId = member.getSuperiorMemberId();
      } else {
        memberCashvalue = memberCashValueDao.getMemberCashvalueById(customerId);
      }
    }

    if (memberCashvalue == null) {
      memberCashvalue = new MemberCashvalue();
      memberCashvalue.setCustomerId(customerId);
      memberCashvalue.setAvailableBalance(BigDecimal.ZERO);
      memberCashvalue.setInitialValue(BigDecimal.ZERO);
      memberCashvalue.setInitialDate(new Date());
    }
    if (memberCashvalue.getAvailableBalance().compareTo(memberCashValuePaymentDto.getTotalAmount())
        <= 0) {
      MemberLimitRule memberLimitRuleCR =
          memberLimitRuleDao.getMemberLimitRule(customerId, LimitType.CR.name());
      if (null != memberLimitRuleCR) {
        BigDecimal numValue = memberLimitRuleCR.getNumValue();
        if (((memberCashvalue
                        .getAvailableBalance()
                        .subtract(memberCashValuePaymentDto.getTotalAmount()))
                    .negate())
                .compareTo(numValue)
            > 0) {
          throw new GTACommonException(GTAError.MemberError.PAYMENTAMOUNT_EXCEEDS_CREDITLIMIT);
        }
      } else {
        throw new GTACommonException(GTAError.MemberError.MEMBER_INSUFFICIENT_BALANCE);
      }
    }
    memberCashvalue.setAvailableBalance(
        memberCashvalue.getAvailableBalance().subtract(memberCashValuePaymentDto.getTotalAmount()));
    memberCashValueDao.saveOrUpdate(memberCashvalue);
    return memberCashvalue;
  }
  private CustomerOrderTransDto saveCustomerOrderTrans(
      Long customerId, MemberCashValuePaymentDto memberCashValuePaymentDto) {
    Timestamp currentTime = new Timestamp(System.currentTimeMillis());
    CustomerOrderHd customerOrderHd = new CustomerOrderHd();
    customerOrderHd.setOrderDate(new Date());
    customerOrderHd.setOrderStatus(Constant.Status.CMP.toString());
    customerOrderHd.setStaffUserId(memberCashValuePaymentDto.getUserId());
    customerOrderHd.setCustomerId(customerId);
    customerOrderHd.setOrderTotalAmount(memberCashValuePaymentDto.getTotalAmount());
    customerOrderHd.setCreateBy(memberCashValuePaymentDto.getUserId());
    customerOrderHd.setCreateDate(currentTime);
    customerOrderHdDao.save(customerOrderHd);

    if (memberCashValuePaymentDto.getItemNos().length > 0) {
      for (int i = 0; i < memberCashValuePaymentDto.getItemNos().length; i++) {
        PosServiceItemPrice posServiceItemPrice =
            posServiceItemPriceDao.get(
                PosServiceItemPrice.class, memberCashValuePaymentDto.getItemNos()[i]);
        CustomerOrderDet customerOrderDet = new CustomerOrderDet();
        customerOrderDet.setCustomerOrderHd(customerOrderHd);
        customerOrderDet.setItemNo(memberCashValuePaymentDto.getItemNos()[i]);
        customerOrderDet.setOrderQty(memberCashValuePaymentDto.getOrderQty());
        customerOrderDet.setItemTotalAmout(
            posServiceItemPrice
                .getItemPrice()
                .multiply(new BigDecimal(memberCashValuePaymentDto.getOrderQty())));
        customerOrderDet.setCreateBy(memberCashValuePaymentDto.getUserId());
        customerOrderDet.setCreateDate(currentTime);
        customerOrderDetDao.save(customerOrderDet);
      }
    }

    CustomerOrderTrans customerOrderTrans = new CustomerOrderTrans();
    customerOrderTrans.setCustomerOrderHd(customerOrderHd);
    customerOrderTrans.setPaymentMethodCode(memberCashValuePaymentDto.getPaymentMethod());
    customerOrderTrans.setTransactionTimestamp(currentTime);
    customerOrderTrans.setPaidAmount(memberCashValuePaymentDto.getTotalAmount());

    if (StringUtils.isEmpty(memberCashValuePaymentDto.getPaymentMethod())
        || memberCashValuePaymentDto.getPaymentMethod().equals(Constant.CASH_Value)) {
      customerOrderTrans.setStatus(Constant.Status.SUC.toString());
      customerOrderTrans.setPaymentMedia(PaymentMediaType.OTH.name());
    } else {
      customerOrderTrans.setStatus(Constant.Status.PND.toString());
    }

    customerOrderTrans.setPaymentRecvBy(memberCashValuePaymentDto.getUserId());
    customerOrderTransDao.save(customerOrderTrans);

    CustomerOrderTransDto customerOrderTransDto = new CustomerOrderTransDto();
    customerOrderTransDto.setOrderNo(customerOrderHd.getOrderNo());
    customerOrderTransDto.setTransactionNo(customerOrderTrans.getTransactionNo());
    customerOrderTransDto.setTransactionTimestamp(
        DateConvertUtil.getYMDDateAndDateDiff(currentTime));
    customerOrderTransDto.setPaidAmount(memberCashValuePaymentDto.getTotalAmount());
    customerOrderTransDto.setPaymentMethodCode(memberCashValuePaymentDto.getPaymentMethod());
    customerOrderTransDto.setStatus(customerOrderTrans.getStatus());
    return customerOrderTransDto;
  }