Merge pull request #12 from hotspotbilling/Development

Update with Balance System
This commit is contained in:
iBNu Maksum 2023-08-15 10:42:47 +07:00 committed by GitHub
commit 8cb277f6d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 1575 additions and 396 deletions

4
.gitignore vendored
View File

@ -20,3 +20,7 @@ system/plugin/ui/*
ui/ui_custom/** ui/ui_custom/**
!ui/ui_custom/index.html !ui/ui_custom/index.html
!ui/ui_custom/README.md !ui/ui_custom/README.md
system/uploads/admin.png
system/uploads/logo.png
system/uploads/user.jpg
system/uploads/notifications.json

View File

@ -2,12 +2,28 @@
# CHANGELOG # CHANGELOG
## 2023.8.15
- Fix PPPOE Delete Customer
- Fix Header Admin and Customer
- Fix PDF Export by Period
- Add pppoe_password for Customer, this pppoe_password only admin can change
- Country Code Number Settings
- Customer Meta Table for Custom Fields
- Fix Add and Edit Customer Form for admin
- add Notification Message Editor
- cron reminder
- Balance System, Customer can deposit money
- Auto renewal when package expired using Customer Balance
## 2023.8.1 ## 2023.8.1
- Add Update file script, one click updating PHPNuxBill - Add Update file script, one click updating PHPNuxBill
- Add Custom UI folder, to custome your own template - Add Custom UI folder, to custome your own template
- Delete debug text - Delete debug text
- Fix Vendor JS - Fix Vendor JS
## 2023.7.28 ## 2023.7.28
- Fix link buy Voucher - Fix link buy Voucher
@ -22,13 +38,13 @@
Because the first time phpmixbill created, plan validity only for days and Months, many request ask for minutes and hours, i change it, but not the database. Because the first time phpmixbill created, plan validity only for days and Months, many request ask for minutes and hours, i change it, but not the database.
## 2023.6.15 ## 2023.6.15
- User can connect to internet from User Dashboard - Customer can connect to internet from Customer Dashboard
- Fix Confirm when delete - Fix Confirm when delete
- Change Logo PHPNuxBill - Change Logo PHPNuxBill
- Using Composer - Using Composer
- Fix Search User - Fix Search Customer
- Fix user check, if not found will logout - Fix Customer check, if not found will logout
- User password show but hidden - Customer password show but hidden
- Voucher code hidden - Voucher code hidden
## 2023.6.8 ## 2023.6.8

View File

@ -33,8 +33,10 @@ Minimum Requirements
- Linux or Windows OS - Linux or Windows OS
- PHP Version 7.4 - PHP Version 7.4
- Both PDO & MySQLi Support - Both PDO & MySQLi Support
- GD2 Image Library - PHP-GD2 Image Library
- CURL support - PHP-CURL
- PHP-ZIP
- PHP-Mbstring
- MySQL Version 4.1.x and above - MySQL Version 4.1.x and above
can be Installed in Raspberry Pi Device. can be Installed in Raspberry Pi Device.
@ -48,6 +50,10 @@ The problem with windows is hard to set cronjob, better Linux
[Installation instructions](https://github.com/hotspotbilling/phpnuxbill/wiki) [Installation instructions](https://github.com/hotspotbilling/phpnuxbill/wiki)
## Docker Version
[Docker Repository](https://github.com/animegasan/phpnuxbill)
## RADIUS system ## RADIUS system
Still on development Still on development

View File

@ -50,10 +50,13 @@ CREATE TABLE
`id` int(10) NOT NULL, `id` int(10) NOT NULL,
`username` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `username` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`password` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `password` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`pppoe_password` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1',
`fullname` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fullname` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`address` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci, `address` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`phonenumber` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0', `phonenumber` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
`email` varchar(128) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1', `email` varchar(128) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1',
`balance` decimal(15,2) NOT NULL COMMENT 'For Money Deposit',
`auto_renewal` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Auto renewal from balance',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_login` datetime DEFAULT NULL `last_login` datetime DEFAULT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci; ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
@ -295,6 +298,19 @@ CREATE TABLE
`status` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL `status` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci; ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
--
-- Struktur dari tabel `tbl_customers_meta`
--
CREATE TABLE `tbl_customers_meta` (
`id` int(11) NOT NULL,
`customer_id` int(11) NOT NULL,
`meta_key` varchar(64) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
`meta_value` longtext COLLATE utf8mb4_general_ci
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- --
-- Indexes for dumped tables -- Indexes for dumped tables
@ -543,6 +559,17 @@ ALTER TABLE
ALTER TABLE ALTER TABLE
`tbl_voucher` MODIFY `id` int(10) NOT NULL AUTO_INCREMENT; `tbl_voucher` MODIFY `id` int(10) NOT NULL AUTO_INCREMENT;
--
-- Indeks untuk tabel `tbl_customers_meta`
--
ALTER TABLE `tbl_customers_meta`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT untuk tabel `tbl_customers_meta`
--
ALTER TABLE `tbl_customers_meta`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT; COMMIT;
-- --

View File

@ -57,7 +57,7 @@
<a href=\"step3.php\" class=\"btn btn-primary\">Continue</a><br><br><a href=\"update.php\" class=\"btn btn-primary\">Update System</a>"); <a href=\"step3.php\" class=\"btn btn-primary\">Continue</a><br><br><a href=\"update.php\" class=\"btn btn-primary\">Update System</a>");
} else { } else {
echo ("<br/> $ltext <br/> Sorry. The requirements of PHPNuxBill is not available on your server. echo ("<br/> $ltext <br/> Sorry. The requirements of PHPNuxBill is not available on your server.
Please contact with us- iesien22@yahoo.com with this code- $passed Or contact with your server administrator Contact with us at Telegram <a href=\"https://t.me/phpnuxbill\">@phpnuxbill</a> with this code- $passed Or contact with your server administrator
<br><br> <br><br>
<a href=\"#\" class=\"btn btn-primary disabled\">Correct The Problem To Continue</a>"); <a href=\"#\" class=\"btn btn-primary disabled\">Correct The Problem To Continue</a>");
} }

View File

@ -0,0 +1,71 @@
<?php
/**
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
* This script is for managing user balance
**/
class Balance
{
public static function plus($id_customer, $amount)
{
$c = ORM::for_table('tbl_customers')->where('id', $id_customer)->find_one();
$c->balance = $amount + $c['balance'];
$c->save();
}
public static function transfer($id_customer, $phoneTarget, $amount)
{
global $config;
if ($config['allow_balance_transfer'] == 'yes') {
if(Balance::min($id_customer, $amount)){
if(Balance::plusByPhone($phoneTarget, $amount)){
return true;
}else{
Balance::plus($id_customer, $amount);
return false;
}
}else{
return false;
}
}else{
return false;
}
}
public static function min($id_customer, $amount)
{
$c = ORM::for_table('tbl_customers')->where('id', $id_customer)->find_one();
if ($c && $c['balance'] >= $amount) {
$c->balance = $amount - $c['balance'];
$c->save();
return true;
} else {
return false;
}
}
public static function plusByPhone($phone_customer, $amount)
{
$c = ORM::for_table('tbl_customers')->where('username', $phone_customer)->find_one();
if($c){
$c->balance = $amount + $c['balance'];
$c->save();
return true;
}
return false;
}
public static function minByPhone($phone_customer, $amount)
{
$c = ORM::for_table('tbl_customers')->where('username', $phone_customer)->find_one();
if ($c && $c['balance'] >= $amount) {
$c->balance = $amount - $c['balance'];
$c->save();
return true;
} else {
return false;
}
}
}

View File

@ -4,12 +4,31 @@
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/) * PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
**/ **/
class Lang { class Lang
public static function T($var) { {
public static function T($var)
{
return Lang($var); return Lang($var);
} }
public static function htmlspecialchars($var) { public static function htmlspecialchars($var)
{
return htmlspecialchars($var); return htmlspecialchars($var);
} }
public static function moneyFormat($var)
{
global $config;
return $config['currency_code'] . ' ' .number_format($var, 0, $config['dec_point'], $config['thousands_sep']);
}
public static function phoneFormat($phone)
{
global $config;
if(Validator::UnsignedNumber($phone) && !empty($config['country_code_phone'])){
return preg_replace('/^0/', $config['country_code_phone'], $phone);
}else{
return $phone;
}
}
} }

View File

@ -39,20 +39,21 @@ class Message
} }
} }
public static function sendExpiredNotification($phone, $name, $package, $textExpired, $via) public static function sendPackageNotification($phone, $name, $package, $message, $via)
{ {
$msg = str_replace('[[name]]', "*$name*", $message);
$msg = str_replace('[[package]]', "*$package*", $msg);
if ( if (
!empty($phone) && strlen($phone) > 5 !empty($phone) && strlen($phone) > 5
&& !empty($textExpired) && in_array($via, ['sms', 'wa']) && !empty($message) && in_array($via, ['sms', 'wa'])
) { ) {
$msg = str_replace('[[name]]', "*$name*", $textExpired);
$msg = str_replace('[[package]]', "*$package*", $msg);
if ($via == 'sms') { if ($via == 'sms') {
Message::sendSMS($phone, $msg); Message::sendSMS($phone, $msg);
} else if ($via == 'wa') { } else if ($via == 'wa') {
Message::sendWhatsapp($phone, $msg); Message::sendWhatsapp($phone, $msg);
} }
} }
return "$via: $msg";
} }
} }

View File

@ -204,24 +204,29 @@ class Mikrotik
'/ppp secret print .proplist=name', '/ppp secret print .proplist=name',
RouterOS\Query::where('name', $username) RouterOS\Query::where('name', $username)
); );
$userName = $client->sendSync($printRequest)->getProperty('name'); $id = $client->sendSync($printRequest)->getProperty('.id');
$removeRequest = new RouterOS\Request('/ppp/secret/remove'); $removeRequest = new RouterOS\Request('/ppp/secret/remove');
$client( $client(
$removeRequest $removeRequest
->setArgument('numbers', $userName) ->setArgument('numbers', $id)
); );
} }
public static function addPpoeUser($client, $plan, $customer) public static function addPpoeUser($client, $plan, $customer)
{ {
$addRequest = new RouterOS\Request('/ppp/secret/add'); $addRequest = new RouterOS\Request('/ppp/secret/add');
if(!empty($customer['pppoe_password'])){
$pass = $customer['pppoe_password'];
}else{
$pass = $customer['password'];
}
$client->sendSync( $client->sendSync(
$addRequest $addRequest
->setArgument('name', $customer['username']) ->setArgument('name', $customer['username'])
->setArgument('service', 'pppoe') ->setArgument('service', 'pppoe')
->setArgument('profile', $plan['name_plan']) ->setArgument('profile', $plan['name_plan'])
->setArgument('password', $customer['password']) ->setArgument('password', $pass)
); );
} }

View File

@ -19,7 +19,7 @@ class Package
*/ */
public static function rechargeUser($id_customer, $router_name, $plan_id, $gateway, $channel) public static function rechargeUser($id_customer, $router_name, $plan_id, $gateway, $channel)
{ {
global $_c, $_L; global $_c, $_L, $_notifmsg;
$date_now = date("Y-m-d H:i:s"); $date_now = date("Y-m-d H:i:s");
$date_only = date("Y-m-d"); $date_only = date("Y-m-d");
$time = date("H:i:s"); $time = date("H:i:s");
@ -30,6 +30,49 @@ class Package
$c = ORM::for_table('tbl_customers')->where('id', $id_customer)->find_one(); $c = ORM::for_table('tbl_customers')->where('id', $id_customer)->find_one();
$p = ORM::for_table('tbl_plans')->where('id', $plan_id)->where('enabled', '1')->find_one(); $p = ORM::for_table('tbl_plans')->where('id', $plan_id)->where('enabled', '1')->find_one();
if ($router_name == 'balance') {
// insert table transactions
$inv = "INV-" . _raid(5);
$t = ORM::for_table('tbl_transactions')->create();
$t->invoice = $inv;
$t->username = $c['username'];
$t->plan_name = $p['name_plan'];
$t->price = $p['price'];
$t->recharged_on = $date_only;
$t->expiration = $date_only;
$t->time = $time;
$t->method = "$gateway - $channel";
$t->routers = $router_name;
$t->type = "Balance";
$t->save();
Balance::plus($id_customer, $p['price']);
$textInvoice = $_notifmsg['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('[[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('[[user_name]]', $c['username'], $textInvoice);
$textInvoice = str_replace('[[user_password]]', $c['password'], $textInvoice);
if ($_c['user_notification_payment'] == 'sms') {
Message::sendSMS($c['phonenumber'], $textInvoice);
} else if ($_c['user_notification_payment'] == 'wa') {
Message::sendWhatsapp($c['phonenumber'], $textInvoice);
}
return true;
}
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->find_one(); $b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->find_one();
$mikrotik = Mikrotik::info($router_name); $mikrotik = Mikrotik::info($router_name);
@ -198,28 +241,25 @@ class Package
$in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one(); $in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one();
$msg = "*$_c[CompanyName]*\n" . $textInvoice = $_notifmsg['invoice_paid'];
"$_c[address]\n" . $textInvoice = str_replace('[[company_name]]', $_c['CompanyName'], $textInvoice);
"$_c[phone]\n" . $textInvoice = str_replace('[[address]]', $_c['address'], $textInvoice);
"\n\n" . $textInvoice = str_replace('[[phone]]', $_c['phone'], $textInvoice);
"INVOICE: *$in[invoice]*\n" . $textInvoice = str_replace('[[invoice]]', $in['invoice'], $textInvoice);
"$_L[Date] : $date_now\n" . $textInvoice = str_replace('[[date]]', date($_c['date_format'], strtotime($date_now)) . " " . $time, $textInvoice);
"$gateway $channel\n" . $textInvoice = str_replace('[[payment_gateway]]', $_c['gateway'], $textInvoice);
"\n\n" . $textInvoice = str_replace('[[payment_channel]]', $_c['channel'], $textInvoice);
"$_L[Type] : *$in[type]*\n" . $textInvoice = str_replace('[[type]]', $in['type'], $textInvoice);
"$_L[Plan_Name] : *$in[plan_name]*\n" . $textInvoice = str_replace('[[plan_name]]', $in['plan_name'], $textInvoice);
"$_L[Plan_Price] : *$_c[currency_code] " . number_format($in['price'], 2, $_c['dec_point'], $_c['thousands_sep']) . "*\n\n" . $textInvoice = str_replace('[[plan_price]]', $_c['currency_code'] . " " . number_format($in['price'], 2, $_c['dec_point'], $_c['thousands_sep']), $textInvoice);
"$_L[Username] : *$in[username]*\n" . $textInvoice = str_replace('[[user_name]]', $in['username'], $textInvoice);
"$_L[Password] : **********\n\n" . $textInvoice = str_replace('[[user_password]]', $c['password'], $textInvoice);
"$_L[Created_On] :\n*" . date($_c['date_format'], strtotime($in['recharged_on'])) . "*\n" . $textInvoice = str_replace('[[expired_date]]', date($_c['date_format'], strtotime($in['expiration'])) . " " . $in['time'], $textInvoice);
"$_L[Expires_On] :\n*" . date($_c['date_format'], strtotime($in['expiration'])) . " $in[time]*\n" .
"\n\n" .
"$_c[note]";
if ($_c['user_notification_payment'] == 'sms') { if ($_c['user_notification_payment'] == 'sms') {
Message::sendSMS($c['phonenumber'], $msg); Message::sendSMS($c['phonenumber'], $textInvoice);
} else if ($_c['user_notification_payment'] == 'wa') { } else if ($_c['user_notification_payment'] == 'wa') {
Message::sendWhatsapp($c['phonenumber'], $msg); Message::sendWhatsapp($c['phonenumber'], $textInvoice);
} }
return true; return true;
} }

View File

@ -128,6 +128,12 @@ if (isset($_SESSION['notify'])) {
include "autoload/Hookers.php"; include "autoload/Hookers.php";
// notification message
if(file_exists("system/uploads/notifications.json")){
$_notifmsg =json_decode(file_get_contents('system/uploads/notifications.json'), true);
}else{
$_notifmsg = json_decode(file_get_contents('system/uploads/notifications.default.json'), true);
}
//register all plugin //register all plugin
foreach (glob("system/plugin/*.php") as $filename) { foreach (glob("system/plugin/*.php") as $filename) {

View File

@ -59,7 +59,11 @@ switch ($action) {
} else { } else {
if (!$config['radius_mode']) { if (!$config['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
if(!empty($d['pppoe_password'])){
Mikrotik::setPpoeUser($client, $c['username'], $d['pppoe_password']);
}else{
Mikrotik::setPpoeUser($client, $c['username'], $npass); Mikrotik::setPpoeUser($client, $c['username'], $npass);
}
Mikrotik::removePpoeActive($client, $user['username']); Mikrotik::removePpoeActive($client, $user['username']);
} }
$d->password = $npass; $d->password = $npass;

View File

@ -116,7 +116,8 @@ switch ($action) {
$username = _post('username'); $username = _post('username');
$fullname = _post('fullname'); $fullname = _post('fullname');
$password = _post('password'); $password = _post('password');
$cpassword = _post('cpassword'); $pppoe_password = _post('pppoe_password');
$email = _post('email');
$address = _post('address'); $address = _post('address');
$phonenumber = _post('phonenumber'); $phonenumber = _post('phonenumber');
run_hook('add_customer'); #HOOK run_hook('add_customer'); #HOOK
@ -130,9 +131,6 @@ switch ($action) {
if (!Validator::Length($password, 35, 2)) { if (!Validator::Length($password, 35, 2)) {
$msg .= 'Password should be between 3 to 35 characters' . '<br>'; $msg .= 'Password should be between 3 to 35 characters' . '<br>';
} }
if ($password != $cpassword) {
$msg .= 'Passwords does not match' . '<br>';
}
$d = ORM::for_table('tbl_customers')->where('username', $username)->find_one(); $d = ORM::for_table('tbl_customers')->where('username', $username)->find_one();
if ($d) { if ($d) {
@ -141,11 +139,13 @@ switch ($action) {
if ($msg == '') { if ($msg == '') {
$d = ORM::for_table('tbl_customers')->create(); $d = ORM::for_table('tbl_customers')->create();
$d->username = $username; $d->username = Lang::phoneFormat($username);
$d->password = $password; $d->password = $password;
$d->pppoe_password = $pppoe_password;
$d->email = $email;
$d->fullname = $fullname; $d->fullname = $fullname;
$d->address = $address; $d->address = $address;
$d->phonenumber = $username; $d->phonenumber = Lang::phoneFormat($phonenumber);
$d->save(); $d->save();
r2(U . 'customers/list', 's', $_L['account_created_successfully']); r2(U . 'customers/list', 's', $_L['account_created_successfully']);
} else { } else {
@ -154,27 +154,25 @@ switch ($action) {
break; break;
case 'edit-post': case 'edit-post':
$username = _post('username'); $username = Lang::phoneFormat(_post('username'));
$fullname = _post('fullname'); $fullname = _post('fullname');
$password = _post('password'); $password = _post('password');
$cpassword = _post('cpassword'); $pppoe_password = _post('pppoe_password');
$email = _post('email');
$address = _post('address'); $address = _post('address');
$phonenumber = _post('phonenumber'); $phonenumber = Lang::phoneFormat(_post('phonenumber'));
run_hook('edit_customer'); #HOOK run_hook('edit_customer'); #HOOK
$msg = ''; $msg = '';
if (Validator::Length($username, 16, 2) == false) { if (Validator::Length($username, 16, 2) == false) {
$msg .= 'Username should be between 3 to 15 characters' . '<br>'; $msg .= 'Username should be between 3 to 15 characters' . '<br>';
} }
if (Validator::Length($fullname, 26, 2) == false) { if (Validator::Length($fullname, 26, 1) == false) {
$msg .= 'Full Name should be between 3 to 25 characters' . '<br>'; $msg .= 'Full Name should be between 2 to 25 characters' . '<br>';
} }
if ($password != '') { if ($password != '') {
if (!Validator::Length($password, 15, 2)) { if (!Validator::Length($password, 15, 2)) {
$msg .= 'Password should be between 3 to 15 characters' . '<br>'; $msg .= 'Password should be between 3 to 15 characters' . '<br>';
} }
if ($password != $cpassword) {
$msg .= 'Passwords does not match' . '<br>';
}
} }
$id = _post('id'); $id = _post('id');
@ -206,7 +204,11 @@ switch ($action) {
} else { } else {
if(!$config['radius_mode']){ if(!$config['radius_mode']){
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
if(!empty($d['pppoe_password'])){
Mikrotik::setPpoeUser($client, $c['username'], $d['pppoe_password']);
}else{
Mikrotik::setPpoeUser($client, $c['username'], $password); Mikrotik::setPpoeUser($client, $c['username'], $password);
}
Mikrotik::removePpoeActive($client,$user['username']); Mikrotik::removePpoeActive($client,$user['username']);
} }
@ -217,7 +219,9 @@ switch ($action) {
if ($password != '') { if ($password != '') {
$d->password = $password; $d->password = $password;
} }
$d->pppoe_password = $pppoe_password;
$d->fullname = $fullname; $d->fullname = $fullname;
$d->email = $email;
$d->address = $address; $d->address = $address;
$d->phonenumber = $phonenumber; $d->phonenumber = $phonenumber;
$d->save(); $d->save();
@ -227,6 +231,8 @@ switch ($action) {
$d->password = $password; $d->password = $password;
} }
$d->fullname = $fullname; $d->fullname = $fullname;
$d->pppoe_password = $pppoe_password;
$d->email = $email;
$d->address = $address; $d->address = $address;
$d->phonenumber = $phonenumber; $d->phonenumber = $phonenumber;
$d->save(); $d->save();

View File

@ -61,6 +61,12 @@ switch ($action) {
$title = ' Reports [' . $mdate . ']'; $title = ' Reports [' . $mdate . ']';
$title = str_replace('-', ' ', $title); $title = str_replace('-', ' ', $title);
if(file_exists('system/uploads/logo.png')){
$logo = 'system/uploads/logo.png';
}else{
$logo = 'system/uploads/logo.default.png';
}
if ($x) { if ($x) {
$html = ' $html = '
<div id="page-wrap"> <div id="page-wrap">
@ -69,7 +75,7 @@ switch ($action) {
' . $config['address'] . '<br> ' . $config['address'] . '<br>
' . $_L['Phone_Number'] . ': ' . $config['phone'] . '<br> ' . $_L['Phone_Number'] . ': ' . $config['phone'] . '<br>
</div> </div>
<div id="logo"><img id="image" src="system/uploads/logo.png" alt="logo" /></div> <div id="logo"><img id="image" src="'.$logo.'" alt="logo" /></div>
</div> </div>
<div id="header">' . $_L['All_Transactions_at_Date'] . ': ' . date($config['date_format'], strtotime($mdate)) . '</div> <div id="header">' . $_L['All_Transactions_at_Date'] . ': ' . date($config['date_format'], strtotime($mdate)) . '</div>
<table id="customers"> <table id="customers">
@ -178,7 +184,6 @@ EOF;
if ($stype != '') { if ($stype != '') {
$d->where('type', $stype); $d->where('type', $stype);
} }
$d->where_gte('recharged_on', $fdate); $d->where_gte('recharged_on', $fdate);
$d->where_lte('recharged_on', $tdate); $d->where_lte('recharged_on', $tdate);
$d->order_by_desc('id'); $d->order_by_desc('id');
@ -207,7 +212,6 @@ EOF;
$fdate = _post('fdate'); $fdate = _post('fdate');
$tdate = _post('tdate'); $tdate = _post('tdate');
$stype = _post('stype'); $stype = _post('stype');
$d = ORM::for_table('tbl_transactions'); $d = ORM::for_table('tbl_transactions');
if ($stype != '') { if ($stype != '') {
$d->where('type', $stype); $d->where('type', $stype);
@ -229,6 +233,11 @@ EOF;
$title = ' Reports [' . $mdate . ']'; $title = ' Reports [' . $mdate . ']';
$title = str_replace('-', ' ', $title); $title = str_replace('-', ' ', $title);
if(file_exists('system/uploads/logo.png')){
$logo = 'system/uploads/logo.png';
}else{
$logo = 'system/uploads/logo.default.png';
}
if ($x) { if ($x) {
$html = ' $html = '
@ -238,7 +247,7 @@ EOF;
' . $config['address'] . '<br> ' . $config['address'] . '<br>
' . $_L['Phone_Number'] . ': ' . $config['phone'] . '<br> ' . $_L['Phone_Number'] . ': ' . $config['phone'] . '<br>
</div> </div>
<div id="logo"><img id="image" src="system/uploads/logo.png" alt="logo" /></div> <div id="logo"><img id="image" src="'.$logo.'" alt="logo" /></div>
</div> </div>
<div id="header">' . $_L['All_Transactions_at_Date'] . ': ' . date($config['date_format'], strtotime($fdate)) . ' - ' . date($config['date_format'], strtotime($tdate)) . '</div> <div id="header">' . $_L['All_Transactions_at_Date'] . ': ' . date($config['date_format'], strtotime($fdate)) . ' - ' . date($config['date_format'], strtotime($tdate)) . '</div>
<table id="customers"> <table id="customers">
@ -281,11 +290,7 @@ EOF;
<h3 class="sum">' . $config['currency_code'] . ' ' . number_format($xy, 2, $config['dec_point'], $config['thousands_sep']) . '</h3>'; <h3 class="sum">' . $config['currency_code'] . ' ' . number_format($xy, 2, $config['dec_point'], $config['thousands_sep']) . '</h3>';
run_hook('pdf_by_period'); #HOOK run_hook('pdf_by_period'); #HOOK
define('_MPDF_PATH', 'system/vendors/mpdf/'); $mpdf = new \Mpdf\Mpdf();
require('system/vendors/mpdf/mpdf.php');
$mpdf = new mPDF('c', 'A4', '', '', 20, 15, 25, 25, 10, 10);
$mpdf->SetProtection(array('print')); $mpdf->SetProtection(array('print'));
$mpdf->SetTitle($config['CompanyName'] . ' Reports'); $mpdf->SetTitle($config['CompanyName'] . ' Reports');
$mpdf->SetAuthor($config['CompanyName']); $mpdf->SetAuthor($config['CompanyName']);

View File

@ -9,6 +9,11 @@ $ui->assign('_title', $_L['Dashboard']);
$user = User::_info(); $user = User::_info();
$ui->assign('_user', $user); $ui->assign('_user', $user);
if(isset($_GET['renewal'])){
$user->auto_renewal = $_GET['renewal'];
$user->save();
}
//Client Page //Client Page
$bill = User::_billing(); $bill = User::_billing();

View File

@ -35,9 +35,13 @@ switch ($action) {
$ui->assign('_title', 'Order Plan'); $ui->assign('_title', 'Order Plan');
$ui->assign('_system_menu', 'package'); $ui->assign('_system_menu', 'package');
$routers = ORM::for_table('tbl_routers')->find_many(); $routers = ORM::for_table('tbl_routers')->find_many();
$plans = ORM::for_table('tbl_plans')->where('enabled', '1')->find_many(); $plans_pppoe = ORM::for_table('tbl_plans')->where('enabled', '1')->where('type', 'PPPOE')->find_many();
$plans_hotspot = ORM::for_table('tbl_plans')->where('enabled', '1')->where('type', 'Hotspot')->find_many();
$plans_balance = ORM::for_table('tbl_plans')->where('enabled', '1')->where('type', 'Balance')->find_many();
$ui->assign('routers', $routers); $ui->assign('routers', $routers);
$ui->assign('plans', $plans); $ui->assign('plans_pppoe', $plans_pppoe);
$ui->assign('plans_hotspot', $plans_hotspot);
$ui->assign('plans_balance', $plans_balance);
run_hook('customer_view_order_plan'); #HOOK run_hook('customer_view_order_plan'); #HOOK
$ui->display('user-orderPlan.tpl'); $ui->display('user-orderPlan.tpl');
break; break;
@ -118,12 +122,16 @@ switch ($action) {
run_hook('customer_buy_plan'); #HOOK run_hook('customer_buy_plan'); #HOOK
include 'system/paymentgateway/' . $config['payment_gateway'] . '.php'; include 'system/paymentgateway/' . $config['payment_gateway'] . '.php';
call_user_func($config['payment_gateway'] . '_validate_config'); call_user_func($config['payment_gateway'] . '_validate_config');
if ($routes['2'] != '0') {
$router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2'] * 1); $router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2']);
$plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3'] * 1);
if (empty($router) || empty($plan)) { if (empty($router) || empty($plan)) {
r2(U . $back, 'e', Lang::T("Plan Not found")); r2(U . $back, 'e', Lang::T("Plan Not found"));
} }
}else{
$router['id'] = 0;
$router['name'] = 'balance';
}
$plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3']);
$d = ORM::for_table('tbl_payment_gateway') $d = ORM::for_table('tbl_payment_gateway')
->where('username', $user['username']) ->where('username', $user['username'])
->where('status', 1) ->where('status', 1)
@ -172,5 +180,5 @@ switch ($action) {
} }
break; break;
default: default:
$ui->display('404.tpl'); r2(U . "order/package/", 's','');
} }

View File

@ -26,7 +26,8 @@ switch ($do) {
$cpassword = _post('cpassword'); $cpassword = _post('cpassword');
$address = _post('address'); $address = _post('address');
if(!empty($config['sms_url'])){ if(!empty($config['sms_url'])){
$phonenumber = $username; $phonenumber = Lang::phoneFormat($username);
$username = $phonenumber;
}else if(strlen($username)<21){ }else if(strlen($username)<21){
$phonenumber = $username; $phonenumber = $username;
} }

View File

@ -96,7 +96,7 @@ switch ($action) {
$validity = _post('validity'); $validity = _post('validity');
$validity_unit = _post('validity_unit'); $validity_unit = _post('validity_unit');
$routers = _post('routers'); $routers = _post('routers');
$enabled = _post('enabled')*1; $enabled = _post('enabled');
$msg = ''; $msg = '';
if (Validator::UnsignedNumber($validity) == false) { if (Validator::UnsignedNumber($validity) == false) {
@ -176,7 +176,7 @@ switch ($action) {
$validity = _post('validity'); $validity = _post('validity');
$validity_unit = _post('validity_unit'); $validity_unit = _post('validity_unit');
$routers = _post('routers'); $routers = _post('routers');
$enabled = _post('enabled')*1; $enabled = _post('enabled');
$msg = ''; $msg = '';
if (Validator::UnsignedNumber($validity) == false) { if (Validator::UnsignedNumber($validity) == false) {
@ -312,7 +312,7 @@ switch ($action) {
$validity_unit = _post('validity_unit'); $validity_unit = _post('validity_unit');
$routers = _post('routers'); $routers = _post('routers');
$pool = _post('pool_name'); $pool = _post('pool_name');
$enabled = _post('enabled')*1; $enabled = _post('enabled');
$msg = ''; $msg = '';
if (Validator::UnsignedNumber($validity) == false) { if (Validator::UnsignedNumber($validity) == false) {
@ -377,7 +377,7 @@ switch ($action) {
$validity_unit = _post('validity_unit'); $validity_unit = _post('validity_unit');
$routers = _post('routers'); $routers = _post('routers');
$pool = _post('pool_name'); $pool = _post('pool_name');
$enabled = _post('enabled')*1; $enabled = _post('enabled');
$msg = ''; $msg = '';
if (Validator::UnsignedNumber($validity) == false) { if (Validator::UnsignedNumber($validity) == false) {
@ -431,7 +431,112 @@ switch ($action) {
r2(U . 'services/pppoe-edit/' . $id, 'e', $msg); r2(U . 'services/pppoe-edit/' . $id, 'e', $msg);
} }
break; break;
case 'balance':
$ui->assign('_title', Lang::T('Balance Plans'));
$name = _post('name');
if ($name != '') {
$paginator = Paginator::bootstrap('tbl_plans', 'name_plan', '%' . $name . '%', 'type', 'Balance');
$d = ORM::for_table('tbl_plans')->where('tbl_plans.type', 'Balance')->where_like('tbl_plans.name_plan', '%' . $name . '%')->offset($paginator['startpoint'])->limit($paginator['limit'])->find_many();
} else {
$paginator = Paginator::bootstrap('tbl_plans', 'type', 'Hotspot');
$d = ORM::for_table('tbl_plans')->where('tbl_plans.type', 'Balance')->offset($paginator['startpoint'])->limit($paginator['limit'])->find_many();
}
$ui->assign('d', $d);
$ui->assign('paginator', $paginator);
run_hook('view_list_balance'); #HOOK
$ui->display('balance.tpl');
break;
case 'balance-add':
$ui->assign('_title', Lang::T('Balance Plans'));
run_hook('view_add_balance'); #HOOK
$ui->display('balance-add.tpl');
break;
case 'balance-edit':
$ui->assign('_title', Lang::T('Balance Plans'));
$id = $routes['2'];
$d = ORM::for_table('tbl_plans')->find_one($id);
$ui->assign('d', $d);
run_hook('view_edit_balance'); #HOOK
$ui->display('balance-edit.tpl');
break;
case 'balance-delete':
$id = $routes['2'];
$d = ORM::for_table('tbl_plans')->find_one($id);
if ($d) {
run_hook('delete_balance'); #HOOK
$d->delete();
r2(U . 'services/balance', 's', $_L['Delete_Successfully']);
}
break;
case 'balance-edit-post':
$id = _post('id');
$name = _post('name');
$price = _post('price');
$enabled = _post('enabled');
$msg = '';
if (Validator::UnsignedNumber($price) == false) {
$msg .= 'The price must be a number' . '<br>';
}
if ($name == '') {
$msg .= $_L['All_field_is_required'] . '<br>';
}
$d = ORM::for_table('tbl_plans')->where('id', $id)->find_one();
if ($d) {
} else {
$msg .= $_L['Data_Not_Found'] . '<br>';
}
run_hook('edit_ppoe'); #HOOK
if ($msg == '') {
$d->name_plan = $name;
$d->price = $price;
$d->enabled = $enabled;
$d->save();
r2(U . 'services/balance', 's', $_L['Updated_Successfully']);
} else {
r2(U . 'services/balance-edit/' . $id, 'e', $msg);
}
break;
case 'balance-add-post':
$name = _post('name');
$price = _post('price');
$enabled = _post('enabled');
$msg = '';
if (Validator::UnsignedNumber($price) == false) {
$msg .= 'The price must be a number' . '<br>';
}
if ($name == '') {
$msg .= $_L['All_field_is_required'] . '<br>';
}
$d = ORM::for_table('tbl_plans')->where('name_plan', $name)->find_one();
if ($d) {
$msg .= $_L['Plan_already_exist'] . '<br>';
}
run_hook('add_ppoe'); #HOOK
if ($msg == '') {
$d = ORM::for_table('tbl_plans')->create();
$d->type = 'Balance';
$d->name_plan = $name;
$d->id_bw = 0;
$d->price = $price;
$d->validity = 0;
$d->validity_unit = 'Months';
$d->routers = '';
$d->pool = '';
$d->enabled = $enabled;
$d->save();
r2(U . 'services/balance', 's', $_L['Created_Successfully']);
} else {
r2(U . 'services/balance-add', 'e', $msg);
}
break;
default: default:
echo 'action not defined'; echo 'action not defined';
} }

View File

@ -206,13 +206,15 @@ switch ($action) {
case 'app-post': case 'app-post':
$company = _post('company'); $company = _post('company');
$footer = _post('footer'); $footer = _post('footer');
$enable_balance = _post('enable_balance');
$allow_balance_transfer = _post('allow_balance_transfer');
$disable_voucher = _post('disable_voucher'); $disable_voucher = _post('disable_voucher');
$telegram_bot = _post('telegram_bot'); $telegram_bot = _post('telegram_bot');
$telegram_target_id = _post('telegram_target_id'); $telegram_target_id = _post('telegram_target_id');
$sms_url = _post('sms_url'); $sms_url = _post('sms_url');
$wa_url = _post('wa_url'); $wa_url = _post('wa_url');
$user_notification_expired = _post('user_notification_expired'); $user_notification_expired = _post('user_notification_expired');
$user_notification_expired_text = _post('user_notification_expired_text'); $user_notification_reminder = _post('user_notification_reminder');
$user_notification_payment = _post('user_notification_payment'); $user_notification_payment = _post('user_notification_payment');
$address = _post('address'); $address = _post('address');
$tawkto = _post('tawkto'); $tawkto = _post('tawkto');
@ -257,6 +259,28 @@ switch ($action) {
$d->save(); $d->save();
} }
$d = ORM::for_table('tbl_appconfig')->where('setting', 'enable_balance')->find_one();
if($d){
$d->value = $enable_balance;
$d->save();
}else{
$d = ORM::for_table('tbl_appconfig')->create();
$d->setting = 'enable_balance';
$d->value = $enable_balance;
$d->save();
}
$d = ORM::for_table('tbl_appconfig')->where('setting', 'allow_balance_transfer')->find_one();
if($d){
$d->value = $allow_balance_transfer;
$d->save();
}else{
$d = ORM::for_table('tbl_appconfig')->create();
$d->setting = 'allow_balance_transfer';
$d->value = $allow_balance_transfer;
$d->save();
}
$d = ORM::for_table('tbl_appconfig')->where('setting', 'telegram_bot')->find_one(); $d = ORM::for_table('tbl_appconfig')->where('setting', 'telegram_bot')->find_one();
if($d){ if($d){
$d->value = $telegram_bot; $d->value = $telegram_bot;
@ -312,14 +336,14 @@ switch ($action) {
$d->save(); $d->save();
} }
$d = ORM::for_table('tbl_appconfig')->where('setting', 'user_notification_expired_text')->find_one(); $d = ORM::for_table('tbl_appconfig')->where('setting', 'user_notification_reminder')->find_one();
if($d){ if($d){
$d->value = $user_notification_expired_text; $d->value = $user_notification_reminder;
$d->save(); $d->save();
}else{ }else{
$d = ORM::for_table('tbl_appconfig')->create(); $d = ORM::for_table('tbl_appconfig')->create();
$d->setting = 'user_notification_expired_text'; $d->setting = 'user_notification_reminder';
$d->value = $user_notification_expired_text; $d->value = $user_notification_reminder;
$d->save(); $d->save();
} }
@ -370,6 +394,7 @@ switch ($action) {
case 'localisation-post': case 'localisation-post':
$tzone = _post('tzone'); $tzone = _post('tzone');
$date_format = _post('date_format'); $date_format = _post('date_format');
$country_code_phone = _post('country_code_phone');
$lan = _post('lan'); $lan = _post('lan');
run_hook('save_localisation'); #HOOK run_hook('save_localisation'); #HOOK
if ($tzone == '' or $date_format == '' or $lan == '') { if ($tzone == '' or $date_format == '' or $lan == '') {
@ -397,6 +422,18 @@ switch ($action) {
$d->save(); $d->save();
} }
$d = ORM::for_table('tbl_appconfig')->where('setting', 'country_code_phone')->find_one();
if($d){
$d->value = $country_code_phone;
$d->save();
}else{
$d = ORM::for_table('tbl_appconfig')->create();
$d->setting = 'country_code_phone';
$d->value = $country_code_phone;
$d->save();
}
$currency_code = $_POST['currency_code']; $currency_code = $_POST['currency_code'];
$d = ORM::for_table('tbl_appconfig')->where('setting', 'currency_code')->find_one(); $d = ORM::for_table('tbl_appconfig')->where('setting', 'currency_code')->find_one();
$d->value = $currency_code; $d->value = $currency_code;
@ -455,7 +492,22 @@ switch ($action) {
} }
break; break;
case 'notifications':
if ($admin['user_type'] != 'Admin' and $admin['user_type'] != 'Sales') {
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
}
run_hook('view_notifications'); #HOOK
if(file_exists("system/uploads/notifications.json")){
$ui->assign('_json', json_decode(file_get_contents('system/uploads/notifications.json'), true));
}else{
$ui->assign('_json', json_decode(file_get_contents('system/uploads/notifications.default.json'), true));
}
$ui->display('app-notifications.tpl');
break;
case 'notifications-post':
file_put_contents("system/uploads/notifications.json", json_encode($_POST));
r2(U . 'settings/notifications', 's', $_L['Settings_Saved_Successfully']);
break;
case 'dbstatus': case 'dbstatus':
if ($admin['user_type'] != 'Admin') { if ($admin['user_type'] != 'Admin') {
r2(U . "dashboard", 'e', $_L['Do_Not_Access']); r2(U . "dashboard", 'e', $_L['Do_Not_Access']);

View File

@ -18,9 +18,15 @@ ORM::configure('logging', true);
include "autoload/Hookers.php"; include "autoload/Hookers.php";
// notification message
if (file_exists("uploads/notifications.json")) {
$_notifmsg = json_decode(file_get_contents('uploads/notifications.json'), true);
} else {
$_notifmsg = json_decode(file_get_contents('uploads/notifications.default.json'), true);
}
//register all plugin //register all plugin
foreach (glob("system/plugin/*.php") as $filename) { foreach (glob("plugin/*.php") as $filename) {
include $filename; include $filename;
} }
@ -55,7 +61,7 @@ foreach ($result as $value) {
} }
date_default_timezone_set($config['timezone']); date_default_timezone_set($config['timezone']);
$textExpired = $config['user_notification_expired_text']; $textExpired = $_notifmsg['expired'];
$d = ORM::for_table('tbl_user_recharges')->where('status', 'on')->find_many(); $d = ORM::for_table('tbl_user_recharges')->where('status', 'on')->find_many();
@ -76,11 +82,26 @@ foreach ($d as $ds) {
$client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']); $client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']);
Mikrotik::setHotspotLimitUptime($client, $c['username']); Mikrotik::setHotspotLimitUptime($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']); Mikrotik::removeHotspotActiveUser($client, $c['username']);
Message::sendExpiredNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $textExpired, $config['user_notification_expired']); Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $textExpired, $config['user_notification_expired']);
} }
//update database user dengan status off //update database user dengan status off
$u->status = 'off'; $u->status = 'off';
$u->save(); $u->save();
// autorenewal from deposit
if ($config['enable_balance'] == 'yes' && $c['auto_renewal']) {
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
if ($p && $p['enabled'] && $c['balance'] >= $p['price']) {
if (Package::rechargeUser($ds['customer_id'], $p['routers'], $p['id'], 'Customer', 'Balance')) {
// if success, then get the balance
Balance::min($ds['customer_id'], $p['price']);
} else {
Message::sendTelegram("FAILED RENEWAL #cron\n\n#u$c[username] #buy #Hotspot \n" . $p['name_plan'] .
"\nRouter: " . $router_name .
"\nPrice: " . $p['price']);
}
}
}
} else echo " : ACTIVE \r\n"; } else echo " : ACTIVE \r\n";
} else { } else {
$date_now = strtotime(date("Y-m-d H:i:s")); $date_now = strtotime(date("Y-m-d H:i:s"));
@ -96,11 +117,26 @@ foreach ($d as $ds) {
$client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']); $client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']);
Mikrotik::disablePpoeUser($client, $c['username']); Mikrotik::disablePpoeUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']); Mikrotik::removePpoeActive($client, $c['username']);
Message::sendExpiredNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $textExpired, $config['user_notification_expired']); Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $textExpired, $config['user_notification_expired']);
} }
$u->status = 'off'; $u->status = 'off';
$u->save(); $u->save();
// autorenewal from deposit
if ($config['enable_balance'] == 'yes' && $c['auto_renewal']) {
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
if ($p && $p['enabled'] && $c['balance'] >= $p['price']) {
if (Package::rechargeUser($ds['customer_id'], $p['routers'], $p['id'], 'Customer', 'Balance')) {
// if success, then get the balance
Balance::min($ds['customer_id'], $p['price']);
} else {
Message::sendTelegram("FAILED RENEWAL #cron\n\n#u$c[username] #buy #Hotspot \n" . $p['name_plan'] .
"\nRouter: " . $router_name .
"\nPrice: " . $p['price']);
}
}
}
} else echo " : ACTIVE \r\n"; } else echo " : ACTIVE \r\n";
} }
} }

90
system/cron_reminder.php Normal file
View File

@ -0,0 +1,90 @@
<?php
/**
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
* This file for reminding user about expiration
* Example to run every at 7:00 in the morning
* 0 7 * * * /usr/bin/php /var/www/system/cron_reminder.php
**/
require('../config.php');
require('orm.php');
require_once 'autoload/PEAR2/Autoload.php';
ORM::configure("mysql:host=$db_host;dbname=$db_name");
ORM::configure('username', $db_user);
ORM::configure('password', $db_password);
ORM::configure('return_result_sets', true);
ORM::configure('logging', true);
include "autoload/Hookers.php";
// notification message
if(file_exists("uploads/notifications.json")){
$_notifmsg =json_decode(file_get_contents('uploads/notifications.json'), true);
}else{
$_notifmsg = json_decode(file_get_contents('uploads/notifications.default.json'), true);
}
//register all plugin
foreach (glob("plugin/*.php") as $filename) {
include $filename;
}
// on some server, it getting error because of slash is backwards
function _autoloader($class)
{
if (strpos($class, '_') !== false) {
$class = str_replace('_', DIRECTORY_SEPARATOR, $class);
if (file_exists('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include '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('autoload' . DIRECTORY_SEPARATOR . $class . '.php')) {
include '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';
}
}
}
spl_autoload_register('_autoloader');
$result = ORM::for_table('tbl_appconfig')->find_many();
foreach ($result as $value) {
$config[$value['setting']] = $value['value'];
}
date_default_timezone_set($config['timezone']);
$d = ORM::for_table('tbl_user_recharges')->where('status', 'on')->find_many();
run_hook('cronjob_reminder'); #HOOK
$day7 = date('Y-m-d', strtotime("+7 day"));
$day3 = date('Y-m-d', strtotime("+3 day"));
$day1 = date('Y-m-d', strtotime("+1 day"));
print_r([$day1,$day3,$day7]);
foreach ($d as $ds) {
if(in_array($ds['expiration'],[$day1,$day3,$day7])){
$u = ORM::for_table('tbl_user_recharges')->where('id', $ds['id'])->find_one();
$c = ORM::for_table('tbl_customers')->where('id', $ds['customer_id'])->find_one();
if($ds['expiration']==$day7){
echo Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $_notifmsg['reminder_7_day'], $config['user_notification_reminder'])."\n";
}else if($ds['expiration']==$day3){
echo Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $_notifmsg['reminder_3_day'], $config['user_notification_reminder'])."\n";
}else if($ds['expiration']==$day1){
echo Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $_notifmsg['reminder_1_day'], $config['user_notification_reminder'])."\n";
}
}
}

View File

@ -332,3 +332,34 @@ $_L['Your_account_not_connected_to_internet'] = 'Your account not connected to i
$_L['Failed_to_create_transaction_'] = 'Failed to create transaction. '; $_L['Failed_to_create_transaction_'] = 'Failed to create transaction. ';
$_L['Failed_to_check_status_transaction_'] = 'Failed to check status transaction. '; $_L['Failed_to_check_status_transaction_'] = 'Failed to check status transaction. ';
$_L['Disable_Voucher'] = 'Disable Voucher'; $_L['Disable_Voucher'] = 'Disable Voucher';
$_L['Balance'] = 'Balance';
$_L['Balance_System'] = 'Balance System';
$_L['Enable_System'] = 'Enable System';
$_L['Allow_Transfer'] = 'Allow Transfer';
$_L['Telegram_Notification'] = 'Telegram Notification';
$_L['SMS_OTP_Registration'] = 'SMS OTP Registration';
$_L['Whatsapp_Notification'] = 'Whatsapp Notification';
$_L['Tawkto_Chat_Widget'] = 'Tawk.to Chat Widget';
$_L['Invoice'] = 'Invoice';
$_L['Country_Code_Phone'] = 'Country Code Phone';
$_L['Voucher_activation_menu_will_be_hidden'] = 'Voucher activation menu will be hidden';
$_L['Customer_can_deposit_money_to_buy_voucher'] = 'Customer can deposit money to buy voucher';
$_L['Allow_balance_transfer_between_customers'] = 'Allow balance transfer between customers';
$_L['Reminder_Notification'] = 'Reminder Notification';
$_L['Reminder_Notification_Message'] = 'Reminder Notification Message';
$_L['Reminder_7_days'] = 'Reminder 7 days';
$_L['Reminder_3_days'] = 'Reminder 3 days';
$_L['Reminder_1_day'] = 'Reminder 1 day';
$_L['PPPOE_Password'] = 'PPPOE Password';
$_L['User_Cannot_change_this_only_admin_if_it_Empty_it_will_use_user_password'] = 'User Cannot change this, only admin. if it Empty it will use user password';
$_L['Invoice_Balance_Message'] = 'Invoice Balance Message';
$_L['Invoice_Notification_Payment'] = 'Invoice Notification Payment';
$_L['Balance_Notification_Payment'] = 'Balance Notification Payment';
$_L['Balance_Plans'] = 'Balance Plans';
$_L['Buy_Balance'] = 'Buy Balance?';
$_L['Price'] = 'Price';
$_L['Validity'] = 'Validity';
$_L['Disable_auto_renewal'] = 'Disable auto renewal?';
$_L['Auto_Renewal_On'] = 'Auto Renewal On';
$_L['Enable_auto_renewal'] = 'Enable auto renewal?';
$_L['Auto_Renewal_Off'] = 'Auto Renewal Off';

View File

@ -325,3 +325,16 @@ $_L['Not_Online_Login_now'] = 'Internet mati, Nyalakan?';
$_L['You_are_Online_Logout'] = 'Internet hidup, Putuskan?'; $_L['You_are_Online_Logout'] = 'Internet hidup, Putuskan?';
$_L['Connect_to_Internet'] = 'Koneksikan internet?'; $_L['Connect_to_Internet'] = 'Koneksikan internet?';
$_L['Your_account_not_connected_to_internet'] = 'Akun tidak terkoneksi dengan internet'; $_L['Your_account_not_connected_to_internet'] = 'Akun tidak terkoneksi dengan internet';
$_L['Balance'] = 'Saldo';
$_L['Balance_System'] = 'Sistem Saldo';
$_L['Enable_System'] = 'Aktifkan Saldo';
$_L['Allow_Transfer'] = 'Bolehkan Transfer';
$_L['Telegram_Notification'] = 'Telegram Notification';
$_L['SMS_OTP_Registration'] = 'SMS OTP Registration';
$_L['Whatsapp_Notification'] = 'Whatsapp Notification';
$_L['Tawkto_Chat_Widget'] = 'Tawk.to Chat Widget';
$_L['Invoice'] = 'Invoice';
$_L['Country_Code_Phone'] = 'Kode Negara Telepon';
$_L['Voucher_activation_menu_will_be_hidden'] = 'Info Pembelian Voucher dan Redeem akan disembunyikan';
$_L['Customer_can_deposit_money_to_buy_voucher'] = 'Pelanggan dapat topup saldo untuk langganan Internet';
$_L['Allow_balance_transfer_between_customers'] = 'Bolehkan transfer saldo antar pelanggan';

View File

@ -328,6 +328,16 @@ $_L['Not_Online_Login_now'] = 'Not Online, Login now?';
$_L['You_are_Online_Logout'] = 'You are Online, Logout?'; $_L['You_are_Online_Logout'] = 'You are Online, Logout?';
$_L['Connect_to_Internet'] = 'Connect to Internet?'; $_L['Connect_to_Internet'] = 'Connect to Internet?';
$_L['Your_account_not_connected_to_internet'] = 'Your account not connected to internet'; $_L['Your_account_not_connected_to_internet'] = 'Your account not connected to internet';
$_L['Balance'] = 'Balance';
$_L['Balance_System'] = 'Balance System';
$_L['Enable_System'] = 'Enable System';
$_L['Allow_Transfer'] = 'Allow Transfer';
$_L['Telegram_Notification'] = 'Telegram Notification';
$_L['SMS_OTP_Registration'] = 'SMS OTP Registration';
$_L['Whatsapp_Notification'] = 'Whatsapp Notification';
$_L['Tawkto_Chat_Widget'] = 'Tawk.to Chat Widget';
$_L['Invoice'] = 'Invoice';
$_L['Country_Code_Phone'] = 'Country Code Phone';
$_L['Voucher_activation_menu_will_be_hidden'] = 'Voucher activation menu will be hidden';
$_L['Customer_can_deposit_money_to_buy_voucher'] = 'Customer can deposit money to buy voucher';
$_L['Allow_balance_transfer_between_customers'] = 'Allow balance transfer between customers';

View File

@ -304,3 +304,16 @@ $_L['Not_Online_Login_now'] = 'Not Online, Login now?';
$_L['You_are_Online_Logout'] = 'You are Online, Logout?'; $_L['You_are_Online_Logout'] = 'You are Online, Logout?';
$_L['Connect_to_Internet'] = 'Connect to Internet?'; $_L['Connect_to_Internet'] = 'Connect to Internet?';
$_L['Your_account_not_connected_to_internet'] = 'Your account not connected to internet'; $_L['Your_account_not_connected_to_internet'] = 'Your account not connected to internet';
$_L['Balance'] = 'Balance';
$_L['Balance_System'] = 'Balance System';
$_L['Enable_System'] = 'Enable System';
$_L['Allow_Transfer'] = 'Allow Transfer';
$_L['Telegram_Notification'] = 'Telegram Notification';
$_L['SMS_OTP_Registration'] = 'SMS OTP Registration';
$_L['Whatsapp_Notification'] = 'Whatsapp Notification';
$_L['Tawkto_Chat_Widget'] = 'Tawk.to Chat Widget';
$_L['Invoice'] = 'Invoice';
$_L['Country_Code_Phone'] = 'Country Code Phone';
$_L['Voucher_activation_menu_will_be_hidden'] = 'Voucher activation menu will be hidden';
$_L['Customer_can_deposit_money_to_buy_voucher'] = 'Customer can deposit money to buy voucher';
$_L['Allow_balance_transfer_between_customers'] = 'Allow balance transfer between customers';

14
system/updates.json Normal file
View File

@ -0,0 +1,14 @@
{
"2023.8.9": [
"ALTER TABLE `tbl_customers` ADD `balance` decimal(15,2) NOT NULL DEFAULT 0.00 COMMENT 'For Money Deposit' AFTER `email`;",
"CREATE TABLE `tbl_customers_meta` (`id` int(11) NOT NULL, `customer_id` int(11) NOT NULL,`meta_key` varchar(64) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', `meta_value` longtext COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;",
"ALTER TABLE `tbl_customers_meta` ADD PRIMARY KEY (`id`);",
"ALTER TABLE `tbl_customers_meta` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;"
],
"2023.8.14": [
"ALTER TABLE `tbl_customers` ADD `pppoe_password` varchar(45) NOT NULL DEFAULT '1' COMMENT 'For PPPOE Login' AFTER `password`;",
"ALTER TABLE `tbl_plans` CHANGE `type` `type` ENUM('Hotspot','PPPOE','Balance') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;",
"ALTER TABLE `tbl_transactions` CHANGE `type` `type` ENUM('Hotspot','PPPOE','Balance') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;",
"ALTER TABLE `tbl_customers` ADD `auto_renewal` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Auto renewall using balance' AFTER `balance`;"
]
}

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,8 @@
{
"expired": "Hello [[name]], your internet package [[package]] has been expired.",
"reminder_7_day": "Hello *[[name]]*, \r\nyour internet package *[[package]]* will be expired in 7 days.",
"reminder_3_day": "Hello *[[name]]*, \r\nyour internet package *[[package]]* will be expired in 3 days.",
"reminder_1_day": "Hello *[[name]]*,\r\n your internet package *[[package]]* will be expired tomorrow.",
"invoice_paid": "*[[company_name]]*\r\n[[address]]\r\n[[phone]]\r\n\r\n\r\nINVOICE: *[[invoice]]*\r\nDate : [[date]]\r\n[[payment_gateway]] [[payment_channel]]\r\n\r\n\r\nType : *[[type]]*\r\nPackage : *[[plan_name]]*\r\nPrice : *[[plan_price]]*\r\n\r\nUsername : *[[user_name]]*\r\nPassword : ***********\r\n\r\nExpired : *[[expired_date]]*\r\n\r\n\r\nThank you...",
"invoice_balance": "*[[company_name]]*\r\n[[address]]\r\n[[phone]]\r\n\r\n\r\nINVOICE: *[[invoice]]*\r\nDate : [[date]]\r\n[[payment_gateway]] [[payment_channel]]\r\n\r\n\r\nType : *[[type]]*\r\nPackage : *[[plan_name]]*\r\nPrice : *[[plan_price]]*\r\n\r\nThank you..."
}

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -12,7 +12,8 @@
<div class="col-md-6"> <div class="col-md-6">
<select name="tzone" id="tzone" class="form-control"> <select name="tzone" id="tzone" class="form-control">
{foreach $tlist as $value => $label} {foreach $tlist as $value => $label}
<option value="{$value}" {if $_c['timezone'] eq $value}selected="selected" {/if}>{$label}</option> <option value="{$value}" {if $_c['timezone'] eq $value}selected="selected" {/if}>
{$label}</option>
{/foreach} {/foreach}
</select> </select>
</div> </div>
@ -21,15 +22,24 @@
<label class="col-md-2 control-label">{$_L['Date_Format']}</label> <label class="col-md-2 control-label">{$_L['Date_Format']}</label>
<div class="col-md-6"> <div class="col-md-6">
<select class="form-control" name="date_format" id="date_format"> <select class="form-control" name="date_format" id="date_format">
<option value="d/m/Y" {if $_c['date_format'] eq 'd/m/Y'} selected="selected" {/if}>{date('d/m/Y')}</option> <option value="d/m/Y" {if $_c['date_format'] eq 'd/m/Y'} selected="selected" {/if}>
<option value="d.m.Y" {if $_c['date_format'] eq 'd.m.Y'} selected="selected" {/if}>{date('d.m.Y')}</option> {date('d/m/Y')}</option>
<option value="d-m-Y" {if $_c['date_format'] eq 'd-m-Y'} selected="selected" {/if}>{date('d-m-Y')}</option> <option value="d.m.Y" {if $_c['date_format'] eq 'd.m.Y'} selected="selected" {/if}>
<option value="m/d/Y" {if $_c['date_format'] eq 'm/d/Y'} selected="selected" {/if}>{date('m/d/Y')}</option> {date('d.m.Y')}</option>
<option value="Y/m/d" {if $_c['date_format'] eq 'Y/m/d'} selected="selected" {/if}>{date('Y/m/d')}</option> <option value="d-m-Y" {if $_c['date_format'] eq 'd-m-Y'} selected="selected" {/if}>
<option value="Y-m-d" {if $_c['date_format'] eq 'Y-m-d'} selected="selected" {/if}>{date('Y-m-d')}</option> {date('d-m-Y')}</option>
<option value="M d Y" {if $_c['date_format'] eq 'M d Y'} selected="selected" {/if}>{date('M d Y')}</option> <option value="m/d/Y" {if $_c['date_format'] eq 'm/d/Y'} selected="selected" {/if}>
<option value="d M Y" {if $_c['date_format'] eq 'd M Y'} selected="selected" {/if}>{date('d M Y')}</option> {date('m/d/Y')}</option>
<option value="jS M y" {if $_c['date_format'] eq 'jS M y'} selected="selected" {/if}>{date('jS M y')}</option> <option value="Y/m/d" {if $_c['date_format'] eq 'Y/m/d'} selected="selected" {/if}>
{date('Y/m/d')}</option>
<option value="Y-m-d" {if $_c['date_format'] eq 'Y-m-d'} selected="selected" {/if}>
{date('Y-m-d')}</option>
<option value="M d Y" {if $_c['date_format'] eq 'M d Y'} selected="selected" {/if}>
{date('M d Y')}</option>
<option value="d M Y" {if $_c['date_format'] eq 'd M Y'} selected="selected" {/if}>
{date('d M Y')}</option>
<option value="jS M y" {if $_c['date_format'] eq 'jS M y'} selected="selected" {/if}>
{date('jS M y')}</option>
</select> </select>
</div> </div>
</div> </div>
@ -38,36 +48,53 @@
<div class="col-md-4"> <div class="col-md-4">
<select class="form-control" name="lan" id="lan"> <select class="form-control" name="lan" id="lan">
{foreach $lan as $lans} {foreach $lan as $lans}
<option value="{$lans['folder']}" {if $_c['language'] eq $lans['folder']} selected="selected" {/if}>{$lans['name']}</option> <option value="{$lans['folder']}" {if $_c['language'] eq $lans['folder']}
selected="selected" {/if}>{$lans['name']}</option>
{/foreach} {/foreach}
</select> </select>
</div> </div>
<div class="col-md-2"> <div class="col-md-2">
<a href="{$_url}settings/language" type="button" class="btn btn-line-success btn-icon-inline"><i class="ion ion-android-add"></i>{$_L['Add_Language']}</a> <a href="{$_url}settings/language" type="button"
class="btn btn-line-success btn-icon-inline"><i
class="ion ion-android-add"></i>{$_L['Add_Language']}</a>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Decimal_Point']}</label> <label class="col-md-2 control-label">{$_L['Decimal_Point']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="dec_point" name="dec_point" value="{$_c['dec_point']}"> <input type="text" class="form-control" id="dec_point" name="dec_point"
value="{$_c['dec_point']}">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Thousands_Separator']}</label> <label class="col-md-2 control-label">{$_L['Thousands_Separator']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="thousands_sep" name="thousands_sep" value="{$_c['thousands_sep']}"> <input type="text" class="form-control" id="thousands_sep" name="thousands_sep"
value="{$_c['thousands_sep']}">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Currency_Code']}</label> <label class="col-md-2 control-label">{$_L['Currency_Code']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="currency_code" name="currency_code" value="{$_c['currency_code']}"> <input type="text" class="form-control" id="currency_code" name="currency_code"
value="{$_c['currency_code']}">
<span class="help-block">{$_L['currency_help']}</span> <span class="help-block">{$_L['currency_help']}</span>
</div> </div>
</div> </div>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Country Code Phone')}</label>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" id="country_code_phone" placeholder="62"
name="country_code_phone" value="{$_c['country_code_phone']}">
</div>
</div>
</div>
<div class="form-group"> <div class="form-group">
<div class="col-lg-offset-2 col-lg-10"> <div class="col-lg-offset-2 col-lg-10">
<button class="btn btn-primary waves-effect waves-light" type="submit">{$_L['Save']}</button> <button class="btn btn-primary waves-effect waves-light"
type="submit">{$_L['Save']}</button>
</div> </div>
</div> </div>
</form> </form>

125
ui/ui/app-notifications.tpl Normal file
View File

@ -0,0 +1,125 @@
{include file="sections/header.tpl"}
<form class="form-horizontal" method="post" role="form" action="{$_url}settings/notifications-post">
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="panel panel-primary panel-hovered panel-stacked mb30">
<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('User Notification')}
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Expired Notification Message')}</label>
<div class="col-md-6">
<textarea class="form-control" id="expired"
name="expired"
placeholder="Hello [[name]], your internet package [[package]] has been expired"
rows="3">{if $_json['expired']!=''}{Lang::htmlspecialchars($_json['expired'])}{else}Hello [[name]], your internet package [[package]] has been expired.{/if}</textarea>
</div>
<p class="help-block col-md-4">
{Lang::T('<b>[[name]]</b> will be replaced with Customer Name. <b>[[package]]</b> will be replaced with Package name.')}
</p>
</div>
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Reminder 7 days')}</label>
<div class="col-md-6">
<textarea class="form-control" id="reminder_7_day" name="reminder_7_day"
rows="3">{Lang::htmlspecialchars($_json['reminder_7_day'])}</textarea>
</div>
<p class="help-block col-md-4">
{Lang::T('<b>[[name]]</b> will be replaced with Customer Name. <b>[[package]]</b> will be replaced with Package name.')}
</p>
</div>
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Reminder 3 days')}</label>
<div class="col-md-6">
<textarea class="form-control" id="reminder_3_day" name="reminder_3_day"
rows="3">{Lang::htmlspecialchars($_json['reminder_3_day'])}</textarea>
</div>
<p class="help-block col-md-4">
{Lang::T('<b>[[name]]</b> will be replaced with Customer Name. <b>[[package]]</b> will be replaced with Package name.')}
</p>
</div>
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Reminder 1 day')}</label>
<div class="col-md-6">
<textarea class="form-control" id="reminder_1_day" name="reminder_1_day"
rows="3">{Lang::htmlspecialchars($_json['reminder_1_day'])}</textarea>
</div>
<p class="help-block col-md-4">
{Lang::T('<b>[[name]]</b> will be replaced with Customer Name. <b>[[package]]</b> will be replaced with Package name.')}
</p>
</div>
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Invoice Notification Payment')}</label>
<div class="col-md-6">
<textarea class="form-control" id="invoice_paid" name="invoice_paid"
placeholder="Hello [[name]], your internet package [[package]] has been expired"
rows="20">{Lang::htmlspecialchars($_json['invoice_paid'])}</textarea>
</div>
<p class="col-md-4 help-block">
<b>[[company_name]]</b> Your Company Name at Settings.<br>
<b>[[address]]</b> Your Company Address at Settings.<br>
<b>[[phone]]</b> Your Company Phone at Settings.<br>
<b>[[invoice]]</b> invoice number.<br>
<b>[[date]]</b> Date invoice created.<br>
<b>[[payment_gateway]]</b> Payment gateway user paid from.<br>
<b>[[payment_channel]]</b> Payment channel user paid from.<br>
<b>[[type]]</b> is Hotspot/PPPOE.<br>
<b>[[plan_name]]</b> Internet Package.<br>
<b>[[plan_price]]</b> Internet Package Prices.<br>
<b>[[user_name]]</b> Username internet.<br>
<b>[[user_password]]</b> User password.<br>
<b>[[expired_date]]</b> Expired datetime.
</p>
</div>
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Balance Notification Payment')}</label>
<div class="col-md-6">
<textarea class="form-control" id="invoice_balance" name="invoice_balance"
placeholder="Hello [[name]], your internet package [[package]] has been expired"
rows="20">{Lang::htmlspecialchars($_json['invoice_balance'])}</textarea>
</div>
<p class="col-md-4 help-block">
<b>[[company_name]]</b> Your Company Name at Settings.<br>
<b>[[address]]</b> Your Company Address at Settings.<br>
<b>[[phone]]</b> Your Company Phone at Settings.<br>
<b>[[invoice]]</b> invoice number.<br>
<b>[[date]]</b> Date invoice created.<br>
<b>[[payment_gateway]]</b> Payment gateway user paid from.<br>
<b>[[payment_channel]]</b> Payment channel user paid from.<br>
<b>[[type]]</b> is Hotspot/PPPOE.<br>
<b>[[plan_name]]</b> Internet Package.<br>
<b>[[plan_price]]</b> Internet Package Prices.<br>
<b>[[user_name]]</b> Username internet.<br>
<b>[[user_password]]</b> User password.<br>
<b>[[trx_date]]</b> Transaction datetime.
</p>
</div>
</div>
</div>
<div class="panel-body">
<div class="form-group">
<button class="btn btn-success btn-block waves-effect waves-light"
type="submit">{$_L['Save']}</button>
</div>
</div>
</div>
</div>
</form>
{include file="sections/footer.tpl"}

View File

@ -4,31 +4,38 @@
<div class="row"> <div class="row">
<div class="col-sm-12 col-md-12"> <div class="col-sm-12 col-md-12">
<div class="panel panel-primary panel-hovered panel-stacked mb30"> <div class="panel panel-primary panel-hovered panel-stacked mb30">
<div class="panel-heading">{$_L['General_Settings']}</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>
{$_L['General_Settings']}
</div>
<div class="panel-body"> <div class="panel-body">
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['App_Name']}</label> <label class="col-md-2 control-label">{$_L['App_Name']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" required class="form-control" id="company" name="company" <input type="text" required class="form-control" id="company" name="company"
value="{$_c['CompanyName']}"> value="{$_c['CompanyName']}">
<span class="help-block">{$_L['App_Name_Help_Text']}</span>
</div> </div>
<span class="help-block col-md-4">{$_L['App_Name_Help_Text']}</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Company Footer')}</label> <label class="col-md-2 control-label">{Lang::T('Company Footer')}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" required class="form-control" id="footer" name="footer" <input type="text" required class="form-control" id="footer" name="footer"
value="{$_c['CompanyFooter']}"> value="{$_c['CompanyFooter']}">
<span class="help-block">{Lang::T('Will show below user pages')}</span>
</div> </div>
<span class="help-block col-md-4">{Lang::T('Will show below user pages')}</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Address']}</label> <label class="col-md-2 control-label">{$_L['Address']}</label>
<div class="col-md-6"> <div class="col-md-6">
<textarea class="form-control" id="address" name="address" <textarea class="form-control" id="address" name="address"
rows="3">{Lang::htmlspecialchars($_c['address'])}</textarea> rows="3">{Lang::htmlspecialchars($_c['address'])}</textarea>
<span class="help-block">{$_L['You_can_use_html_tag']}</span>
</div> </div>
<span class="help-block col-md-4">{$_L['You_can_use_html_tag']}</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Phone_Number']}</label> <label class="col-md-2 control-label">{$_L['Phone_Number']}</label>
@ -43,31 +50,71 @@
<option value="0">No</option> <option value="0">No</option>
<option value="1" {if $_c['radius_mode']}selected="selected" {/if}>Yes</option> <option value="1" {if $_c['radius_mode']}selected="selected" {/if}>Yes</option>
</select> </select>
<p class="help-block">Still on Testing.</p>
<p class="help-block">Changing from Radius will not add existing user to Mikrotik Hotspot.
</p>
<p class="help-block">With Radius user can use Hotspot or PPOE.</p>
</div> </div>
<p class="help-block col-md-4">Still on Testing.<br>
Changing from Radius will not add existing user to Mikrotik Hotspot.<br>
With Radius user can use Hotspot or PPOE.</p>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">APP URL</label> <label class="col-md-2 control-label">APP URL</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" readonly class="form-control" value="{$app_url}"> <input type="text" readonly class="form-control" value="{$app_url}">
<p class="help-block">edit at config.php</p>
</div> </div>
<p class="help-block col-md-4">edit at config.php</p>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Disable Voucher')}</label> <label class="col-md-2 control-label">{Lang::T('Disable Voucher')}</label>
<div class="col-md-6"> <div class="col-md-6">
<select name="disable_voucher" id="disable_voucher" class="form-control"> <select name="disable_voucher" id="disable_voucher" class="form-control">
<option value="no" {if $_c['disable_voucher'] == 'no'}selected="selected" {/if}>No</option> <option value="no" {if $_c['disable_voucher'] == 'no'}selected="selected" {/if}>No
<option value="yes" {if $_c['disable_voucher'] == 'yes'}selected="selected" {/if}>Yes</option> </option>
<option value="yes" {if $_c['disable_voucher'] == 'yes'}selected="selected" {/if}>Yes
</option>
</select> </select>
<p class="help-block">Voucher activation menu will be hidden</p> </div>
<p class="help-block col-md-4">{Lang::T('Voucher activation menu will be hidden')}</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>
{Lang::T('Balance System')}
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Enable System')}</label>
<div class="col-md-6">
<select name="enable_balance" id="enable_balance" class="form-control">
<option value="no" {if $_c['enable_balance'] == 'no'}selected="selected" {/if}>No
</option>
<option value="yes" {if $_c['enable_balance'] == 'yes'}selected="selected" {/if}>Yes
</option>
</select>
</div>
<p class="help-block col-md-4">{Lang::T('Customer can deposit money to buy voucher')}</p>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Allow Transfer')}</label>
<div class="col-md-6">
<select name="allow_balance_transfer" id="allow_balance_transfer" class="form-control">
<option value="no" {if $_c['allow_balance_transfer'] == 'no'}selected="selected" {/if}>
No</option>
<option value="yes" {if $_c['allow_balance_transfer'] == 'yes'}selected="selected"
{/if}>Yes</option>
</select>
</div>
<p class="help-block col-md-4">{Lang::T('Allow balance transfer between customers')}</p>
</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('Telegram Notification')}
</div> </div>
<div class="panel-heading">Telegram Notification</div>
<div class="panel-body"> <div class="panel-body">
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">Telegram Bot Token</label> <label class="col-md-2 control-label">Telegram Bot Token</label>
@ -83,88 +130,122 @@
value="{$_c['telegram_target_id']}" placeholder="12345678"> value="{$_c['telegram_target_id']}" placeholder="12345678">
</div> </div>
</div> </div>
<small id="emailHelp" class="form-text text-muted">You will get Payment and Error notification</small> <small id="emailHelp" class="form-text text-muted">You will get Payment and Error
notification</small>
</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('SMS OTP Registration')}
</div> </div>
<div class="panel-heading">SMS OTP Registration</div>
<div class="panel-body"> <div class="panel-body">
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">SMS Server URL</label> <label class="col-md-2 control-label">SMS Server URL</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="sms_url" name="sms_url" value="{$_c['sms_url']}" <input type="text" class="form-control" id="sms_url" name="sms_url" value="{$_c['sms_url']}"
placeholder="https://domain/?param_number=[number]&param_text=[text]&secret="> placeholder="https://domain/?param_number=[number]&param_text=[text]&secret=">
<p class="help-block">Must include <b>[text]</b> &amp; <b>[number]</b>, it will be replaced. </div>
<p class="help-block col-md-4">Must include <b>[text]</b> &amp; <b>[number]</b>, it will be
replaced.
</p> </p>
</div> </div>
<small id="emailHelp" class="form-text text-muted">You can use WhatsApp in here too. <a
href="https://wa.nux.my.id/login" target="_blank">Free Server</a></small>
</div> </div>
<small id="emailHelp" class="form-text text-muted">You can use WhatsApp in here too. <a href="https://wa.nux.my.id/login" target="_blank">Free Server</a></small> <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('Whatsapp Notification')}
</div> </div>
<div class="panel-heading">Whatsapp Notification</div>
<div class="panel-body"> <div class="panel-body">
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">Whatsapp Server URL</label> <label class="col-md-2 control-label">Whatsapp Server URL</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="wa_url" name="wa_url" value="{$_c['wa_url']}" <input type="text" class="form-control" id="wa_url" name="wa_url" value="{$_c['wa_url']}"
placeholder="https://domain/?param_number=[number]&param_text=[text]&secret="> placeholder="https://domain/?param_number=[number]&param_text=[text]&secret=">
<p class="help-block">Must include <b>[text]</b> &amp; <b>[number]</b>, it will be replaced. </div>
<p class="help-block col-md-4">Must include <b>[text]</b> &amp; <b>[number]</b>, it will be
replaced.
</p> </p>
</div> </div>
<small id="emailHelp" class="form-text text-muted">You can use WhatsApp in here too. <a
href="https://wa.nux.my.id/login" target="_blank">Free Server</a></small>
</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('User Notification')}
</div> </div>
<div class="panel-heading">{Lang::T('User Notification')}</div>
<div class="panel-body"> <div class="panel-body">
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Expired Notification')}</label> <label class="col-md-2 control-label">{Lang::T('Expired Notification')}</label>
<div class="col-md-6"> <div class="col-md-6">
<select name="user_notification_expired" id="user_notification_expired" class="form-control"> <select name="user_notification_expired" id="user_notification_expired"
class="form-control">
<option value="none">None</option> <option value="none">None</option>
<option value="wa" {if $_c['user_notification_expired'] == 'wa'}selected="selected" {/if}>Whatsapp</option> <option value="wa" {if $_c['user_notification_expired'] == 'wa'}selected="selected"
<option value="sms" {if $_c['user_notification_expired'] == 'sms'}selected="selected" {/if}>SMS</option> {/if}>Whatsapp</option>
<option value="sms" {if $_c['user_notification_expired'] == 'sms'}selected="selected"
{/if}>SMS</option>
</select> </select>
<p class="help-block">{Lang::T('User will get notification when package expired')}</p>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Expired Notification Message')}</label>
<div class="col-md-6">
<textarea class="form-control" id="user_notification_expired_text" name="user_notification_expired_text" placeholder="Hello [[name]], your internet package [[package]] has been expired" rows="3">{if $_c['user_notification_expired_text']!=''}{Lang::htmlspecialchars($_c['user_notification_expired_text'])}{else}Hello [[name]], your internet package [[package]] has been expired.{/if}</textarea>
<p class="help-block">{Lang::T('<b>[[name]]</b> will be replaced with Customer Name. <b>[[package]]</b> will be replaced with Package name.')}</p>
</div> </div>
<p class="help-block col-md-4">{Lang::T('User will get notification when package expired')}</p>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Payment Notification')}</label> <label class="col-md-2 control-label">{Lang::T('Payment Notification')}</label>
<div class="col-md-6"> <div class="col-md-6">
<select name="user_notification_payment" id="user_notification_payment" class="form-control"> <select name="user_notification_payment" id="user_notification_payment"
class="form-control">
<option value="none">None</option> <option value="none">None</option>
<option value="wa" {if $_c['user_notification_payment'] == 'wa'}selected="selected" {/if}>Whatsapp</option> <option value="wa" {if $_c['user_notification_payment'] == 'wa'}selected="selected"
<option value="sms" {if $_c['user_notification_payment'] == 'sms'}selected="selected" {/if}>SMS</option> {/if}>Whatsapp</option>
<option value="sms" {if $_c['user_notification_payment'] == 'sms'}selected="selected"
{/if}>SMS</option>
</select>
</div>
<p class="help-block col-md-4">
{Lang::T('User will get invoice notification when buy package or package refilled')}</p>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Reminder Notification')}</label>
<div class="col-md-6">
<select name="user_notification_reminder" id="user_notification_reminder"
class="form-control">
<option value="none">None</option>
<option value="wa" {if $_c['user_notification_reminder'] == 'wa'}selected="selected"
{/if}>Whatsapp</option>
<option value="sms" {if $_c['user_notification_reminder'] == 'sms'}selected="selected"
{/if}>SMS</option>
</select> </select>
<p class="help-block">{Lang::T('User will get invoice notification when buy package or package refilled')}</p>
</div> </div>
</div> </div>
</div> </div>
<div class="panel-heading">Tawk.to Chat Widget</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('Tawk.to Chat Widget')}
</div>
<div class="panel-body"> <div class="panel-body">
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">https://tawk.to/chat/</label> <label class="col-md-2 control-label">https://tawk.to/chat/</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="tawkto" name="tawkto" value="{$_c['tawkto']}" <input type="text" class="form-control" id="tawkto" name="tawkto" value="{$_c['tawkto']}"
placeholder="62f1ca7037898912e961f5/1ga07df"> placeholder="62f1ca7037898912e961f5/1ga07df">
<p class="help-block">From Direct Chat Link.</p>
<pre>/ip hotspot walled-garden
add dst-host=tawk.to
add dst-host=*.tawk.to</pre>
</div>
</div>
</div>
<div class="panel-heading">Invoice</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">Note Invoice</label>
<div class="col-md-6">
<textarea class="form-control" id="note" name="note" rows="3">{Lang::htmlspecialchars($_c['note'])}</textarea>
<span class="help-block">{$_L['You_can_use_html_tag']}</span>
</div> </div>
<p class="help-block col-md-4">From Direct Chat Link.</p>
</div> </div>
<label class="col-md-2"></label>
<p class="col-md-6 help-block">/ip hotspot walled-garden<br>
add dst-host=tawk.to<br>
add dst-host=*.tawk.to</p>
</div> </div>
</div> </div>

48
ui/ui/balance-add.tpl Normal file
View File

@ -0,0 +1,48 @@
{include file="sections/header.tpl"}
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="panel panel-primary panel-hovered panel-stacked mb30">
<div class="panel-heading">{$_L['Add_Plan']}</div>
<div class="panel-body">
<form class="form-horizontal" method="post" role="form" action="{$_url}services/balance-add-post" >
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Status')}</label>
<div class="col-md-10">
<label class="radio-inline warning">
<input type="radio" checked name="enabled" value="1"> Enable
</label>
<label class="radio-inline">
<input type="radio" name="enabled" value="0"> Disable
</label>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Plan_Name']}</label>
<div class="col-md-6">
<input type="text" required class="form-control" id="name" name="name" maxlength="40" placeholder="Topup 100">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Plan_Price']}</label>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-addon">{$_c['currency_code']}</span>
<input type="number" class="form-control" name="price" required>
</div>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button class="btn btn-success waves-effect waves-light" type="submit">{$_L['Save']}</button>
Or <a href="{$_url}services/balance">{$_L['Cancel']}</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file="sections/footer.tpl"}

49
ui/ui/balance-edit.tpl Normal file
View File

@ -0,0 +1,49 @@
{include file="sections/header.tpl"}
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="panel panel-primary panel-hovered panel-stacked mb30">
<div class="panel-heading">{$_L['Edit_Plan']}</div>
<div class="panel-body">
<form class="form-horizontal" method="post" role="form" action="{$_url}services/balance-edit-post">
<input type="hidden" name="id" value="{$d['id']}">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Status')}</label>
<div class="col-md-10">
<label class="radio-inline warning">
<input type="radio" checked name="enabled" value="1"> Enable
</label>
<label class="radio-inline">
<input type="radio" name="enabled" value="0"> Disable
</label>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Plan_Name']}</label>
<div class="col-md-6">
<input type="text" required class="form-control" id="name" value="{$d['name_plan']}" name="name" maxlength="40" placeholder="Topup 100">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Plan_Price']}</label>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-addon">{$_c['currency_code']}</span>
<input type="number" class="form-control" name="price" value="{$d['price']}" required>
</div>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button class="btn btn-success waves-effect waves-light" type="submit">{$_L['Save']}</button>
Or <a href="{$_url}services/balance">{$_L['Cancel']}</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file="sections/footer.tpl"}

56
ui/ui/balance.tpl Normal file
View File

@ -0,0 +1,56 @@
{include file="sections/header.tpl"}
<div class="row">
<div class="col-sm-12">
<div class="panel panel-hovered mb20 panel-primary">
<div class="panel-heading">{Lang::T('Balance Plans')}</div>
<div class="panel-body">
<div class="md-whiteframe-z1 mb20 text-center" style="padding: 15px">
<div class="col-md-8">
<form id="site-search" method="post" action="{$_url}services/balance/">
<div class="input-group">
<div class="input-group-addon">
<span class="fa fa-search"></span>
</div>
<input type="text" name="name" class="form-control" placeholder="{$_L['Search_by_Name']}...">
<div class="input-group-btn">
<button class="btn btn-success" type="submit">{$_L['Search']}</button>
</div>
</div>
</form>
</div>
<div class="col-md-4">
<a href="{$_url}services/balance-add" class="btn btn-primary btn-block waves-effect"><i class="ion ion-android-add"> </i> {$_L['New_Plan']}</a>
</div>&nbsp;
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{$_L['Plan_Name']}</th>
<th>{$_L['Plan_Price']}</th>
<th>{$_L['Manage']}</th>
</tr>
</thead>
<tbody>
{foreach $d as $ds}
<tr {if $ds['enabled'] != 1}class="danger" title="disabled"{/if}>
<td>{$ds['name_plan']}</td>
<td>{Lang::moneyFormat($ds['price'])}</td>
<td>
<a href="{$_url}services/balance-edit/{$ds['id']}" class="btn btn-info btn-xs">{$_L['Edit']}</a>
<a href="{$_url}services/balance-delete/{$ds['id']}" onclick="return confirm('{$_L['Delete']}?')" id="{$ds['id']}" class="btn btn-danger btn-xs">{$_L['Delete']}</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{$paginator['contents']}
</div>
</div>
</div>
</div>
{include file="sections/footer.tpl"}

View File

@ -10,7 +10,11 @@
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Username']}</label> <label class="col-md-2 control-label">{$_L['Username']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="username" name="username" required placeholder="Phone number"> <div class="input-group">
<span class="input-group-addon">+</span>
<input type="text" class="form-control" name="username" required
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
</div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -20,15 +24,32 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Password']}</label> <label class="col-md-2 control-label">{$_L['Email']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="password" class="form-control" required id="password" name="password"> <input type="email" class="form-control" id="email" name="email">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Confirm_Password']}</label> <label class="col-md-2 control-label">{$_L['Phone_Number']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="password" class="form-control" required id="cpassword" name="cpassword"> <div class="input-group">
<span class="input-group-addon">+</span>
<input type="text" class="form-control" name="phonenumber"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Password']}</label>
<div class="col-md-6">
<input type="text" class="form-control" autocomplete="off" required id="password" name="password">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('PPPOE Password')}</label>
<div class="col-md-6">
<input type="password" class="form-control" id="pppoe_password" name="pppoe_password" value="{$d['pppoe_password']}">
<span class="help-block">{Lang::T('User Cannot change this, only admin. if it Empty it will use user password')}</span>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -11,7 +11,11 @@
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Username']}</label> <label class="col-md-2 control-label">{$_L['Username']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="username" name="username" value="{$d['username']}" placeholder="Phone Number" required> <div class="input-group">
<span class="input-group-addon">+</span>
<input type="text" class="form-control" name="username" value="{$d['username']}" required
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
</div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -20,17 +24,34 @@
<input type="text" class="form-control" id="fullname" name="fullname" value="{$d['fullname']}"> <input type="text" class="form-control" id="fullname" name="fullname" value="{$d['fullname']}">
</div> </div>
</div> </div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Email']}</label>
<div class="col-md-6">
<input type="email" class="form-control" id="email" name="email" value="{$d['email']}">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Phone_Number']}</label>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-addon">+</span>
<input type="text" class="form-control" name="phonenumber" value="{$d['phonenumber']}"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
</div>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Password']}</label> <label class="col-md-2 control-label">{$_L['Password']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="password" class="form-control" id="password" name="password"> <input type="password" autocomplete="off" class="form-control" id="password" name="password" onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'" value="{$d['password']}">
<span class="help-block">{$_L['password_change_help']}</span> <span class="help-block">{$_L['password_change_help']}</span>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Confirm_Password']}</label> <label class="col-md-2 control-label">{Lang::T('PPPOE Password')}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="password" class="form-control" id="cpassword" name="cpassword"> <input type="password" autocomplete="off" class="form-control" id="pppoe_password" name="pppoe_password" value="{$d['pppoe_password']}" onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'">
<span class="help-block">{Lang::T('User Cannot change this, only admin. if it Empty it will use user password')}</span>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -39,12 +60,6 @@
<textarea name="address" id="address" class="form-control">{$d['address']}</textarea> <textarea name="address" id="address" class="form-control">{$d['address']}</textarea>
</div> </div>
</div> </div>
<div class="form-group">
<label class="col-md-2 control-label">{$_L['Phone_Number']}</label>
<div class="col-md-6">
<input type="text" class="form-control" id="phonenumber" name="phonenumber" value="{$d['phonenumber']}">
</div>
</div>
<div class="form-group"> <div class="form-group">
<div class="col-lg-offset-2 col-lg-10"> <div class="col-lg-offset-2 col-lg-10">

View File

@ -21,7 +21,6 @@
<label class="col-md-2 control-label">{$_L['Plan_Name']}</label> <label class="col-md-2 control-label">{$_L['Plan_Name']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="name" name="name" maxlength="40"> <input type="text" class="form-control" id="name" name="name" maxlength="40">
<p class="help-block">{Lang::T('Cannot be change after saved')}</p>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -83,7 +82,10 @@
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Plan_Price']}</label> <label class="col-md-2 control-label">{$_L['Plan_Price']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="pricebp" name="pricebp"> <div class="input-group">
<span class="input-group-addon">{$_c['currency_code']}</span>
<input type="number" class="form-control" name="pricebp" required>
</div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -21,7 +21,7 @@
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Plan_Name']}</label> <label class="col-md-2 control-label">{$_L['Plan_Name']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="name" name="name" maxlength="40" value="{$d['name_plan']}" readonly> <input type="text" class="form-control" id="name" name="name" maxlength="40" value="{$d['name_plan']}">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -82,7 +82,10 @@
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Plan_Price']}</label> <label class="col-md-2 control-label">{$_L['Plan_Price']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="price" name="price" value="{$d['price']}"> <div class="input-group">
<span class="input-group-addon">{$_c['currency_code']}</span>
<input type="number" class="form-control" name="pricebp" value="{$d['price']}" required>
</div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

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

View File

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

View File

@ -21,7 +21,6 @@
<label class="col-md-2 control-label">{$_L['Plan_Name']}</label> <label class="col-md-2 control-label">{$_L['Plan_Name']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="name_plan" maxlength="40" name="name_plan"> <input type="text" class="form-control" id="name_plan" maxlength="40" name="name_plan">
<p class="help-block">{Lang::T('Cannot be change after saved')}</p>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -38,7 +37,10 @@
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Plan_Price']}</label> <label class="col-md-2 control-label">{$_L['Plan_Price']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="price" name="price"> <div class="input-group">
<span class="input-group-addon">{$_c['currency_code']}</span>
<input type="number" class="form-control" name="price" required>
</div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -21,7 +21,7 @@
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Plan_Name']}</label> <label class="col-md-2 control-label">{$_L['Plan_Name']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="name_plan" maxlength="40" name="name_plan" value="{$d['name_plan']}" readonly> <input type="text" class="form-control" id="name_plan" maxlength="40" name="name_plan" value="{$d['name_plan']}">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -37,7 +37,10 @@
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Plan_Price']}</label> <label class="col-md-2 control-label">{$_L['Plan_Price']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="price" name="price" value="{$d['price']}"> <div class="input-group">
<span class="input-group-addon">{$_c['currency_code']}</span>
<input type="number" class="form-control" name="price" required value="{$d['price']}">
</div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -47,7 +47,7 @@
<td>{$ds['routers']}</td> <td>{$ds['routers']}</td>
<td> <td>
<a href="{$_url}services/pppoe-edit/{$ds['id']}" class="btn btn-info btn-xs">{$_L['Edit']}</a> <a href="{$_url}services/pppoe-edit/{$ds['id']}" class="btn btn-info btn-xs">{$_L['Edit']}</a>
<a href="{$_url}services/pppoe-delete/{$ds['id']}" id="{$ds['id']}" class="btn btn-danger btn-xs">{$_L['Delete']}</a> <a href="{$_url}services/pppoe-delete/{$ds['id']}" onclick="return confirm('{$_L['Delete']}?')" id="{$ds['id']}" class="btn btn-danger btn-xs">{$_L['Delete']}</a>
</td> </td>
</tr> </tr>
{/foreach} {/foreach}

View File

@ -45,8 +45,11 @@
<div class="form-container"> <div class="form-container">
<div class="form-group"> <div class="form-group">
<label>{$_L['Phone_Number']}</label> <label>{$_L['Phone_Number']}</label>
<input type="text" required class="form-control" readonly id="username" <div class="input-group">
value="{$username}" placeholder="{$_L['Phone_Number']}" name="username"> <span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" name="username" value="{$username}"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>{Lang::T('SMS Verification Code')}</label> <label>{Lang::T('SMS Verification Code')}</label>

View File

@ -58,8 +58,11 @@
<div class="panel-body"> <div class="panel-body">
<div class="form-group"> <div class="form-group">
<label>{$_L['Phone_Number']}</label> <label>{$_L['Phone_Number']}</label>
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" name="username" <input type="text" class="form-control" name="username"
placeholder="{$_L['Phone_Number']}"> placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
</div>
</div> </div>
<div class="btn-group btn-group-justified mb15"> <div class="btn-group btn-group-justified mb15">
<div class="btn-group"> <div class="btn-group">

View File

@ -45,8 +45,11 @@
<div class="form-container"> <div class="form-container">
<div class="md-input-container"> <div class="md-input-container">
<label>{$_L['Phone_Number']}</label> <label>{$_L['Phone_Number']}</label>
<input type="text" required class="form-control" id="username" value="{$username}" <div class="input-group">
placeholder="{$_L['Phone_Number']}" name="username"> <span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" name="username"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
</div>
</div> </div>
<div class="md-input-container md-float-label"> <div class="md-input-container md-float-label">
<label>{$_L['Full_Name']}</label> <label>{$_L['Full_Name']}</label>

View File

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

View File

@ -53,12 +53,14 @@
<li class="dropdown user user-menu"> <li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img src="https://robohash.org/{$_admin['id']}?set=set3&size=100x100&bgset=bg1" <img src="https://robohash.org/{$_admin['id']}?set=set3&size=100x100&bgset=bg1"
onerror="this.src='system/uploads/admin.default.png'"
class="user-image" alt="Avatar"> class="user-image" alt="Avatar">
<span class="hidden-xs">{$_admin['fullname']}</span> <span class="hidden-xs">{$_admin['fullname']}</span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li class="user-header"> <li class="user-header">
<img src="https://robohash.org/{$_admin['id']}?set=set3&size=100x100&bgset=bg1" <img src="https://robohash.org/{$_admin['id']}?set=set3&size=100x100&bgset=bg1"
onerror="this.src='system/uploads/admin.default.png'"
class="img-circle" alt="Avatar"> class="img-circle" alt="Avatar">
<p> <p>
@ -70,12 +72,12 @@
</li> </li>
<li class="user-body"> <li class="user-body">
<div class="row"> <div class="row">
<div class="col-xs-6 text-center"> <div class="col-xs-7 text-center text-sm">
<a href="{$_url}settings/change-password"> {$_L['Change_Password']}</a> <a href="{$_url}settings/change-password"><i class="ion ion-settings"></i> {$_L['Change_Password']}</a>
</div> </div>
<div class="col-xs-6 text-center"> <div class="col-xs-5 text-center text-sm">
<a href="{$_url}settings/users-edit/{$_admin['id']}"> <a href="{$_url}settings/users-edit/{$_admin['id']}">
{$_L['My_Account']}</a> <i class="ion ion-person"></i> {$_L['My_Account']}</a>
</div> </div>
</div> </div>
</li> </li>
@ -155,6 +157,8 @@
href="{$_url}services/pppoe">{$_L['PPPOE_Plans']}</a></li> href="{$_url}services/pppoe">{$_L['PPPOE_Plans']}</a></li>
<li {if $_routes[1] eq 'list'}class="active" {/if}><a <li {if $_routes[1] eq 'list'}class="active" {/if}><a
href="{$_url}bandwidth/list">{$_L['Bandwidth_Plans']}</a></li> href="{$_url}bandwidth/list">{$_L['Bandwidth_Plans']}</a></li>
<li {if $_routes[1] eq 'balance'}class="active" {/if}><a
href="{$_url}services/balance">{Lang::T('Balance Plans')}</a></li>
{$_MENU_SERVICES} {$_MENU_SERVICES}
</ul> </ul>
</li> </li>
@ -225,6 +229,8 @@
href="{$_url}settings/app">{$_L['General_Settings']}</a></li> href="{$_url}settings/app">{$_L['General_Settings']}</a></li>
<li {if $_routes[1] eq 'localisation'}class="active" {/if}><a <li {if $_routes[1] eq 'localisation'}class="active" {/if}><a
href="{$_url}settings/localisation">{$_L['Localisation']}</a></li> href="{$_url}settings/localisation">{$_L['Localisation']}</a></li>
<li {if $_routes[1] eq 'notifications'}class="active" {/if}><a
href="{$_url}settings/notifications">{Lang::T('User Notification')}</a></li>
<li {if $_routes[1] eq 'users'}class="active" {/if}><a <li {if $_routes[1] eq 'users'}class="active" {/if}><a
href="{$_url}settings/users">{$_L['Administrator_Users']}</a></li> href="{$_url}settings/users">{$_L['Administrator_Users']}</a></li>
<li {if $_routes[1] eq 'dbstatus'}class="active" {/if}><a <li {if $_routes[1] eq 'dbstatus'}class="active" {/if}><a

View File

@ -53,12 +53,14 @@
<li class="dropdown user user-menu"> <li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img src="https://robohash.org/{$_user['id']}?set=set3&size=100x100&bgset=bg1" <img src="https://robohash.org/{$_user['id']}?set=set3&size=100x100&bgset=bg1"
onerror="this.src='system/uploads/user.default.jpg'"
class="user-image" alt="User Image"> class="user-image" alt="User Image">
<span class="hidden-xs">{$_user['fullname']}</span> <span class="hidden-xs">{$_user['fullname']}</span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li class="user-header"> <li class="user-header">
<img src="https://robohash.org/{$_user['id']}?set=set3&size=100x100&bgset=bg1" <img src="https://robohash.org/{$_user['id']}?set=set3&size=100x100&bgset=bg1"
onerror="this.src='system/uploads/user.default.jpg'"
class="img-circle" alt="User Image"> class="img-circle" alt="User Image">
<p> <p>
@ -69,11 +71,11 @@
</li> </li>
<li class="user-body"> <li class="user-body">
<div class="row"> <div class="row">
<div class="col-xs-7 text-center"> <div class="col-xs-7 text-center text-sm">
<a href="{$_url}accounts/change-password"><i class="ion ion-settings"></i> <a href="{$_url}accounts/change-password"><i class="ion ion-settings"></i>
{$_L['Change_Password']}</a> {$_L['Change_Password']}</a>
</div> </div>
<div class="col-xs-5 text-center"> <div class="col-xs-5 text-center text-sm">
<a href="{$_url}accounts/profile"><i class="ion ion-person"></i> <a href="{$_url}accounts/profile"><i class="ion ion-person"></i>
{$_L['My_Account']}</a> {$_L['My_Account']}</a>
</div> </div>

View File

@ -62,6 +62,21 @@
style="background-color: black; color:black; width:100%; border: 0px;" style="background-color: black; color:black; width:100%; border: 0px;"
onclick="this.select()"></td> onclick="this.select()"></td>
</tr> </tr>
{if $_c['enable_balance'] == 'yes'}
<tr>
<td class="small text-warning text-uppercase text-normal">{Lang::T('Balance')}</td>
<td class="small mb15 text-bold">
{Lang::moneyFormat($_user['balance'])}
{if $_user['auto_renewal'] == 1}
<a class="label label-success pull-right" href="{$_url}home&renewal=0"
onclick="return confirm('{Lang::T('Disable auto renewal?')}')">{Lang::T('Auto Renewal On')}</a>
{else}
<a class="label label-danger pull-right" href="{$_url}home&renewal=1"
onclick="return confirm('{Lang::T('Enable auto renewal?')}')">{Lang::T('Auto Renewal Off')}</a>
{/if}
</td>
</tr>
{/if}
<tr> <tr>
<td class="small text-primary text-uppercase text-normal">{$_L['Plan_Name']}</td> <td class="small text-primary text-uppercase text-normal">{$_L['Plan_Name']}</td>
<td class="small mb15">{$_bill['namebp']}</td> <td class="small mb15">{$_bill['namebp']}</td>

View File

@ -43,8 +43,12 @@
<form action="{$_url}login/post" method="post"> <form action="{$_url}login/post" method="post">
<div class="form-group"> <div class="form-group">
<label>{$_L['Phone_Number']}</label> <label>{$_L['Phone_Number']}</label>
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" name="username" <input type="text" class="form-control" name="username"
placeholder="{$_L['Phone_Number']}"> placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>{$_L['Password']}</label> <label>{$_L['Password']}</label>

View File

@ -5,17 +5,45 @@
<div class="box box-solid box-default"> <div class="box box-solid box-default">
<div class="box-header">{Lang::T('Order Internet Package')}</div> <div class="box-header">{Lang::T('Order Internet Package')}</div>
</div> </div>
<div class="box box-solid box-primary">
<div class="box-header">{Lang::T('Balance Plans')}</div>
<div class="box-body row">
{foreach $plans_balance as $plan}
<div class="col col-md-4">
<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('Price')}</td>
<td>{Lang::moneyFormat($plan['price'])}</td>
</tr>
</tbody>
</table>
</div>
<div class="box-body">
<a href="{$_url}order/buy/0/{$plan['id']}"
onclick="return confirm('{Lang::T('Buy Balance?')}')"
class="btn btn-sm btn-block btn-primary">Buy</a>
</div>
</div>
</div>
{/foreach}
</div>
</div>
{foreach $routers as $router} {foreach $routers as $router}
<div class="box box-solid box-info"> <div class="box box-solid box-info">
<div class="box-header">{$router['name']}</div> <div class="box-header text-black">{$router['name']}</div>
{if $router['description'] != ''} {if $router['description'] != ''}
<div class="box-body"> <div class="box-body">
{$router['description']} {$router['description']}
</div> </div>
{/if} {/if}
{if count($plans_hotspot)>0}
<div class="box-header">Hotspot</div>
<div class="box-body row"> <div class="box-body row">
{foreach $plans as $plan} {foreach $plans_hotspot as $plan}
{if $router['name'] eq $plan['routers']} {if $router['name'] eq $plan['routers']}
<div class="col col-md-4"> <div class="col col-md-4">
<div class="box box-solid box-default"> <div class="box box-solid box-default">
@ -28,11 +56,11 @@
<td>{$plan['type']}</td> <td>{$plan['type']}</td>
</tr> </tr>
<tr> <tr>
<td>Price</td> <td>{Lang::T('Price')}</td>
<td>{$plan['price']}</td> <td>{Lang::moneyFormat($plan['price'])}</td>
</tr> </tr>
<tr> <tr>
<td>Validity</td> <td>{Lang::T('Validity')}</td>
<td>{$plan['validity']} {$plan['validity_unit']}</td> <td>{$plan['validity']} {$plan['validity_unit']}</td>
</tr> </tr>
</tbody> </tbody>
@ -48,6 +76,44 @@
{/if} {/if}
{/foreach} {/foreach}
</div> </div>
{/if}
{if count($plans_pppoe)>0}
<div class="box-header text-sm">PPPOE</div>
<div class="box-body row">
{foreach $plans_pppoe as $plan}
{if $router['name'] eq $plan['routers']}
<div class="col col-md-4">
<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-body">
<a href="{$_url}order/buy/{$router['id']}/{$plan['id']}"
onclick="return confirm('{Lang::T('Buy this? your active package will be overwrite')}')"
class="btn btn-sm btn-block btn-primary">Buy</a>
</div>
</div>
</div>
{/if}
{/foreach}
</div>
{/if}
</div> </div>
{/foreach} {/foreach}
</div> </div>

View File

@ -3,8 +3,10 @@
<div class="row"> <div class="row">
<div class="col-md-3"></div> <div class="col-md-3"></div>
<div class="col-md-6"> <div class="col-md-6">
<div class="panel mb20 {if $trx['status']==1}panel-warning{elseif $trx['status']==2}panel-success{elseif $trx['status']==3}panel-danger{elseif $trx['status']==4}panel-danger{else}panel-primary{/if} panel-hovered"> <div
class="panel mb20 {if $trx['status']==1}panel-warning{elseif $trx['status']==2}panel-success{elseif $trx['status']==3}panel-danger{elseif $trx['status']==4}panel-danger{else}panel-primary{/if} panel-hovered">
<div class="panel-footer">Transaction #{$trx['id']}</div> <div class="panel-footer">Transaction #{$trx['id']}</div>
{if $plan['type']!='Balance'}
<div class="panel-body"> <div class="panel-body">
<div class="panel panel-primary panel-hovered"> <div class="panel panel-primary panel-hovered">
<div class="panel-heading">{$router['name']}</div> <div class="panel-heading">{$router['name']}</div>
@ -13,21 +15,25 @@
</div> </div>
</div> </div>
</div> </div>
{/if}
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered table-striped table-bordered"> <table class="table table-bordered table-striped table-bordered">
<tbody> <tbody>
<tr> <tr>
<td>{Lang::T('Status')}</td> <td>{Lang::T('Status')}</td>
<td>{if $trx['status']==1}{Lang::T('UNPAID')}{elseif $trx['status']==2}{Lang::T('PAID')}{elseif $trx['status']==3}{Lang::T('FAILED')}{elseif $trx['status']==4}{Lang::T('CANCELED')}{else}{Lang::T('UNKNOWN')}{/if}</td> <td>{if $trx['status']==1}{Lang::T('UNPAID')}{elseif $trx['status']==2}{Lang::T('PAID')}{elseif $trx['status']==3}{Lang::T('FAILED')}{elseif $trx['status']==4}{Lang::T('CANCELED')}{else}{Lang::T('UNKNOWN')}{/if}
</td>
</tr> </tr>
<tr> <tr>
<td>{Lang::T('expired')}</td> <td>{Lang::T('expired')}</td>
<td>{date($_c['date_format'], strtotime($trx['expired_date']))} {date('H:i', strtotime($trx['expired_date']))} </td> <td>{date($_c['date_format'], strtotime($trx['expired_date']))}
{date('H:i', strtotime($trx['expired_date']))} </td>
</tr> </tr>
{if $trx['status']==2} {if $trx['status']==2}
<tr> <tr>
<td>{Lang::T('Paid Date')}</td> <td>{Lang::T('Paid Date')}</td>
<td>{date($_c['date_format'], strtotime($trx['paid_date']))} {date('H:i', strtotime($trx['paid_date']))} </td> <td>{date($_c['date_format'], strtotime($trx['paid_date']))}
{date('H:i', strtotime($trx['paid_date']))} </td>
</tr> </tr>
{/if} {/if}
<tr> <tr>
@ -36,12 +42,13 @@
</tr> </tr>
<tr> <tr>
<td>{$_L['Plan_Price']}</td> <td>{$_L['Plan_Price']}</td>
<td>{$plan['price']}</td> <td>{Lang::moneyFormat($plan['price'])}</td>
</tr> </tr>
<tr> <tr>
<td>{Lang::T('Type')}</td> <td>{Lang::T('Type')}</td>
<td>{$plan['type']}</td> <td>{$plan['type']}</td>
</tr> </tr>
{if $plan['type']!='Balance'}
{if $plan['type'] eq 'Hotspot'} {if $plan['type'] eq 'Hotspot'}
<tr> <tr>
<td>{Lang::T('Plan_Type')}</td> <td>{Lang::T('Plan_Type')}</td>
@ -68,23 +75,25 @@
</tr> </tr>
<tr> <tr>
<td>{$_L['Bandwidth_Plans']}</td> <td>{$_L['Bandwidth_Plans']}</td>
<td>{$bandw['name_bw']}<br>{$bandw['rate_down']}{$bandw['rate_down_unit']}/{$bandw['rate_up']}{$bandw['rate_up_unit']}</td> <td>{$bandw['name_bw']}<br>{$bandw['rate_down']}{$bandw['rate_down_unit']}/{$bandw['rate_up']}{$bandw['rate_up_unit']}
</td>
</tr> </tr>
{/if}
</tbody> </tbody>
</table> </table>
</div> </div>
{if $trx['status']==1} {if $trx['status']==1}
<div class="panel-footer "> <div class="panel-footer ">
<div class="btn-group btn-group-justified"> <div class="btn-group btn-group-justified">
<a href="{$trx['pg_url_payment']}" <a href="{$trx['pg_url_payment']}" {if $trx['gateway']=='midtrans'} target="_blank" {/if}
{if $trx['gateway']=='midtrans'} class="btn btn-primary">{Lang::T('PAY NOW')}</a>
target="_blank" <a href="{$_url}order/view/{$trx['id']}/check"
{/if} class="btn btn-primary">{Lang::T('PAY NOW')}</a> class="btn btn-info">{Lang::T('Check for Payment')}</a>
<a href="{$_url}order/view/{$trx['id']}/check" class="btn btn-info">{Lang::T('Check for Payment')}</a>
</div> </div>
</div> </div>
<div class="panel-footer "> <div class="panel-footer ">
<a href="{$_url}order/view/{$trx['id']}/cancel" class="btn btn-danger" onclick="return confirm('{Lang::T('Cancel it?')}')">{Lang::T('Cancel')}</a> <a href="{$_url}order/view/{$trx['id']}/cancel" class="btn btn-danger"
onclick="return confirm('{Lang::T('Cancel it?')}')">{Lang::T('Cancel')}</a>
</div> </div>
{/if} {/if}
</div> </div>

View File

@ -12,8 +12,12 @@
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Username']}</label> <label class="col-md-2 control-label">{$_L['Username']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="username" name="username" <div class="input-group">
value="{$d['username']}" readonly> <span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" name="username" id="username" readonly
value="{$d['username']}"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
</div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -33,15 +37,18 @@
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{$_L['Phone_Number']}</label> <label class="col-md-2 control-label">{$_L['Phone_Number']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="phonenumber" name="phonenumber" <div class="input-group">
value="{$d['phonenumber']}"> <span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" name="phonenumber" id="phonenumber"
value="{$d['phonenumber']}"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {$_L['Phone_Number']}">
</div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Email')}</label> <label class="col-md-2 control-label">{Lang::T('Email')}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="email" name="email" <input type="text" class="form-control" id="email" name="email" value="{$d['email']}">
value="{$d['email']}">
</div> </div>
</div> </div>

View File

@ -82,6 +82,32 @@ if (empty($step)) {
$msgType = "danger"; $msgType = "danger";
$continue = false; $continue = false;
} }
} else if ($step == 4) {
if (file_exists("system/updates.json")) {
require 'config.php';
$db = new pdo(
"mysql:host=$db_host;dbname=$db_name",
$db_user,
$db_password,
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
);
$updates = json_decode(file_get_contents("system/updates.json"), true);
$dones = [];
if (file_exists("system/cache/updates.done.json")) {
$dones = json_decode(file_get_contents("system/cache/updates.done.json"), true);
}
foreach ($updates as $version => $queries) {
if (!in_array($version, $dones)) {
foreach ($queries as $q) {
$dbh->exec($q);
}
$dones[] = $version;
}
}
file_put_contents("system/cache/updates.done.json", json_encode($dones));
}
$step++;
} else { } else {
$version = json_decode(file_get_contents('version.json'), true)['version']; $version = json_decode(file_get_contents('version.json'), true)['version'];
$continue = false; $continue = false;
@ -152,7 +178,7 @@ function deleteFolder($path)
<link rel="stylesheet" href="ui/ui/styles/adminlte.min.css"> <link rel="stylesheet" href="ui/ui/styles/adminlte.min.css">
<link rel="stylesheet" href="ui/ui/styles/skin-blue.min.css"> <link rel="stylesheet" href="ui/ui/styles/skin-blue.min.css">
<?php if ($continue) { ?> <?php if ($continue) { ?>
<meta http-equiv="refresh" content="1; ./update.php?step=<?= $step ?>"> <meta http-equiv="refresh" content="3; ./update.php?step=<?= $step ?>">
<?php } ?> <?php } ?>
<style> <style>
::-moz-selection { ::-moz-selection {
@ -212,6 +238,13 @@ function deleteFolder($path)
</div> </div>
</div> </div>
<?php } else if ($step == 4) { ?> <?php } else if ($step == 4) { ?>
<div class="panel panel-primary">
<div class="panel-heading">Step 3</div>
<div class="panel-body">
Updating database...
</div>
</div>
<?php } else if ($step == 5) { ?>
<div class="panel panel-primary"> <div class="panel panel-primary">
<div class="panel-success">Update Finished</div> <div class="panel-success">Update Finished</div>
<div class="panel-body"> <div class="panel-body">

View File

@ -1,3 +1,3 @@
{ {
"version": "2023.8.1" "version": "2023.8.15"
} }