Просмотр исходного кода

Ticket #3777 - Credits: Improve withdraw process.

AntonLV 4 лет назад
Родитель
Сommit
d2f7bb183f

+ 33 - 0
modules/boonex/credits/classes/BxCreditsConfig.php

@@ -46,6 +46,11 @@ class BxCreditsConfig extends BxBaseModGeneralConfig
 
             'FIELD_C_MESSAGE' => 'message',
 
+            'FIELD_H_ID' => 'id',
+            'FIELD_H_DIRECTION' => 'direction',
+            'FIELD_H_DATE' => 'date',
+            'FIELD_H_CLEARED' => 'cleared',
+
             // page URIs
             'URI_HOME' => 'credits-home',
             'URL_HOME' => 'page.php?i=credits-home',
@@ -58,6 +63,9 @@ class BxCreditsConfig extends BxBaseModGeneralConfig
             // some params
             'PARAM_WITHDRAW' => 'bx_credits_enable_withdraw',
             'PARAM_WITHDRAW_EMAIL' => 'bx_credits_withdraw_email',
+            'PARAM_WITHDRAW_CLEARING' => 'bx_credits_withdraw_clearing',
+            'PARAM_WITHDRAW_MINIMUM' => 'bx_credits_withdraw_minimum',
+            'PARAM_WITHDRAW_REMAINING' => 'bx_credits_withdraw_remaining',
             'PARAM_PRECISION' => 'bx_credits_precision',
             'PARAM_CR_USE' => 'bx_credits_conversion_rate_use',
             'PARAM_CR_WITHDRAW' => 'bx_credits_conversion_rate_withdraw',
@@ -178,6 +186,31 @@ class BxCreditsConfig extends BxBaseModGeneralConfig
         return $sEmail;
     }
 
+    public function getWithdrawClearing()
+    {
+        return (int)getParam($this->CNF['PARAM_WITHDRAW_CLEARING']);
+    }
+
+    public function getTransferTypesForClearing()
+    {
+        return [
+            BX_CREDITS_TRANSFER_TYPE_PURCHASE,
+            BX_CREDITS_TRANSFER_TYPE_CHECKOUT,
+            BX_CREDITS_TRANSFER_TYPE_GRANT,
+            BX_CREDITS_TRANSFER_TYPE_SEND,
+            BX_CREDITS_TRANSFER_TYPE_SERVICE
+        ];
+    }
+
+    public function getTransferTypesForSpending()
+    {
+        return [
+            BX_CREDITS_TRANSFER_TYPE_CHECKOUT,
+            BX_CREDITS_TRANSFER_TYPE_SEND,
+            BX_CREDITS_TRANSFER_TYPE_SERVICE
+        ];
+    }
+
     public function getPrecision()
     {
         return (int)getParam($this->CNF['PARAM_PRECISION']);

+ 31 - 0
modules/boonex/credits/classes/BxCreditsCronClearing.php

@@ -0,0 +1,31 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Credits Credits
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxCreditsCronClearing extends BxDolCron
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    public function __construct()
+    {
+        parent::__construct();
+
+    	$this->_sModule = 'bx_credits';
+    	$this->_oModule = BxDolModule::getInstance($this->_sModule);
+    }
+
+    function processing()
+    {
+        $this->_oModule->processClearing();
+    }
+}
+
+/** @} */

+ 43 - 9
modules/boonex/credits/classes/BxCreditsDb.php

@@ -273,16 +273,20 @@ class BxCreditsDb extends BxBaseModGeneralDb
         return (int)$this->query($sQuery) > 0;
     }
 
-    public function updateProfileBalance($iId, $fBalance)
+    public function updateProfileBalance($iId, $fAmount, $bCleared = false)
     {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sBalance = $bCleared ? 'cleared' : 'balance';
+
         if(!$this->isProfile($iId))
-            return $this->insertProfile(array('id' => $iId, 'balance' => $fBalance));
+            return $this->insertProfile(['id' => $iId, $sBalance => $fAmount]);
 
-        $sQuery = "UPDATE `" . $this->_oConfig->CNF['TABLE_PROFILES'] . "` SET `balance`=`balance`+:balance WHERE `id`=:id";
-        return (int)$this->query($sQuery, array(
+        $sQuery = "UPDATE `" . $CNF['TABLE_PROFILES'] . "` SET `" . $sBalance . "`=`" . $sBalance . "`+:amount WHERE `id`=:id";
+        return (int)$this->query($sQuery, [
             'id' => $iId,
-            'balance' => $fBalance
-        )) > 0;
+            'amount' => $fAmount
+        ]) > 0;
     }
 
     public function deleteProfile($aWhere)
@@ -300,16 +304,38 @@ class BxCreditsDb extends BxBaseModGeneralDb
     public function getHistory($aParams = array())
     {
     	$CNF = &$this->_oConfig->CNF;
-    	$aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
+    	$aMethod = ['name' => 'getAll', 'params' => [0 => 'query']];
 
     	$sSelectClause = "`th`.*";
     	$sJoinClause = $sWhereClause = $sLimitClause = "";
         switch($aParams['type']) {
+            case 'cleared':
+                $aMethod['name'] = 'getOne';
+                $aMethod['params'][1] = [
+                    'profile' => $aParams['profile']
+                ];
+
+                $sSelectClause = "SUM(`th`.`amount`)";
+                $sWhereClause = " AND `th`.`first_pid`=:profile AND `th`.`direction`='in' AND `th`.`type` IN (" . $this->implode_escape($this->_oConfig->getTransferTypesForClearing()) . ") AND `th`.`cleared`<>'0'";
+                break;
+
+            case 'spent':
+                $aMethod['name'] = 'getOne';
+                $aMethod['params'][1] = [
+                    'profile' => $aParams['profile'],
+                    'type_cancel' => BX_CREDITS_TRANSFER_TYPE_CANCELLATION
+                ];
+
+                $sSelectClause = "SUM(`th`.`amount`)";
+                $sJoinClause = " LEFT JOIN `" . $CNF['TABLE_HISTORY'] . "` AS `thc` ON `th`.`order`=`thc`.`order` AND `thc`.`type`=:type_cancel";
+                $sWhereClause = " AND `th`.`first_pid`=:profile AND `th`.`direction`='out' AND `th`.`type` IN (" . $this->implode_escape($this->_oConfig->getTransferTypesForSpending()) . ") AND ISNULL(`thc`.`id`)";
+                break;
+
             case 'id':
             	$aMethod['name'] = 'getRow';
-            	$aMethod['params'][1] = array(
+            	$aMethod['params'][1] = [
                     'id' => $aParams['id']
-                );
+                ];
 
                 $sWhereClause = " AND `th`.`id`=:id";
                 break;
@@ -318,6 +344,14 @@ class BxCreditsDb extends BxBaseModGeneralDb
                 $aMethod['name'] = 'getRow';
                 $sWhereClause = " AND " . $this->arrayToSQL($aParams['by'], ' AND ');
                 break;
+
+            case 'clearing':
+                $aMethod['params'][1] = [
+                    'clearing' => $aParams['clearing']
+                ];
+
+                $sWhereClause = " AND `th`.`direction`='in' AND `th`.`type` IN (" . $this->implode_escape($this->_oConfig->getTransferTypesForClearing()) . ") AND `th`.`date` < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL :clearing DAY)) AND `th`.`cleared`='0'";
+                break;
         }
 
         $sLimitClause = !empty($sLimitClause) ? "LIMIT " . $sLimitClause : $sLimitClause;

+ 9 - 2
modules/boonex/credits/classes/BxCreditsFormCredit.php

@@ -69,14 +69,21 @@ class BxCreditsFormCredit extends BxTemplFormView
 
         return $this->genRowStandard($aInput);
     }
-    
+
     protected function genCustomInputBalance(&$aInput)
     {
         $aInput['value'] = $this->_oModule->getProfileBalance();
 
         return $this->genInputStandard($aInput);
     }
-    
+
+    protected function genCustomInputCleared(&$aInput)
+    {
+        $aInput['value'] = $this->_oModule->getProfileBalanceCleared();
+
+        return $this->genInputStandard($aInput);
+    }
+
     protected function genCustomInputRate(&$aInput)
     {
         $aInput['value'] = $this->_fRate;

+ 23 - 0
modules/boonex/credits/classes/BxCreditsGridHistoryAdministration.php

@@ -104,6 +104,29 @@ class BxCreditsGridHistoryAdministration extends BxTemplGrid
         return parent::_getCellDefault(bx_time_js($mixedValue, BX_FORMAT_DATE, true), $sKey, $aField, $aRow);
     }
 
+    protected function _getCellCleared($mixedValue, $sKey, $aField, $aRow)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if($aRow[$CNF['FIELD_H_DIRECTION']] == BX_CREDITS_DIRECTION_IN) {
+            if(empty($mixedValue)) {
+                $iPeriod = $this->_oModule->_oConfig->getWithdrawClearing();
+                if($iPeriod == 0)
+                    $iPeriod = 1;
+
+                $oDate = date_create('@' . $aRow[$CNF['FIELD_H_DATE']]);
+                date_add($oDate, new DateInterval('P' . $iPeriod . 'D'));
+                $mixedValue = date_format($oDate, 'U');
+            }
+
+            $mixedValue = bx_time_js($mixedValue, BX_FORMAT_DATE, true);
+        }
+        else 
+            $mixedValue = '';
+
+        return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
+
     protected function _getProfile($mixedValue) 
     {
         if(is_numeric($mixedValue) && (int)$mixedValue == 0)

+ 74 - 31
modules/boonex/credits/classes/BxCreditsModule.php

@@ -9,6 +9,14 @@
  * @{
  */
 
+define('BX_CREDITS_TRANSFER_TYPE_PURCHASE', 'purchase');
+define('BX_CREDITS_TRANSFER_TYPE_CHECKOUT', 'checkout');
+define('BX_CREDITS_TRANSFER_TYPE_CANCELLATION', 'cancellation');
+define('BX_CREDITS_TRANSFER_TYPE_GRANT', 'grant');
+define('BX_CREDITS_TRANSFER_TYPE_SEND', 'send');
+define('BX_CREDITS_TRANSFER_TYPE_WITHDRAW', 'withdraw');
+define('BX_CREDITS_TRANSFER_TYPE_SERVICE', 'service');
+
 define('BX_CREDITS_DIRECTION_IN', 'in');
 define('BX_CREDITS_DIRECTION_OUT', 'out');
 
@@ -78,8 +86,8 @@ class BxCreditsModule extends BxBaseModGeneralModule
             'precision' => $this->_oConfig->getPrecision()
         ));
 
-        $this->updateProfileBalance($iBuyerId, $iSellerId, -$fAmount, $sOrder, $sInfo, $sData);
-        $this->updateProfileBalance($iSellerId, $iBuyerId, $fAmount, $sOrder, $sInfo, $sData);
+        $this->updateProfileBalance($iBuyerId, $iSellerId, -$fAmount, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sOrder, $sInfo, $sData);
+        $this->updateProfileBalance($iSellerId, $iBuyerId, $fAmount, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sOrder, $sInfo, $sData);
 
         bx_alert($this->getName(), 'checkout', 0, false, array(
             'seller' => $iSellerId,
@@ -661,18 +669,18 @@ class BxCreditsModule extends BxBaseModGeneralModule
         if(empty($sInfo))
             $sInfo = '_bx_credits_txt_history_info_service';
 
-        return $this->updateProfileBalance($iFirstPid, $iSecondPid, $fAmount, $sOrder, $sInfo);
+        return $this->updateProfileBalance($iFirstPid, $iSecondPid, $fAmount, BX_CREDITS_TRANSFER_TYPE_SERVICE, $sOrder, $sInfo);
     }
     
     public function serviceMakePayment($iBuyerPid, $fAmount, $iSellerPid, $sOrder = '')
     {
         $sInfo = '_bx_credits_txt_history_info_checkout';
 
-        if(!$this->updateProfileBalance($iBuyerPid, $iSellerPid, -$fAmount, $sOrder, $sInfo))
+        if(!$this->updateProfileBalance($iBuyerPid, $iSellerPid, -$fAmount, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sOrder, $sInfo))
             return false;
 
-        if(!$this->updateProfileBalance($iSellerPid, $iBuyerPid, $fAmount, $sOrder, $sInfo)) {
-            $this->updateProfileBalance($iBuyerPid, 0, $fAmount, $sOrder, '_bx_credits_txt_history_info_cancellation');
+        if(!$this->updateProfileBalance($iSellerPid, $iBuyerPid, $fAmount, $sOrder, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sInfo)) {
+            $this->updateProfileBalance($iBuyerPid, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_CANCELLATION, $sOrder, '_bx_credits_txt_history_info_cancellation');
             return false;
         }
 
@@ -717,7 +725,21 @@ class BxCreditsModule extends BxBaseModGeneralModule
         return (float)$this->_oDb->getProfile(array('type' => 'balance', 'id' => $iProfileId));
     }
 
-    public function updateProfileBalance($iFirstPid, $iSecondPid, $fAmount, $sOrder = '', $sInfo = '', $sData = '')
+    public function getProfileBalanceCleared($iProfileId = 0)
+    {
+        if(empty($iProfileId))
+            $iProfileId = bx_get_logged_profile_id();
+
+        if(empty($iProfileId))
+            return 0;
+
+        $fCleared = (float)$this->_oDb->getHistory(['type' => 'cleared', 'profile' => $iProfileId]);
+        $fSpent = (float)$this->_oDb->getHistory(['type' => 'spent', 'profile' => $iProfileId]);
+
+        return $fCleared > $fSpent ? $fCleared - $fSpent : 0;
+    }
+
+    public function updateProfileBalance($iFirstPid, $iSecondPid, $fAmount, $sType, $sOrder = '', $sInfo = '', $sData = '')
     {
         $CNF = &$this->_oConfig->CNF;
 
@@ -736,16 +758,17 @@ class BxCreditsModule extends BxBaseModGeneralModule
         $fAmountAbs = abs($fAmount);
         $sDirection = $fAmount > 0 ? BX_CREDITS_DIRECTION_IN : BX_CREDITS_DIRECTION_OUT;
 
-        $iHistoryId = $this->_oDb->insertHistory(array(
+        $iHistoryId = $this->_oDb->insertHistory([
             'first_pid' => $iFirstPid,
             'second_pid' => $iSecondPid,
             'amount' => $fAmountAbs,
+            'type' => $sType,
             'direction' => $sDirection,
             'order' => $sOrder,
             'data' => $sData,
             'info' => $sInfo,
             'date' => time()
-        ));
+        ]);
 
         if(!$iHistoryId)
             return false;
@@ -754,6 +777,7 @@ class BxCreditsModule extends BxBaseModGeneralModule
             'first_pid' => $iFirstPid,
             'second_pid' => $iSecondPid,
             'amount' => $fAmountAbs,
+            'type' => $sType,
             'direction' => $sDirection,
             'order' => $sOrder,
         ));
@@ -776,7 +800,7 @@ class BxCreditsModule extends BxBaseModGeneralModule
             return ['code' => 2, 'msg' => '_bx_credits_err_profile_not_found'];
 
         $sInfo = '_bx_credits_txt_history_info_grant';
-        $iHistoryId = $this->updateProfileBalance($iProfileId, 0, $fAmount, '', $sInfo);
+        $iHistoryId = $this->updateProfileBalance($iProfileId, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_GRANT, '', $sInfo);
         if(!$iHistoryId)
             return ['code' => 3, 'msg' => '_bx_credits_err_cannot_update_balance'];
 
@@ -808,13 +832,13 @@ class BxCreditsModule extends BxBaseModGeneralModule
         $sOrder = $this->_oConfig->getOrder();
         $sInfo = !empty($sMessage) ? $sMessage : '_bx_credits_txt_history_info_send';
 
-        $iHistoryId = $this->updateProfileBalance($iUserId, $iProfileId, -$fAmount, $sOrder, $sInfo);
+        $iHistoryId = $this->updateProfileBalance($iUserId, $iProfileId, -$fAmount, BX_CREDITS_TRANSFER_TYPE_SEND, $sOrder, $sInfo);
         if(!$iHistoryId)
             return ['code' => 3, 'msg' => '_bx_credits_err_cannot_update_balance'];
 
-        if(!$this->updateProfileBalance($iProfileId, $iUserId, $fAmount, $sOrder, $sInfo)) {
+        if(!$this->updateProfileBalance($iProfileId, $iUserId, $fAmount, BX_CREDITS_TRANSFER_TYPE_SEND, $sOrder, $sInfo)) {
             $sInfo = '_bx_credits_txt_history_info_cancellation';
-            $iHistoryId = $this->updateProfileBalance($iUserId, 0, $fAmount, $sOrder, $sInfo);
+            $iHistoryId = $this->updateProfileBalance($iUserId, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_CANCELLATION, $sOrder, $sInfo);
 
             return ['code' => 3, 'id' => $iHistoryId, 'msg' => '_bx_credits_err_cannot_update_balance'];
         }
@@ -847,47 +871,50 @@ class BxCreditsModule extends BxBaseModGeneralModule
             $iProfileId = bx_get_logged_profile_id ();
 
         if(empty($iProfileId))
-            return array('code' => 1, 'msg' => '_bx_credits_err_login_required');
+            return ['code' => 1, 'msg' => '_bx_credits_err_login_required'];
 
         $oProfile = BxDolProfile::getInstance($iProfileId);
         if(!$oProfile)
-            return array('code' => 1, 'msg' => '_bx_credits_err_login_required');
+            return ['code' => 1, 'msg' => '_bx_credits_err_login_required'];
 
-        $fBalance = $this->getProfileBalance($iProfileId);
-        if($fAmount > $fBalance)
-            return array('code' => 2, 'msg' => '_bx_credits_err_low_balance');
+        $fBalanceCleared = $this->getProfileBalanceCleared($iProfileId);
+        if($fAmount > $fBalanceCleared)
+            return ['code' => 2, 'msg' => '_bx_credits_err_low_balance'];
 
-        $aResult = array('code' => 3, 'msg' => '_bx_credits_err_cannot_send');
+        if($fAmount < ($iWithdrawMinimum = (int)getParam($CNF['PARAM_WITHDRAW_MINIMUM'])))
+            return ['code' => 3, 'msg' => _t('_bx_credits_err_withdraw_minimum', $iWithdrawMinimum)];
 
-        $oEmailTemplates = BxDolEmailTemplates::getInstance();
-        if(!$oEmailTemplates)
-            return $aResult;
+        $fBalance = $this->getProfileBalance($iProfileId);
+        if(($fBalance - $fAmount) < ($iWithdrawRemaining = (int)getParam($CNF['PARAM_WITHDRAW_REMAINING'])))
+            return ['code' => 4, 'msg' => _t('_bx_credits_err_withdraw_remaining', $iWithdrawRemaining)];
+
+        $aResult = ['code' => 5, 'msg' => '_bx_credits_err_cannot_send'];
 
         $fRate = $this->_oConfig->getConversionRateWithdraw();
 
-        $aTemplateVars = array(
+        $aTemplateVars = [
             'profile_link' => $oProfile->getUrl(),
             'profile_name' => $oProfile->getDisplayName(),
             'amount' => $fAmount,
             'rate' => $fRate,
             'message' => $sMessage,
             'confirm_url' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($CNF['URL_HISTORY_ADMINISTRATION'])
-        );
-        $aTemplate = $oEmailTemplates->parseTemplate($CNF['ETEMPLATE_WITHDRAW_REQUESTED'], $aTemplateVars);
+        ];
+        $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate($CNF['ETEMPLATE_WITHDRAW_REQUESTED'], $aTemplateVars);
         if(!$aTemplate)
             return $aResult;
 
         $sEmail = $this->_oConfig->getWithdrawEmail();
-        if(!sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, array(), BX_EMAIL_SYSTEM, 'html', false, array(), true))
+        if(!sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, [], BX_EMAIL_SYSTEM, 'html', false, [], true))
             return $aResult;
 
-        bx_alert($this->getName(), 'withdraw_requested', 0, $iProfileId, array(
+        bx_alert($this->getName(), 'withdraw_requested', 0, $iProfileId, [
             'profile' => $iProfileId,
             'amount' => $fAmount,
             'rate' => $fRate
-        ));
+        ]);
 
-        return array('code' => 0);
+        return ['code' => 0];
     }
 
     public function processWithdrawConfirm($iUserId, $iProfileId, $fAmount, $sMessage = '')
@@ -903,7 +930,7 @@ class BxCreditsModule extends BxBaseModGeneralModule
             return ['code' => 2, 'msg' => '_bx_credits_err_low_balance'];
 
         $sInfo = '_bx_credits_txt_history_info_withdraw';
-        $iHistoryId = $this->updateProfileBalance($iProfileId, 0, -$fAmount, '', $sInfo);
+        $iHistoryId = $this->updateProfileBalance($iProfileId, 0, -$fAmount, BX_CREDITS_TRANSFER_TYPE_WITHDRAW, '', $sInfo);
         if(!$iHistoryId)
             return ['code' => 3, 'msg' => '_bx_credits_err_cannot_update_balance'];
 
@@ -921,6 +948,22 @@ class BxCreditsModule extends BxBaseModGeneralModule
         return ['code' => 0, 'id' => $iHistoryId];
     }
 
+    public function processClearing()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aItems = $this->_oDb->getHistory(['type' => 'clearing', 'clearing' => $this->_oConfig->getWithdrawClearing()]);
+        if(empty($aItems) || !is_array($aItems))
+            return;
+
+        $iNow = time();
+        foreach($aItems as $aItem) {
+            $this->_oDb->updateHistory([$CNF['FIELD_H_CLEARED'] => $iNow], [$CNF['FIELD_H_ID'] => $aItem['id']]);
+
+            //TODO: Some action(s) related to clearing can be performed here.
+        }
+    }
+
     /*
      * Internal methods
      */
@@ -952,7 +995,7 @@ class BxCreditsModule extends BxBaseModGeneralModule
 
         $sInfo = '_bx_credits_txt_history_info_purchase';
         $fAmount = ((float)$aBundle[$CNF['FIELD_AMOUNT']] + (float)$aBundle[$CNF['FIELD_BONUS']]) * $iItemCount;
-        if(!$this->updateProfileBalance($iClientId, 0, $fAmount, '', $sInfo))
+        if(!$this->updateProfileBalance($iClientId, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_PURCHASE, '', $sInfo))
             return array();
 
         bx_alert($this->getName(), 'order_' . $sAction, 0, false, array(

+ 8 - 0
modules/boonex/credits/install/langs/en.xml

@@ -6,6 +6,9 @@
     <!-- Options -->
     <string name="_bx_credits_option_enable_withdraw"><![CDATA[Allow members to withdraw credits converting them to money]]></string>
     <string name="_bx_credits_option_withdraw_email"><![CDATA[Email for withdraw requests]]></string>
+    <string name="_bx_credits_option_withdraw_clearing"><![CDATA[Clearing period (in days) before received credits can be withdrawn]]></string>
+    <string name="_bx_credits_option_withdraw_minimum"><![CDATA[Minimum amount of cleared credits which can be withdrawn]]></string>
+    <string name="_bx_credits_option_withdraw_remaining"><![CDATA[Minimum credits balance after withdrawal]]></string>
     <string name="_bx_credits_option_precision"><![CDATA[Precision (number of digits after the decimal point)]]></string>
     <string name="_bx_credits_option_conversion_rate_use"><![CDATA[Conversion rate to pay with credits]]></string>
     <string name="_bx_credits_option_conversion_rate_withdraw"><![CDATA[Conversion rate to withdraw credits]]></string>
@@ -44,6 +47,8 @@
     <string name="_bx_credits_form_credit_display_withdraw_confirm"><![CDATA[Confirm withdraw]]></string>
     <string name="_bx_credits_form_credit_input_sys_balance"><![CDATA[Balance]]></string>
     <string name="_bx_credits_form_credit_input_balance"><![CDATA[Balance]]></string>
+    <string name="_bx_credits_form_credit_input_sys_cleared"><![CDATA[Cleared Balance]]></string>
+    <string name="_bx_credits_form_credit_input_cleared"><![CDATA[Cleared Balance]]></string>
     <string name="_bx_credits_form_credit_input_sys_rate"><![CDATA[Conversion rate]]></string>
     <string name="_bx_credits_form_credit_input_rate"><![CDATA[Conversion rate]]></string>
     <string name="_bx_credits_form_credit_input_sys_result"><![CDATA[Result]]></string>
@@ -141,6 +146,7 @@
     <string name="_bx_credits_grid_column_title_htr_direction"><![CDATA[Direction]]></string>
     <string name="_bx_credits_grid_column_title_htr_info"><![CDATA[Notice]]></string>
     <string name="_bx_credits_grid_column_title_htr_date"><![CDATA[Date]]></string>
+    <string name="_bx_credits_grid_column_title_htr_cleared"><![CDATA[Clearing]]></string>
     <string name="_bx_credits_grid_action_title_htr_grant"><![CDATA[Grant]]></string>
     <string name="_bx_credits_grid_action_title_htr_send"><![CDATA[Send]]></string>
     <string name="_bx_credits_grid_action_title_htr_withdraw_confirm"><![CDATA[Confirm withdraw]]></string>
@@ -236,6 +242,8 @@
     <string name="_bx_credits_err_profile_not_found"><![CDATA[Profile wasn't found.]]></string>
     <string name="_bx_credits_err_login_required"><![CDATA[Login required.]]></string>
     <string name="_bx_credits_err_low_balance"><![CDATA[Low balance.]]></string>
+    <string name="_bx_credits_err_withdraw_minimum"><![CDATA[Withdrawal less then {0} credits isn't available.]]></string>
+    <string name="_bx_credits_err_withdraw_remaining"><![CDATA[Minimum remaining balance after withdrawal should be more then {0} credits.]]></string>
     <string name="_bx_credits_err_cannot_update_balance"><![CDATA[Cannot update balance.]]></string>
     <string name="_bx_credits_err_cannot_send"><![CDATA[Cannot send message. Please report.]]></string>
     <string name="_bx_credits_err_cannot_perform_action"><![CDATA[Cannot perform the action. Please report.]]></string>

+ 3 - 0
modules/boonex/credits/install/sql/disable.sql

@@ -27,3 +27,6 @@ DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandler;
 
 -- EMAIL TEMPLATES
 DELETE FROM `sys_email_templates` WHERE `Module` = 'bx_credits';
+
+-- CRON
+DELETE FROM `sys_cron_jobs` WHERE `name` LIKE 'bx_credits_%';

+ 14 - 4
modules/boonex/credits/install/sql/enable.sql

@@ -12,6 +12,9 @@ SET @iCategId = LAST_INSERT_ID();
 INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `extra`, `order`) VALUES
 ('bx_credits_enable_withdraw', '', @iCategId, '_bx_credits_option_enable_withdraw', 'checkbox', '', '', '', 1),
 ('bx_credits_withdraw_email', '', @iCategId, '_bx_credits_option_withdraw_email', 'digit', '', '', '', 2),
+('bx_credits_withdraw_clearing', '30', @iCategId, '_bx_credits_option_withdraw_clearing', 'digit', '', '', '', 3),
+('bx_credits_withdraw_minimum', '500', @iCategId, '_bx_credits_option_withdraw_minimum', 'digit', '', '', '', 4),
+('bx_credits_withdraw_remaining', '100', @iCategId, '_bx_credits_option_withdraw_remaining', 'digit', '', '', '', 5),
 
 ('bx_credits_precision', '2', @iCategId, '_bx_credits_option_precision', 'digit', '', '', '', 10),
 ('bx_credits_conversion_rate_use', '1.0', @iCategId, '_bx_credits_option_conversion_rate_use', 'digit', '', '', '', 11),
@@ -171,15 +174,17 @@ INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable
 ('bx_credits_history_administration', 'second_pid', '_bx_credits_grid_column_title_htr_second_pid', '15%', 0, '', '', 3),
 ('bx_credits_history_administration', 'amount', '_bx_credits_grid_column_title_htr_amount', '10%', 1, '', '', 4),
 ('bx_credits_history_administration', 'order', '_bx_credits_grid_column_title_htr_order', '15%', 0, '16', '', 5),
-('bx_credits_history_administration', 'info', '_bx_credits_grid_column_title_htr_info', '20%', 1, '24', '', 6),
-('bx_credits_history_administration', 'date', '_bx_credits_grid_column_title_htr_date', '15%', 0, '', '', 7),
+('bx_credits_history_administration', 'info', '_bx_credits_grid_column_title_htr_info', '15%', 1, '24', '', 6),
+('bx_credits_history_administration', 'date', '_bx_credits_grid_column_title_htr_date', '10%', 0, '', '', 7),
+('bx_credits_history_administration', 'cleared', '_bx_credits_grid_column_title_htr_cleared', '10%', 0, '', '', 8),
 
 ('bx_credits_history_common', 'direction', '_bx_credits_grid_column_title_htr_direction', '10%', 0, '', '', 1),
 ('bx_credits_history_common', 'second_pid', '_bx_credits_grid_column_title_htr_pid', '25%', 0, '', '', 2),
 ('bx_credits_history_common', 'amount', '_bx_credits_grid_column_title_htr_amount', '15%', 1, '', '', 3),
 ('bx_credits_history_common', 'order', '_bx_credits_grid_column_title_htr_order', '15%', 0, '16', '', 4),
-('bx_credits_history_common', 'info', '_bx_credits_grid_column_title_htr_info', '20%', 1, '32', '', 5),
-('bx_credits_history_common', 'date', '_bx_credits_grid_column_title_htr_date', '15%', 0, '', '', 6);
+('bx_credits_history_common', 'info', '_bx_credits_grid_column_title_htr_info', '15%', 1, '32', '', 5),
+('bx_credits_history_common', 'date', '_bx_credits_grid_column_title_htr_date', '10%', 0, '', '', 6),
+('bx_credits_history_common', 'cleared', '_bx_credits_grid_column_title_htr_cleared', '10%', 0, '', '', 7);
 
 INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
 ('bx_credits_history_administration', 'independent', 'grant', '_bx_credits_grid_action_title_htr_grant', '', 0, 0, 1),
@@ -209,3 +214,8 @@ INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `B
 ('bx_credits', '_bx_credits_et_txt_name_out', 'bx_credits_out', '_bx_credits_et_txt_subject_out', '_bx_credits_et_txt_body_out'),
 ('bx_credits', '_bx_credits_et_txt_name_withdraw_requested', 'bx_credits_withdraw_requested', '_bx_credits_et_txt_subject_withdraw_requested', '_bx_credits_et_txt_body_withdraw_requested'),
 ('bx_credits', '_bx_credits_et_txt_name_withdraw_sent', 'bx_credits_withdraw_sent', '_bx_credits_et_txt_subject_withdraw_sent', '_bx_credits_et_txt_body_withdraw_sent');
+
+
+-- CRON
+INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VALUES
+('bx_credits_clearing', '0 0 * * *', 'BxCreditsCronClearing', 'modules/boonex/credits/classes/BxCreditsCronClearing.php', '');

+ 11 - 7
modules/boonex/credits/install/sql/install.sql

@@ -60,11 +60,13 @@ CREATE TABLE IF NOT EXISTS `bx_credits_history` (
   `first_pid` int(11) NOT NULL DEFAULT '0',
   `second_pid` int(11) NOT NULL DEFAULT '0',
   `amount` float NOT NULL DEFAULT '0',
+  `type` varchar(16) NOT NULL default '',
   `direction` enum('in', 'out') NOT NULL DEFAULT 'in',
   `order` varchar(32) NOT NULL default '',
   `data` text NOT NULL default '',
   `info` varchar(255) NOT NULL DEFAULT '',
   `date` int(11) NOT NULL DEFAULT '0',
+  `cleared` int(11) NOT NULL DEFAULT '0',
   PRIMARY KEY (`id`)
 );
 
@@ -81,6 +83,7 @@ INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`,
 
 INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES 
 ('bx_credits_credit', 'bx_credits', 'balance', '', '', 0, 'text', '_bx_credits_form_credit_input_sys_balance', '_bx_credits_form_credit_input_balance', '', 0, 0, 0, 'a:1:{s:8:"disabled";s:8:"disabled";}', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_credits_credit', 'bx_credits', 'cleared', '', '', 0, 'text', '_bx_credits_form_credit_input_sys_cleared', '_bx_credits_form_credit_input_cleared', '', 0, 0, 0, 'a:1:{s:8:"disabled";s:8:"disabled";}', '', '', '', '', '', 'Xss', '', 1, 0),
 ('bx_credits_credit', 'bx_credits', 'rate', '', '', 0, 'text', '_bx_credits_form_credit_input_sys_rate', '_bx_credits_form_credit_input_rate', '', 0, 0, 0, 'a:1:{s:8:"disabled";s:8:"disabled";}', '', '', '', '', '', 'Xss', '', 1, 0),
 ('bx_credits_credit', 'bx_credits', 'result', '', '', 0, 'text', '_bx_credits_form_credit_input_sys_result', '_bx_credits_form_credit_input_result', '', 0, 0, 0, 'a:1:{s:8:"disabled";s:8:"disabled";}', '', '', '', '', '', 'Xss', '', 1, 0),
 ('bx_credits_credit', 'bx_credits', 'amount', '', '', 0, 'text', '_bx_credits_form_credit_input_sys_amount', '_bx_credits_form_credit_input_amount', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_credits_form_credit_input_amount_err', 'Xss', '', 1, 0),
@@ -106,13 +109,14 @@ INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for
 ('bx_credits_credit_grant', 'do_cancel', 2147483647, 1, 6),
 
 ('bx_credits_credit_withdraw_request', 'balance', 2147483647, 1, 1),
-('bx_credits_credit_withdraw_request', 'rate', 2147483647, 1, 2),
-('bx_credits_credit_withdraw_request', 'amount', 2147483647, 1, 3),
-('bx_credits_credit_withdraw_request', 'result', 2147483647, 1, 4),
-('bx_credits_credit_withdraw_request', 'message', 2147483647, 1, 5),
-('bx_credits_credit_withdraw_request', 'controls', 2147483647, 1, 6),
-('bx_credits_credit_withdraw_request', 'do_submit', 2147483647, 1, 7),
-('bx_credits_credit_withdraw_request', 'do_cancel', 2147483647, 1, 8),
+('bx_credits_credit_withdraw_request', 'cleared', 2147483647, 1, 2),
+('bx_credits_credit_withdraw_request', 'rate', 2147483647, 1, 3),
+('bx_credits_credit_withdraw_request', 'amount', 2147483647, 1, 4),
+('bx_credits_credit_withdraw_request', 'result', 2147483647, 1, 5),
+('bx_credits_credit_withdraw_request', 'message', 2147483647, 1, 6),
+('bx_credits_credit_withdraw_request', 'controls', 2147483647, 1, 7),
+('bx_credits_credit_withdraw_request', 'do_submit', 2147483647, 1, 8),
+('bx_credits_credit_withdraw_request', 'do_cancel', 2147483647, 1, 9),
 
 ('bx_credits_credit_withdraw_confirm', 'profile', 2147483647, 1, 1),
 ('bx_credits_credit_withdraw_confirm', 'amount', 2147483647, 1, 2),

+ 8 - 0
modules/boonex/russian/data/langs/bx_credits/ru.xml

@@ -6,6 +6,9 @@
     <!-- Options -->
     <string name="_bx_credits_option_enable_withdraw"><![CDATA[Позволить пользователям снимать кредиты, конвертируя их в деньги]]></string>
     <string name="_bx_credits_option_withdraw_email"><![CDATA[Email, на который будут приходить запросы на снятие]]></string>
+    <string name="_bx_credits_option_withdraw_clearing"><![CDATA[Промежуток времени (в днях), в течение которого полученные кредиты не могут быть сняты]]></string>
+    <string name="_bx_credits_option_withdraw_minimum"><![CDATA[Минимальная сумма очищенных кредитов, которая может быть снята]]></string>
+    <string name="_bx_credits_option_withdraw_remaining"><![CDATA[Минимальный баланс кредитов после снятия]]></string>
     <string name="_bx_credits_option_precision"><![CDATA[Точность (количество цифр после десятичной точки)]]></string>
     <string name="_bx_credits_option_conversion_rate_use"><![CDATA[Коэффициент конвертации для оплаты кредитами]]></string>
     <string name="_bx_credits_option_conversion_rate_withdraw"><![CDATA[Коэффициент конвертации для снятия кредитов]]></string>
@@ -44,6 +47,8 @@
     <string name="_bx_credits_form_credit_display_withdraw_confirm"><![CDATA[Подтвердить снятие]]></string>
     <string name="_bx_credits_form_credit_input_sys_balance"><![CDATA[Баланс]]></string>
     <string name="_bx_credits_form_credit_input_balance"><![CDATA[Баланс]]></string>
+    <string name="_bx_credits_form_credit_input_sys_cleared"><![CDATA[Очищенный баланс]]></string>
+    <string name="_bx_credits_form_credit_input_cleared"><![CDATA[Очищенный баланс]]></string>
     <string name="_bx_credits_form_credit_input_sys_rate"><![CDATA[Коэффициент конвертации]]></string>
     <string name="_bx_credits_form_credit_input_rate"><![CDATA[Коэффициент конвертации]]></string>
     <string name="_bx_credits_form_credit_input_sys_result"><![CDATA[Результат]]></string>
@@ -141,6 +146,7 @@
     <string name="_bx_credits_grid_column_title_htr_direction"><![CDATA[Направление]]></string>
     <string name="_bx_credits_grid_column_title_htr_info"><![CDATA[Пометка]]></string>
     <string name="_bx_credits_grid_column_title_htr_date"><![CDATA[Дата]]></string>
+    <string name="_bx_credits_grid_column_title_htr_cleared"><![CDATA[Очищение]]></string>
     <string name="_bx_credits_grid_action_title_htr_grant"><![CDATA[Подарить]]></string>
     <string name="_bx_credits_grid_action_title_htr_send"><![CDATA[Отправить]]></string>
     <string name="_bx_credits_grid_action_title_htr_withdraw_confirm"><![CDATA[Подтвердить снятие]]></string>
@@ -235,6 +241,8 @@
     <string name="_bx_credits_err_profile_not_found"><![CDATA[Профиль не был найден.]]></string>
     <string name="_bx_credits_err_login_required"><![CDATA[Необходимо войти.]]></string>
     <string name="_bx_credits_err_low_balance"><![CDATA[Недостаточно средств на балансе.]]></string>
+    <string name="_bx_credits_err_withdraw_minimum"><![CDATA[Вывод менее {0} кредитов недоступен.]]></string>
+    <string name="_bx_credits_err_withdraw_remaining"><![CDATA[Минимальный остаток на счете после вывода должен быть более {0} кредитов.]]></string>
     <string name="_bx_credits_err_cannot_update_balance"><![CDATA[Невозможно обновить баланс.]]></string>
     <string name="_bx_credits_err_cannot_send"><![CDATA[Невозможно отправить сообщение. Пожалуйста, оповестите нас об этой проблеме.]]></string>
     <string name="_bx_credits_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие. Пожалуйста, оповестите нас об этой проблеме.]]></string>