Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
66432eda56 | |||
92eee8245d | |||
f62f07d102 | |||
671154d146 | |||
ac84e4b235 | |||
db7c6014dc | |||
21b57ef471 | |||
79e5c72ca2 | |||
5921fef67e | |||
1e0b246d74 | |||
009c890ab6 | |||
f3d7687cdb | |||
80cecabfb0 | |||
00ac91903f | |||
500f3de6a9 | |||
6c2658bf03 | |||
59de353353 | |||
d5ea56d078 |
@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## 2024.2.7
|
||||||
|
|
||||||
|
- Hide Dashboard content
|
||||||
|
|
||||||
|
## 2024.2.6
|
||||||
|
|
||||||
|
- Cache graph for faster opening graph
|
||||||
|
|
||||||
## 2024.2.5
|
## 2024.2.5
|
||||||
|
|
||||||
- Admin Dashboard Update
|
- Admin Dashboard Update
|
||||||
|
@ -188,6 +188,8 @@ CREATE TABLE `tb_languages` (
|
|||||||
`id` int(11) NOT NULL
|
`id` int(11) NOT NULL
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `tbl_voucher` ADD `generated_by` INT NOT NULL DEFAULT '0' COMMENT 'id admin' AFTER `status`;
|
||||||
|
ALTER TABLE `tbl_users` ADD `root` INT NOT NULL DEFAULT '0' COMMENT 'for sub account' AFTER `id`;
|
||||||
|
|
||||||
ALTER TABLE `tbl_appconfig`
|
ALTER TABLE `tbl_appconfig`
|
||||||
ADD PRIMARY KEY (`id`);
|
ADD PRIMARY KEY (`id`);
|
||||||
|
@ -56,6 +56,24 @@ class Lang
|
|||||||
return date($config['date_format'] . ' H:i', strtotime("$date $time"));
|
return date($config['date_format'] . ' H:i', strtotime("$date $time"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function timeElapsed($time){
|
||||||
|
$s = $time%60;
|
||||||
|
$m = floor(($time%3600)/60);
|
||||||
|
$h = floor(($time%86400)/3600);
|
||||||
|
$d = floor(($time%2592000)/86400);
|
||||||
|
$M = floor($time/2592000);
|
||||||
|
$result = '';
|
||||||
|
if($M>0){
|
||||||
|
$result = $M.'m ';
|
||||||
|
}
|
||||||
|
if($d>0){
|
||||||
|
$result .= $d.'d ';
|
||||||
|
}else if($M>0){
|
||||||
|
$result .= '0d ';
|
||||||
|
}
|
||||||
|
return "$result$h:$m:$s";
|
||||||
|
}
|
||||||
|
|
||||||
public static function nl2br($text)
|
public static function nl2br($text)
|
||||||
{
|
{
|
||||||
return nl2br($text);
|
return nl2br($text);
|
||||||
|
@ -111,8 +111,9 @@ class Message
|
|||||||
$textInvoice = str_replace('[[phone]]', $config['phone'], $textInvoice);
|
$textInvoice = str_replace('[[phone]]', $config['phone'], $textInvoice);
|
||||||
$textInvoice = str_replace('[[invoice]]', $trx['invoice'], $textInvoice);
|
$textInvoice = str_replace('[[invoice]]', $trx['invoice'], $textInvoice);
|
||||||
$textInvoice = str_replace('[[date]]', Lang::dateAndTimeFormat($trx['recharged_on'], $trx['recharged_time']), $textInvoice);
|
$textInvoice = str_replace('[[date]]', Lang::dateAndTimeFormat($trx['recharged_on'], $trx['recharged_time']), $textInvoice);
|
||||||
$textInvoice = str_replace('[[payment_gateway]]', $config['gateway'], $textInvoice);
|
$gc = explode("-", $trx['method']);
|
||||||
$textInvoice = str_replace('[[payment_channel]]', $config['channel'], $textInvoice);
|
$textInvoice = str_replace('[[payment_gateway]]', trim($gc[0]), $textInvoice);
|
||||||
|
$textInvoice = str_replace('[[payment_channel]]', trim($gc[1]), $textInvoice);
|
||||||
$textInvoice = str_replace('[[type]]', $trx['type'], $textInvoice);
|
$textInvoice = str_replace('[[type]]', $trx['type'], $textInvoice);
|
||||||
$textInvoice = str_replace('[[plan_name]]', $trx['plan_name'], $textInvoice);
|
$textInvoice = str_replace('[[plan_name]]', $trx['plan_name'], $textInvoice);
|
||||||
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($trx['price']), $textInvoice);
|
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($trx['price']), $textInvoice);
|
||||||
|
@ -514,4 +514,37 @@ class Mikrotik
|
|||||||
->setArgument('message', $message);
|
->setArgument('message', $message);
|
||||||
$client->sendSync($smsRequest);
|
$client->sendSync($smsRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function addIpToAddressList($client, $ip, $listName, $comment = '')
|
||||||
|
{
|
||||||
|
global $_app_stage;
|
||||||
|
if ($_app_stage == 'demo') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$addRequest = new RouterOS\Request('/ip/firewall/address-list/add');
|
||||||
|
$client->sendSync(
|
||||||
|
$addRequest
|
||||||
|
->setArgument('address', $ip)
|
||||||
|
->setArgument('comment', $comment)
|
||||||
|
->setArgument('list', $listName)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function removeIpFromAddressList($client, $ip)
|
||||||
|
{
|
||||||
|
global $_app_stage;
|
||||||
|
if ($_app_stage == 'demo') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$printRequest = new RouterOS\Request(
|
||||||
|
'/ip firewall address-list print .proplist=.id',
|
||||||
|
RouterOS\Query::where('address', $ip)
|
||||||
|
);
|
||||||
|
$id = $client->sendSync($printRequest)->getProperty('.id');
|
||||||
|
$removeRequest = new RouterOS\Request('/ip/firewall/address-list/remove');
|
||||||
|
$client->sendSync(
|
||||||
|
$removeRequest
|
||||||
|
->setArgument('numbers', $id)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ class Package
|
|||||||
$textInvoice = str_replace('[[phone]]', $_c['phone'], $textInvoice);
|
$textInvoice = str_replace('[[phone]]', $_c['phone'], $textInvoice);
|
||||||
$textInvoice = str_replace('[[invoice]]', $inv, $textInvoice);
|
$textInvoice = str_replace('[[invoice]]', $inv, $textInvoice);
|
||||||
$textInvoice = str_replace('[[date]]', Lang::dateTimeFormat($date_now), $textInvoice);
|
$textInvoice = str_replace('[[date]]', Lang::dateTimeFormat($date_now), $textInvoice);
|
||||||
$textInvoice = str_replace('[[payment_gateway]]', $_c['gateway'], $textInvoice);
|
$textInvoice = str_replace('[[payment_gateway]]', $gateway, $textInvoice);
|
||||||
$textInvoice = str_replace('[[payment_channel]]', $_c['channel'], $textInvoice);
|
$textInvoice = str_replace('[[payment_channel]]', $channel, $textInvoice);
|
||||||
$textInvoice = str_replace('[[type]]', 'Balance', $textInvoice);
|
$textInvoice = str_replace('[[type]]', 'Balance', $textInvoice);
|
||||||
$textInvoice = str_replace('[[plan_name]]', $p['name_plan'], $textInvoice);
|
$textInvoice = str_replace('[[plan_name]]', $p['name_plan'], $textInvoice);
|
||||||
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($p['price']), $textInvoice);
|
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($p['price']), $textInvoice);
|
||||||
@ -316,8 +316,7 @@ class Package
|
|||||||
"\nPrice: " . Lang::moneyFormat($p['price']));
|
"\nPrice: " . Lang::moneyFormat($p['price']));
|
||||||
}
|
}
|
||||||
|
|
||||||
$in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one();
|
Message::sendInvoice($c, $t);
|
||||||
Message::sendInvoice($c, $in);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,26 +51,28 @@ if (empty($c_all)) {
|
|||||||
}
|
}
|
||||||
$ui->assign('c_all', $c_all);
|
$ui->assign('c_all', $c_all);
|
||||||
|
|
||||||
//user expire
|
if($config['hide_uet'] != 'yes'){
|
||||||
$paginator = Paginator::build(ORM::for_table('tbl_user_recharges'));
|
//user expire
|
||||||
$expire = ORM::for_table('tbl_user_recharges')
|
$paginator = Paginator::build(ORM::for_table('tbl_user_recharges'));
|
||||||
->where_lte('expiration', $mdate)
|
$expire = ORM::for_table('tbl_user_recharges')
|
||||||
->offset($paginator['startpoint'])
|
->where_lte('expiration', $mdate)
|
||||||
->limit($paginator['limit'])
|
->offset($paginator['startpoint'])
|
||||||
->order_by_desc('expiration')
|
->limit($paginator['limit'])
|
||||||
->find_many();
|
->order_by_desc('expiration')
|
||||||
|
->find_many();
|
||||||
|
|
||||||
// Get the total count of expired records for pagination
|
// Get the total count of expired records for pagination
|
||||||
$totalCount = ORM::for_table('tbl_user_recharges')
|
$totalCount = ORM::for_table('tbl_user_recharges')
|
||||||
->where_lte('expiration', $mdate)
|
->where_lte('expiration', $mdate)
|
||||||
->count();
|
->count();
|
||||||
|
|
||||||
// Pass the total count and current page to the paginator
|
// Pass the total count and current page to the paginator
|
||||||
$paginator['total_count'] = $totalCount;
|
$paginator['total_count'] = $totalCount;
|
||||||
|
|
||||||
// Assign the pagination HTML to the template variable
|
// Assign the pagination HTML to the template variable
|
||||||
$ui->assign('paginator', $paginator);
|
$ui->assign('paginator', $paginator);
|
||||||
$ui->assign('expire', $expire);
|
$ui->assign('expire', $expire);
|
||||||
|
}
|
||||||
|
|
||||||
//activity log
|
//activity log
|
||||||
$dlog = ORM::for_table('tbl_logs')->limit(5)->order_by_desc('id')->find_many();
|
$dlog = ORM::for_table('tbl_logs')->limit(5)->order_by_desc('id')->find_many();
|
||||||
@ -78,90 +80,113 @@ $ui->assign('dlog', $dlog);
|
|||||||
$log = ORM::for_table('tbl_logs')->count();
|
$log = ORM::for_table('tbl_logs')->count();
|
||||||
$ui->assign('log', $log);
|
$ui->assign('log', $log);
|
||||||
|
|
||||||
// Count stock
|
|
||||||
$tmp = $v = ORM::for_table('tbl_plans')->select('id')->select('name_plan')->find_many();
|
if($config['hide_vs'] != 'yes'){
|
||||||
$plans = array();
|
$cacheStocksfile = File::pathFixer('system/cache/VoucherStocks.temp');
|
||||||
$stocks = array("used" => 0, "unused" => 0);
|
$cachePlanfile = File::pathFixer('system/cache/VoucherPlans.temp');
|
||||||
$n = 0;
|
//Cache for 5 minutes
|
||||||
foreach ($tmp as $plan) {
|
if(file_exists($cacheStocksfile) && time()- filemtime($cacheStocksfile) < 600){
|
||||||
$unused = ORM::for_table('tbl_voucher')
|
$stocks = json_decode(file_get_contents($cacheStocksfile), true);
|
||||||
->where('id_plan', $plan['id'])
|
$plans = json_decode(file_get_contents($cachePlanfile), true);
|
||||||
->where('status', 0)->count();
|
}else{
|
||||||
$used = ORM::for_table('tbl_voucher')
|
// Count stock
|
||||||
->where('id_plan', $plan['id'])
|
$tmp = $v = ORM::for_table('tbl_plans')->select('id')->select('name_plan')->find_many();
|
||||||
->where('status', 1)->count();
|
$plans = array();
|
||||||
if ($unused > 0 || $used > 0) {
|
$stocks = array("used" => 0, "unused" => 0);
|
||||||
$plans[$n]['name_plan'] = $plan['name_plan'];
|
$n = 0;
|
||||||
$plans[$n]['unused'] = $unused;
|
foreach ($tmp as $plan) {
|
||||||
$plans[$n]['used'] = $used;
|
$unused = ORM::for_table('tbl_voucher')
|
||||||
$stocks["unused"] += $unused;
|
->where('id_plan', $plan['id'])
|
||||||
$stocks["used"] += $used;
|
->where('status', 0)->count();
|
||||||
$n++;
|
$used = ORM::for_table('tbl_voucher')
|
||||||
|
->where('id_plan', $plan['id'])
|
||||||
|
->where('status', 1)->count();
|
||||||
|
if ($unused > 0 || $used > 0) {
|
||||||
|
$plans[$n]['name_plan'] = $plan['name_plan'];
|
||||||
|
$plans[$n]['unused'] = $unused;
|
||||||
|
$plans[$n]['used'] = $used;
|
||||||
|
$stocks["unused"] += $unused;
|
||||||
|
$stocks["used"] += $used;
|
||||||
|
$n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_put_contents($cacheStocksfile, json_encode($stocks));
|
||||||
|
file_put_contents($cachePlanfile, json_encode($plans));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Monthly Registered Customers
|
$cacheMRfile = File::pathFixer('system/cache/monthlyRegistered.temp');
|
||||||
$result = ORM::for_table('tbl_customers')
|
//Cache for 1 hour
|
||||||
->select_expr('MONTH(created_at)', 'month')
|
if(file_exists($cacheMRfile) && time()- filemtime($cacheMRfile) < 3600){
|
||||||
->select_expr('COUNT(*)', 'count')
|
$monthlyRegistered = json_decode(file_get_contents($cacheMRfile), true);
|
||||||
->where_raw('YEAR(created_at) = YEAR(NOW())')
|
}else{
|
||||||
->group_by_expr('MONTH(created_at)')
|
//Monthly Registered Customers
|
||||||
->find_many();
|
$result = ORM::for_table('tbl_customers')
|
||||||
|
->select_expr('MONTH(created_at)', 'month')
|
||||||
|
->select_expr('COUNT(*)', 'count')
|
||||||
|
->where_raw('YEAR(created_at) = YEAR(NOW())')
|
||||||
|
->group_by_expr('MONTH(created_at)')
|
||||||
|
->find_many();
|
||||||
|
|
||||||
$counts = [];
|
$monthlyRegistered = [];
|
||||||
foreach ($result as $row) {
|
foreach ($result as $row) {
|
||||||
$counts[] = [
|
$monthlyRegistered[] = [
|
||||||
'date' => $row->month,
|
'date' => $row->month,
|
||||||
'count' => $row->count
|
'count' => $row->count
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
file_put_contents($cacheMRfile, json_encode($monthlyRegistered));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query to retrieve monthly data
|
$cacheMSfile = File::pathFixer('system/cache/monthlySales.temp');
|
||||||
$query = ORM::for_table('tbl_transactions')
|
//Cache for 12 hours
|
||||||
->select_expr('MONTH(recharged_on)', 'month')
|
if(file_exists($cacheMSfile) && time()- filemtime($cacheMSfile) < 43200){
|
||||||
->select_expr('SUM(price)', 'total')
|
$monthlySales = json_decode(file_get_contents($cacheMSfile), true);
|
||||||
->where_raw("YEAR(recharged_on) = YEAR(CURRENT_DATE())") // Filter by the current year
|
}else{
|
||||||
->group_by_expr('MONTH(recharged_on)')
|
// Query to retrieve monthly data
|
||||||
->find_many();
|
$results = ORM::for_table('tbl_transactions')
|
||||||
|
->select_expr('MONTH(recharged_on)', 'month')
|
||||||
|
->select_expr('SUM(price)', 'total')
|
||||||
|
->where_raw("YEAR(recharged_on) = YEAR(CURRENT_DATE())") // Filter by the current year
|
||||||
|
->group_by_expr('MONTH(recharged_on)')
|
||||||
|
->find_many();
|
||||||
|
|
||||||
// Execute the query and retrieve the monthly sales data
|
// Create an array to hold the monthly sales data
|
||||||
$results = $query->find_many();
|
$monthlySales = array();
|
||||||
|
|
||||||
// Create an array to hold the monthly sales data
|
// Iterate over the results and populate the array
|
||||||
$monthlySales = array();
|
foreach ($results as $result) {
|
||||||
|
$month = $result->month;
|
||||||
|
$totalSales = $result->total;
|
||||||
|
|
||||||
// Iterate over the results and populate the array
|
|
||||||
foreach ($results as $result) {
|
|
||||||
$month = $result->month;
|
|
||||||
$totalSales = $result->total;
|
|
||||||
|
|
||||||
$monthlySales[$month] = array(
|
|
||||||
'month' => $month,
|
|
||||||
'totalSales' => $totalSales
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill in missing months with zero sales
|
|
||||||
for ($month = 1; $month <= 12; $month++) {
|
|
||||||
if (!isset($monthlySales[$month])) {
|
|
||||||
$monthlySales[$month] = array(
|
$monthlySales[$month] = array(
|
||||||
'month' => $month,
|
'month' => $month,
|
||||||
'totalSales' => 0
|
'totalSales' => $totalSales
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fill in missing months with zero sales
|
||||||
|
for ($month = 1; $month <= 12; $month++) {
|
||||||
|
if (!isset($monthlySales[$month])) {
|
||||||
|
$monthlySales[$month] = array(
|
||||||
|
'month' => $month,
|
||||||
|
'totalSales' => 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the array by month
|
||||||
|
ksort($monthlySales);
|
||||||
|
|
||||||
|
// Reindex the array
|
||||||
|
$monthlySales = array_values($monthlySales);
|
||||||
|
file_put_contents($cacheMSfile, json_encode($monthlySales));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the array by month
|
|
||||||
ksort($monthlySales);
|
|
||||||
|
|
||||||
// Reindex the array
|
|
||||||
$monthlySales = array_values($monthlySales);
|
|
||||||
|
|
||||||
// Assign the monthly sales data to Smarty
|
// Assign the monthly sales data to Smarty
|
||||||
$ui->assign('monthlySales', $monthlySales);
|
$ui->assign('monthlySales', $monthlySales);
|
||||||
$ui->assign('xheader', '<script src="https://cdn.jsdelivr.net/npm/apexcharts@3.28.0/dist/apexcharts.min.js"></script>');
|
|
||||||
$ui->assign('xfooter', '');
|
$ui->assign('xfooter', '');
|
||||||
$ui->assign('counts', $counts);
|
$ui->assign('monthlyRegistered', $monthlyRegistered);
|
||||||
$ui->assign('stocks', $stocks);
|
$ui->assign('stocks', $stocks);
|
||||||
$ui->assign('plans', $plans);
|
$ui->assign('plans', $plans);
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ switch ($action) {
|
|||||||
if($d['status'] == 'on'){
|
if($d['status'] == 'on'){
|
||||||
Package::changeTo($username, $id_plan, $id);
|
Package::changeTo($username, $id_plan, $id);
|
||||||
}
|
}
|
||||||
_log('[' . $admin['username'] . ']: ' . 'Edit Plan for Customer ' . $d['username'] . ' to [' . $d['namebp'] . '][' . Lang::moneyFormat($d['price']) . ']', 'Admin', $admin['id']);
|
_log('[' . $admin['username'] . ']: ' . 'Edit Plan for Customer ' . $d['username'] . ' to [' . $d['namebp'] . '][' . Lang::moneyFormat($p['price']) . ']', 'Admin', $admin['id']);
|
||||||
r2(U . 'prepaid/list', 's', $_L['Updated_Successfully']);
|
r2(U . 'prepaid/list', 's', $_L['Updated_Successfully']);
|
||||||
} else {
|
} else {
|
||||||
r2(U . 'prepaid/edit/' . $id, 'e', $msg);
|
r2(U . 'prepaid/edit/' . $id, 'e', $msg);
|
||||||
@ -452,6 +452,7 @@ switch ($action) {
|
|||||||
$d->code = $prefix.$code;
|
$d->code = $prefix.$code;
|
||||||
$d->user = '0';
|
$d->user = '0';
|
||||||
$d->status = '0';
|
$d->status = '0';
|
||||||
|
$d->generated_by = $admin['id'];
|
||||||
$d->save();
|
$d->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,6 +299,23 @@ switch ($action) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//checkbox
|
||||||
|
$checks = ['hide_mrc','hide_tms','hide_aui','hide_al','hide_uet','hide_vs','hide_pg'];
|
||||||
|
foreach ($checks as $check) {
|
||||||
|
if(!isset($_POST[$check])){
|
||||||
|
$d = ORM::for_table('tbl_appconfig')->where('setting', $check)->find_one();
|
||||||
|
if ($d) {
|
||||||
|
$d->value = 'no';
|
||||||
|
$d->save();
|
||||||
|
} else {
|
||||||
|
$d = ORM::for_table('tbl_appconfig')->create();
|
||||||
|
$d->setting = $check;
|
||||||
|
$d->value = 'no';
|
||||||
|
$d->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_log('[' . $admin['username'] . ']: ' . $_L['Settings_Saved_Successfully'], 'Admin', $admin['id']);
|
_log('[' . $admin['username'] . ']: ' . $_L['Settings_Saved_Successfully'], 'Admin', $admin['id']);
|
||||||
|
|
||||||
r2(U . 'settings/app', 's', $_L['Settings_Saved_Successfully']);
|
r2(U . 'settings/app', 's', $_L['Settings_Saved_Successfully']);
|
||||||
|
@ -81,6 +81,7 @@ $result = ORM::for_table('tbl_appconfig')->find_many();
|
|||||||
foreach ($result as $value) {
|
foreach ($result as $value) {
|
||||||
$config[$value['setting']] = $value['value'];
|
$config[$value['setting']] = $value['value'];
|
||||||
}
|
}
|
||||||
|
date_default_timezone_set($config['timezone']);
|
||||||
|
|
||||||
if (!empty($radius_user) && $config['radius_enable']) {
|
if (!empty($radius_user) && $config['radius_enable']) {
|
||||||
ORM::configure("mysql:host=$radius_host;dbname=$radius_name", null, 'radius');
|
ORM::configure("mysql:host=$radius_host;dbname=$radius_name", null, 'radius');
|
||||||
@ -100,7 +101,6 @@ while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
|
|||||||
|
|
||||||
$_c = $config;
|
$_c = $config;
|
||||||
|
|
||||||
date_default_timezone_set($config['timezone']);
|
|
||||||
|
|
||||||
$textExpired = Lang::getNotifText('expired');
|
$textExpired = Lang::getNotifText('expired');
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ foreach ($d as $ds) {
|
|||||||
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
||||||
echo "auto renewall Failed\n";
|
echo "auto renewall Failed\n";
|
||||||
Message::sendTelegram("FAILED RENEWAL #cron\n\n#u$c[username] #buy #Hotspot \n" . $p['name_plan'] .
|
Message::sendTelegram("FAILED RENEWAL #cron\n\n#u$c[username] #buy #Hotspot \n" . $p['name_plan'] .
|
||||||
"\nRouter: " . $router_name .
|
"\nRouter: " . $p['routers'] .
|
||||||
"\nPrice: " . $p['price']);
|
"\nPrice: " . $p['price']);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -208,7 +208,7 @@ foreach ($d as $ds) {
|
|||||||
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
||||||
echo "auto renewall Failed\n";
|
echo "auto renewall Failed\n";
|
||||||
Message::sendTelegram("FAILED RENEWAL #cron\n\n#u$c[username] #buy #PPPOE \n" . $p['name_plan'] .
|
Message::sendTelegram("FAILED RENEWAL #cron\n\n#u$c[username] #buy #PPPOE \n" . $p['name_plan'] .
|
||||||
"\nRouter: " . $router_name .
|
"\nRouter: " . $p['routers'] .
|
||||||
"\nPrice: " . $p['price']);
|
"\nPrice: " . $p['price']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,3 +427,4 @@ $_L['Buy_this_your_active_package_will_be_overwrite'] = 'Buy this? your active p
|
|||||||
$_L['Monthly_Registered_Customers'] = 'Monthly Registered Customers';
|
$_L['Monthly_Registered_Customers'] = 'Monthly Registered Customers';
|
||||||
$_L['Total_Monthly_Sales'] = 'Total Monthly Sales';
|
$_L['Total_Monthly_Sales'] = 'Total Monthly Sales';
|
||||||
$_L['Active_Users'] = 'Active Users';
|
$_L['Active_Users'] = 'Active Users';
|
||||||
|
$_L['All_Users_Insights'] = 'All Users Insights';
|
||||||
|
@ -41,5 +41,9 @@
|
|||||||
],
|
],
|
||||||
"2024.1.11": [
|
"2024.1.11": [
|
||||||
"ALTER TABLE `tbl_plans` ADD `allow_purchase` ENUM('yes','no') DEFAULT 'yes' COMMENT 'allow to show package in buy package page' AFTER `enabled`;"
|
"ALTER TABLE `tbl_plans` ADD `allow_purchase` ENUM('yes','no') DEFAULT 'yes' COMMENT 'allow to show package in buy package page' AFTER `enabled`;"
|
||||||
|
],
|
||||||
|
"2024.2.7": [
|
||||||
|
"ALTER TABLE `tbl_voucher` ADD `generated_by` INT NOT NULL DEFAULT '0' COMMENT 'id admin' AFTER `status`;",
|
||||||
|
"ALTER TABLE `tbl_users` ADD `root` INT NOT NULL DEFAULT '0' COMMENT 'for sub account' AFTER `id`;"
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -86,6 +86,24 @@
|
|||||||
<p class="help-block col-md-4">edit at config.php</p>
|
<p class="help-block col-md-4">edit at config.php</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="panel-heading">
|
||||||
|
<div class="btn-group pull-right">
|
||||||
|
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
|
||||||
|
class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span></button>
|
||||||
|
</div>
|
||||||
|
Hide Dashboard Content
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-md-3 control-label"><input type="checkbox" name="hide_mrc" value="yes" {if $_c['hide_mrc'] eq 'yes'}checked{/if}> {Lang::T('Monthly Registered Customers')}</label>
|
||||||
|
<label class="col-md-2 control-label"><input type="checkbox" name="hide_tms" value="yes" {if $_c['hide_tms'] eq 'yes'}checked{/if}> {Lang::T('Total Monthly Sales')}</label>
|
||||||
|
<label class="col-md-2 control-label"><input type="checkbox" name="hide_aui" value="yes" {if $_c['hide_aui'] eq 'yes'}checked{/if}> {Lang::T('All Users Insights')}</label>
|
||||||
|
<label class="col-md-2 control-label"><input type="checkbox" name="hide_al" value="yes" {if $_c['hide_al'] eq 'yes'}checked{/if}> {$_L['Activity_Log']}</label>
|
||||||
|
<label class="col-md-2 control-label"><input type="checkbox" name="hide_uet" value="yes" {if $_c['hide_uet'] eq 'yes'}checked{/if}> {$_L['User_Expired_Today']}</label>
|
||||||
|
<label class="col-md-2 control-label"><input type="checkbox" name="hide_vs" value="yes" {if $_c['hide_vs'] eq 'yes'}checked{/if}> Vouchers Stock</label>
|
||||||
|
<label class="col-md-2 control-label"><input type="checkbox" name="hide_pg" value="yes" {if $_c['hide_pg'] eq 'yes'}checked{/if}> Payment Gateway</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
|
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
|
||||||
@ -417,7 +435,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-heading" id="envato">
|
{* <div class="panel-heading" id="envato">
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
|
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
|
||||||
class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span></button>
|
class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span></button>
|
||||||
@ -444,7 +462,7 @@
|
|||||||
class="btn btn-xs btn-primary">View MarketPlace</a>
|
class="btn btn-xs btn-primary">View MarketPlace</a>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> *}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
|
@ -61,129 +61,144 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- solid sales graph -->
|
<!-- solid sales graph -->
|
||||||
<div class="box box-solid ">
|
{if $_c['hide_mrc'] != 'yes'}
|
||||||
<div class="box-header">
|
<div class="box box-solid ">
|
||||||
<i class="fa fa-th"></i>
|
<div class="box-header">
|
||||||
|
<i class="fa fa-th"></i>
|
||||||
|
|
||||||
<h3 class="box-title">{Lang::T('Monthly Registered Customers')}</h3>
|
<h3 class="box-title">{Lang::T('Monthly Registered Customers')}</h3>
|
||||||
|
|
||||||
<div class="box-tools pull-right">
|
<div class="box-tools pull-right">
|
||||||
<button type="button" class="btn bg-teal btn-sm" data-widget="collapse"><i class="fa fa-minus"></i>
|
<button type="button" class="btn bg-teal btn-sm" data-widget="collapse"><i class="fa fa-minus"></i>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn bg-teal btn-sm" data-widget="remove"><i class="fa fa-times"></i>
|
<button type="button" class="btn bg-teal btn-sm" data-widget="remove"><i class="fa fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box-body border-radius-none">
|
||||||
|
<canvas class="chart" id="chart" style="height: 250px;"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body border-radius-none">
|
{/if}
|
||||||
<canvas class="chart" id="chart" style="height: 250px;"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- solid sales graph -->
|
<!-- solid sales graph -->
|
||||||
<div class="box box-solid ">
|
{if $_c['hide_tms'] != 'yes'}
|
||||||
<div class="box-header">
|
<div class="box box-solid ">
|
||||||
<i class="fa fa-inbox"></i>
|
<div class="box-header">
|
||||||
|
<i class="fa fa-inbox"></i>
|
||||||
|
|
||||||
<h3 class="box-title">{Lang::T('Total Monthly Sales')}</h3>
|
<h3 class="box-title">{Lang::T('Total Monthly Sales')}</h3>
|
||||||
|
|
||||||
<div class="box-tools pull-right">
|
<div class="box-tools pull-right">
|
||||||
<button type="button" class="btn bg-teal btn-sm" data-widget="collapse"><i class="fa fa-minus"></i>
|
<button type="button" class="btn bg-teal btn-sm" data-widget="collapse"><i class="fa fa-minus"></i>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn bg-teal btn-sm" data-widget="remove"><i class="fa fa-times"></i>
|
<button type="button" class="btn bg-teal btn-sm" data-widget="remove"><i class="fa fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box-body border-radius-none">
|
||||||
|
<canvas class="chart" id="salesChart" style="height: 250px;"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body border-radius-none">
|
{/if}
|
||||||
<canvas class="chart" id="salesChart" style="height: 250px;"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-7">
|
<div class="col-md-7">
|
||||||
{if $_c['disable_voucher'] != 'yes' && $stocks['unused']>0 || $stocks['used']>0}
|
{if $_c['disable_voucher'] != 'yes' && $stocks['unused']>0 || $stocks['used']>0}
|
||||||
<div class="panel panel-primary mb20 panel-hovered project-stats table-responsive">
|
{if $_c['hide_vs'] != 'yes'}
|
||||||
<div class="panel-heading">Vouchers Stock</div>
|
<div class="panel panel-primary mb20 panel-hovered project-stats table-responsive">
|
||||||
<div class="table-responsive">
|
<div class="panel-heading">Vouchers Stock</div>
|
||||||
<table class="table">
|
<div class="table-responsive">
|
||||||
<thead>
|
<table class="table">
|
||||||
<tr>
|
<thead>
|
||||||
<th>{$_L['Plan_Name']}</th>
|
<tr>
|
||||||
<th>unused</th>
|
<th>{$_L['Plan_Name']}</th>
|
||||||
<th>used</th>
|
<th>unused</th>
|
||||||
</tr>
|
<th>used</th>
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
</thead>
|
||||||
{foreach $plans as $stok}
|
<tbody>
|
||||||
<tr>
|
{foreach $plans as $stok}
|
||||||
<td>{$stok['name_plan']}</td>
|
<tr>
|
||||||
<td>{$stok['unused']}</td>
|
<td>{$stok['name_plan']}</td>
|
||||||
<td>{$stok['used']}</td>
|
<td>{$stok['unused']}</td>
|
||||||
</tr>
|
<td>{$stok['used']}</td>
|
||||||
</tbody>
|
</tr>
|
||||||
{/foreach}
|
</tbody>
|
||||||
<tr>
|
{/foreach}
|
||||||
<td>Total</td>
|
<tr>
|
||||||
<td>{$stocks['unused']}</td>
|
<td>Total</td>
|
||||||
<td>{$stocks['used']}</td>
|
<td>{$stocks['unused']}</td>
|
||||||
</tr>
|
<td>{$stocks['used']}</td>
|
||||||
</table>
|
</tr>
|
||||||
</div>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
<div class="panel panel-warning mb20 panel-hovered project-stats table-responsive">
|
{if $_c['hide_uet'] != 'yes'}
|
||||||
<div class="panel-heading">{$_L['User_Expired_Today']}</div>
|
<div class="panel panel-warning mb20 panel-hovered project-stats table-responsive">
|
||||||
<div class="table-responsive">
|
<div class="panel-heading">{$_L['User_Expired_Today']}</div>
|
||||||
<table class="table">
|
<div class="table-responsive">
|
||||||
<thead>
|
<table class="table">
|
||||||
<tr>
|
<thead>
|
||||||
<th>Id</th>
|
<tr>
|
||||||
<th>{$_L['Username']}</th>
|
<th>Id</th>
|
||||||
<th>{$_L['Created_On']}</th>
|
<th>{$_L['Username']}</th>
|
||||||
<th>{$_L['Expires_On']}</th>
|
<th>{$_L['Created_On']}</th>
|
||||||
</tr>
|
<th>{$_L['Expires_On']}</th>
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
</thead>
|
||||||
{$no = 1}
|
<tbody>
|
||||||
{foreach $expire as $expired}
|
{$no = 1}
|
||||||
<tr>
|
{foreach $expire as $expired}
|
||||||
<td>{$no++}</td>
|
<tr>
|
||||||
<td><a href="{$_url}customers/viewu/{$expired['username']}">{$expired['username']}</a></td>
|
<td>{$no++}</td>
|
||||||
<td>{Lang::dateAndTimeFormat($expired['recharged_on'],$expired['recharged_time'])}
|
<td><a href="{$_url}customers/viewu/{$expired['username']}">{$expired['username']}</a></td>
|
||||||
</td>
|
<td>{Lang::dateAndTimeFormat($expired['recharged_on'],$expired['recharged_time'])}
|
||||||
<td>{Lang::dateAndTimeFormat($expired['expiration'],$expired['time'])}
|
</td>
|
||||||
</td>
|
<td>{Lang::dateAndTimeFormat($expired['expiration'],$expired['time'])}
|
||||||
</tr>
|
</td>
|
||||||
</tbody>
|
</tr>
|
||||||
{/foreach}
|
</tbody>
|
||||||
</table>
|
{/foreach}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{$paginator['contents']}
|
||||||
</div>
|
</div>
|
||||||
{$paginator['contents']}
|
{/if}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
<div class="panel panel-success panel-hovered mb20 activities">
|
{if $_c['hide_pg'] != 'yes'}
|
||||||
<div class="panel-heading">{Lang::T('Payment Gateway')}: {$_c['payment_gateway']}</div>
|
<div class="panel panel-success panel-hovered mb20 activities">
|
||||||
</div>
|
<div class="panel-heading">{Lang::T('Payment Gateway')}: {$_c['payment_gateway']}</div>
|
||||||
<div class="panel panel-info panel-hovered mb20 activities">
|
|
||||||
<div class="panel-heading">{Lang::T('Active Users')}</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<canvas id="userRechargesChart"></canvas>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
<div class="panel panel-info panel-hovered mb20 activities">
|
{if $_c['hide_aui'] != 'yes'}
|
||||||
<div class="panel-heading"><a href="{$_url}logs">{$_L['Activity_Log']}</a></div>
|
<div class="panel panel-info panel-hovered mb20 activities">
|
||||||
<div class="panel-body">
|
<div class="panel-heading">{Lang::T('All Users Insights')}</div>
|
||||||
<ul class="list-unstyled">
|
<div class="panel-body">
|
||||||
{foreach $dlog as $dlogs}
|
<canvas id="userRechargesChart"></canvas>
|
||||||
<li class="primary">
|
</div>
|
||||||
<span class="point"></span>
|
|
||||||
<span class="time small text-muted">{time_elapsed_string($dlogs['date'],true)}</span>
|
|
||||||
<p>{$dlogs['description']}</p>
|
|
||||||
</li>
|
|
||||||
{/foreach}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
|
{if $_c['hide_al'] != 'yes'}
|
||||||
|
<div class="panel panel-info panel-hovered mb20 activities">
|
||||||
|
<div class="panel-heading"><a href="{$_url}logs">{$_L['Activity_Log']}</a></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
{foreach $dlog as $dlogs}
|
||||||
|
<li class="primary">
|
||||||
|
<span class="point"></span>
|
||||||
|
<span class="time small text-muted">{time_elapsed_string($dlogs['date'],true)}</span>
|
||||||
|
<p>{$dlogs['description']}</p>
|
||||||
|
</li>
|
||||||
|
{/foreach}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@ -191,169 +206,178 @@
|
|||||||
|
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.5.1/dist/chart.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.5.1/dist/chart.min.js"></script>
|
||||||
{literal}
|
|
||||||
<script type="text/javascript">
|
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
|
||||||
var counts = JSON.parse('{/literal}{$counts|json_encode}{literal}');
|
|
||||||
|
|
||||||
var monthNames = [
|
|
||||||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
|
||||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
|
|
||||||
];
|
|
||||||
|
|
||||||
var labels = [];
|
|
||||||
var data = [];
|
|
||||||
|
|
||||||
for (var i = 1; i <= 12; i++) {
|
|
||||||
var month = counts.find(count => count.date === i);
|
|
||||||
labels.push(month ? monthNames[i - 1] : monthNames[i - 1].substring(0, 3));
|
|
||||||
data.push(month ? month.count : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
var ctx = document.getElementById('chart').getContext('2d');
|
|
||||||
var chart = new Chart(ctx, {
|
|
||||||
type: 'bar',
|
|
||||||
data: {
|
|
||||||
labels: labels,
|
|
||||||
datasets: [{
|
|
||||||
label: 'Registered Members',
|
|
||||||
data: data,
|
|
||||||
backgroundColor: 'rgba(0, 0, 255, 0.5)',
|
|
||||||
borderColor: 'rgba(0, 0, 255, 0.7)',
|
|
||||||
borderWidth: 1
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
grid: {
|
|
||||||
display: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
beginAtZero: true,
|
|
||||||
grid: {
|
|
||||||
color: 'rgba(0, 0, 0, 0.1)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
{if $_c['hide_mrc'] != 'yes'}
|
||||||
var monthlySales = JSON.parse('{/literal}{$monthlySales|json_encode}{literal}');
|
{literal}
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
var counts = JSON.parse('{/literal}{$monthlyRegistered|json_encode}{literal}');
|
||||||
|
|
||||||
var monthNames = [
|
var monthNames = [
|
||||||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
|
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
|
||||||
];
|
];
|
||||||
|
|
||||||
var labels = [];
|
var labels = [];
|
||||||
var data = [];
|
var data = [];
|
||||||
|
|
||||||
for (var i = 1; i <= 12; i++) {
|
for (var i = 1; i <= 12; i++) {
|
||||||
var month = findMonthData(monthlySales, i);
|
var month = counts.find(count => count.date === i);
|
||||||
labels.push(month ? monthNames[i - 1] : monthNames[i - 1].substring(0, 3));
|
labels.push(month ? monthNames[i - 1] : monthNames[i - 1].substring(0, 3));
|
||||||
data.push(month ? month.totalSales : 0);
|
data.push(month ? month.count : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var ctx = document.getElementById('salesChart').getContext('2d');
|
var ctx = document.getElementById('chart').getContext('2d');
|
||||||
var chart = new Chart(ctx, {
|
var chart = new Chart(ctx, {
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
data: {
|
data: {
|
||||||
labels: labels,
|
labels: labels,
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'Monthly Sales',
|
label: 'Registered Members',
|
||||||
data: data,
|
data: data,
|
||||||
backgroundColor: 'rgba(2, 10, 242)', // Customize the background color
|
backgroundColor: 'rgba(0, 0, 255, 0.5)',
|
||||||
borderColor: 'rgba(255, 99, 132, 1)', // Customize the border color
|
borderColor: 'rgba(0, 0, 255, 0.7)',
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
}]
|
}]
|
||||||
},
|
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
grid: {
|
|
||||||
display: false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
y: {
|
options: {
|
||||||
beginAtZero: true,
|
responsive: true,
|
||||||
grid: {
|
scales: {
|
||||||
color: 'rgba(0, 0, 0, 0.1)'
|
x: {
|
||||||
|
grid: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(0, 0, 0, 0.1)'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
{/literal}
|
||||||
|
{/if}
|
||||||
|
{if $_c['hide_tmc'] != 'yes'}
|
||||||
|
{literal}
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
var monthlySales = JSON.parse('{/literal}{$monthlySales|json_encode}{literal}');
|
||||||
|
|
||||||
|
var monthNames = [
|
||||||
|
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||||
|
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
|
||||||
|
];
|
||||||
|
|
||||||
|
var labels = [];
|
||||||
|
var data = [];
|
||||||
|
|
||||||
|
for (var i = 1; i <= 12; i++) {
|
||||||
|
var month = findMonthData(monthlySales, i);
|
||||||
|
labels.push(month ? monthNames[i - 1] : monthNames[i - 1].substring(0, 3));
|
||||||
|
data.push(month ? month.totalSales : 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function findMonthData(monthlySales, month) {
|
var ctx = document.getElementById('salesChart').getContext('2d');
|
||||||
for (var i = 0; i < monthlySales.length; i++) {
|
var chart = new Chart(ctx, {
|
||||||
if (monthlySales[i].month === month) {
|
type: 'bar',
|
||||||
return monthlySales[i];
|
data: {
|
||||||
}
|
labels: labels,
|
||||||
}
|
datasets: [{
|
||||||
return null;
|
label: 'Monthly Sales',
|
||||||
}
|
data: data,
|
||||||
|
backgroundColor: 'rgba(2, 10, 242)', // Customize the background color
|
||||||
|
borderColor: 'rgba(255, 99, 132, 1)', // Customize the border color
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
grid: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(0, 0, 0, 0.1)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function findMonthData(monthlySales, month) {
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
for (var i = 0; i < monthlySales.length; i++) {
|
||||||
// Get the data from PHP and assign it to JavaScript variables
|
if (monthlySales[i].month === month) {
|
||||||
var u_act = '{/literal}{$u_act}{literal}';
|
return monthlySales[i];
|
||||||
var u_all = '{/literal}{$u_all}{literal}';
|
|
||||||
|
|
||||||
// Create the chart data
|
|
||||||
var data = {
|
|
||||||
labels: ['Active Users', 'Inactive Users'],
|
|
||||||
datasets: [{
|
|
||||||
label: 'User Recharges',
|
|
||||||
data: [parseInt(u_act), parseInt(u_all)],
|
|
||||||
backgroundColor: ['rgba(4, 191, 13)', 'rgba(191, 35, 4)'],
|
|
||||||
borderColor: ['rgba(0, 255, 0, 1)', 'rgba(255, 99, 132, 1)'],
|
|
||||||
borderWidth: 1
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create chart options
|
|
||||||
var options = {
|
|
||||||
responsive: true,
|
|
||||||
aspectRatio: 1,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
position: 'bottom',
|
|
||||||
labels: {
|
|
||||||
boxWidth: 15
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
};
|
{/literal}
|
||||||
|
{/if}
|
||||||
|
{if $_c['hide_aui'] != 'yes'}
|
||||||
|
{literal}
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
// Get the data from PHP and assign it to JavaScript variables
|
||||||
|
var u_act = '{/literal}{$u_act}{literal}';
|
||||||
|
var c_all = '{/literal}{$c_all}{literal}';
|
||||||
|
var u_all = '{/literal}{$u_all}{literal}';
|
||||||
|
//lets calculate the inactive users as reported
|
||||||
|
var expired = u_all - u_act;
|
||||||
|
var inactive = c_all - u_all;
|
||||||
|
// Create the chart data
|
||||||
|
var data = {
|
||||||
|
labels: ['Active Users', 'Expired Users', 'Inactive Users'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'User Recharges',
|
||||||
|
data: [parseInt(u_act), parseInt(expired), parseInt(inactive)],
|
||||||
|
backgroundColor: ['rgba(4, 191, 13)', 'rgba(191, 35, 4)', 'rgba(0, 0, 255, 0.5'],
|
||||||
|
borderColor: ['rgba(0, 255, 0, 1)', 'rgba(255, 99, 132, 1)', 'rgba(0, 0, 255, 0.7'],
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
// Get the canvas element and create the chart
|
// Create chart options
|
||||||
var ctx = document.getElementById('userRechargesChart').getContext('2d');
|
var options = {
|
||||||
var chart = new Chart(ctx, {
|
responsive: true,
|
||||||
type: 'pie',
|
aspectRatio: 1,
|
||||||
data: data,
|
plugins: {
|
||||||
options: options
|
legend: {
|
||||||
});
|
position: 'bottom',
|
||||||
});
|
labels: {
|
||||||
|
boxWidth: 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the canvas element and create the chart
|
||||||
|
var ctx = document.getElementById('userRechargesChart').getContext('2d');
|
||||||
|
var chart = new Chart(ctx, {
|
||||||
|
type: 'pie',
|
||||||
|
data: data,
|
||||||
|
options: options
|
||||||
|
});
|
||||||
|
});
|
||||||
|
{/literal}
|
||||||
|
{/if}
|
||||||
</script>
|
</script>
|
||||||
{/literal}
|
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener('DOMContentLoaded', function () {
|
window.addEventListener('DOMContentLoaded', function() {
|
||||||
$.getJSON("./version.json?" + Math.random(), function (data) {
|
$.getJSON("./version.json?" + Math.random(), function(data) {
|
||||||
var localVersion = data.version;
|
var localVersion = data.version;
|
||||||
$('#version').html('Version: ' + localVersion);
|
$('#version').html('Version: ' + localVersion);
|
||||||
$.getJSON(
|
$.getJSON(
|
||||||
"https://raw.githubusercontent.com/hotspotbilling/phpnuxbill/master/version.json?" +
|
"https://raw.githubusercontent.com/hotspotbilling/phpnuxbill/master/version.json?" +
|
||||||
Math
|
Math
|
||||||
.random(),
|
.random(),
|
||||||
function (data) {
|
function(data) {
|
||||||
var latestVersion = data.version;
|
var latestVersion = data.version;
|
||||||
if (localVersion !== latestVersion) {
|
if (localVersion !== latestVersion) {
|
||||||
$('#version').html('Latest Version: ' + latestVersion);
|
$('#version').html('Latest Version: ' + latestVersion);
|
||||||
|
@ -279,10 +279,10 @@
|
|||||||
<a href="{$_url}pluginmanager"><i class="glyphicon glyphicon-tasks"></i>
|
<a href="{$_url}pluginmanager"><i class="glyphicon glyphicon-tasks"></i>
|
||||||
{Lang::T('Plugin Manager')} <small class="label pull-right">Free</small></a>
|
{Lang::T('Plugin Manager')} <small class="label pull-right">Free</small></a>
|
||||||
</li>
|
</li>
|
||||||
<li {if $_routes[0] eq 'codecanyon'}class="active" {/if}>
|
{* <li {if $_routes[0] eq 'codecanyon'}class="active" {/if}>
|
||||||
<a href="{$_url}codecanyon"><i class="glyphicon glyphicon-shopping-cart"></i>
|
<a href="{$_url}codecanyon"><i class="glyphicon glyphicon-shopping-cart"></i>
|
||||||
Codecanyon.net <small class="label pull-right">Paid</small></a>
|
Codecanyon.net <small class="label pull-right">Paid</small></a>
|
||||||
</li>
|
</li> *}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
{$_MENU_AFTER_SETTINGS}
|
{$_MENU_AFTER_SETTINGS}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"version": "2024.2.5"
|
"version": "2024.2.7"
|
||||||
}
|
}
|
Reference in New Issue
Block a user