/**
  * If the payout-limit of current merchant is 'follow parent', TE should query its parent merchant
  * till find a parent merchant whose payout-limit isn't 'follow parent'.
  *
  * @return the PrizeGroup which will be applied at final.
  */
 private PrizeGroup determinePrizeGroup(Context respCtx, Operator operator)
     throws ApplicationException {
   PrizeGroup prizeGroup = operator.getPrizeGroup();
   if (prizeGroup == null) {
     throw new ApplicationException(
         SystemException.CODE_MERCHANT_UNALLOWED_PAY,
         "No any prize group definition found of Operator("
             + operator
             + "), System will simply reject this payout request.");
   }
   if (PrizeGroup.ALLOWTYPE_USEPARENT == prizeGroup.getAllowType()) {
     // lookup prize group definition of operator's parent merchant
     Merchant leafMerchant =
         this.getMerchantDao().findById(Merchant.class, respCtx.getTransaction().getMerchantId());
     if (leafMerchant == null) {
       throw new ApplicationException(
           SystemException.CODE_NO_MERCHANT,
           "can NOT find merhcant by id=" + respCtx.getTransaction().getMerchantId());
     }
     prizeGroup = this.determinePrizeGroup(leafMerchant);
   } else {
     if (logger.isDebugEnabled()) {
       logger.debug(
           "Use the payout-limit setting(max="
               + prizeGroup.getMaxPayoutAmount()
               + ",min="
               + prizeGroup.getMinPayoutAmount()
               + ") of Operator("
               + operator
               + ") to verify payout limit.");
     }
   }
   return prizeGroup;
 }
 /**
  * This operation will check whether a merchant has privilege to payout a set of specific prize
  * levels.
  *
  * @param respCtx The context of current transaction.
  * @param operator The operator who try to perform payout.
  * @param requestedPrizeLevels The requested prize levels which the merchant try to payout.
  * @param gameType The game type of prize.
  * @param groupType Refer to PrizeGroupItem.GROUP_TYPE_XXX
  * @throws ApplicationException if any of the requested prize level is rejected.
  */
 protected void verifyPayoutByLevel(
     Context respCtx,
     Operator operator,
     Set<Integer> requestedPrizeLevels,
     int gameType,
     int groupType)
     throws ApplicationException {
   List<PrizeGroupItem> prizeGroupItems =
       this.getPrizeGroupItemDao()
           .findByGroupAndGameTypeAndGroupType(
               operator.getPrizeGroup().getId(), gameType, groupType);
   // if no any prize group items found for given groupType, merchant and
   // gameType, simply let the merchant perform payout.
   if (prizeGroupItems == null || prizeGroupItems.size() == 0) {
     throw new ApplicationException(
         SystemException.CODE_MERCHANT_UNALLOWED_PAY,
         "No any prize group definition found by (operatorId="
             + operator.getId()
             + ",prizeGroupId="
             + operator.getPrizeGroup().getId()
             + ",gameType="
             + gameType
             + ",prizeGroupType="
             + groupType
             + "), System will simply reject this payout request.");
   }
   for (int prizeLevel : requestedPrizeLevels) {
     if (!PrizeGroupItem.allow(prizeLevel, prizeGroupItems)) {
       throw new ApplicationException(
           SystemException.CODE_MERCHANT_UNALLOWED_PAY,
           "Operator("
               + operator
               + ") has no priviledge to pay prize (level:"
               + prizeLevel
               + ",groupType="
               + groupType
               + ",gameType="
               + gameType
               + ")");
     }
   }
 }