/** Found the valid prize group definition recursively. */ private PrizeGroup determinePrizeGroup(Merchant merchant) throws ApplicationException { if (Merchant.SUPER_MERCHANT_ID == merchant.getId()) { return null; } PrizeGroup prizeGroup = merchant.getPrizeGroup(); if (prizeGroup == null) { throw new ApplicationException( SystemException.CODE_MERCHANT_UNALLOWED_PAY, "No any prize group definition found of Merchant(" + merchant + "), System will simply reject this payout request."); } if (PrizeGroup.ALLOWTYPE_USEPARENT == prizeGroup.getAllowType()) { prizeGroup = this.determinePrizeGroup(merchant.getParentMerchant()); } else { if (logger.isDebugEnabled()) { logger.debug( "Use the payout-limit setting(max=" + prizeGroup.getMaxPayoutAmount() + ",min=" + prizeGroup.getMinPayoutAmount() + ") of merhcant(" + merchant + ") to verify payout limit."); } if (!prizeGroup.isPayoutAllowed()) { throw new ApplicationException( SystemException.CODE_MERCHANT_UNALLOWED_PAY, "Merchant(" + merchant + ") doesn't allow payout."); } } return prizeGroup; }
// ----------------------------------------------------- // HELP METHOD // ----------------------------------------------------- private void cashoutLogic( Context respCtx, CashoutPass cashoutpass, String cashoutOperatorid, BigDecimal cashoutAmount, int transType) throws ApplicationException { GsonCashOutOperator gcoo = new GsonCashOutOperator(); // check account whether or not sufficient Operator operator = this.operatorDao.findById(Operator.class, cashoutOperatorid); if (operator == null) { throw new ApplicationException( SystemException.CODE_NO_OPERATOR, "[Cashout] operator(id=" + cashoutOperatorid + ") doesn't exist."); } // check cash out operator id whether equals respCtx operator id , should not be the same if (cashoutOperatorid.equals(respCtx.getOperatorId())) { throw new ApplicationException( SystemException.CODE_CASHOUT_OPERATOR_SHOULD_NOT_SAME, "[Cashout] operator(id=" + cashoutOperatorid + ") should not the same with Operator."); } if (operator.getCreditType() == Merchant.CREDIT_TYPE_DEFINITIVEVALUE) { // check operator balance BigDecimal totalBalance = new BigDecimal("0"); totalBalance = totalBalance.add(operator.getCommisionBalance()); totalBalance = totalBalance.add(operator.getPayoutCreditLevel()); totalBalance = totalBalance.add(operator.getCashoutBalance()); if (logger.isDebugEnabled()) { logger.debug( "[Cashout] current operator :operator_id:" + operator.getId() + ",totalbalance=" + totalBalance.toPlainString()); } // judge the balance whether or not sufficient if (totalBalance.compareTo(cashoutAmount) < 0) { throw new ApplicationException( SystemException.CODE_INSUFFICIENT_BALANCE, "[Cashout] OPERATOR(id=" + operator.getId() + ") insufficient balance[commission balance,cashout balance,payout balance]."); } // ============== // deduct the money from balance order by [1)Commission balance // 2)Payout balance 3)Cash-out balance] BigDecimal commissionDeducted = new BigDecimal("0"); BigDecimal payoutDeducted = new BigDecimal("0"); BigDecimal cashoutDeducted = new BigDecimal("0"); BigDecimal cashoutAmountTemp = operator.getCommisionBalance().subtract(cashoutAmount); if (cashoutAmountTemp.doubleValue() >= 0) { commissionDeducted = cashoutAmount; } else { // negative value if (operator.getCommisionBalance().doubleValue() < 0 && operator.getPayoutCreditLevel().doubleValue() < 0) { cashoutDeducted = cashoutAmount; } else if (operator.getCommisionBalance().doubleValue() < 0) { // deducted account only (payout balance) if (operator.getPayoutCreditLevel().subtract(cashoutAmount).doubleValue() > 0) { payoutDeducted = cashoutAmount; } else { payoutDeducted = operator.getPayoutCreditLevel(); cashoutDeducted = (cashoutAmount.subtract(payoutDeducted)); } } else { // deducted account (commission balance + payout balance) if ((operator.getCommisionBalance().add(operator.getPayoutCreditLevel())) .subtract(cashoutAmount) .doubleValue() >= 0) { commissionDeducted = operator.getCommisionBalance(); payoutDeducted = cashoutAmount.subtract(commissionDeducted); } else { if ((operator .getCommisionBalance() .add(operator.getPayoutCreditLevel()) .add(operator.getCashoutBalance())) .subtract(cashoutAmount) .doubleValue() >= 0) { commissionDeducted = operator.getCommisionBalance(); payoutDeducted = operator.getPayoutCreditLevel(); cashoutDeducted = (cashoutAmount.subtract(commissionDeducted)).subtract(payoutDeducted); } } } } if (logger.isDebugEnabled()) { logger.debug( "[Cashout] current operator :operator_id:" + cashoutOperatorid + ",deducted money balance:commissionDeducted=" + commissionDeducted.toPlainString() + ";payoutdeducted:" + payoutDeducted + ";cashoutdeducted:" + cashoutDeducted); } // set 2 decimals place commissionDeducted.setScale( MLotteryContext.getInstance().getInt(MLotteryContext.COMMISSION_BALANCE_PRECISION), BigDecimal.ROUND_HALF_UP); payoutDeducted.setScale(2, BigDecimal.ROUND_HALF_UP); cashoutDeducted.setScale(2, BigDecimal.ROUND_HALF_UP); this.operatorDao.deductBalanceByOperator( commissionDeducted, payoutDeducted, cashoutDeducted, cashoutOperatorid); // ADD BALANCE_TRANSACTION RECORD addBalanceTransactionRecord( respCtx, new BigDecimal(String.valueOf(cashoutAmount.doubleValue())), transType, cashoutOperatorid, BalanceTransactions.OWNER_TYPE_OPERATOR, BalanceTransactions.PAYMENT_TYPE_DEDUCTING_MONEY, new BigDecimal("0"), new BigDecimal("0")); // assemble the Json obj gcoo.setOperatorMerchantType(BalanceTransactions.OWNER_TYPE_OPERATOR); gcoo.setOperatorMerchantid(cashoutOperatorid); gcoo.setOperatorid(cashoutOperatorid); gcoo.setTotalAmount(cashoutAmount); gcoo.setCommission(commissionDeducted); gcoo.setPayout(payoutDeducted); gcoo.setCashout(cashoutDeducted); } 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(cashoutAmount) < 0) { throw new ApplicationException( SystemException.CODE_INSUFFICIENT_BALANCE, "MERCHANT(id=" + finalMerchant.getId() + ") insufficient balance[commission balance,cashout balance,payout balance]."); } // ============== // deduct the money from balance order by [1)Commission balance // 2)Payout balance 3)Cash-out balance] BigDecimal commissionDeducted = new BigDecimal("0"); BigDecimal payoutDeducted = new BigDecimal("0"); BigDecimal cashoutDeducted = new BigDecimal("0"); BigDecimal cashoutAmountTemp = finalMerchant.getCommisionBalance().subtract(cashoutAmount); if (cashoutAmountTemp.doubleValue() >= 0) { commissionDeducted = cashoutAmount; } else { // negative value if (finalMerchant.getCommisionBalance().doubleValue() < 0 && finalMerchant.getPayoutCreditLevel().doubleValue() < 0) { cashoutDeducted = cashoutAmount; } else if (finalMerchant.getCommisionBalance().doubleValue() < 0) { // deducted account only (payout balance) if (finalMerchant.getPayoutCreditLevel().subtract(cashoutAmount).doubleValue() > 0) { payoutDeducted = cashoutAmount; } else { payoutDeducted = finalMerchant.getPayoutCreditLevel(); cashoutDeducted = (cashoutAmount.subtract(payoutDeducted)); } } else { // deducted account (commission balance + payout balance) if ((finalMerchant.getCommisionBalance().add(finalMerchant.getPayoutCreditLevel())) .subtract(cashoutAmount) .doubleValue() >= 0) { commissionDeducted = finalMerchant.getCommisionBalance(); payoutDeducted = cashoutAmount.subtract(commissionDeducted); } else { if ((finalMerchant .getCommisionBalance() .add(finalMerchant.getPayoutCreditLevel()) .add(finalMerchant.getCashoutBalance())) .subtract(cashoutAmount) .doubleValue() >= 0) { commissionDeducted = finalMerchant.getCommisionBalance(); payoutDeducted = finalMerchant.getPayoutCreditLevel(); cashoutDeducted = (cashoutAmount.subtract(commissionDeducted)).subtract(payoutDeducted); } } } } if (logger.isDebugEnabled()) { logger.debug( "[Cashout] current merchant :merchant_id:" + finalMerchant.getId() + ",deducted money balance:commissionDeducted=" + commissionDeducted.toPlainString() + ";payoutdeducted:" + payoutDeducted + ";cashoutdeducted:" + cashoutDeducted); } commissionDeducted.setScale( MLotteryContext.getInstance().getInt(MLotteryContext.COMMISSION_BALANCE_PRECISION), BigDecimal.ROUND_HALF_UP); payoutDeducted.setScale(2, BigDecimal.ROUND_HALF_UP); cashoutDeducted.setScale(2, BigDecimal.ROUND_HALF_UP); this.merchantDao.deductBalanceByMerchant( commissionDeducted, payoutDeducted, cashoutDeducted, finalMerchant.getId()); // ADD BALANCE_TRANSACTION RECORD addBalanceTransactionRecord( respCtx, new BigDecimal(String.valueOf(cashoutAmount.doubleValue())), transType, String.valueOf(finalMerchant.getId()), BalanceTransactions.OWNER_TYPE_MERCHANT, BalanceTransactions.PAYMENT_TYPE_DEDUCTING_MONEY, new BigDecimal("0"), new BigDecimal("0")); // assemble the Json obj gcoo.setOperatorMerchantType(BalanceTransactions.OWNER_TYPE_MERCHANT); gcoo.setOperatorMerchantid(String.valueOf(finalMerchant.getId())); gcoo.setOperatorid(cashoutOperatorid); gcoo.setTotalAmount(cashoutAmount); gcoo.setCommission(commissionDeducted); gcoo.setPayout(payoutDeducted); gcoo.setCashout(cashoutDeducted); } // update 'CASHOUT_PASS' the field 'cashout_te_transaction_id' // increase the tried times add 1 if (cashoutpass != null) { cashoutpass.setId(cashoutpass.getId()); cashoutpass.setTriedTimes(cashoutpass.getTriedTimes()); cashoutpass.setCashoutTeTransactionId(respCtx.getTransaction().getId()); cashoutpass.setUpdateBy(respCtx.getOperatorId()); cashoutpass.setUpdateTime(net.mpos.fk.util.DateUtils.getCurrentDate()); this.cashoutPassDao.update(cashoutpass); } // ========================== // //add cash out balance & commission to self operator String commissionOperatorId = respCtx.getOperatorId(); Operator commisionOperator = this.operatorDao.findById(Operator.class, commissionOperatorId); if (commisionOperator == null) { throw new ApplicationException( SystemException.CODE_NO_OPERATOR, "[CashoutByPassword] commisionOperator(id=" + commissionOperatorId + ") doesn't exist."); } // credit if (commisionOperator.getCreditType() == Merchant.CREDIT_TYPE_DEFINITIVEVALUE) { BigDecimal cashoutrate = commisionOperator.getCashoutRate(); BigDecimal cashoutamount = cashoutAmount; // BigDecimal commissionAmount = cashoutamount.multiply(cashoutrate); BigDecimal commissionAmount = SimpleToolkit.mathMultiple( cashoutamount, cashoutrate, MLotteryContext.getInstance().getInt(MLotteryContext.COMMISSION_BALANCE_PRECISION)); cashoutamount.setScale(2, BigDecimal.ROUND_HALF_UP); this.operatorDao.addCashoutAndCommissionToOperator( cashoutamount, commissionAmount, commissionOperatorId); // insert record into 'BALANCE_TRANSACTIONS' // ADD BALANCE_TRANSACTION RECORD addBalanceTransactionRecord( respCtx, cashoutAmount, transType, commissionOperatorId, BalanceTransactions.OWNER_TYPE_OPERATOR, BalanceTransactions.PAYMENT_TYPE_PLUSING_MONEY, commissionAmount, cashoutrate); // assemble the Json obj gcoo.setPlusOperatorMerchantType(BalanceTransactions.OWNER_TYPE_OPERATOR); gcoo.setPlusOperatorid(commissionOperatorId); gcoo.setPlusOperatorCashoutBalance(cashoutamount); gcoo.setPlusOperatorCommissionBalance(commissionAmount); gcoo.setPlusOperatorCommissionRate(cashoutrate); } else if (commisionOperator.getCreditType() == Merchant.CREDIT_TYPE_USE_PARENT) { // lookup the merchant Merchant originmerchant = getMerchantByOperator(commissionOperatorId, false); Merchant finalMerchant = this.merchantDao.findDistributeMerchantByMerchantId(originmerchant.getId()); if (finalMerchant == null) { throw new ApplicationException( SystemException.CODE_NO_MERCHANT, "commission operator(id=" + commissionOperatorId + ") doesn't exist parent merchant."); } // use operator cash out rate BigDecimal cashoutrate = commisionOperator.getCashoutRate(); BigDecimal cashoutamount = cashoutAmount; // BigDecimal commissionOperatorAmount = cashoutamount.multiply(cashoutrate); BigDecimal commissionOperatorAmount = SimpleToolkit.mathMultiple( cashoutamount, cashoutrate, MLotteryContext.getInstance().getInt(MLotteryContext.COMMISSION_BALANCE_PRECISION)); // merchant cash out rate // BigDecimal finalcashoutrate = finalMerchant.getCashoutRate(); // BigDecimal finalcashoutamount = cashoutAmount; // BigDecimal commissionMerchantAmount = finalcashoutamount.multiply(finalcashoutrate); cashoutamount.setScale(2, BigDecimal.ROUND_HALF_UP); this.merchantDao.addCashoutAndCommissionToMerchant( cashoutamount, null, finalMerchant.getId()); // ADD BALANCE_TRANSACTION RECORD addBalanceTransactionRecord( respCtx, cashoutAmount, transType, commissionOperatorId, BalanceTransactions.OWNER_TYPE_OPERATOR, BalanceTransactions.PAYMENT_TYPE_PLUSING_MONEY, commissionOperatorAmount, cashoutrate); addBalanceTransactionRecord( respCtx, cashoutAmount, transType, String.valueOf(finalMerchant.getId()), BalanceTransactions.OWNER_TYPE_MERCHANT, BalanceTransactions.PAYMENT_TYPE_PLUSING_MONEY, new BigDecimal("0"), new BigDecimal("0")); // assemble the Json obj gcoo.setPlusOperatorMerchantType(BalanceTransactions.OWNER_TYPE_OPERATOR); gcoo.setPlusOperatorid(commissionOperatorId); gcoo.setPlusOperatorCashoutBalance(cashoutamount); gcoo.setPlusOperatorCommissionBalance(commissionOperatorAmount); gcoo.setPlusOperatorCommissionRate(cashoutrate); gcoo.setPlusOperatorMerchantType(BalanceTransactions.OWNER_TYPE_MERCHANT); gcoo.setPlusMerchantid(String.valueOf(finalMerchant.getId())); gcoo.setPlusMerchantCashoutBalance(cashoutamount); gcoo.setPlusMerchantCommissionBalance(new BigDecimal("0")); gcoo.setPlusMerchantCommissionRate(new BigDecimal("0")); } // DESTINATION_OPEATOR respCtx.getTransaction().setDestinationOpeator(cashoutOperatorid); respCtx.getTransaction().setTotalAmount(cashoutAmount); // write transaction message for reversal. // add record to te_transaction_msg // assemble request message use JSON String reqmsg = new Gson().toJson(gcoo); TransactionMessage msg = new TransactionMessage(); msg.setTransactionId(respCtx.getTransaction().getId()); msg.setRequestMsg(reqmsg); respCtx.getTransaction().setTransMessage(msg); }
@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; }