Compare commits

...

18 Commits

Author SHA1 Message Date
c754338599 hide backup 2023-09-14 14:28:44 +07:00
a85ccf06fa check error Database 2023-09-14 13:53:28 +07:00
e64527cee2 Show some error page when crash 2023-09-14 13:45:35 +07:00
fc5aa083a1 2023.9.13 2023-09-13 17:31:47 +07:00
53eb817de4 Add Balance to notification 2023-09-13 16:23:51 +07:00
309bbc0059 fix customer count 2023-09-13 15:50:20 +07:00
5fc2190f4a show customer package instead active only 2023-09-13 15:50:12 +07:00
f292da9d8d send package to friend 2023-09-13 15:38:56 +07:00
28fcabd1fd Balance on Top 2023-09-13 14:04:13 +07:00
4bbb98fb98 check if connection error 2023-09-13 10:07:58 +07:00
ee2e67f490 add proxy to connection 2023-09-13 10:00:26 +07:00
e3ec8b18fa Remove User before Remove Active User 2023-09-13 09:37:05 +07:00
f396d7183b add name to invoice notification 2023-09-11 16:26:41 +07:00
b5ddf37649 using Http::getData instead file_get_contents 2023-09-11 14:26:58 +07:00
c57bbeace3 show user active 2023-09-07 10:54:20 +07:00
eeae60d88e show mac and IP 2023-09-07 09:42:28 +07:00
14ed0236d0 Remove active user Before remove user 2023-09-07 09:35:00 +07:00
3833afb3be Fix delete PPPOE 2023-09-07 09:20:31 +07:00
36 changed files with 682 additions and 250 deletions

View File

@ -2,6 +2,21 @@
# CHANGELOG
- add Current balance in notification
- Buy Plan for Friend
- Recharge Friend plan
- Fix recharge Plan
- Show Customer active plan in Customer list
- Fix Customer counter in dashboard
- Show Customer Balance in header
- Fix Plugin Manager using Http::Get
- Show Some error page when crash
## 2023.9.7
- Fix PPPOE Delete Customer
- Remove active Customer before deleting
- Show IP and Mac even if it not Hotspot
## 2023.9.6
- Expired Pool

View File

@ -19,12 +19,7 @@ class Balance
{
global $config;
if (Balance::min($id_customer, $amount)) {
if (Balance::plusByPhone($phoneTarget, $amount)) {
return true;
} else {
Balance::plus($id_customer, $amount);
return false;
}
return Balance::plusByPhone($phoneTarget, $amount);
} else {
return false;
}

View File

@ -2,12 +2,17 @@
/**
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
* using proxy, add this variable in config.php
* $http_proxy = '127.0.0.1:3128';
* if proxy using authentication, use this parameter
* $http_proxyauth = 'user:password';
**/
class Http
{
public static function getData($url, $headers)
public static function getData($url, $headers = [])
{
global $http_proxy, $http_proxyauth, $admin;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 0);
@ -15,13 +20,26 @@ class Http
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if (!empty($http_proxy)) {
curl_setopt($ch, CURLOPT_PROXY, $http_proxy);
if (!empty($http_proxyauth)) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $http_proxyauth);
}
}
$server_output = curl_exec($ch);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
curl_close($ch);
return $server_output;
if($admin && $error_msg){
r2(U . 'dashboard', 'd', $error_msg);
}
return ($server_output) ? $server_output : $error_msg;
}
public static function postJsonData($url, $array_post, $headers = [], $basic = null)
{
global $http_proxy, $http_proxyauth, $admin;
$headers[] = 'Content-Type: application/json';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
@ -30,6 +48,12 @@ class Http
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
if (!empty($http_proxy)) {
curl_setopt($ch, CURLOPT_PROXY, $http_proxy);
if (!empty($http_proxyauth)) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $http_proxyauth);
}
}
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($array_post));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if (!empty($basic)) {
@ -37,13 +61,20 @@ class Http
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
curl_close($ch);
return $server_output;
if($admin && $error_msg){
r2(U . 'dashboard', 'd', $error_msg);
}
return ($server_output) ? $server_output : $error_msg;
}
public static function postData($url, $array_post, $headers = [], $basic = null)
{
global $http_proxy, $http_proxyauth, $admin;
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
@ -52,6 +83,12 @@ class Http
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLINFO_HEADER_OUT, false);
if (!empty($http_proxy)) {
curl_setopt($ch, CURLOPT_PROXY, $http_proxy);
if (!empty($http_proxyauth)) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $http_proxyauth);
}
}
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array_post));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if (!empty($basic)) {
@ -59,7 +96,13 @@ class Http
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}
curl_close($ch);
return $server_output;
if($admin && $error_msg){
r2(U . 'dashboard', 'd', $error_msg);
}
return ($server_output) ? $server_output : $error_msg;
}
}

View File

@ -12,7 +12,7 @@ class Message
global $config;
run_hook('send_telegram'); #HOOK
if (!empty($config['telegram_bot']) && !empty($config['telegram_target_id'])) {
file_get_contents('https://api.telegram.org/bot' . $config['telegram_bot'] . '/sendMessage?chat_id=' . $config['telegram_target_id'] . '&text=' . urlencode($txt));
Http::getData('https://api.telegram.org/bot' . $config['telegram_bot'] . '/sendMessage?chat_id=' . $config['telegram_target_id'] . '&text=' . urlencode($txt));
}
}
@ -24,7 +24,7 @@ class Message
if (!empty($config['sms_url'])) {
$smsurl = str_replace('[number]', urlencode($phone), $config['sms_url']);
$smsurl = str_replace('[text]', urlencode($txt), $smsurl);
file_get_contents($smsurl);
Http::getData($smsurl);
}
}
@ -35,7 +35,7 @@ class Message
if (!empty($config['wa_url'])) {
$waurl = str_replace('[number]', urlencode($phone), $config['wa_url']);
$waurl = str_replace('[text]', urlencode($txt), $waurl);
file_get_contents($waurl);
Http::getData($waurl);
}
}
@ -56,9 +56,10 @@ class Message
return "$via: $msg";
}
public static function sendBalanceNotification($phone, $name, $balance, $message, $via)
public static function sendBalanceNotification($phone, $name, $balance, $balance_now, $message, $via)
{
$msg = str_replace('[[name]]', "*$name*", $message);
$msg = str_replace('[[current_balance]]', Lang::moneyFormat($balance_now), $msg);
$msg = str_replace('[[balance]]', "*" . Lang::moneyFormat($balance) . "*", $msg);
if (
!empty($phone) && strlen($phone) > 5

View File

@ -17,7 +17,8 @@ class Mikrotik
$iport = explode(":", $ip);
return new RouterOS\Client($iport[0], $user, $pass, ($iport[1]) ? $iport[1] : null);
} catch (Exception $e) {
$ui->assign("error_meesage", "Unable to connect to the router.<br>" . $e->getMessage());
$ui->assign("error_title", "Mikrotik Connection Error");
$ui->assign("error_message", "Unable to connect to the router.<br>" . $e->getMessage());
$ui->display('router-error.tpl');
die();
}
@ -252,15 +253,12 @@ class Mikrotik
{
$printRequest = new RouterOS\Request('/ppp/secret/print');
$printRequest->setArgument('.proplist', '.id');
//$printRequest->setArgument('.proplist', '.id');
$printRequest->setQuery(RouterOS\Query::where('name', $username));
$id = $client->sendSync($printRequest)->getProperty('.id');
$removeRequest = new RouterOS\Request('/ppp/secret/remove');
$client(
$removeRequest
->setArgument('numbers', $id)
);
$removeRequest->setArgument('numbers', $id);
$client->sendSync($removeRequest);
}
public static function addPpoeUser($client, $plan, $customer)

View File

@ -5,8 +5,6 @@
**/
use PEAR2\Net\RouterOS;
class Package
{
/**
@ -49,22 +47,27 @@ class Package
$t->type = "Balance";
$t->save();
$balance_before = $c['balance'];
Balance::plus($id_customer, $p['price']);
$balance = $c['balance'] + $p['price'];
$textInvoice = Lang::getNotifText('invoice_balance');
$textInvoice = str_replace('[[company_name]]', $_c['CompanyName'], $textInvoice);
$textInvoice = str_replace('[[address]]', $_c['address'], $textInvoice);
$textInvoice = str_replace('[[phone]]', $_c['phone'], $textInvoice);
$textInvoice = str_replace('[[invoice]]', $inv, $textInvoice);
$textInvoice = str_replace('[[date]]', date($_c['date_format'], strtotime($date_only)) . " " . $time, $textInvoice);
$textInvoice = str_replace('[[date]]', Lang::dateTimeFormat($date_now), $textInvoice);
$textInvoice = str_replace('[[payment_gateway]]', $_c['gateway'], $textInvoice);
$textInvoice = str_replace('[[payment_channel]]', $_c['channel'], $textInvoice);
$textInvoice = str_replace('[[type]]', 'Balance', $textInvoice);
$textInvoice = str_replace('[[plan_name]]', $p['name_plan'], $textInvoice);
$textInvoice = str_replace('[[plan_price]]', $_c['currency_code'] . " " . number_format($p['price'], 2, $_c['dec_point'], $_c['thousands_sep']), $textInvoice);
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($p['price']), $textInvoice);
$textInvoice = str_replace('[[name]]', $c['fullname'], $textInvoice);
$textInvoice = str_replace('[[user_name]]', $c['username'], $textInvoice);
$textInvoice = str_replace('[[user_password]]', $c['password'], $textInvoice);
$textInvoice = str_replace('[[footer]]', $_c['note'], $textInvoice);
$textInvoice = str_replace('[[balance_before]]', Lang::moneyFormat($balance_before), $textInvoice);
$textInvoice = str_replace('[[balance]]', Lang::moneyFormat($balance), $textInvoice);
if ($_c['user_notification_payment'] == 'sms') {
Message::sendSMS($c['phonenumber'], $textInvoice);
@ -99,6 +102,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addHotspotUser($client, $p, $c);
}
@ -154,6 +159,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addHotspotUser($client, $p, $c);
}
@ -199,6 +206,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addPpoeUser($client, $p, $c);
}
@ -255,6 +264,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addPpoeUser($client, $p, $c);
}
@ -302,15 +313,16 @@ class Package
$textInvoice = str_replace('[[address]]', $_c['address'], $textInvoice);
$textInvoice = str_replace('[[phone]]', $_c['phone'], $textInvoice);
$textInvoice = str_replace('[[invoice]]', $in['invoice'], $textInvoice);
$textInvoice = str_replace('[[date]]', date($_c['date_format'], strtotime($date_now)) . " " . $time, $textInvoice);
$textInvoice = str_replace('[[date]]', Lang::dateTimeFormat($date_now), $textInvoice);
$textInvoice = str_replace('[[payment_gateway]]', $_c['gateway'], $textInvoice);
$textInvoice = str_replace('[[payment_channel]]', $_c['channel'], $textInvoice);
$textInvoice = str_replace('[[type]]', $in['type'], $textInvoice);
$textInvoice = str_replace('[[plan_name]]', $in['plan_name'], $textInvoice);
$textInvoice = str_replace('[[plan_price]]', $_c['currency_code'] . " " . number_format($in['price'], 2, $_c['dec_point'], $_c['thousands_sep']), $textInvoice);
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($in['price']), $textInvoice);
$textInvoice = str_replace('[[name]]', $c['fullname'], $textInvoice);
$textInvoice = str_replace('[[user_name]]', $in['username'], $textInvoice);
$textInvoice = str_replace('[[user_password]]', $c['password'], $textInvoice);
$textInvoice = str_replace('[[expired_date]]', date($_c['date_format'], strtotime($in['expiration'])) . " " . $in['time'], $textInvoice);
$textInvoice = str_replace('[[expired_date]]', Lang::dateAndTimeFormat($in['expiration'], $in['time']), $textInvoice);
$textInvoice = str_replace('[[footer]]', $_c['note'], $textInvoice);
if ($_c['user_notification_payment'] == 'sms') {
@ -334,6 +346,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addHotspotUser($client, $p, $c);
}
} else {
@ -341,6 +355,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addHotspotUser($client, $p, $c);
}
}
@ -350,6 +366,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addPpoeUser($client, $p, $c);
}
} else {
@ -357,6 +375,8 @@ class Package
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::addPpoeUser($client, $p, $c);
}
}

View File

@ -73,32 +73,52 @@ function _get($param, $defvalue = '')
return safedata($_GET[$param]);
}
}
try {
require_once File::pathFixer('system/orm.php');
require_once File::pathFixer('system/orm.php');
ORM::configure("mysql:host=$db_host;dbname=$db_name");
ORM::configure('username', $db_user);
ORM::configure('password', $db_password);
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
ORM::configure('return_result_sets', true);
if ($_app_stage != 'Live') {
ORM::configure("mysql:host=$db_host;dbname=$db_name");
ORM::configure('username', $db_user);
ORM::configure('password', $db_password);
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
ORM::configure('return_result_sets', true);
if ($_app_stage != 'Live') {
ORM::configure('logging', true);
}
}
$result = ORM::for_table('tbl_appconfig')->find_many();
foreach ($result as $value) {
$result = ORM::for_table('tbl_appconfig')->find_many();
foreach ($result as $value) {
$config[$value['setting']] = $value['value'];
}
}
date_default_timezone_set($config['timezone']);
$_c = $config;
date_default_timezone_set($config['timezone']);
$_c = $config;
if ($config['radius_mode']) {
// check if proxy setup in database
if (empty($http_proxy) && !empty($config['http_proxy'])) {
$http_proxy = $config['http_proxy'];
if (empty($http_proxyauth) && !empty($config['http_proxyauth'])) {
$http_proxyauth = $config['http_proxyauth'];
}
}
if ($config['radius_mode']) {
ORM::configure("mysql:host=$radius_host;dbname=$radius_name", null, 'radius');
ORM::configure('username', $radius_user, 'radius');
ORM::configure('password', $radius_password, 'radius');
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'), 'radius');
ORM::configure('return_result_sets', true, 'radius');
}
} catch (Exception $e) {
$ui = new Smarty();
$ui->setTemplateDir(['custom' => File::pathFixer('ui/ui_custom/'), 'default' => File::pathFixer('ui/ui/')]);
$ui->assign('_url', APP_URL . '/index.php?_route=');
$ui->setCompileDir(File::pathFixer('ui/compiled/'));
$ui->setConfigDir(File::pathFixer('ui/conf/'));
$ui->setCacheDir(File::pathFixer('ui/cache/'));
$ui->assign("error_title", "PHPNuxBill Crash");
$ui->assign("error_message", $e->getMessage());
$ui->display('router-error.tpl');
die();
}
function _notify($msg, $type = 'e')
@ -283,8 +303,10 @@ $handler = $routes[0];
if ($handler == '') {
$handler = 'default';
}
$sys_render = File::pathFixer('system/controllers/' . $handler . '.php');
if (file_exists($sys_render)) {
try {
$sys_render = File::pathFixer('system/controllers/' . $handler . '.php');
if (file_exists($sys_render)) {
$menus = array();
// "name" => $name,
// "admin" => $admin,
@ -311,6 +333,12 @@ if (file_exists($sys_render)) {
}
unset($menus, $menu_registered);
include($sys_render);
} else {
} else {
r2(U . 'dashboard', 'e', 'not found');
}
} catch (Exception $e) {
$ui->assign("error_title", "PHPNuxBill Crash");
$ui->assign("error_message", $e->getMessage());
$ui->display('router-error.tpl');
die();
}

View File

@ -36,6 +36,18 @@ switch ($action) {
$ui->display('autoload.tpl');
break;
case 'customer_is_active':
$d = ORM::for_table('tbl_user_recharges')->where('customer_id', $routes['2'])->findOne();
if ($d) {
if ($d['status'] == 'on') {
die('<span class="label label-success" title="Expired ' . Lang::dateAndTimeFormat($d['expiration'], $d['time']) . '">'.$d['namebp'].'</span>');
} else {
die('<span class="label label-danger" title="Expired ' . Lang::dateAndTimeFormat($d['expiration'], $d['time']) . '">'.$d['namebp'].'</span>');
}
} else {
die('<span class="label label-danger">&bull;</span>');
}
break;
case 'customer_select2':
$s = addslashes(_get('s'));

View File

@ -12,9 +12,6 @@ $action = $routes['1'];
$admin = Admin::_info();
$ui->assign('_admin', $admin);
use PEAR2\Net\RouterOS;
require_once 'system/autoload/PEAR2/Autoload.php';
if ($admin['user_type'] != 'Admin' and $admin['user_type'] != 'Sales') {
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
@ -34,7 +31,8 @@ switch ($action) {
->order_by_desc('id')->find_many();
} else {
$paginator = Paginator::bootstrap('tbl_customers');
$d = ORM::for_table('tbl_customers')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
$d = ORM::for_table('tbl_customers')
->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
}
$ui->assign('search', htmlspecialchars($search));
@ -113,14 +111,14 @@ switch ($action) {
if ($c['type'] == 'Hotspot') {
if (!$config['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Mikrotik::removeHotspotUser($client, $d['username']);
Mikrotik::removeHotspotActiveUser($client, $d['username']);
}
} else {
if (!$config['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
Mikrotik::removePpoeUser($client, $d['username']);
Mikrotik::removePpoeActive($client, $d['username']);
}
}
try {

View File

@ -1,13 +1,14 @@
<?php
/**
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
**/
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
**/
_admin();
$ui->assign('_title', $_L['Dashboard']);
$admin = Admin::_info();
$ui->assign('_admin', $admin);
if(!in_array($admin['user_type'],['Admin','Sales'])){
r2(U."home",'e',$_L['Do_Not_Access']);
if (!in_array($admin['user_type'], ['Admin', 'Sales'])) {
r2(U . "home", 'e', $_L['Do_Not_Access']);
}
$fdate = date('Y-m-01');
@ -17,59 +18,67 @@ $first_day_month = date('Y-m-01');
$mdate = date('Y-m-d');
$month_n = date('n');
$iday = ORM::for_table('tbl_transactions')->where('recharged_on',$mdate)->sum('price');
if($iday == ''){
$iday = ORM::for_table('tbl_transactions')->where('recharged_on', $mdate)->sum('price');
if ($iday == '') {
$iday = '0.00';
}
$ui->assign('iday',$iday);
$ui->assign('iday', $iday);
$imonth = ORM::for_table('tbl_transactions')->where_gte('recharged_on',$first_day_month)->where_lte('recharged_on',$mdate)->sum('price');
if($imonth == ''){
$imonth = ORM::for_table('tbl_transactions')->where_gte('recharged_on', $first_day_month)->where_lte('recharged_on', $mdate)->sum('price');
if ($imonth == '') {
$imonth = '0.00';
}
$ui->assign('imonth',$imonth);
$ui->assign('imonth', $imonth);
$u_act = ORM::for_table('tbl_user_recharges')->where('status','on')->count();
if($u_act == ''){
$u_act = ORM::for_table('tbl_user_recharges')->where('status', 'on')->count();
if (empty($u_act)) {
$u_act = '0';
}
$ui->assign('u_act',$u_act);
$ui->assign('u_act', $u_act);
$u_all = ORM::for_table('tbl_user_recharges')->count();
if($u_all == ''){
if (empty($u_all)) {
$u_all = '0';
}
$ui->assign('u_all',$u_all);
$ui->assign('u_all', $u_all);
$c_all = ORM::for_table('tbl_customers')->count();
if (empty($c_all)) {
$c_all = '0';
}
$ui->assign('c_all', $c_all);
//user expire
$expire = ORM::for_table('tbl_user_recharges')->where('expiration',$mdate)->order_by_desc('id')->find_many();
$ui->assign('expire',$expire);
$expire = ORM::for_table('tbl_user_recharges')->where('expiration', $mdate)->order_by_desc('id')->find_many();
$ui->assign('expire', $expire);
//activity log
$dlog = ORM::for_table('tbl_logs')->limit(5)->order_by_desc('id')->find_many();
$ui->assign('dlog',$dlog);
$ui->assign('dlog', $dlog);
$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();
$plans = array();
$stocks = array("used"=>0,"unused"=>0);
$stocks = array("used" => 0, "unused" => 0);
$n = 0;
foreach($tmp as $plan){
foreach ($tmp as $plan) {
$plans[$n]['name_plan'] = $plan['name_plan'];
$plans[$n]['unused'] = ORM::for_table('tbl_voucher')
->where('id_plan',$plan['id'])
->where('status',0)->count();;
->where('id_plan', $plan['id'])
->where('status', 0)->count();;
$stocks["unused"] += $plans[$n]['unused'];
$plans[$n]['used'] = ORM::for_table('tbl_voucher')
->where('id_plan',$plan['id'])
->where('status',1)->count();;
->where('id_plan', $plan['id'])
->where('status', 1)->count();;
$stocks["used"] += $plans[$n]['used'];
$n++;
}
$ui->assign('stocks',$stocks);
$ui->assign('plans',$plans);
$ui->assign('stocks', $stocks);
$ui->assign('plans', $plans);
run_hook('view_dashboard'); #HOOK
$ui->display('dashboard.tpl');

View File

@ -25,7 +25,7 @@ if (_post('send') == 'balance') {
if ($user['balance'] < $balance) {
r2(U . 'home', 'd', Lang::T('insufficient balance'));
}
if (!empty($config['minimum_transfer']) && intval($balance) <= intval($config['minimum_transfer'])) {
if (!empty($config['minimum_transfer']) && intval($balance) < intval($config['minimum_transfer'])) {
r2(U . 'home', 'd', Lang::T('Minimum Transfer') . ' ' . Lang::moneyFormat($config['minimum_transfer']));
}
if ($user['username'] == $target['username']) {
@ -66,13 +66,23 @@ if (_post('send') == 'balance') {
$d->pg_url_payment = 'balance';
$d->status = 2;
$d->save();
Message::sendBalanceNotification($user['phonenumber'], $target['fullname'] . ' (' . $target['username'] . ')', $balance, Lang::getNotifText('balance_send'), $config['user_notification_payment']);
Message::sendBalanceNotification($target['phonenumber'], $user['fullname'] . ' (' . $user['username'] . ')', $balance, Lang::getNotifText('balance_received'), $config['user_notification_payment']);
Message::sendBalanceNotification($user['phonenumber'], $target['fullname'] . ' (' . $target['username'] . ')', $balance, ($user['balance'] - $balance), Lang::getNotifText('balance_send'), $config['user_notification_payment']);
Message::sendBalanceNotification($target['phonenumber'], $user['fullname'] . ' (' . $user['username'] . ')', $balance, ($target['balance'] + $balance), Lang::getNotifText('balance_received'), $config['user_notification_payment']);
Message::sendTelegram("#u$user[username] send balance to #u$target[username] \n" . Lang::moneyFormat($balance));
r2(U . 'home', 's', Lang::T('Sending balance success'));
}
} else {
r2(U . 'home', 'd', 'Failed, balance is not available');
r2(U . 'home', 'd', Lang::T('Failed, balance is not available'));
}
} else if (_post('send') == 'plan') {
$active = ORM::for_table('tbl_user_recharges')
->where('username', _post('username'))
->find_one();
$router = ORM::for_table('tbl_routers')->where('name', $active['routers'])->find_one();
if ($router) {
r2(U . "order/send/$router[id]/$active[plan_id]&u=" . trim(_post('username')), 's', Lang::T('Review package before recharge'));
} else {
r2(U . 'package/order', 'w', Lang::T('Your friend do not have active package'));
}
}

View File

@ -98,7 +98,7 @@ switch ($action) {
}
}
if (empty($trx)) {
r2(U . "order", 'e', Lang::T("Transaction Not found"));
r2(U . "order/package", 'e', Lang::T("Transaction Not found"));
}
$router = ORM::for_table('tbl_routers')->find_one($trx['routers_id']);
$plan = ORM::for_table('tbl_plans')->find_one($trx['plan_id']);
@ -111,8 +111,8 @@ switch ($action) {
$ui->display('user-orderView.tpl');
break;
case 'pay':
if ($_c['enable_balance'] != 'yes'){
r2(U . "order", 'e', Lang::T("Balance not enabled"));
if ($_c['enable_balance'] != 'yes' && $config['allow_balance_transfer'] != 'yes') {
r2(U . "order/package", 'e', Lang::T("Balance not enabled"));
}
$plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3']);
$router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2']);
@ -130,10 +130,91 @@ switch ($action) {
"\nRouter: " . $router_name .
"\nPrice: " . $p['price']);
}
}else{
} else {
echo "no renewall | plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
}
break;
case 'send':
if ($_c['enable_balance'] != 'yes') {
r2(U . "order/package", 'e', Lang::T("Balance not enabled"));
}
$ui->assign('_title', Lang::T('Buy for friend'));
$ui->assign('_system_menu', 'package');
$plan = ORM::for_table('tbl_plans')->find_one($routes['3']);
if (empty($plan)) {
r2(U . "order/package", 'e', Lang::T("Plan Not found"));
}
if (isset($_POST['send']) && $_POST['send'] == 'plan') {
$target = ORM::for_table('tbl_customers')->where('username', _post('username'))->find_one();
if (!$target) {
r2(U . 'home', 'd', Lang::T('Username not found'));
}
if ($user['balance'] < $plan['price']) {
r2(U . 'home', 'd', Lang::T('insufficient balance'));
}
if ($user['username'] == $target['username']) {
r2(U . "order/pay/$routes[2]/$routes[3]", 's', '^_^ v');
}
$active = ORM::for_table('tbl_user_recharges')
->where('username', _post('username'))
->where('status', 'on')
->find_one();
if ($active['plan_id'] != $plan['id']) {
r2(U . "order/package", 'e', Lang::T("Target has active plan, different with current plant.")." [ <b>$active[namebp]</b> ]");
}
if (Package::rechargeUser($target['id'], $plan['routers'], $plan['id'], $user['fullname'], 'Balance')) {
// if success, then get the balance
Balance::min($user['id'], $plan['price']);
//sender
$d = ORM::for_table('tbl_payment_gateway')->create();
$d->username = $user['username'];
$d->gateway = $target['username'];
$d->plan_id = $plan['id'];
$d->plan_name = $plan['name_plan'];
$d->routers_id = $routes['2'];
$d->routers = $plan['routers'];
$d->price = $plan['price'];
$d->payment_method = "Balance";
$d->payment_channel = "Send Plan";
$d->created_date = date('Y-m-d H:i:s');
$d->paid_date = date('Y-m-d H:i:s');
$d->expired_date = date('Y-m-d H:i:s');
$d->pg_url_payment = 'balance';
$d->status = 2;
$d->save();
$trx_id = $d->id();
//receiver
$d = ORM::for_table('tbl_payment_gateway')->create();
$d->username = $target['username'];
$d->gateway = $user['username'];
$d->plan_id = $plan['id'];
$d->plan_name = $plan['name_plan'];
$d->routers_id = $routes['2'];
$d->routers = $plan['routers'];
$d->price = $plan['price'];
$d->payment_method = "Balance";
$d->payment_channel = "Received Plan";
$d->created_date = date('Y-m-d H:i:s');
$d->paid_date = date('Y-m-d H:i:s');
$d->expired_date = date('Y-m-d H:i:s');
$d->pg_url_payment = 'balance';
$d->status = 2;
$d->save();
r2(U . "order/view/$trx_id", 's', Lang::T("Success to send package"));
} else {
r2(U . "order/package", 'e', Lang::T("Failed to Send package"));
Message::sendTelegram("Send Package with Balance Failed\n\n#u$user[username] #send \n" . $plan['name_plan'] .
"\nRouter: " . $plan['routers'] .
"\nPrice: " . $plan['price']);
}
}
$ui->assign('username', $_GET['u']);
$ui->assign('router', $router);
$ui->assign('plan', $plan);
$ui->display('user-sendPlan.tpl');
break;
case 'buy':
if (strpos($user['email'], '@') === false) {
r2(U . 'accounts/profile', 'e', Lang::T("Please enter your email address"));
@ -147,9 +228,9 @@ switch ($action) {
run_hook('customer_buy_plan'); #HOOK
include 'system/paymentgateway/' . $config['payment_gateway'] . '.php';
call_user_func($config['payment_gateway'] . '_validate_config');
if ($routes['2']>0) {
if ($routes['2'] > 0) {
$router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2']);
}else{
} else {
$router['id'] = 0;
$router['name'] = 'balance';
}
@ -205,5 +286,5 @@ switch ($action) {
}
break;
default:
r2(U . "order/package/", 's','');
r2(U . "order/package/", 's', '');
}

View File

@ -21,9 +21,14 @@ if ($admin['user_type'] != 'Admin') {
$cache = File::pathFixer('system/cache/plugin_repository.json');
if (file_exists($cache) && time() - filemtime($cache) < (24 * 60 * 60)) {
$json = json_decode(file_get_contents($cache), true);
$txt = file_get_contents($cache);
$json = json_decode($txt, true);
if(empty($json['plugins']) && empty($json['payment_gateway'])){
unlink($cache);
r2(U . 'dashboard', 'd', $txt);
}
} else {
$data = file_get_contents($plugin_repository);
$data = Http::getData($plugin_repository);
file_put_contents($cache, $data);
$json = json_decode($data, true);
}

View File

@ -146,14 +146,16 @@ switch ($action) {
if ($d['type'] == 'Hotspot') {
if (!$config['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removeHotspotUser($client, $d['username']);
Mikrotik::removeHotspotActiveUser($client, $d['username']);
}
$d->delete();
} else {
if (!$config['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removePpoeUser($client, $d['username']);
Mikrotik::removePpoeActive($client, $d['username']);
}
$d->delete();
}

View File

@ -231,6 +231,8 @@ switch ($action) {
$user_notification_payment = _post('user_notification_payment');
$address = _post('address');
$tawkto = _post('tawkto');
$http_proxy = _post('http_proxy');
$http_proxyauth = _post('http_proxyauth');
$radius_mode = _post('radius_mode') * 1;
run_hook('save_settings'); #HOOK
@ -257,6 +259,28 @@ switch ($action) {
$d->save();
$d = ORM::for_table('tbl_appconfig')->where('setting', 'http_proxy')->find_one();
if ($d) {
$d->value = $http_proxy;
$d->save();
} else {
$d = ORM::for_table('tbl_appconfig')->create();
$d->setting = 'http_proxy';
$d->value = $http_proxy;
$d->save();
}
$d = ORM::for_table('tbl_appconfig')->where('setting', 'http_proxyauth')->find_one();
if ($d) {
$d->value = $http_proxyauth;
$d->save();
} else {
$d = ORM::for_table('tbl_appconfig')->create();
$d->setting = 'http_proxyauth';
$d->value = $http_proxyauth;
$d->save();
}
$d = ORM::for_table('tbl_appconfig')->where('setting', 'CompanyFooter')->find_one();
if ($d) {
$d->value = $footer;

View File

@ -28,6 +28,12 @@ function _autoloader($class)
}
spl_autoload_register('_autoloader');
if(php_sapi_name() !== 'cli'){
echo "<pre>";
}
require_once '../config.php';
require_once 'orm.php';
require_once 'autoload/PEAR2/Autoload.php';
@ -56,6 +62,14 @@ foreach ($result as $value) {
$config[$value['setting']] = $value['value'];
}
echo "PHP Time\t" . date('Y-m-d H:i:s') . "\n";
$res = ORM::raw_execute('SELECT NOW() AS WAKTU;');
$statement = ORM::get_last_statement();
$rows = array();
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
echo "MYSQL Time\t" . $row['WAKTU'] . "\n";
}
$_c = $config;
date_default_timezone_set($config['timezone']);
@ -80,12 +94,12 @@ foreach ($d as $ds) {
if (!$_c['radius_mode']) {
$client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
if(!empty($p['pool_expired'])){
Mikrotik::setHotspotUserPackage($client, $c['username'], 'EXPIRED NUXBILL '.$p['pool_expired']);
}else{
Mikrotik::removeHotspotUser($client, $c['username']);
}
Mikrotik::removeHotspotActiveUser($client, $c['username']);
Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $textExpired, $config['user_notification_expired']);
}
//update database user dengan status off
@ -127,12 +141,12 @@ foreach ($d as $ds) {
if (!$_c['radius_mode']) {
$client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']);
Mikrotik::removePpoeActive($client, $c['username']);
if(!empty($p['pool_expired'])){
Mikrotik::setPpoeUserPlan($client, $c['username'], 'EXPIRED NUXBILL '.$p['pool_expired']);
}else{
Mikrotik::removePpoeUser($client, $c['username']);
}
Mikrotik::removePpoeActive($client, $c['username']);
Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $textExpired, $config['user_notification_expired']);
}

View File

@ -12,16 +12,16 @@ function _autoloader($class)
{
if (strpos($class, '_') !== false) {
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include __DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
}
} else {
if (file_exists(__DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include __DIR__.DIRECTORY_SEPARATOR.'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include __DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php';
} else {
$class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'autoload' . DIRECTORY_SEPARATOR . $class . '.php'))
@ -31,10 +31,14 @@ function _autoloader($class)
}
spl_autoload_register('_autoloader');
require_once '../config.php';
require_once 'orm.php';
require_once 'autoload/PEAR2/Autoload.php';
include "autoload/Hookers.php";
if(php_sapi_name() !== 'cli'){
echo "<pre>";
}
require_once '../config.php';
require_once 'orm.php';
require_once 'autoload/PEAR2/Autoload.php';
include "autoload/Hookers.php";
ORM::configure("mysql:host=$db_host;dbname=$db_name");
ORM::configure('username', $db_user);
@ -65,6 +69,14 @@ $d = ORM::for_table('tbl_user_recharges')->where('status', 'on')->find_many();
run_hook('cronjob_reminder'); #HOOK
echo "PHP Time\t" . date('Y-m-d H:i:s') . "\n";
$res = ORM::raw_execute('SELECT NOW() AS WAKTU;');
$statement = ORM::get_last_statement();
$rows = array();
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
echo "MYSQL Time\t" . $row['WAKTU'] . "\n";
}
$day7 = date('Y-m-d', strtotime("+7 day"));
$day3 = date('Y-m-d', strtotime("+3 day"));

View File

@ -387,3 +387,16 @@ $_L['Minimum_Transfer'] = 'Minimum Transfer';
$_L['Company_Logo'] = 'Company Logo';
$_L['Expired_IP_Pool'] = 'Expired IP Pool';
$_L['Expired_IP_Pool'] = 'Expired IP Pool';
$_L['Proxy'] = 'Proxy';
$_L['Proxy_Server'] = 'Proxy Server';
$_L['Proxy_Server_Login'] = 'Proxy Server Login';
$_L['Hotspot_Plan'] = 'Hotspot Plan';
$_L['PPPOE_Plan'] = 'PPPOE Plan';
$_L['UNKNOWN'] = 'UNKNOWN';
$_L['Are_You_Sure'] = 'Are You Sure?';
$_L['Success_to_send_package'] = 'Success to send package';
$_L['Target_has_active_plan_different_with_current_plant'] = 'Target has active plan, different with current plant.';
$_L['Recharge_a_friend'] = 'Recharge a friend';
$_L['Buy_for_friend'] = 'Buy for friend';
$_L['Buy_this_for_friend_account'] = 'Buy this for friend account?';
$_L['Review_package_before_recharge'] = 'Review package before recharge';

View File

@ -80,6 +80,7 @@
<b>[[type]]</b> is Hotspot/PPPOE.<br>
<b>[[plan_name]]</b> Internet Package.<br>
<b>[[plan_price]]</b> Internet Package Prices.<br>
<b>[[name]]</b> Receiver name.<br>
<b>[[user_name]]</b> Username internet.<br>
<b>[[user_password]]</b> User password.<br>
<b>[[expired_date]]</b> Expired datetime.<br>
@ -106,9 +107,12 @@
<b>[[type]]</b> is Hotspot/PPPOE.<br>
<b>[[plan_name]]</b> Internet Package.<br>
<b>[[plan_price]]</b> Internet Package Prices.<br>
<b>[[name]]</b> Receiver name.<br>
<b>[[user_name]]</b> Username internet.<br>
<b>[[user_password]]</b> User password.<br>
<b>[[trx_date]]</b> Transaction datetime.<br>
<b>[[balance_before]]</b> Balance Before.<br>
<b>[[balance]]</b> Balance After.<br>
<b>[[footer]]</b> Invoice Footer.
</p>
</div>
@ -122,7 +126,8 @@
</div>
<p class="col-md-4 help-block">
<b>[[name]]</b> Receiver name.<br>
<b>[[balance]]</b> how much balance have been send.
<b>[[balance]]</b> how much balance have been send.<br>
<b>[[current_balance]]</b> Current Balance.
</p>
</div>
</div>
@ -135,7 +140,8 @@
</div>
<p class="col-md-4 help-block">
<b>[[name]]</b> Sender name.<br>
<b>[[balance]]</b> how much balance have been received.
<b>[[balance]]</b> how much balance have been received.<br>
<b>[[current_balance]]</b> Current Balance.
</p>
</div>
</div>

View File

@ -24,7 +24,8 @@
<label class="col-md-2 control-label">{Lang::T('Company Logo')}</label>
<div class="col-md-6">
<input type="file" class="form-control" id="logo" name="logo" accept="image/*">
<span class="help-block">For PDF Reports | Best size 1078 x 200 | uploaded image will be autosize</span>
<span class="help-block">For PDF Reports | Best size 1078 x 200 | uploaded image will be
autosize</span>
</div>
<span class="help-block col-md-4">
<a href="./{$logo}" target="_blank"><img src="./{$logo}" height="48" alt="logo for PDF"></a>
@ -135,7 +136,8 @@
<div class="form-group">
<label class="col-md-2 control-label">Telegram Bot Token</label>
<div class="col-md-6">
<input type="text" class="form-control" id="telegram_bot" name="telegram_bot"
<input type="password" class="form-control" id="telegram_bot" name="telegram_bot" onmouseleave="this.type = 'password'"
onmouseenter="this.type = 'text'"
value="{$_c['telegram_bot']}" placeholder="123456:asdasgdkuasghddlashdashldhalskdklasd">
</div>
</div>
@ -270,7 +272,6 @@
</div>
{Lang::T('Invoice')}
</div>
<div class="panel-heading"></div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Invoice Footer')}</label>
@ -281,6 +282,30 @@
</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>
{Lang::T('Proxy')}
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Proxy Server')}</label>
<div class="col-md-6">
<input type="text" class="form-control" id="http_proxy" name="http_proxy"
value="{$_c['http_proxy']}" placeholder="127.0.0.1:3128">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Proxy Server Login')}</label>
<div class="col-md-6">
<input type="password" class="form-control" id="http_proxyauth" name="http_proxyauth" autocomplete="off"
value="{$_c['http_proxyauth']}" placeholder="username:password" onmouseleave="this.type = 'password'"
onmouseenter="this.type = 'text'">
</div>
</div>
</div>
</div>
<div class="panel-body">

View File

@ -1,4 +1,4 @@
<option value="">Select Plans</option>
{foreach $d as $ds}
<option value="{$ds['id']}">{$ds['name_plan']}</option>
<option value="{$ds['id']}">{$ds['name_plan']} &bull; {Lang::moneyFormat($ds['price'])}</option>
{/foreach}

View File

@ -130,7 +130,7 @@
</div>
</div>
</div>
<div class="col-sm-6">
<div class="col-sm-6" id="update">
<div class="box box-primary box-hovered mb20 activities">
<div class="box-header">
<h3 class="box-title">PHPNUXBILL</h3>

View File

@ -24,34 +24,37 @@
</div>&nbsp;
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{$_L['Manage']}</th>
<th>{$_L['Username']}</th>
<th>{$_L['Full_Name']}</th>
<th>{Lang::T('Balance')}</th>
<th>{$_L['Phone_Number']}</th>
<th>{$_L['Email']}</th>
<th>{$_L['Package']}</th>
<th>{$_L['Created_On']}</th>
<th>{$_L['Recharge']}</th>
<th>{$_L['Manage']}</th>
</tr>
</thead>
<tbody>
{foreach $d as $ds}
<tr>
<td align="center">
<a href="{$_url}customers/view/{$ds['id']}" id="{$ds['id']}"
class="btn btn-success btn-sm">{Lang::T('View')}</a>
</td>
<td>{$ds['username']}</td>
<td>{$ds['fullname']}</td>
<td onclick="window.location.href = '{$_url}customers/view/{$ds['id']}'" style="cursor:pointer;">{$ds['username']}</td>
<td onclick="window.location.href = '{$_url}customers/view/{$ds['id']}'" style="cursor: pointer;">{$ds['fullname']}</td>
<td>{Lang::moneyFormat($ds['balance'])}</td>
<td>{$ds['phonenumber']}</td>
<td>{$ds['email']}</td>
<td align="center" api-get-text="{$_url}autoload/customer_is_active/{$ds['id']}">
<span class="label label-default">&bull;</span>
</td>
<td>{Lang::dateTimeFormat($ds['created_at'])}</td>
<td align="center"><a href="{$_url}prepaid/recharge-user/{$ds['id']}" id="{$ds['id']}"
class="btn btn-primary btn-sm">{$_L['Recharge']}</a></td>
<td align="center">
<a href="{$_url}customers/view/{$ds['id']}" id="{$ds['id']}" style="margin: 0px;"
class="btn btn-success btn-xs">&nbsp;&nbsp;{Lang::T('View')}&nbsp;&nbsp;</a>
<a href="{$_url}prepaid/recharge-user/{$ds['id']}" id="{$ds['id']}" style="margin: 0px;"
class="btn btn-primary btn-xs">{$_L['Recharge']}</a>
</td>
</tr>
{/foreach}
</tbody>

View File

@ -33,7 +33,7 @@
<div class="col-lg-3 col-xs-6">
<div class="small-box bg-yellow">
<div class="inner">
<h4>{$u_act}</h4>
<h4>{$u_act}/{$u_all}</h4>
<p>{$_L['Users_Active']}</p>
</div>
@ -47,7 +47,7 @@
<div class="col-lg-3 col-xs-6">
<div class="small-box bg-red">
<div class="inner">
<h4>{$u_all}</h4>
<h4>{$c_all}</h4>
<p>{$_L['Total_Users']}</p>
</div>

BIN
ui/ui/images/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

View File

@ -28,12 +28,15 @@
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Created_On']}</label>
<div class="col-md-6">
<input type="date" class="form-control" id="recharged_on" name="recharged_on" readonly
value="{$d['recharged_on']} {$d['recharged_time']}">
<div class="col-md-4">
<input type="date" class="form-control" name="expiration" readonly
value="{$d['recharged_on']}">
</div>
<div class="col-md-2">
<input type="text" class="form-control" placeholder="00:00:00" readonly
value="{$d['recharged_time']}">
</div>
</div>
<div class="form-group">

View File

@ -53,6 +53,7 @@
<a href="{$_url}prepaid/edit/{$ds['id']}"
class="btn btn-warning btn-xs">{$_L['Edit']}</a>
<a href="{$_url}prepaid/delete/{$ds['id']}" id="{$ds['id']}"
onclick="return confirm('{$_L['Delete']}?')"
class="btn btn-danger btn-xs">{$_L['Delete']}</a>
</td>
</tr>

View File

@ -4,7 +4,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Router Error - PHPNuxBill</title>
<title>Error - PHPNuxBill</title>
<link rel="shortcut icon" href="ui/ui/images/logo.png" type="image/x-icon" />
<link rel="stylesheet" href="ui/ui/styles/bootstrap.min.css">
@ -32,27 +32,45 @@
<body class="hold-transition skin-blue">
<div class="container">
<section class="content-header">
<h1 class="text-center">
Router Error
</h1>
</section>
<section class="content">
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<div class="alert alert-danger text-center">
{$error_meesage}
<div class="col-md-3">
<img src="./ui/ui/images/error.png" class="img-responsive hidden-sm hidden-xs">
</div>
<a href="javascript::history.back()" onclick="history.back()" class="btn btn-warning btn-block">back</a>
<div class="col-md-6">
<div class="box box-danger box-solid text-center">
<section class="content-header">
<h1 class="text-center">
{$error_title}
</h1>
</section>
<div class="box-title" style="font-size:xx-large; color:red">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
</div>
<div class="box-body" style="font-size: larger;">
<br><br>
{$error_message}
<br><br><br>
</div>
<div class="box-footer">
<div class="btn-group btn-group-justified" role="group" aria-label="...">
<a href="./update.php?step=4" class="btn btn-info btn-sm btn-block">Update Database</a>
<a href="{$_url}community#update" class="btn btn-primary btn-sm btn-block">Update
PHPNuxBill</a>
</div>
<br><br>
<a href="javascript::history.back()" onclick="history.back()"
class="btn btn-warning btn-block">back</a>
</div>
</div>
</div>
<div class="col-md-4">
<img src="./ui/ui/images/error.png" class="img-responsive hidden-md hidden-lg">
</div>
</div>
</section>
<footer class="footer text-center">
PHPNuxBill by <a href="https://github.com/hotspotbilling/phpnuxbill" rel="nofollow noreferrer noopener"
target="_blank">iBNuX</a>
</footer>
</div>
</body>

View File

@ -22,6 +22,13 @@
$(document).ready(function() {
$('.select2').select2({theme: "bootstrap"});
});
var listAtts = document.querySelectorAll(`[api-get-text]`);
listAtts.forEach(function(el) {
$.get(el.getAttribute('api-get-text'), function(data) {
el.innerHTML = data;
});
});
</script>
{/literal}

View File

@ -241,8 +241,8 @@
href="{$_url}settings/notifications">{Lang::T('User Notification')}</a></li>
<li {if $_routes[1] eq 'users'}class="active" {/if}><a
href="{$_url}settings/users">{$_L['Administrator_Users']}</a></li>
<li {if $_routes[1] eq 'dbstatus'}class="active" {/if}><a
href="{$_url}settings/dbstatus">{$_L['Backup_Restore']}</a></li>
{* <li {if $_routes[1] eq 'dbstatus'}class="active" {/if}><a
href="{$_url}settings/dbstatus">{$_L['Backup_Restore']}</a></li> *}
<li {if $_routes[0] eq 'pluginmanager'}class="active" {/if}>
<a href="{$_url}pluginmanager">{Lang::T('Plugin Manager')}</a>
</li>

View File

@ -6,23 +6,25 @@
</footer>
{else}
<footer class="main-footer">
PHPNuxBill by <a href="https://github.com/hotspotbilling/phpnuxbill" rel="nofollow noreferrer noopener" target="_blank">iBNuX</a>, Theme by <a href="https://adminlte.io/" rel="nofollow noreferrer noopener" target="_blank">AdminLTE</a>
PHPNuxBill by <a href="https://github.com/hotspotbilling/phpnuxbill" rel="nofollow noreferrer noopener"
target="_blank">iBNuX</a>, Theme by <a href="https://adminlte.io/" rel="nofollow noreferrer noopener"
target="_blank">AdminLTE</a>
</footer>
{/if}
</div>
</div>
<script src="ui/ui/scripts/jquery.min.js"></script>
<script src="ui/ui/scripts/bootstrap.min.js"></script>
<script src="ui/ui/scripts/adminlte.min.js"></script>
<script src="ui/ui/scripts/jquery.min.js"></script>
<script src="ui/ui/scripts/bootstrap.min.js"></script>
<script src="ui/ui/scripts/adminlte.min.js"></script>
<script src="ui/ui/scripts/plugins/select2.min.js"></script>
<script src="ui/ui/scripts/custom.js"></script>
<script src="ui/ui/scripts/plugins/select2.min.js"></script>
<script src="ui/ui/scripts/custom.js"></script>
{if isset($xfooter)}
{if isset($xfooter)}
{$xfooter}
{/if}
{/if}
{if $_c['tawkto'] != ''}
{if $_c['tawkto'] != ''}
<!--Start of Tawk.to Script-->
<script type="text/javascript">
var Tawk_API = Tawk_API || {},
@ -38,8 +40,19 @@
})();
</script>
<!--End of Tawk.to Script-->
{/if}
{/if}
</body>
{literal}
<script>
var listAtts = document.querySelectorAll(`[api-get-text]`);
listAtts.forEach(function(el) {
$.get(el.getAttribute('api-get-text'), function(data) {
el.innerHTML = data;
});
});
</script>
{/literal}
</body>
</html>

View File

@ -27,6 +27,15 @@
color: red;
background: yellow;
}
.content-wrapper{
margin-top: 50px;
}
@media (max-width: 767px) {
.content-wrapper{
margin-top: 100px;
}
}
</style>
{if isset($xheader)}
@ -37,8 +46,7 @@
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<header class="main-header">
<header class="main-header" style="position:fixed; width: 100%">
<a href="{$_url}home" class="logo">
<span class="logo-mini"><b>N</b>uX</span>
<span class="logo-lg">{$_c['CompanyName']}</span>
@ -47,8 +55,10 @@
<a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
<span class="sr-only">Toggle navigation</span>
</a>
{if $_c['enable_balance'] == 'yes'}
<p class="navbar-text text-white" style="float: inline-start; color: whitesmoke; text-align: center !important;">{Lang::T('Balance')} {Lang::moneyFormat($_user['balance'])}</p>
{/if}
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
@ -94,7 +104,7 @@
</nav>
</header>
<aside class="main-sidebar">
<aside class="main-sidebar" style="position:fixed;">
<section class="sidebar">
<ul class="sidebar-menu" data-widget="tree">
<li {if $_system_menu eq 'home'}class="active" {/if}>

View File

@ -104,7 +104,6 @@
{if $_bill['time'] ne ''}{Lang::dateAndTimeFormat($_bill['expiration'],$_bill['time'])}{/if}&nbsp;
</td>
</tr>
{if $_bill['type'] == 'Hotspot' && $_bill['status'] == 'on'}
{if $nux_ip}
<tr>
<td class="small text-primary text-uppercase text-normal">{Lang::T('Current IP')}</td>
@ -117,6 +116,7 @@
<td class="small mb15">{$nux_mac}</td>
</tr>
{/if}
{if $_bill['type'] == 'Hotspot' && $_bill['status'] == 'on'}
<tr>
<td class="small text-primary text-uppercase text-normal">{Lang::T('Login Status')}</td>
<td class="small mb15" id="login_status">
@ -167,7 +167,7 @@
</div>
<div class="form-group col-sm-2" align="center">
<button class="btn btn-success btn-block" id="sendBtn" type="submit" name="send"
value="balance"><i class="glyphicon glyphicon-send"></i></button>
onclick="return confirm('{Lang::T("Are You Sure?")}')" value="balance"><i class="glyphicon glyphicon-send"></i></button>
</div>
</div>
</form>
@ -183,6 +183,23 @@
}
</script>
</div>
<div class="box-header">
<h4 class="box-title">{Lang::T("Recharge a friend")}</h4>
</div>
<div class="box-body p-0">
<form method="post" role="form" action="{$_url}home">
<div class="form-group">
<div class="col-sm-10">
<input type="text" id="username" name="username" class="form-control" required
placeholder="{$_L['Username']}">
</div>
<div class="form-group col-sm-2" align="center">
<button class="btn btn-success btn-block" id="sendBtn" type="submit" name="send"
onclick="return confirm('{Lang::T("Are You Sure?")}')" value="plan"><i class="glyphicon glyphicon-send"></i></button>
</div>
</div>
</form>
</div>
</div>
{/if}
<br>

View File

@ -33,10 +33,6 @@
{/foreach}
</div>
</div>
<div class="box box-solid box-success">
<div class="box-header text-center text-bold">{Lang::T('Balance')} {Lang::moneyFormat($_user['balance'])}</div>
</div>
{/if}
{foreach $routers as $router}
<div class="box box-solid box-info">
@ -47,7 +43,7 @@
</div>
{/if}
{if count($plans_hotspot)>0}
<div class="box-header">Hotspot</div>
<div class="box-header">{Lang::T('Hotspot Plan')}</div>
<div class="box-body row">
{foreach $plans_hotspot as $plan}
{if $router['name'] eq $plan['routers']}
@ -83,6 +79,11 @@
class="btn btn-sm btn-block btn-success">{Lang::T('Pay With Balance')}</a>
{/if}
</div>
{if $_c['enable_balance'] == 'yes' && $_c['allow_balance_transfer'] == 'yes' && $_user['balance']>=$plan['price']}
<a href="{$_url}order/send/{$router['id']}/{$plan['id']}"
onclick="return confirm('{Lang::T('Buy this for friend account?')}')"
class="btn btn-sm btn-block btn-primary">{Lang::T('Buy for friend')}</a>
{/if}
</div>
</div>
</div>
@ -91,7 +92,7 @@
</div>
{/if}
{if count($plans_pppoe)>0}
<div class="box-header text-sm">PPPOE</div>
<div class="box-header text-sm">{Lang::T('PPPOE Plan')}</div>
<div class="box-body row">
{foreach $plans_pppoe as $plan}
{if $router['name'] eq $plan['routers']}
@ -127,6 +128,11 @@
class="btn btn-sm btn-block btn-success">{Lang::T('Pay With Balance')}</a>
{/if}
</div>
{if $_c['enable_balance'] == 'yes' && $_c['allow_balance_transfer'] == 'yes' && $_user['balance']>=$plan['price']}
<a href="{$_url}order/send/{$router['id']}/{$plan['id']}"
onclick="return confirm('{Lang::T('Buy this for friend account?')}')"
class="btn btn-sm btn-block btn-primary">{Lang::T('Buy for friend')}</a>
{/if}
</div>
</div>
</div>

43
ui/ui/user-sendPlan.tpl Normal file
View File

@ -0,0 +1,43 @@
{include file="sections/user-header.tpl"}
<!-- user-orderView -->
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<div class="box box-solid box-default">
<div class="box-header">{$plan['name_plan']}</div>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<tbody>
<tr>
<td>{Lang::T('Type')}</td>
<td>{$plan['type']}</td>
</tr>
<tr>
<td>{Lang::T('Price')}</td>
<td>{Lang::moneyFormat($plan['price'])}</td>
</tr>
<tr>
<td>{Lang::T('Validity')}</td>
<td>{$plan['validity']} {$plan['validity_unit']}</td>
</tr>
</tbody>
</table>
</div>
<div class="box-footer">
<form method="post" onsubmit="return askConfirm()" role="form">
<div class="form-group">
<div class="col-sm-9">
<input type="text" id="username" name="username" class="form-control" required value="{$username}"
placeholder="{$_L['Username']}">
</div>
<div class="form-group col-sm-3" align="center">
<button class="btn btn-success btn-block" id="sendBtn" type="submit" name="send" onclick="return confirm('{Lang::T("Are You Sure?")}')"
value="plan"><i class="glyphicon glyphicon-send"></i></button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file="sections/user-footer.tpl"}

View File

@ -1,3 +1,3 @@
{
"version": "2023.9.6"
"version": "2023.9.13"
}