diff --git a/public/include/classes/roundstats.class.php b/public/include/classes/roundstats.class.php
index 45dbb7ea..efe2e161 100644
--- a/public/include/classes/roundstats.class.php
+++ b/public/include/classes/roundstats.class.php
@@ -225,6 +225,97 @@ class RoundStats {
return false;
}
+ /**
+ * Get ALL last blocks from height for admin panel
+ **/
+ public function getAllReportBlocksFoundHeight($iHeight=0, $limit=10) {
+ $stmt = $this->mysqli->prepare("
+ SELECT
+ height, shares
+ FROM $this->tableBlocks
+ WHERE height <= ?
+ ORDER BY height DESC LIMIT ?");
+ if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $iHeight, $limit) && $stmt->execute() && $result = $stmt->get_result())
+ return $result->fetch_all(MYSQLI_ASSOC);
+ return false;
+ }
+
+ /**
+ * Get USER last blocks from height for admin panel
+ **/
+ public function getUserReportBlocksFoundHeight($iHeight=0, $limit=10, $iUser) {
+ $stmt = $this->mysqli->prepare("
+ SELECT
+ b.height, b.shares
+ FROM $this->tableBlocks AS b
+ LEFT JOIN $this->tableStats AS s ON s.block_id = b.id
+ LEFT JOIN $this->tableUsers AS a ON a.id = s.account_id
+ WHERE b.height <= ? AND a.id = ?
+ ORDER BY height DESC LIMIT ?");
+ if ($this->checkStmt($stmt) && $stmt->bind_param('iii', $iHeight, $iUser, $limit) && $stmt->execute() && $result = $stmt->get_result())
+ return $result->fetch_all(MYSQLI_ASSOC);
+ return false;
+ }
+
+ /**
+ * Get shares for block height for user admin panel
+ **/
+ public function getRoundStatsForUser($iHeight=0, $iUser) {
+ $stmt = $this->mysqli->prepare("
+ SELECT
+ s.valid,
+ s.invalid,
+ s.pplns_valid,
+ s.pplns_invalid
+ FROM $this->tableStats AS s
+ LEFT JOIN $this->tableBlocks AS b ON s.block_id = b.id
+ LEFT JOIN $this->tableUsers AS a ON a.id = s.account_id
+ WHERE b.height = ? AND a.id = ?");
+ if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $iUser) && $stmt->execute() && $result = $stmt->get_result())
+ return $result->fetch_assoc();
+ return false;
+ }
+
+ /**
+ * Get credit transactions for round block height for admin panel
+ **/
+ public function getUserRoundTransHeight($iHeight=0, $iUser) {
+ $this->debug->append("STA " . __METHOD__, 4);
+ $stmt = $this->mysqli->prepare("
+ SELECT
+ IFNULL(t.amount, 0) AS amount
+ FROM $this->tableTrans AS t
+ LEFT JOIN $this->tableBlocks AS b ON t.block_id = b.id
+ LEFT JOIN $this->tableUsers AS a ON t.account_id = a.id
+ WHERE b.height = ? AND t.type = 'Credit' AND t.account_id = ?");
+ if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $iUser) && $stmt->execute() && $result = $stmt->get_result())
+ return $result->fetch_object()->amount;
+ $this->debug->append('Unable to fetch transactions');
+ return false;
+ }
+
+ /**
+ * Get all users for admin panel
+ **/
+ public function getAllUsers($filter='%') {
+ $this->debug->append("STA " . __METHOD__, 4);
+ $stmt = $this->mysqli->prepare("
+ SELECT
+ a.id AS id,
+ a.username AS username
+ FROM $this->tableUsers AS a
+ WHERE a.username LIKE ?
+ GROUP BY username
+ ORDER BY username");
+ if ($this->checkStmt($stmt) && $stmt->bind_param('s', $filter) && $stmt->execute() && $result = $stmt->get_result()) {
+ while ($row = $result->fetch_assoc()) {
+ $aData[$row['id']] = $row['username'];
+ }
+ return $aData;
+ }
+ return false;
+ }
+
private function checkStmt($bState) {
if ($bState ===! true) {
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
diff --git a/public/include/pages/admin/reports.inc.php b/public/include/pages/admin/reports.inc.php
new file mode 100644
index 00000000..1ce870f4
--- /dev/null
+++ b/public/include/pages/admin/reports.inc.php
@@ -0,0 +1,86 @@
+isAuthenticated() || !$user->isAdmin($_SESSION['USERDATA']['id'])) {
+ header("HTTP/1.1 404 Page not found");
+ die("404 Page not found");
+}
+
+if (!$smarty->isCached('master.tpl', $smarty_cache_key)) {
+ $debug->append('No cached version available, fetching from backend', 3);
+
+ $aUserList = $roundstats->getAllUsers('%');
+
+ $iHeight = 0;
+ $iUserId = 0;
+ $filter = 0;
+ $userName = 'None';
+ if (@$_REQUEST['id']) {
+ $iUserId = $_REQUEST['id'];
+ $userName = $user->getUserName($_REQUEST['id']);
+ }
+
+ $setting->getValue('statistics_block_count') ? $iLimit = $setting->getValue('statistics_block_count') : $iLimit = 20;
+ if (@$_REQUEST['limit']) {
+ $iLimit = $_REQUEST['limit'];
+ if ( $iLimit > 1000 )
+ $iLimit = 1000;
+ }
+
+ if (@$_REQUEST['next'] && !empty($_REQUEST['height'])) {
+ $iHeight = @$roundstats->getNextBlockForStats($_REQUEST['height'], $iLimit);
+ if (!$iHeight) {
+ $aBlock = $block->getLast();
+ $iHeight = $aBlock['height'];
+ }
+ } else if (@$_REQUEST['prev'] && !empty($_REQUEST['height'])) {
+ $iHeight = $_REQUEST['height'];
+ } else if (!empty($_REQUEST['height']) && is_numeric($_REQUEST['height'])) {
+ $iHeight = $_REQUEST['height'];
+ } else {
+ $aBlock = $block->getLast();
+ $iHeight = $aBlock['height'];
+ }
+
+ if (@$_REQUEST['search']) {
+ $iHeight = $roundstats->searchForBlockHeight($_REQUEST['search']);
+ }
+
+ if (@$_REQUEST['filter']) {
+ $filter = $_REQUEST['filter'];
+ }
+
+ $aBlocksData = array();
+ if ( $iUserId ) {
+ if ($filter) {
+ $aBlocksData = $roundstats->getAllReportBlocksFoundHeight($iHeight, $iLimit);
+ } else {
+ $aBlocksData = $roundstats->getUserReportBlocksFoundHeight($iHeight, $iLimit, $iUserId);
+ }
+ foreach($aBlocksData as $key => $aData) {
+ $aBlocksData[$key]['pplns_shares'] = @$roundstats->getPPLNSRoundShares($aData['height']);
+ $aBlocksData[$key]['user'] = @$roundstats->getRoundStatsForUser($aData['height'], $iUserId);
+ $aBlocksData[$key]['user_credit'] = @$roundstats->getUserRoundTransHeight($aData['height'], $iUserId);
+ }
+ }
+
+ $smarty->assign('REPORTDATA', $aBlocksData);
+ $smarty->assign("USERLIST", $aUserList);
+ $smarty->assign("USERNAME", $userName);
+ $smarty->assign("USERID", $iUserId);
+ $smarty->assign("BLOCKLIMIT", $iLimit);
+ $smarty->assign("HEIGHT", $iHeight);
+ $smarty->assign("FILTER", $filter);
+} else {
+ $debug->append('Using cached page', 3);
+}
+
+if ($user->isAuthenticated(false)) {
+ $smarty->assign("CONTENT", "default.tpl");
+} else {
+ $smarty->assign("CONTENT", "empty");
+}
+?>
diff --git a/public/templates/mmcFE/admin/reports/default.tpl b/public/templates/mmcFE/admin/reports/default.tpl
new file mode 100644
index 00000000..53ca1869
--- /dev/null
+++ b/public/templates/mmcFE/admin/reports/default.tpl
@@ -0,0 +1,2 @@
+{include file="admin/reports/earnings_control.tpl"}
+{include file="admin/reports/earnings_report.tpl"}
diff --git a/public/templates/mmcFE/admin/reports/earnings_control.tpl b/public/templates/mmcFE/admin/reports/earnings_control.tpl
new file mode 100644
index 00000000..d6c7d0a5
--- /dev/null
+++ b/public/templates/mmcFE/admin/reports/earnings_control.tpl
@@ -0,0 +1,50 @@
+{include file="global/block_header.tpl" ALIGN="left" BLOCK_STYLE="width: 100%" BLOCK_HEADER="Earnings Information" STYLE="padding-left:5px;padding-right:5px;"}
+
+{include file="global/block_footer.tpl"}
diff --git a/public/templates/mmcFE/admin/reports/earnings_report.tpl b/public/templates/mmcFE/admin/reports/earnings_report.tpl
new file mode 100644
index 00000000..a724eb13
--- /dev/null
+++ b/public/templates/mmcFE/admin/reports/earnings_report.tpl
@@ -0,0 +1,85 @@
+{include file="global/block_header.tpl" ALIGN="left" BLOCK_STYLE="width: 100%" BLOCK_HEADER="Earnings Report Last {$BLOCKLIMIT} Blocks For User: {$USERNAME}" STYLE="padding-left:5px;padding-right:5px;"}
+
+
+
+ | Block |
+ Round Shares |
+ Round Valid |
+ Invalid |
+ Invalid % |
+ Round % |
+ PPLNS Shares |
+ PPLNS Valid |
+ Invalid |
+ Invalid % |
+ PPLNS % |
+ Variance |
+ Amount |
+
+
+
+{assign var=percentage value=0}
+{assign var=percentage1 value=0}
+{assign var=percentage2 value=0}
+{assign var=totalvalid value=0}
+{assign var=totalinvalid value=0}
+{assign var=totalshares value=0}
+{assign var=usertotalshares value=0}
+{assign var=totalpercentage value=0}
+{assign var=pplnsshares value=0}
+{assign var=userpplnsshares value=0}
+{assign var=pplnsvalid value=0}
+{assign var=pplnsinvalid value=0}
+{assign var=amount value=0}
+{section txs $REPORTDATA}
+ {assign var="totalshares" value=$totalshares+$REPORTDATA[txs].shares}
+ {assign var=totalvalid value=$totalvalid+$REPORTDATA[txs]['user'].valid}
+ {assign var=totalinvalid value=$totalinvalid+$REPORTDATA[txs]['user'].invalid}
+ {assign var="pplnsshares" value=$pplnsshares+$REPORTDATA[txs].pplns_shares}
+ {assign var=pplnsvalid value=$pplnsvalid+$REPORTDATA[txs]['user'].pplns_valid}
+ {assign var=pplnsinvalid value=$pplnsinvalid+$REPORTDATA[txs]['user'].pplns_invalid}
+ {assign var=amount value=$amount+$REPORTDATA[txs].user_credit}
+ {if $REPORTDATA[txs]['user'].pplns_valid > 0}
+ {assign var="userpplnsshares" value=$userpplnsshares+$REPORTDATA[txs].pplns_shares}
+ {/if}
+ {if $REPORTDATA[txs]['user'].valid > 0}
+ {assign var="usertotalshares" value=$usertotalshares+$REPORTDATA[txs].shares}
+ {/if}
+
+ | {$REPORTDATA[txs].height|default:"0"} |
+ {$REPORTDATA[txs].shares|default:"0"} |
+ {$REPORTDATA[txs]['user'].valid|number_format|default:"0"} |
+ {$REPORTDATA[txs]['user'].invalid|number_format|default:"0"} |
+ {if $REPORTDATA[txs]['user'].invalid > 0 }{($REPORTDATA[txs]['user'].invalid / $REPORTDATA[txs]['user'].valid * 100)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $REPORTDATA[txs]['user'].valid > 0 }{(( 100 / $REPORTDATA[txs].shares) * $REPORTDATA[txs]['user'].valid)|number_format:"2"}{else}0.00{/if} |
+ {$REPORTDATA[txs].pplns_shares|number_format|default:"0"} |
+ {$REPORTDATA[txs]['user'].pplns_valid|number_format|default:"0"} |
+ {$REPORTDATA[txs]['user'].pplns_invalid|number_format|default:"0"} |
+ {if $REPORTDATA[txs]['user'].pplns_invalid > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0 }{($REPORTDATA[txs]['user'].pplns_invalid / $REPORTDATA[txs]['user'].pplns_valid * 100)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $REPORTDATA[txs].shares > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0}{(( 100 / $REPORTDATA[txs].pplns_shares) * $REPORTDATA[txs]['user'].pplns_valid)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $REPORTDATA[txs]['user'].valid > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0}{math assign="percentage1" equation=(100 / ((( 100 / $REPORTDATA[txs].shares) * $REPORTDATA[txs]['user'].valid) / (( 100 / $REPORTDATA[txs].pplns_shares) * $REPORTDATA[txs]['user'].pplns_valid)))}{else if $REPORTDATA[txs]['user'].pplns_valid == 0}{assign var=percentage1 value=0}{else}{assign var=percentage1 value=100}{/if}
+ {$percentage1|number_format:"2"|default:"0"} |
+ {$REPORTDATA[txs].user_credit|default:"0"|number_format:"8"} |
+ {assign var=percentage1 value=0}
+
+{/section}
+
+ | Totals |
+ {$totalshares|number_format} |
+ {$totalvalid|number_format} |
+ {$totalinvalid|number_format} |
+ {if $totalinvalid > 0 && $totalvalid > 0 }{($totalinvalid / $totalvalid * 100)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $usertotalshares > 0 && $totalvalid > 0}{(( 100 / $usertotalshares) * $totalvalid)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {$pplnsshares|number_format} |
+ {$pplnsvalid|number_format} |
+ {$pplnsinvalid|number_format} |
+ {if $pplnsinvalid > 0 && $pplnsvalid > 0 }{($pplnsinvalid / $pplnsvalid * 100)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $userpplnsshares > 0 && $pplnsvalid > 0}{(( 100 / $userpplnsshares) * $pplnsvalid)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $totalvalid > 0 && $pplnsvalid > 0}{math assign="percentage2" equation=(100 / ((( 100 / $usertotalshares) * $totalvalid) / (( 100 / $userpplnsshares) * $pplnsvalid)))}{else if $pplnsvalid == 0}{assign var=percentage2 value=0}{else}{assign var=percentage2 value=100}{/if}
+ {$percentage2|number_format:"2"|default:"0"} |
+ {$amount|default:"0"|number_format:"8"} |
+ {assign var=percentage2 value=0}
+
+
+
+{include file="global/block_footer.tpl"}
diff --git a/public/templates/mmcFE/global/navigation.tpl b/public/templates/mmcFE/global/navigation.tpl
index c7f762e9..978a31b4 100644
--- a/public/templates/mmcFE/global/navigation.tpl
+++ b/public/templates/mmcFE/global/navigation.tpl
@@ -21,6 +21,7 @@
Transactions
Settings
News
+ Reports
{/if}
diff --git a/public/templates/mpos/admin/reports/default.tpl b/public/templates/mpos/admin/reports/default.tpl
new file mode 100644
index 00000000..53ca1869
--- /dev/null
+++ b/public/templates/mpos/admin/reports/default.tpl
@@ -0,0 +1,2 @@
+{include file="admin/reports/earnings_control.tpl"}
+{include file="admin/reports/earnings_report.tpl"}
diff --git a/public/templates/mpos/admin/reports/earnings_control.tpl b/public/templates/mpos/admin/reports/earnings_control.tpl
new file mode 100644
index 00000000..bbdf7321
--- /dev/null
+++ b/public/templates/mpos/admin/reports/earnings_control.tpl
@@ -0,0 +1,55 @@
+
diff --git a/public/templates/mpos/admin/reports/earnings_report.tpl b/public/templates/mpos/admin/reports/earnings_report.tpl
new file mode 100644
index 00000000..292642bf
--- /dev/null
+++ b/public/templates/mpos/admin/reports/earnings_report.tpl
@@ -0,0 +1,88 @@
+
+ Earnings Report Last {$BLOCKLIMIT} Blocks For User: {$USERNAME}
+
+
+
+ | Block |
+ Round Shares |
+ Round Valid |
+ Invalid |
+ Invalid % |
+ Round % |
+ PPLNS Shares |
+ PPLNS Valid |
+ Invalid |
+ Invalid % |
+ PPLNS % |
+ Variance |
+ Amount |
+
+
+
+{assign var=percentage value=0}
+{assign var=percentage1 value=0}
+{assign var=percentage2 value=0}
+{assign var=totalvalid value=0}
+{assign var=totalinvalid value=0}
+{assign var=totalshares value=0}
+{assign var=usertotalshares value=0}
+{assign var=totalpercentage value=0}
+{assign var=pplnsshares value=0}
+{assign var=userpplnsshares value=0}
+{assign var=pplnsvalid value=0}
+{assign var=pplnsinvalid value=0}
+{assign var=amount value=0}
+{section txs $REPORTDATA}
+ {assign var="totalshares" value=$totalshares+$REPORTDATA[txs].shares}
+ {assign var=totalvalid value=$totalvalid+$REPORTDATA[txs]['user'].valid}
+ {assign var=totalinvalid value=$totalinvalid+$REPORTDATA[txs]['user'].invalid}
+ {assign var="pplnsshares" value=$pplnsshares+$REPORTDATA[txs].pplns_shares}
+ {assign var=pplnsvalid value=$pplnsvalid+$REPORTDATA[txs]['user'].pplns_valid}
+ {assign var=pplnsinvalid value=$pplnsinvalid+$REPORTDATA[txs]['user'].pplns_invalid}
+ {assign var=amount value=$amount+$REPORTDATA[txs].user_credit}
+ {if $REPORTDATA[txs]['user'].pplns_valid > 0}
+ {assign var="userpplnsshares" value=$userpplnsshares+$REPORTDATA[txs].pplns_shares}
+ {/if}
+ {if $REPORTDATA[txs]['user'].valid > 0}
+ {assign var="usertotalshares" value=$usertotalshares+$REPORTDATA[txs].shares}
+ {/if}
+
+ | {$REPORTDATA[txs].height|default:"0"} |
+ {$REPORTDATA[txs].shares|default:"0"} |
+ {$REPORTDATA[txs]['user'].valid|number_format|default:"0"} |
+ {$REPORTDATA[txs]['user'].invalid|number_format|default:"0"} |
+ {if $REPORTDATA[txs]['user'].invalid > 0 }{($REPORTDATA[txs]['user'].invalid / $REPORTDATA[txs]['user'].valid * 100)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $REPORTDATA[txs]['user'].valid > 0 }{(( 100 / $REPORTDATA[txs].shares) * $REPORTDATA[txs]['user'].valid)|number_format:"2"}{else}0.00{/if} |
+ {$REPORTDATA[txs].pplns_shares|number_format|default:"0"} |
+ {$REPORTDATA[txs]['user'].pplns_valid|number_format|default:"0"} |
+ {$REPORTDATA[txs]['user'].pplns_invalid|number_format|default:"0"} |
+ {if $REPORTDATA[txs]['user'].pplns_invalid > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0 }{($REPORTDATA[txs]['user'].pplns_invalid / $REPORTDATA[txs]['user'].pplns_valid * 100)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $REPORTDATA[txs].shares > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0}{(( 100 / $REPORTDATA[txs].pplns_shares) * $REPORTDATA[txs]['user'].pplns_valid)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $REPORTDATA[txs]['user'].valid > 0 && $REPORTDATA[txs]['user'].pplns_valid > 0}{math assign="percentage1" equation=(100 / ((( 100 / $REPORTDATA[txs].shares) * $REPORTDATA[txs]['user'].valid) / (( 100 / $REPORTDATA[txs].pplns_shares) * $REPORTDATA[txs]['user'].pplns_valid)))}{else if $REPORTDATA[txs]['user'].pplns_valid == 0}{assign var=percentage1 value=0}{else}{assign var=percentage1 value=100}{/if}
+ {$percentage1|number_format:"2"|default:"0"} |
+ {$REPORTDATA[txs].user_credit|default:"0"|number_format:"8"} |
+ {assign var=percentage1 value=0}
+
+{/section}
+
+ | Totals |
+ {$totalshares|number_format} |
+ {$totalvalid|number_format} |
+ {$totalinvalid|number_format} |
+ {if $totalinvalid > 0 && $totalvalid > 0 }{($totalinvalid / $totalvalid * 100)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $usertotalshares > 0 && $totalvalid > 0}{(( 100 / $usertotalshares) * $totalvalid)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {$pplnsshares|number_format} |
+ {$pplnsvalid|number_format} |
+ {$pplnsinvalid|number_format} |
+ {if $pplnsinvalid > 0 && $pplnsvalid > 0 }{($pplnsinvalid / $pplnsvalid * 100)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $userpplnsshares > 0 && $pplnsvalid > 0}{(( 100 / $userpplnsshares) * $pplnsvalid)|number_format:"2"|default:"0"}{else}0.00{/if} |
+ {if $totalvalid > 0 && $pplnsvalid > 0}{math assign="percentage2" equation=(100 / ((( 100 / $usertotalshares) * $totalvalid) / (( 100 / $userpplnsshares) * $pplnsvalid)))}{else if $pplnsvalid == 0}{assign var=percentage2 value=0}{else}{assign var=percentage2 value=100}{/if}
+ {$percentage2|number_format:"2"|default:"0"} |
+ {$amount|default:"0"|number_format:"8"} |
+ {assign var=percentage2 value=0}
+
+
+
+
+
diff --git a/public/templates/mpos/global/navigation.tpl b/public/templates/mpos/global/navigation.tpl
index af922939..ae4a024f 100644
--- a/public/templates/mpos/global/navigation.tpl
+++ b/public/templates/mpos/global/navigation.tpl
@@ -22,6 +22,7 @@
Transactions
Settings
News
+ Reports
{/if}
{if $smarty.session.AUTHENTICATED|default}