From c00b6d6757a051a786ab97eb8bbeeddf9698ea5c Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 31 Jan 2014 14:51:00 +0100 Subject: [PATCH] [IMPROVED] Payout logics * [ADDED] More methods to our transaction class * `createDebitAPRecord` and `createDebitMPRecord`, will handle the * entire debit process * Adds Debit transaction * Adds TXFee transaction * mark transactions as archived * validate user is fully paid out * send notification to user * `getMPQueue` was added to unify the process of getting payout queues * [MOVED] Only one mail template for both payout methods * [ADDED] Some minor calls to user class * [ADDED] Full address validation to bitcoin class * [SQL] New SQL upgrade and Version Increment * Adding UNIQUE index to coin_address in accounts table * preperation for `sendmany` implementation --- cronjobs/payouts.php | 218 +++++------------- public/include/classes/base.class.php | 6 + public/include/classes/bitcoin.class.php | 12 + public/include/classes/payout.class.php | 12 - public/include/classes/transaction.class.php | 95 +++++++- public/include/classes/user.class.php | 20 +- public/include/version.inc.php | 2 +- .../mail/notifications/manual_payout.tpl | 8 - .../{auto_payout.tpl => payout.tpl} | 2 +- sql/015_accounts_update.sql | 2 + 10 files changed, 195 insertions(+), 182 deletions(-) delete mode 100644 public/templates/mail/notifications/manual_payout.tpl rename public/templates/mail/notifications/{auto_payout.tpl => payout.tpl} (52%) create mode 100644 sql/015_accounts_update.sql diff --git a/cronjobs/payouts.php b/cronjobs/payouts.php index 821ac8eb..908734ee 100755 --- a/cronjobs/payouts.php +++ b/cronjobs/payouts.php @@ -34,169 +34,77 @@ if ($bitcoin->can_connect() !== true) { $log->logFatal(" unable to connect to RPC server, exiting"); $monitoring->endCronjob($cron_name, 'E0006', 1, true); } -if ($setting->getValue('disable_manual_payouts') != 1) { - // Fetch outstanding payout requests - if ($aPayouts = $oPayout->getUnprocessedPayouts()) { - if (count($aPayouts) > 0) { - $log->logInfo("\tStarting Manual Payments..."); - $log->logInfo("\tAccount ID\tUsername\tBalance\t\tCoin Address"); - foreach ($aPayouts as $aData) { - $transaction_id = NULL; - $rpc_txid = NULL; - $aBalance = $transaction->getBalance($aData['account_id']); - $dBalance = $aBalance['confirmed']; - $aData['coin_address'] = $user->getCoinAddress($aData['account_id']); - $aData['username'] = $user->getUserName($aData['account_id']); - // Validate address against RPC - try { - $aStatus = $bitcoin->validateaddress($aData['coin_address']); - if (!$aStatus['isvalid']) { - $log->logError('User: ' . $aData['username'] . ' - Failed to verify this users coin address, skipping payout'); - continue; - } - } catch (Exception $e) { - $log->logError('User: ' . $aData['username'] . ' - Failed to verify this users coin address, skipping payout'); - continue; - } - if ($dBalance > $config['txfee_manual']) { - // To ensure we don't run this transaction again, lets mark it completed - if (!$oPayout->setProcessed($aData['id'])) { - $log->logFatal('unable to mark transactions ' . $aData['id'] . ' as processed. ERROR: ' . $oPayout->getCronError()); - $monitoring->endCronjob($cron_name, 'E0010', 1, true); - } - $log->logInfo("\t" . $aData['account_id'] . "\t\t" . $aData['username'] . "\t" . $dBalance . "\t\t" . $aData['coin_address']); - if ($transaction->addTransaction($aData['account_id'], $dBalance - $config['txfee_manual'], 'Debit_MP', NULL, $aData['coin_address'], NULL)) { - // Store debit transaction ID for later update - $transaction_id = $transaction->insert_id; - if (!$transaction->addTransaction($aData['account_id'], $config['txfee_manual'], 'TXFee', NULL, $aData['coin_address'])) - $log->logError('Failed to add TXFee record: ' . $transaction->getCronError()); - // Mark all older transactions as archived - if (!$transaction->setArchived($aData['account_id'], $transaction->insert_id)) - $log->logError('Failed to mark transactions for #' . $aData['account_id'] . ' prior to #' . $transaction->insert_id . ' as archived. ERROR: ' . $transaction->getCronError()); - // Run the payouts from RPC now that the user is fully debited - try { - $rpc_txid = $bitcoin->sendtoaddress($aData['coin_address'], $dBalance - $config['txfee_manual']); - } catch (Exception $e) { - $log->logError('E0078: RPC method did not return 200 OK: Address: ' . $aData['coin_address'] . ' ERROR: ' . $e->getMessage()); - // Remove this line below if RPC calls are failing but transactions are still added to it - // Don't blame MPOS if you run into issues after commenting this out! - $monitoring->endCronjob($cron_name, 'E0078', 1, true); - } - // Update our transaction and add the RPC Transaction ID - if (empty($rpc_txid) || !$transaction->setRPCTxId($transaction_id, $rpc_txid)) - $log->logError('Unable to add RPC transaction ID ' . $rpc_txid . ' to transaction record ' . $transaction_id . ': ' . $transaction->getCronError()); - // Notify user via mail - $aMailData['email'] = $user->getUserEmail($user->getUserName($aData['account_id'])); - $aMailData['subject'] = 'Manual Payout Completed'; - $aMailData['amount'] = $dBalance - $config['txfee_manual']; - $aMailData['payout_id'] = $aData['id']; - if (!$notification->sendNotification($aData['account_id'], 'manual_payout', $aMailData)) - $log->logError('Failed to send notification email to users address: ' . $aMailData['email'] . 'ERROR: ' . $notification->getCronError()); - // Recheck the users balance to make sure it is now 0 - if (!$aBalance = $transaction->getBalance($aData['account_id'])) { - $log->logFatal('Failed to fetch balance for account ' . $aData['account_id'] . '. ERROR: ' . $transaction->getCronError()); - $monitoring->endCronjob($cron_name, 'E0065', 1, true); - } - if ($aBalance['confirmed'] > 0) { - $log->logFatal('User has a remaining balance of ' . $aBalance['confirmed'] . ' after a successful payout!'); - $monitoring->endCronjob($cron_name, 'E0065', 1, true); - } - } else { - $log->logFatal('Failed to add new Debit_MP transaction in database for user ' . $user->getUserName($aData['account_id']) . ' ERROR: ' . $transaction->getCronError()); - $monitoring->endCronjob($cron_name, 'E0064', 1, true); - } - } - } +// Fetch our manual payouts, process them +if ($setting->getValue('disable_manual_payouts') != 1 && $aManualPayouts = $transaction->getMPQueue()) { + $log->logInfo(' found ' . count($aManualPayouts) . ' queued manual payouts'); + $mask = ' | %-10.10s | %-25.25s | %-20.20s | %-40.40s | %-20.20s |'; + $log->logInfo(sprintf($mask, 'UserID', 'Username', 'Balance', 'Address', 'Payout ID')); + foreach ($aManualPayouts as $aUserData) { + $transaction_id = NULL; + $rpc_txid = NULL; + $log->logInfo(sprintf($mask, $aUserData['id'], $aUserData['username'], $aUserData['confirmed'], $aUserData['coin_address'], $aUserData['payout_id'])); + if (!$oPayout->setProcessed($aUserData['payout_id'])) { + $log->logFatal(' unable to mark transactions ' . $aData['id'] . ' as processed. ERROR: ' . $oPayout->getCronError()); + $monitoring->endCronjob($cron_name, 'E0010', 1, true); } - } else if (empty($aPayouts)) { - $log->logInfo("\tStopping Payments. No Payout Requests Found."); - } else { - $log->logFatal("\tFailed Processing Manual Payment Queue...Aborting..."); - $monitoring->endCronjob($cron_name, 'E0050', 1, true); - } - if (count($aPayouts > 0)) $log->logDebug(" found " . count($aPayouts) . " queued manual payout requests"); -} else { - $log->logDebug("Manual payouts are disabled via admin panel"); -} -if ($setting->getValue('disable_auto_payouts') != 1) { - // Fetch all users balances - if ($users = $transaction->getAPQueue()) { - if (!empty($users)) { - if (count($users) > 0) $log->logDebug(" found " . count($users) . " queued payout(s)"); - // Go through users and run transactions - $log->logInfo("Starting Payments..."); - $log->logInfo("\tUserID\tUsername\tBalance\tThreshold\tAddress"); - foreach ($users as $aUserData) { - $transaction_id = NULL; - $rpc_txid = NULL; - $dBalance = $aUserData['confirmed']; - // Validate address against RPC + if ($bitcoin->validateaddress($aUserData['coin_address'])) { + if (!$transaction_id = $transaction->createDebitAPRecord($aUserData['id'], $aUserData['coin_address'], $aUserData['confirmed'] - $config['txfee_manual'])) { + $log->logFatal(' failed to fullt debit user ' . $aUserData['username'] . ': ' . $transaction->getCronError()); + $monitoring->endCronjob($cron_name, 'E0064', 1, true); + } else { + // Run the payouts from RPC now that the user is fully debited try { - $aStatus = $bitcoin->validateaddress($aUserData['coin_address']); - if (!$aStatus['isvalid']) { - $log->logError('User: ' . $aUserData['username'] . ' - Failed to verify this users coin address, skipping payout'); - continue; - } + $rpc_txid = $bitcoin->sendtoaddress($aUserData['coin_address'], $aUserData['confirmed'] - $config['txfee_manual']); } catch (Exception $e) { - $log->logError('User: ' . $aUserData['username'] . ' - Failed to verify this users coin address, skipping payout'); - continue; - } - $log->logInfo("\t" . $aUserData['id'] . "\t" . $aUserData['username'] . "\t" . $dBalance . "\t" . $aUserData['ap_threshold'] . "\t\t" . $aUserData['coin_address']); - // Only run if balance meets threshold and can pay the potential transaction fee - if ($dBalance > $aUserData['ap_threshold'] && $dBalance > $config['txfee_auto']) { - // Create transaction record - if ($transaction->addTransaction($aUserData['id'], $dBalance - $config['txfee_auto'], 'Debit_AP', NULL, $aUserData['coin_address'], NULL)) { - // Store debit ID for later update - $transaction_id = $transaction->insert_id; - if (!$transaction->addTransaction($aUserData['id'], $config['txfee_auto'], 'TXFee', NULL, $aUserData['coin_address'])) - $log->logError('Failed to add TXFee record: ' . $transaction->getCronError()); - // Mark all older transactions as archived - if (!$transaction->setArchived($aUserData['id'], $transaction->insert_id)) - $log->logError('Failed to mark transactions for user #' . $aUserData['id'] . ' prior to #' . $transaction->insert_id . ' as archived. ERROR: ' . $transaction->getCronError()); - // Run the payouts from RPC now that the user is fully debited - try { - $rpc_txid = $bitcoin->sendtoaddress($aUserData['coin_address'], $dBalance - $config['txfee_auto']); - } catch (Exception $e) { - $log->logError('E0078: RPC method did not return 200 OK: Address: ' . $aUserData['coin_address'] . ' ERROR: ' . $e->getMessage()); - // Remove this line below if RPC calls are failing but transactions are still added to it - // Don't blame MPOS if you run into issues after commenting this out! - $monitoring->endCronjob($cron_name, 'E0078', 1, true); - } - // Update our transaction and add the RPC Transaction ID - if (empty($rpc_txid) || !$transaction->setRPCTxId($transaction_id, $rpc_txid)) - $log->logError('Unable to add RPC transaction ID ' . $rpc_txid . ' to transaction record ' . $transaction_id . ': ' . $transaction->getCronError()); - // Notify user via mail - $aMailData['email'] = $user->getUserEmail($user->getUserName($aUserData['id'])); - $aMailData['subject'] = 'Auto Payout Completed'; - $aMailData['amount'] = $dBalance - $config['txfee_auto']; - if (!$notification->sendNotification($aUserData['id'], 'auto_payout', $aMailData)) - $log->logError('Failed to send notification email to users address: ' . $aMailData['email'] . ' ERROR: ' . $notification->getCronError()); - // Recheck the users balance to make sure it is now 0 - $aBalance = $transaction->getBalance($aUserData['id']); - if ($aBalance['confirmed'] > 0) { - $log->logFatal('User has a remaining balance of ' . $aBalance['confirmed'] . ' after a successful payout!'); - $monitoring->endCronjob($cron_name, 'E0065', 1, true); - } - } else { - $log->logFatal('Failed to add new Debit_AP transaction in database for user ' . $user->getUserName($aUserData['id']) . ' ERROR: ' . $transaction->getCronError()); - $monitoring->endCronjob($cron_name, 'E0064', 1, true); - } + $log->logError('E0078: RPC method did not return 200 OK: Address: ' . $aUserData['coin_address'] . ' ERROR: ' . $e->getMessage()); + // Remove this line below if RPC calls are failing but transactions are still added to it + // Don't blame MPOS if you run into issues after commenting this out! + $monitoring->endCronjob($cron_name, 'E0078', 1, true); } + // Update our transaction and add the RPC Transaction ID + if (empty($rpc_txid) || !$transaction->setRPCTxId($transaction_id, $rpc_txid)) + $log->logError('Unable to add RPC transaction ID ' . $rpc_txid . ' to transaction record ' . $transaction_id . ': ' . $transaction->getCronError()); } + } else { + $log->logInfo(' failed to validate address for user: ' . $aUserData['username']); + continue; + } + } +} + +// Fetch our auto payouts, process them +if ($setting->getValue('disable_auto_payouts') != 1 && $aAutoPayouts = $transaction->getAPQueue()) { + $log->logInfo(' found ' . count($aAutoPayouts) . ' queued auto payouts'); + $mask = ' | %-10.10s | %-25.25s | %-20.20s | %-40.40s | %-20.20s |'; + $log->logInfo(sprintf($mask, 'UserID', 'Username', 'Balance', 'Address', 'Threshold')); + foreach ($aAutoPayouts as $aUserData) { + $transaction_id = NULL; + $rpc_txid = NULL; + $log->logInfo(sprintf($mask, $aUserData['id'], $aUserData['username'], $aUserData['confirmed'], $aUserData['coin_address'], $aUserData['ap_threshold'])); + if ($bitcoin->validateaddress($aUserData['coin_address'])) { + if (!$transaction_id = $transaction->createDebitAPRecord($aUserData['id'], $aUserData['coin_address'], $aUserData['confirmed'] - $config['txfee_manual'])) { + $log->logFatal(' failed to fully debit user ' . $aUserData['username'] . ': ' . $transaction->getCronError()); + $monitoring->endCronjob($cron_name, 'E0064', 1, true); + } else { + // Run the payouts from RPC now that the user is fully debited + try { + $rpc_txid = $bitcoin->sendtoaddress($aUserData['coin_address'], $aUserData['confirmed'] - $config['txfee_manual']); + } catch (Exception $e) { + $log->logError('E0078: RPC method did not return 200 OK: Address: ' . $aUserData['coin_address'] . ' ERROR: ' . $e->getMessage()); + // Remove this line below if RPC calls are failing but transactions are still added to it + // Don't blame MPOS if you run into issues after commenting this out! + $monitoring->endCronjob($cron_name, 'E0078', 1, true); + } + // Update our transaction and add the RPC Transaction ID + if (empty($rpc_txid) || !$transaction->setRPCTxId($transaction_id, $rpc_txid)) + $log->logError('Unable to add RPC transaction ID ' . $rpc_txid . ' to transaction record ' . $transaction_id . ': ' . $transaction->getCronError()); + } + } else { + $log->logInfo(' failed to validate address for user: ' . $aUserData['username']); + continue; } - } else if(empty($users)) { - $log->logInfo("\tSkipping payments. No Auto Payments Eligible."); - $log->logDebug("Users have not configured their AP > 0"); - } else{ - $log->logFatal("\tFailed Processing Auto Payment Payment Queue. ERROR: " . $transaction->getCronError()); - $monitoring->endCronjob($cron_name, 'E0050', 1, true); } -} else { - $log->logDebug("Auto payouts disabled via admin panel"); } -$log->logInfo("Completed Payouts"); -// Cron cleanup and monitoring require_once('cron_end.inc.php'); -?> diff --git a/public/include/classes/base.class.php b/public/include/classes/base.class.php index 385474f2..4971ad17 100644 --- a/public/include/classes/base.class.php +++ b/public/include/classes/base.class.php @@ -52,6 +52,12 @@ class Base { public function setBlock($block) { $this->block = $block; } + public function setPayout($payout) { + $this->payout = $payout; + } + public function setNotification($notification) { + $this->notification = $notification; + } public function setTransaction($transaction) { $this->transaction = $transaction; } diff --git a/public/include/classes/bitcoin.class.php b/public/include/classes/bitcoin.class.php index 01b2a71d..11e82f70 100644 --- a/public/include/classes/bitcoin.class.php +++ b/public/include/classes/bitcoin.class.php @@ -296,4 +296,16 @@ class BitcoinClient extends jsonRPCClient { } return true; } + + public function validateaddress($coin_address) { + try { + $aStatus = parent::validateaddress($coin_address); + if (!$aStatus['isvalid']) { + return false; + } + } catch (Exception $e) { + return false; + } + return true; + } } diff --git a/public/include/classes/payout.class.php b/public/include/classes/payout.class.php index 5255dbde..34446a83 100644 --- a/public/include/classes/payout.class.php +++ b/public/include/classes/payout.class.php @@ -16,18 +16,6 @@ class Payout Extends Base { return $this->sqlError('E0048'); } - /** - * Get all new, unprocessed payout requests - * @param none - * @return data Associative array with DB Fields - **/ - public function getUnprocessedPayouts() { - $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE completed = 0"); - if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) - return $result->fetch_all(MYSQLI_ASSOC); - return $this->sqlError('E0050'); - } - /** * Insert a new payout request * @param account_id int Account ID diff --git a/public/include/classes/transaction.class.php b/public/include/classes/transaction.class.php index 24fe9034..1306a470 100644 --- a/public/include/classes/transaction.class.php +++ b/public/include/classes/transaction.class.php @@ -312,21 +312,110 @@ class Transaction extends Base { ON t.account_id = a.id WHERE t.archived = 0 AND a.ap_threshold > 0 AND a.coin_address IS NOT NULL AND a.coin_address != '' GROUP BY t.account_id - HAVING confirmed > a.ap_threshold - "); + HAVING confirmed > a.ap_threshold AND confirmed > " . $this->config['txfee_auto']); if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) return $result->fetch_all(MYSQLI_ASSOC); return $this->sqlError(); } + + + /** + * Debit a user account + * @param account_id int Account ID + * @param coin_address string Coin Address + * @param amount float Balance to record + * @return int Debit transaction ID or false + **/ + public function createDebitMPRecord($account_id, $coin_address, $amount) { + return $this->createDebitRecord($account_id, $coin_address, $amount, 'Debit_MP'); + } + public function createDebitAPRecord($account_id, $coin_address, $amount) { + return $this->createDebitRecord($account_id, $coin_address, $amount, 'Debit_AP'); + } + private function createDebitRecord($account_id, $coin_address, $amount, $type) { + $type == 'Debit_MP' ? $txfee = $this->config['txfee_manual'] : $txfee = $this->config['txfee_auto']; + // Add Debit record + if (!$this->addTransaction($account_id, $amount, $type, NULL, $coin_address, NULL)) { + $this->setErrorMessage('Failed to create ' . $type . ' transaction record in database'); + return false; + } + // Fetch the inserted record ID so we can return this at the end + $transaction_id = $this->insert_id; + // Add TXFee record + if (!$this->addTransaction($account_id, $txfee, 'TXFee', NULL, $coin_address)) { + $this->setErrorMessage('Failed to create TXFee transaction record in database: ' . $this->getError()); + return false; + } + // Mark transactions archived + if (!$this->setArchived($account_id, $this->insert_id)) { + $this->setErrorMessage('Failed to mark transactions <= #' . $this->insert_id . ' as archived. ERROR: ' . $this->getError()); + return false; + } + // Recheck the users balance to make sure it is now 0 + if (!$aBalance = $this->getBalance($account_id)) { + $this->setErrorMessage('Failed to fetch balance for account ' . $account_id . '. ERROR: ' . $this->getCronError()); + return false; + } + if ($aBalance['confirmed'] > 0) { + $this->setErrorMessage('User has a remaining balance of ' . $aBalance['confirmed'] . ' after a successful payout!'); + return false; + } + // Notify user via mail + $aMailData['email'] = $this->user->getUserEmailById($account_id); + $aMailData['subject'] = $type . ' Completed'; + $aMailData['amount'] = $amount - $txfee; + if (!$this->notification->sendNotification($account_id, 'payout', $aMailData)) { + $this->setErrorMessage('Failed to send notification email to users address: ' . $aMailData['email'] . 'ERROR: ' . $this->notification->getCronError()); + } + return $transaction_id; + } + + /** + * Get all new, unprocessed manual payout requests + * @param none + * @return data Associative array with DB Fields + **/ + public function getMPQueue() { + $stmt = $this->mysqli->prepare(" + SELECT + a.id, + a.username, + a.ap_threshold, + a.coin_address, + p.id AS payout_id, + IFNULL( + ROUND( + ( + SUM( IF( ( t.type IN ('Credit','Bonus') AND b.confirmations >= " . $this->config['confirmations'] . ") OR t.type = 'Credit_PPS', t.amount, 0 ) ) - + SUM( IF( t.type IN ('Debit_MP', 'Debit_AP'), t.amount, 0 ) ) - + SUM( IF( ( t.type IN ('Donation','Fee') AND b.confirmations >= " . $this->config['confirmations'] . ") OR ( t.type IN ('Donation_PPS', 'Fee_PPS', 'TXFee') ), t.amount, 0 ) ) + ), 8 + ), 0 + ) AS confirmed + FROM " . $this->payout->getTableName() . " AS p + JOIN " . $this->user->getTableName() . " AS a + ON p.account_id = a.id + JOIN " . $this->getTableName() . " AS t + ON t.account_id = p.account_id + JOIN " . $this->block->getTableName() . " AS b + ON t.block_id = b.id + WHERE p.completed = 0 AND t.archived = 0 AND a.coin_address IS NOT NULL AND a.coin_address != '' + GROUP BY t.account_id + HAVING confirmed > " . $this->config['txfee_manual']); + if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) + return $result->fetch_all(MYSQLI_ASSOC); + return $this->sqlError('E0050'); + } } $transaction = new Transaction(); $transaction->setMemcache($memcache); +$transaction->setNotification($notification); $transaction->setDebug($debug); $transaction->setMysql($mysqli); $transaction->setConfig($config); $transaction->setBlock($block); $transaction->setUser($user); +$transaction->setPayout($oPayout); $transaction->setErrorCodes($aErrorCodes); - ?> diff --git a/public/include/classes/user.class.php b/public/include/classes/user.class.php index 7c012d92..91aad4d8 100644 --- a/public/include/classes/user.class.php +++ b/public/include/classes/user.class.php @@ -25,8 +25,8 @@ class User extends Base { public function getUserEmail($username, $lower=false) { return $this->getSingle($username, 'email', 'username', 's', $lower); } - public function getUserNotifyEmail($username, $lower=false) { - return $this->getSingle($username, 'notify_email', 'username', 's', $lower); + public function getUserEmailById($id) { + return $this->getSingle($id, 'email', 'id', 'i'); } public function getUserNoFee($id) { return $this->getSingle($id, 'no_fees', 'id'); @@ -280,6 +280,16 @@ class User extends Base { return $this->getSingle($userID, 'coin_address', 'id'); } + /** + * Check if a coin address exists already + * @param address string Coin Address + * @return bool True of false + **/ + public function existsCoinAddress($address) { + $this->debug->append("STA " . __METHOD__, 4); + return $this->getSingle($address, 'coin_address', 'coin_address') === $address; + } + /** * Fetch users donation value * @param userID int UserID @@ -413,6 +423,10 @@ class User extends Base { return false; } if (!empty($address)) { + if ($this->existsCoinAddress($address)) { + $this->setErrorMessage('Address is already in use'); + return false; + } if ($this->bitcoin->can_connect() === true) { try { $aStatus = $this->bitcoin->validateaddress($address); @@ -428,6 +442,8 @@ class User extends Base { $this->setErrorMessage('Unable to connect to RPC server for coin address validation'); return false; } + } else { + $address = NULL; } // Number sanitizer, just in case we fall through above diff --git a/public/include/version.inc.php b/public/include/version.inc.php index c6204c76..6d4cc3a6 100644 --- a/public/include/version.inc.php +++ b/public/include/version.inc.php @@ -2,7 +2,7 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1; define('MPOS_VERSION', '0.0.3'); -define('DB_VERSION', '0.0.4'); +define('DB_VERSION', '0.0.5'); define('CONFIG_VERSION', '0.0.7'); // Fetch installed database version diff --git a/public/templates/mail/notifications/manual_payout.tpl b/public/templates/mail/notifications/manual_payout.tpl deleted file mode 100644 index 32253718..00000000 --- a/public/templates/mail/notifications/manual_payout.tpl +++ /dev/null @@ -1,8 +0,0 @@ - - -

An manual payout request completed.

-

Amount: {nocache}{$DATA.amount}{/nocache}

-
-
- - diff --git a/public/templates/mail/notifications/auto_payout.tpl b/public/templates/mail/notifications/payout.tpl similarity index 52% rename from public/templates/mail/notifications/auto_payout.tpl rename to public/templates/mail/notifications/payout.tpl index e8519acc..a5713b95 100644 --- a/public/templates/mail/notifications/auto_payout.tpl +++ b/public/templates/mail/notifications/payout.tpl @@ -1,6 +1,6 @@ -

An automated payout completed.

+

You account has been debited and the coins have been sent to your wallet.

Amount: {nocache}{$DATA.amount}{/nocache}



diff --git a/sql/015_accounts_update.sql b/sql/015_accounts_update.sql new file mode 100644 index 00000000..a6e3a978 --- /dev/null +++ b/sql/015_accounts_update.sql @@ -0,0 +1,2 @@ +ALTER TABLE `accounts` ADD UNIQUE INDEX ( `coin_address` ) ; +INSERT INTO `settings` (`name`, `value`) VALUES ('DB_VERSION', '0.0.5') ON DUPLICATE KEY UPDATE `value` = '0.0.5';