diff --git a/.gitignore b/.gitignore
index 5a2ce6e7..85d079af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,4 +19,8 @@ system/plugin/ui/*
!system/plugin/ui/index.html
ui/ui_custom/**
!ui/ui_custom/index.html
-!ui/ui_custom/README.md
\ No newline at end of file
+!ui/ui_custom/README.md
+system/uploads/admin.png
+system/uploads/logo.png
+system/uploads/user.jpg
+system/uploads/notifications.json
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e65825bc..273041d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,12 +2,34 @@
# CHANGELOG
+## 2023.8.16
+
+- Admin Can Add Balance to Customer
+- Show Balance in user
+- Using Select2 for Dropdown
+
+## 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
- Add Update file script, one click updating PHPNuxBill
- Add Custom UI folder, to custome your own template
- Delete debug text
- Fix Vendor JS
+
## 2023.7.28
- Fix link buy Voucher
@@ -22,13 +44,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.
## 2023.6.15
-- User can connect to internet from User Dashboard
+- Customer can connect to internet from Customer Dashboard
- Fix Confirm when delete
- Change Logo PHPNuxBill
- Using Composer
-- Fix Search User
-- Fix user check, if not found will logout
-- User password show but hidden
+- Fix Search Customer
+- Fix Customer check, if not found will logout
+- Customer password show but hidden
- Voucher code hidden
## 2023.6.8
diff --git a/README.md b/README.md
index d19af204..9c802f68 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,8 @@
- Voucher Generator and Print
- Self registration
+- User Balance
+- Auto Renewal Package using Balance
- Multi Router Mikrotik
- Hotspot & PPPOE
- Easy Installation
@@ -33,8 +35,10 @@ Minimum Requirements
- Linux or Windows OS
- PHP Version 7.4
- Both PDO & MySQLi Support
-- GD2 Image Library
-- CURL support
+- PHP-GD2 Image Library
+- PHP-CURL
+- PHP-ZIP
+- PHP-Mbstring
- MySQL Version 4.1.x and above
can be Installed in Raspberry Pi Device.
@@ -48,6 +52,10 @@ The problem with windows is hard to set cronjob, better Linux
[Installation instructions](https://github.com/hotspotbilling/phpnuxbill/wiki)
+## Docker Version
+
+[Docker Repository](https://github.com/animegasan/phpnuxbill)
+
## RADIUS system
Still on development
diff --git a/install/phpnuxbill.sql b/install/phpnuxbill.sql
index 38169450..602f8364 100644
--- a/install/phpnuxbill.sql
+++ b/install/phpnuxbill.sql
@@ -50,10 +50,13 @@ CREATE TABLE
`id` int(10) 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,
+ `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,
`address` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`phonenumber` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
`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,
`last_login` datetime DEFAULT NULL
) 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
) 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
@@ -543,6 +559,17 @@ ALTER TABLE
ALTER TABLE
`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;
--
diff --git a/install/step2.php b/install/step2.php
index f65f6de4..df1989e3 100644
--- a/install/step2.php
+++ b/install/step2.php
@@ -57,7 +57,7 @@
Continue Update System ");
} else {
echo (" $ltext 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 @phpnuxbill with this code- $passed Or contact with your server administrator
Correct The Problem To Continue ");
}
diff --git a/system/autoload/Balance.php b/system/autoload/Balance.php
new file mode 100644
index 00000000..2b3713d2
--- /dev/null
+++ b/system/autoload/Balance.php
@@ -0,0 +1,71 @@
+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;
+ }
+ }
+}
diff --git a/system/autoload/Lang.php b/system/autoload/Lang.php
index dc9292f6..6c790bd4 100644
--- a/system/autoload/Lang.php
+++ b/system/autoload/Lang.php
@@ -4,12 +4,31 @@
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
**/
-class Lang {
- public static function T($var) {
+class Lang
+{
+ public static function T($var)
+ {
return Lang($var);
}
- public static function htmlspecialchars($var) {
+ public static function 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;
+ }
+ }
}
diff --git a/system/autoload/Message.php b/system/autoload/Message.php
index 0606f42c..0373d682 100644
--- a/system/autoload/Message.php
+++ b/system/autoload/Message.php
@@ -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 (
!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') {
Message::sendSMS($phone, $msg);
} else if ($via == 'wa') {
Message::sendWhatsapp($phone, $msg);
}
}
+ return "$via: $msg";
}
}
diff --git a/system/autoload/Mikrotik.php b/system/autoload/Mikrotik.php
index 0b98ecd4..17b344e0 100644
--- a/system/autoload/Mikrotik.php
+++ b/system/autoload/Mikrotik.php
@@ -204,24 +204,29 @@ class Mikrotik
'/ppp secret print .proplist=name',
RouterOS\Query::where('name', $username)
);
- $userName = $client->sendSync($printRequest)->getProperty('name');
+ $id = $client->sendSync($printRequest)->getProperty('.id');
$removeRequest = new RouterOS\Request('/ppp/secret/remove');
$client(
$removeRequest
- ->setArgument('numbers', $userName)
+ ->setArgument('numbers', $id)
);
}
public static function addPpoeUser($client, $plan, $customer)
{
$addRequest = new RouterOS\Request('/ppp/secret/add');
+ if(!empty($customer['pppoe_password'])){
+ $pass = $customer['pppoe_password'];
+ }else{
+ $pass = $customer['password'];
+ }
$client->sendSync(
$addRequest
->setArgument('name', $customer['username'])
->setArgument('service', 'pppoe')
->setArgument('profile', $plan['name_plan'])
- ->setArgument('password', $customer['password'])
+ ->setArgument('password', $pass)
);
}
diff --git a/system/autoload/Package.php b/system/autoload/Package.php
index 384140dd..0a803dfc 100644
--- a/system/autoload/Package.php
+++ b/system/autoload/Package.php
@@ -19,7 +19,7 @@ class Package
*/
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_only = date("Y-m-d");
$time = date("H:i:s");
@@ -30,6 +30,50 @@ class Package
$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();
+
+ 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);
+ $textInvoice = str_replace('[[footer]]', $_c['note'], $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();
$mikrotik = Mikrotik::info($router_name);
@@ -198,29 +242,63 @@ class Package
$in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one();
- $msg = "*$_c[CompanyName]*\n" .
- "$_c[address]\n" .
- "$_c[phone]\n" .
- "\n\n" .
- "INVOICE: *$in[invoice]*\n" .
- "$_L[Date] : $date_now\n" .
- "$gateway $channel\n" .
- "\n\n" .
- "$_L[Type] : *$in[type]*\n" .
- "$_L[Plan_Name] : *$in[plan_name]*\n" .
- "$_L[Plan_Price] : *$_c[currency_code] " . number_format($in['price'], 2, $_c['dec_point'], $_c['thousands_sep']) . "*\n\n" .
- "$_L[Username] : *$in[username]*\n" .
- "$_L[Password] : **********\n\n" .
- "$_L[Created_On] :\n*" . date($_c['date_format'], strtotime($in['recharged_on'])) . "*\n" .
- "$_L[Expires_On] :\n*" . date($_c['date_format'], strtotime($in['expiration'])) . " $in[time]*\n" .
- "\n\n" .
- "$_c[note]";
+ $textInvoice = $_notifmsg['invoice_paid'];
+ $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]]', $in['invoice'], $textInvoice);
+ $textInvoice = str_replace('[[date]]', date($_c['date_format'], strtotime($date_now)) . " " . $time, $textInvoice);
+ $textInvoice = str_replace('[[payment_gateway]]', $_c['gateway'], $textInvoice);
+ $textInvoice = str_replace('[[payment_channel]]', $_c['channel'], $textInvoice);
+ $textInvoice = str_replace('[[type]]', $in['type'], $textInvoice);
+ $textInvoice = str_replace('[[plan_name]]', $in['plan_name'], $textInvoice);
+ $textInvoice = str_replace('[[plan_price]]', $_c['currency_code'] . " " . number_format($in['price'], 2, $_c['dec_point'], $_c['thousands_sep']), $textInvoice);
+ $textInvoice = str_replace('[[user_name]]', $in['username'], $textInvoice);
+ $textInvoice = str_replace('[[user_password]]', $c['password'], $textInvoice);
+ $textInvoice = str_replace('[[expired_date]]', date($_c['date_format'], strtotime($in['expiration'])) . " " . $in['time'], $textInvoice);
+ $textInvoice = str_replace('[[footer]]', $_c['note'], $textInvoice);
if ($_c['user_notification_payment'] == 'sms') {
- Message::sendSMS($c['phonenumber'], $msg);
+ Message::sendSMS($c['phonenumber'], $textInvoice);
} else if ($_c['user_notification_payment'] == 'wa') {
- Message::sendWhatsapp($c['phonenumber'], $msg);
+ Message::sendWhatsapp($c['phonenumber'], $textInvoice);
}
return true;
}
+
+ public static function changeTo($username, $plan_id)
+ {
+ global $_c;
+ $c = ORM::for_table('tbl_customers')->where('username', $username)->find_one();
+ $p = ORM::for_table('tbl_plans')->where('id', $plan_id)->where('enabled', '1')->find_one();
+ $b = ORM::for_table('tbl_user_recharges')->where('customer_id', $c['id'])->find_one();
+ $mikrotik = Mikrotik::info($p['routers']);
+ if ($p['type'] == 'Hotspot') {
+ if ($b) {
+ if (!$_c['radius_mode']) {
+ $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
+ Mikrotik::removeHotspotUser($client, $c['username']);
+ Mikrotik::addHotspotUser($client, $p, $c);
+ }
+ } else {
+ if (!$_c['radius_mode']) {
+ $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
+ Mikrotik::addHotspotUser($client, $p, $c);
+ }
+ }
+ } else {
+ if ($b) {
+ if (!$_c['radius_mode']) {
+ $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
+ Mikrotik::removePpoeUser($client, $c['username']);
+ Mikrotik::addPpoeUser($client, $p, $c);
+ }
+ } else {
+ if (!$_c['radius_mode']) {
+ $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
+ Mikrotik::addPpoeUser($client, $p, $c);
+ }
+ }
+ }
+ }
}
diff --git a/system/boot.php b/system/boot.php
index c2e0c637..9e458289 100644
--- a/system/boot.php
+++ b/system/boot.php
@@ -128,6 +128,12 @@ if (isset($_SESSION['notify'])) {
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
foreach (glob("system/plugin/*.php") as $filename) {
diff --git a/system/controllers/accounts.php b/system/controllers/accounts.php
index b586fdb2..559d7bd2 100644
--- a/system/controllers/accounts.php
+++ b/system/controllers/accounts.php
@@ -59,7 +59,11 @@ switch ($action) {
} else {
if (!$config['radius_mode']) {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::setPpoeUser($client, $c['username'], $npass);
+ if(!empty($d['pppoe_password'])){
+ Mikrotik::setPpoeUser($client, $c['username'], $d['pppoe_password']);
+ }else{
+ Mikrotik::setPpoeUser($client, $c['username'], $npass);
+ }
Mikrotik::removePpoeActive($client, $user['username']);
}
$d->password = $npass;
diff --git a/system/controllers/customers.php b/system/controllers/customers.php
index 3aabc72b..cd12ed48 100644
--- a/system/controllers/customers.php
+++ b/system/controllers/customers.php
@@ -116,7 +116,8 @@ switch ($action) {
$username = _post('username');
$fullname = _post('fullname');
$password = _post('password');
- $cpassword = _post('cpassword');
+ $pppoe_password = _post('pppoe_password');
+ $email = _post('email');
$address = _post('address');
$phonenumber = _post('phonenumber');
run_hook('add_customer'); #HOOK
@@ -130,9 +131,6 @@ switch ($action) {
if (!Validator::Length($password, 35, 2)) {
$msg .= 'Password should be between 3 to 35 characters' . ' ';
}
- if ($password != $cpassword) {
- $msg .= 'Passwords does not match' . ' ';
- }
$d = ORM::for_table('tbl_customers')->where('username', $username)->find_one();
if ($d) {
@@ -141,11 +139,13 @@ switch ($action) {
if ($msg == '') {
$d = ORM::for_table('tbl_customers')->create();
- $d->username = $username;
+ $d->username = Lang::phoneFormat($username);
$d->password = $password;
+ $d->pppoe_password = $pppoe_password;
+ $d->email = $email;
$d->fullname = $fullname;
$d->address = $address;
- $d->phonenumber = $username;
+ $d->phonenumber = Lang::phoneFormat($phonenumber);
$d->save();
r2(U . 'customers/list', 's', $_L['account_created_successfully']);
} else {
@@ -154,27 +154,25 @@ switch ($action) {
break;
case 'edit-post':
- $username = _post('username');
+ $username = Lang::phoneFormat(_post('username'));
$fullname = _post('fullname');
$password = _post('password');
- $cpassword = _post('cpassword');
+ $pppoe_password = _post('pppoe_password');
+ $email = _post('email');
$address = _post('address');
- $phonenumber = _post('phonenumber');
+ $phonenumber = Lang::phoneFormat(_post('phonenumber'));
run_hook('edit_customer'); #HOOK
$msg = '';
if (Validator::Length($username, 16, 2) == false) {
$msg .= 'Username should be between 3 to 15 characters' . ' ';
}
- if (Validator::Length($fullname, 26, 2) == false) {
- $msg .= 'Full Name should be between 3 to 25 characters' . ' ';
+ if (Validator::Length($fullname, 26, 1) == false) {
+ $msg .= 'Full Name should be between 2 to 25 characters' . ' ';
}
if ($password != '') {
if (!Validator::Length($password, 15, 2)) {
$msg .= 'Password should be between 3 to 15 characters' . ' ';
}
- if ($password != $cpassword) {
- $msg .= 'Passwords does not match' . ' ';
- }
}
$id = _post('id');
@@ -206,7 +204,11 @@ switch ($action) {
} else {
if(!$config['radius_mode']){
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::setPpoeUser($client,$c['username'],$password);
+ if(!empty($d['pppoe_password'])){
+ Mikrotik::setPpoeUser($client, $c['username'], $d['pppoe_password']);
+ }else{
+ Mikrotik::setPpoeUser($client, $c['username'], $password);
+ }
Mikrotik::removePpoeActive($client,$user['username']);
}
@@ -217,7 +219,9 @@ switch ($action) {
if ($password != '') {
$d->password = $password;
}
+ $d->pppoe_password = $pppoe_password;
$d->fullname = $fullname;
+ $d->email = $email;
$d->address = $address;
$d->phonenumber = $phonenumber;
$d->save();
@@ -227,6 +231,8 @@ switch ($action) {
$d->password = $password;
}
$d->fullname = $fullname;
+ $d->pppoe_password = $pppoe_password;
+ $d->email = $email;
$d->address = $address;
$d->phonenumber = $phonenumber;
$d->save();
diff --git a/system/controllers/export.php b/system/controllers/export.php
index 0cd60ac7..0d2ba727 100644
--- a/system/controllers/export.php
+++ b/system/controllers/export.php
@@ -61,6 +61,12 @@ switch ($action) {
$title = ' Reports [' . $mdate . ']';
$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) {
$html = '
@@ -69,7 +75,7 @@ switch ($action) {
' . $config['address'] . '
' . $_L['Phone_Number'] . ': ' . $config['phone'] . '
-
+
@@ -178,7 +184,6 @@ EOF;
if ($stype != '') {
$d->where('type', $stype);
}
-
$d->where_gte('recharged_on', $fdate);
$d->where_lte('recharged_on', $tdate);
$d->order_by_desc('id');
@@ -207,7 +212,6 @@ EOF;
$fdate = _post('fdate');
$tdate = _post('tdate');
$stype = _post('stype');
-
$d = ORM::for_table('tbl_transactions');
if ($stype != '') {
$d->where('type', $stype);
@@ -229,6 +233,11 @@ EOF;
$title = ' Reports [' . $mdate . ']';
$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) {
$html = '
@@ -238,7 +247,7 @@ EOF;
' . $config['address'] . '
' . $_L['Phone_Number'] . ': ' . $config['phone'] . '
-
+
@@ -281,11 +290,7 @@ EOF;
' . $config['currency_code'] . ' ' . number_format($xy, 2, $config['dec_point'], $config['thousands_sep']) . ' ';
run_hook('pdf_by_period'); #HOOK
- define('_MPDF_PATH', 'system/vendors/mpdf/');
-
- require('system/vendors/mpdf/mpdf.php');
-
- $mpdf = new mPDF('c', 'A4', '', '', 20, 15, 25, 25, 10, 10);
+ $mpdf = new \Mpdf\Mpdf();
$mpdf->SetProtection(array('print'));
$mpdf->SetTitle($config['CompanyName'] . ' Reports');
$mpdf->SetAuthor($config['CompanyName']);
diff --git a/system/controllers/home.php b/system/controllers/home.php
index a4372225..6108d816 100644
--- a/system/controllers/home.php
+++ b/system/controllers/home.php
@@ -9,6 +9,11 @@ $ui->assign('_title', $_L['Dashboard']);
$user = User::_info();
$ui->assign('_user', $user);
+if(isset($_GET['renewal'])){
+ $user->auto_renewal = $_GET['renewal'];
+ $user->save();
+}
+
//Client Page
$bill = User::_billing();
diff --git a/system/controllers/order.php b/system/controllers/order.php
index 016c2c4c..19ee3e2d 100644
--- a/system/controllers/order.php
+++ b/system/controllers/order.php
@@ -35,9 +35,13 @@ switch ($action) {
$ui->assign('_title', 'Order Plan');
$ui->assign('_system_menu', 'package');
$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('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
$ui->display('user-orderPlan.tpl');
break;
@@ -118,11 +122,15 @@ switch ($action) {
run_hook('customer_buy_plan'); #HOOK
include 'system/paymentgateway/' . $config['payment_gateway'] . '.php';
call_user_func($config['payment_gateway'] . '_validate_config');
-
- $router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2'] * 1);
- $plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3'] * 1);
+ if ($routes['2']>0) {
+ $router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2']);
+ }else{
+ $router['id'] = 0;
+ $router['name'] = 'balance';
+ }
+ $plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3']);
if (empty($router) || empty($plan)) {
- r2(U . $back, 'e', Lang::T("Plan Not found"));
+ r2(U . "order/package", 'e', Lang::T("Plan Not found"));
}
$d = ORM::for_table('tbl_payment_gateway')
->where('username', $user['username'])
@@ -172,5 +180,5 @@ switch ($action) {
}
break;
default:
- $ui->display('404.tpl');
+ r2(U . "order/package/", 's','');
}
diff --git a/system/controllers/prepaid.php b/system/controllers/prepaid.php
index 0fbee57f..0ba294d0 100644
--- a/system/controllers/prepaid.php
+++ b/system/controllers/prepaid.php
@@ -72,8 +72,6 @@ switch ($action) {
$type = _post('type');
$server = _post('server');
$plan = _post('plan');
-
- $date_now = date("Y-m-d H:i:s");
$date_only = date("Y-m-d");
$time = date("H:i:s");
@@ -83,212 +81,28 @@ switch ($action) {
}
if ($msg == '') {
- $c = ORM::for_table('tbl_customers')->where('id', $id_customer)->find_one();
- $p = ORM::for_table('tbl_plans')->where('id', $plan)->where('enabled', '1')->find_one();
- $b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->find_one();
-
- $mikrotik = Mikrotik::info($server);
- if($p['validity_unit']=='Months'){
- $date_exp = date("Y-m-d", strtotime('+'.$p['validity'].' month'));
- }else if($p['validity_unit']=='Days'){
- $date_exp = date("Y-m-d", strtotime('+'.$p['validity'].' day'));
- }else if($p['validity_unit']=='Hrs'){
- $datetime = explode(' ',date("Y-m-d H:i:s", strtotime('+'.$p['validity'].' hour')));
- $date_exp = $datetime[0];
- $time = $datetime[1];
- }else if($p['validity_unit']=='Mins'){
- $datetime = explode(' ',date("Y-m-d H:i:s", strtotime('+'.$p['validity'].' minute')));
- $date_exp = $datetime[0];
- $time = $datetime[1];
+ if(Package::rechargeUser($id_customer, $server, $plan, "Recharge", $admin['fullname'])){
+ $c = ORM::for_table('tbl_customers')->where('id', $id_customer)->find_one();
+ $in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one();
+ $ui->assign('in', $in);
+ $ui->assign('date', date("Y-m-d H:i:s"));
+ $ui->display('invoice.tpl');
+ _log('[' . $admin['username'] . ']: ' . 'Recharge '.$c['username'].' ['.$in['plan_name'].']['.Lang::moneyFormat($in['price']).']', 'Admin', $admin['id']);
+ }else{
+ r2(U . 'prepaid/recharge', 'e', "Failed to recharge account");
}
- run_hook('recharge_customer'); #HOOK
- if ($type == 'Hotspot') {
- if ($b) {
- if(!$config['radius_mode']){
- $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::removeHotspotUser($client,$c['username']);
- Mikrotik::addHotspotUser($client,$p,$c);
- }
-
- $b->customer_id = $id_customer;
- $b->username = $c['username'];
- $b->plan_id = $plan;
- $b->namebp = $p['name_plan'];
- $b->recharged_on = $date_only;
- $b->expiration = $date_exp;
- $b->time = $time;
- $b->status = "on";
- $b->method = "admin";
- $b->routers = $server;
- $b->type = "Hotspot";
- $b->save();
-
- // insert table transactions
- $t = ORM::for_table('tbl_transactions')->create();
- $t->invoice = "INV-" . _raid(5);
- $t->username = $c['username'];
- $t->plan_name = $p['name_plan'];
- $t->price = $p['price'];
- $t->recharged_on = $date_only;
- $t->expiration = $date_exp;
- $t->time = $time;
- $t->method = "admin";
- $t->routers = $server;
- $t->type = "Hotspot";
- $t->save();
- } else {
- if(!$config['radius_mode']){
- $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::addHotspotUser($client,$p,$c);
- }
-
- $d = ORM::for_table('tbl_user_recharges')->create();
- $d->customer_id = $id_customer;
- $d->username = $c['username'];
- $d->plan_id = $plan;
- $d->namebp = $p['name_plan'];
- $d->recharged_on = $date_only;
- $d->expiration = $date_exp;
- $d->time = $time;
- $d->status = "on";
- $d->method = "admin";
- $d->routers = $server;
- $d->type = "Hotspot";
- $d->save();
-
- // insert table transactions
- $t = ORM::for_table('tbl_transactions')->create();
- $t->invoice = "INV-" . _raid(5);
- $t->username = $c['username'];
- $t->plan_name = $p['name_plan'];
- $t->price = $p['price'];
- $t->recharged_on = $date_only;
- $t->expiration = $date_exp;
- $t->time = $time;
- $t->method = "admin";
- $t->routers = $server;
- $t->type = "Hotspot";
- $t->save();
- }
- Message::sendTelegram( "$admin[fullname] #Recharge Voucher #Hotspot for #u$c[username]\n".$p['name_plan'].
- "\nRouter: ".$server.
- "\nPrice: ".$p['price']);
- } else {
-
- if ($b) {
- if(!$config['radius_mode']){
- $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::removePpoeUser($client,$c['username']);
- Mikrotik::addPpoeUser($client,$p,$c);
- }
-
- $b->customer_id = $id_customer;
- $b->username = $c['username'];
- $b->plan_id = $plan;
- $b->namebp = $p['name_plan'];
- $b->recharged_on = $date_only;
- $b->expiration = $date_exp;
- $b->time = $time;
- $b->status = "on";
- $b->method = "admin";
- $b->routers = $server;
- $b->type = "PPPOE";
- $b->save();
-
- // insert table transactions
- $t = ORM::for_table('tbl_transactions')->create();
- $t->invoice = "INV-" . _raid(5);
- $t->username = $c['username'];
- $t->plan_name = $p['name_plan'];
- $t->price = $p['price'];
- $t->recharged_on = $date_only;
- $t->expiration = $date_exp;
- $t->time = $time;
- $t->method = "admin";
- $t->routers = $server;
- $t->type = "PPPOE";
- $t->save();
- } else {
- if(!$config['radius_mode']){
- $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::addPpoeUser($client,$p,$c);
- }
-
- $d = ORM::for_table('tbl_user_recharges')->create();
- $d->customer_id = $id_customer;
- $d->username = $c['username'];
- $d->plan_id = $plan;
- $d->namebp = $p['name_plan'];
- $d->recharged_on = $date_only;
- $d->expiration = $date_exp;
- $d->time = $time;
- $d->status = "on";
- $d->method = "admin";
- $d->routers = $server;
- $d->type = "PPPOE";
- $d->save();
-
- // insert table transactions
- $t = ORM::for_table('tbl_transactions')->create();
- $t->invoice = "INV-" . _raid(5);
- $t->username = $c['username'];
- $t->plan_name = $p['name_plan'];
- $t->price = $p['price'];
- $t->recharged_on = $date_only;
- $t->expiration = $date_exp;
- $t->time = $time;
- $t->method = "admin";
- $t->routers = $server;
- $t->type = "PPPOE";
- $t->save();
- }
- Message::sendTelegram( "$admin[fullname] #Recharge Voucher #PPPOE for #u$c[username]\n".$p['name_plan'].
- "\nRouter: ".$server.
- "\nPrice: ".$p['price']);
- }
-
- $in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one();
- $ui->assign('in', $in);
-
- $msg = "*$config[CompanyName]*\n".
- "$config[address]\n".
- "$config[phone]\n".
- "\n\n".
- "INVOICE: *$in[invoice]*\n".
- "$_L[Date] : $date_now\n".
- "$_L[Sales] : $admin[fullname]\n".
- "\n\n".
- "$_L[Type] : *$in[type]*\n".
- "$_L[Plan_Name] : *$in[plan_name]*\n".
- "$_L[Plan_Price] : *$config[currency_code] ".number_format($in['price'],2,$config['dec_point'],$config['thousands_sep'])."*\n\n".
- "$_L[Username] : *$in[username]*\n".
- "$_L[Password] : **********\n\n".
- "$_L[Created_On] :\n*".date($config['date_format'], strtotime($in['recharged_on']))."*\n".
- "$_L[Expires_On] :\n*".date($config['date_format'], strtotime($in['expiration']))." $in[time]*\n".
- "\n\n".
- "$config[note]";
-
- if ($_c['user_notification_payment'] == 'sms') {
- Message::sendSMS($c['phonenumber'], $msg);
- } else if ($_c['user_notification_payment'] == 'wa') {
- Message::sendWhatsapp($c['phonenumber'], $msg);
- }
-
- $ui->assign('date', $date_now);
- $ui->display('invoice.tpl');
} else {
r2(U . 'prepaid/recharge', 'e', $msg);
}
break;
case 'print':
- $date_now = date("Y-m-d H:i:s");
$id = _post('id');
$d = ORM::for_table('tbl_transactions')->where('id', $id)->find_one();
$ui->assign('d', $d);
- $ui->assign('date', $date_now);
+ $ui->assign('date', date("Y-m-d H:i:s"));
run_hook('print_invoice'); #HOOK
$ui->display('invoice-print.tpl');
break;
@@ -328,6 +142,7 @@ switch ($action) {
}
$d->delete();
}
+ _log('[' . $admin['username'] . ']: ' . 'Delete Plan for Customer '.$c['username'].' ['.$in['plan_name'].']['.Lang::moneyFormat($in['price']).']', 'Admin', $admin['id']);
r2(U . 'prepaid/list', 's', $_L['Delete_Successfully']);
}
break;
@@ -352,7 +167,8 @@ switch ($action) {
$d->recharged_on = $recharged_on;
$d->expiration = $expiration;
$d->save();
- //TODO set mikrotik for editedd plan
+ Package::changeTo($username,$id_plan);
+ _log('[' . $admin['username'] . ']: ' . 'Edit Plan for Customer '.$d['username'].' to ['.$d['plan_name'].']['.Lang::moneyFormat($d['price']).']', 'Admin', $admin['id']);
r2(U . 'prepaid/list', 's', $_L['Updated_Successfully']);
} else {
r2(U . 'prepaid/edit/' . $id, 'e', $msg);
@@ -526,7 +342,7 @@ switch ($action) {
case 'refill':
$ui->assign('xfooter', '');
-
+ $ui->assign('_title', $_L['Refill_Account']);
$c = ORM::for_table('tbl_customers')->find_many();
$ui->assign('c', $c);
run_hook('view_refill'); #HOOK
@@ -540,221 +356,50 @@ switch ($action) {
$v1 = ORM::for_table('tbl_voucher')->where('code', $code)->where('status', 0)->find_one();
- $c = ORM::for_table('tbl_customers')->find_one($user);
- $p = ORM::for_table('tbl_plans')->find_one($v1['id_plan']);
- $b = ORM::for_table('tbl_user_recharges')->where('customer_id', $user)->find_one();
-
- $date_now = date("Y-m-d H:i:s");
- $date_only = date("Y-m-d");
- $time = date("H:i:s");
-
- $mikrotik = Mikrotik::info($v1['routers']);
-
- if($p['validity_unit']=='Months'){
- $date_exp = date("Y-m-d", strtotime('+'.$p['validity'].' month'));
- }else if($p['validity_unit']=='Days'){
- $date_exp = date("Y-m-d", strtotime('+'.$p['validity'].' day'));
- }else if($p['validity_unit']=='Hrs'){
- $datetime = explode(' ',date("Y-m-d H:i:s", strtotime('+'.$p['validity'].' hour')));
- $date_exp = $datetime[0];
- $time = $datetime[1];
- }else if($p['validity_unit']=='Mins'){
- $datetime = explode(' ',date("Y-m-d H:i:s", strtotime('+'.$p['validity'].' minute')));
- $date_exp = $datetime[0];
- $time = $datetime[1];
- }
run_hook('refill_customer'); #HOOK
if ($v1) {
- if ($v1['type'] == 'Hotspot') {
- if ($b) {
- if(!$config['radius_mode']){
- $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::removeHotspotUser($client,$c['username']);
- Mikrotik::addHotspotUser($client,$p,$c);
- }
-
- $b->customer_id = $user;
- $b->username = $c['username'];
- $b->plan_id = $v1['id_plan'];
- $b->namebp = $p['name_plan'];
- $b->recharged_on = $date_only;
- $b->expiration = $date_exp;
- $b->time = $time;
- $b->status = "on";
- $b->method = "voucher";
- $b->routers = $v1['routers'];
- $b->type = "Hotspot";
- $b->save();
-
- // insert table transactions
- $t = ORM::for_table('tbl_transactions')->create();
- $t->invoice = "INV-" . _raid(5);
- $t->username = $c['username'];
- $t->plan_name = $p['name_plan'];
- $t->price = $p['price'];
- $t->recharged_on = $date_only;
- $t->expiration = $date_exp;
- $t->time = $time;
- $t->method = "voucher";
- $t->routers = $v1['routers'];
- $t->type = "Hotspot";
- $t->save();
- } else {
- if(!$config['radius_mode']){
- $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::addHotspotUser($client,$p,$c);
- }
-
- $d = ORM::for_table('tbl_user_recharges')->create();
- $d->customer_id = $user;
- $d->username = $c['username'];
- $d->plan_id = $v1['id_plan'];
- $d->namebp = $p['name_plan'];
- $d->recharged_on = $date_only;
- $d->expiration = $date_exp;
- $d->time = $time;
- $d->status = "on";
- $d->method = "voucher";
- $d->routers = $v1['routers'];
- $d->type = "Hotspot";
- $d->save();
-
- // insert table transactions
- $t = ORM::for_table('tbl_transactions')->create();
- $t->invoice = "INV-" . _raid(5);
- $t->username = $c['username'];
- $t->plan_name = $p['name_plan'];
- $t->price = $p['price'];
- $t->recharged_on = $date_only;
- $t->expiration = $date_exp;
- $t->time = $time;
- $t->method = "voucher";
- $t->routers = $v1['routers'];
- $t->type = "Hotspot";
- $t->save();
- }
-
+ if(Package::rechargeUser($user, $v1['routers'], $v1['id_plan'], "Refill", "Voucher")){
$v1->status = "1";
$v1->user = $c['username'];
$v1->save();
-
- Message::sendTelegram( "$admin[fullname] #Refill #Voucher #Hotspot for #u$c[username]\n".$p['name_plan'].
- "\nCode: ".$code.
- "\nRouter: ".$v1['routers'].
- "\nPrice: ".$p['price']);
- } else {
- if ($b) {
- if(!$config['radius_mode']){
- $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::removePpoeUser($client,$c['username']);
- Mikrotik::addPpoeUser($client,$p,$c);
- }
-
- $b->customer_id = $user;
- $b->username = $c['username'];
- $b->plan_id = $v1['id_plan'];
- $b->namebp = $p['name_plan'];
- $b->recharged_on = $date_only;
- $b->expiration = $date_exp;
- $b->time = $time;
- $b->status = "on";
- $b->method = "voucher";
- $b->routers = $v1['routers'];
- $b->type = "PPPOE";
- $b->save();
-
- // insert table transactions
- $t = ORM::for_table('tbl_transactions')->create();
- $t->invoice = "INV-" . _raid(5);
- $t->username = $c['username'];
- $t->plan_name = $p['name_plan'];
- $t->price = $p['price'];
- $t->recharged_on = $date_only;
- $t->expiration = $date_exp;
- $t->time = $time;
- $t->method = "voucher";
- $t->routers = $v1['routers'];
- $t->type = "PPPOE";
- $t->save();
- } else {
- if(!$config['radius_mode']){
- $client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::addPpoeUser($client,$p,$c);
- }
-
- $d = ORM::for_table('tbl_user_recharges')->create();
- $d->customer_id = $user;
- $d->username = $c['username'];
- $d->plan_id = $v1['id_plan'];
- $d->namebp = $p['name_plan'];
- $d->recharged_on = $date_only;
- $d->expiration = $date_exp;
- $d->time = $time;
- $d->status = "on";
- $d->method = "voucher";
- $d->routers = $v1['routers'];
- $d->type = "PPPOE";
- $d->save();
-
- // insert table transactions
- $t = ORM::for_table('tbl_transactions')->create();
- $t->invoice = "INV-" . _raid(5);
- $t->username = $c['username'];
- $t->plan_name = $p['name_plan'];
- $t->price = $p['price'];
- $t->recharged_on = $date_only;
- $t->expiration = $date_exp;
- $t->time = $time;
- $t->method = "voucher";
- $t->routers = $v1['routers'];
- $t->type = "PPPOE";
- $t->save();
- }
-
- $v1->status = "1";
- $v1->user = $c['username'];
- $v1->save();
-
-
- Message::sendTelegram( "$admin[fullname] Refill #Voucher #PPPOE for #u$c[username]\n".$p['name_plan'].
- "\nCode: ".$code.
- "\nRouter: ".$v1['routers'].
- "\nPrice: ".$p['price']);
+ $c = ORM::for_table('tbl_customers')->where('id', $id_customer)->find_one();
+ $in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one();
+ $ui->assign('in', $in);
+ $ui->assign('date', date("Y-m-d H:i:s"));
+ $ui->display('invoice.tpl');
+ }else{
+ r2(U . 'prepaid/refill', 'e', "Failed to refill account");
}
- $in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one();
- $ui->assign('in', $in);
-
-
- $msg = "*$config[CompanyName]*\n".
- "$config[address]\n".
- "$config[phone]\n".
- "\n\n".
- "INVOICE: *$in[invoice]*\n".
- "$_L[Date] : $date_now\n".
- "$_L[Sales] : $admin[fullname]\n".
- "\n\n".
- "$_L[Type] : *$in[type]*\n".
- "$_L[Plan_Name] : *$in[plan_name]*\n".
- "$_L[Plan_Price] : *$config[currency_code] ".number_format($in['price'],2,$config['dec_point'],$config['thousands_sep'])."*\n\n".
- "$_L[Username] : *$in[username]*\n".
- "$_L[Password] : **********\n\n".
- "$_L[Created_On] :\n*".date($config['date_format'], strtotime($in['recharged_on']))."*\n".
- "$_L[Expires_On] :\n*".date($config['date_format'], strtotime($in['expiration']))." $in[time]*\n".
- "\n\n".
- "$config[note]";
-
- if ($_c['user_notification_payment'] == 'sms') {
- Message::sendSMS($c['phonenumber'], $msg);
- } else if ($_c['user_notification_payment'] == 'wa') {
- Message::sendWhatsapp($c['phonenumber'], $msg);
- }
- $ui->assign('date', $date_now);
- $ui->display('invoice.tpl');
} else {
r2(U . 'prepaid/refill', 'e', $_L['Voucher_Not_Valid']);
}
break;
+ case 'deposit':
+ $ui->assign('_title', Lang::T('Refill Balance'));
+ $ui->assign('c', ORM::for_table('tbl_customers')->find_many());
+ $ui->assign('p', ORM::for_table('tbl_plans')->where('enabled', '1')->where('type', 'Balance')->find_many());
+ run_hook('view_deposit'); #HOOK
+ $ui->display('deposit.tpl');
+ break;
+ case 'deposit-post':
+ $user = _post('id_customer');
+ $plan = _post('id_plan');
+ run_hook('deposit_customer'); #HOOK
+ if (!empty($user) && !empty($plan)) {
+ if(Package::rechargeUser($user, 'balance', $plan, "Deposit", $admin['fullname'])){
+ $c = ORM::for_table('tbl_customers')->where('id', $user)->find_one();
+ $in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one();
+ $ui->assign('in', $in);
+ $ui->assign('date', date("Y-m-d H:i:s"));
+ $ui->display('invoice.tpl');
+ }else{
+ r2(U . 'prepaid/refill', 'e', "Failed to refill account");
+ }
+ } else {
+ r2(U . 'prepaid/refill', 'e', "All field is required");
+ }
+ break;
default:
echo 'action not defined';
}
diff --git a/system/controllers/register.php b/system/controllers/register.php
index 5f41f97f..8ebd8226 100644
--- a/system/controllers/register.php
+++ b/system/controllers/register.php
@@ -26,7 +26,8 @@ switch ($do) {
$cpassword = _post('cpassword');
$address = _post('address');
if(!empty($config['sms_url'])){
- $phonenumber = $username;
+ $phonenumber = Lang::phoneFormat($username);
+ $username = $phonenumber;
}else if(strlen($username)<21){
$phonenumber = $username;
}
diff --git a/system/controllers/services.php b/system/controllers/services.php
index 7621a535..ed44feb3 100644
--- a/system/controllers/services.php
+++ b/system/controllers/services.php
@@ -70,10 +70,10 @@ switch ($action) {
$d = ORM::for_table('tbl_plans')->find_one($id);
if ($d) {
run_hook('delete_plan'); #HOOK
- if(!$config['radius_mode']){
+ if (!$config['radius_mode']) {
$mikrotik = Mikrotik::info($d['routers']);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
- Mikrotik::removeHotspotPlan($client,$d['name_plan']);
+ Mikrotik::removeHotspotPlan($client, $d['name_plan']);
}
$d->delete();
@@ -91,12 +91,12 @@ switch ($action) {
$data_limit = _post('data_limit');
$data_unit = _post('data_unit');
$id_bw = _post('id_bw');
- $price = _post('pricebp');
+ $price = _post('price');
$sharedusers = _post('sharedusers');
$validity = _post('validity');
$validity_unit = _post('validity_unit');
$routers = _post('routers');
- $enabled = _post('enabled')*1;
+ $enabled = _post('enabled');
$msg = '';
if (Validator::UnsignedNumber($validity) == false) {
@@ -130,7 +130,7 @@ switch ($action) {
}
$rate = $b['rate_up'] . $unitup . "/" . $b['rate_down'] . $unitdown;
- if(!$config['radius_mode']){
+ if (!$config['radius_mode']) {
$mikrotik = Mikrotik::info($routers);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::addHotspotPlan($client, $name, $sharedusers, $rate);
@@ -176,7 +176,7 @@ switch ($action) {
$validity = _post('validity');
$validity_unit = _post('validity_unit');
$routers = _post('routers');
- $enabled = _post('enabled')*1;
+ $enabled = _post('enabled');
$msg = '';
if (Validator::UnsignedNumber($validity) == false) {
@@ -209,7 +209,7 @@ switch ($action) {
}
$rate = $b['rate_up'] . $unitup . "/" . $b['rate_down'] . $unitdown;
- if(!$config['radius_mode']){
+ if (!$config['radius_mode']) {
$mikrotik = Mikrotik::info($routers);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::setHotspotPlan($client, $name, $sharedusers, $rate);
@@ -293,7 +293,7 @@ switch ($action) {
$d = ORM::for_table('tbl_plans')->find_one($id);
if ($d) {
run_hook('delete_ppoe'); #HOOK
- if(!$config['radius_mode']){
+ if (!$config['radius_mode']) {
$mikrotik = Mikrotik::info($d['routers']);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removePpoePlan($client, $d['name_plan']);
@@ -312,7 +312,7 @@ switch ($action) {
$validity_unit = _post('validity_unit');
$routers = _post('routers');
$pool = _post('pool_name');
- $enabled = _post('enabled')*1;
+ $enabled = _post('enabled');
$msg = '';
if (Validator::UnsignedNumber($validity) == false) {
@@ -344,7 +344,7 @@ switch ($action) {
}
$rate = $b['rate_up'] . $unitup . "/" . $b['rate_down'] . $unitdown;
- if(!$config['radius_mode']){
+ if (!$config['radius_mode']) {
$mikrotik = Mikrotik::info($routers);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::addPpoePlan($client, $name, $pool, $rate);
@@ -377,7 +377,7 @@ switch ($action) {
$validity_unit = _post('validity_unit');
$routers = _post('routers');
$pool = _post('pool_name');
- $enabled = _post('enabled')*1;
+ $enabled = _post('enabled');
$msg = '';
if (Validator::UnsignedNumber($validity) == false) {
@@ -410,7 +410,7 @@ switch ($action) {
}
$rate = $b['rate_up'] . $unitup . "/" . $b['rate_down'] . $unitdown;
- if(!$config['radius_mode']){
+ if (!$config['radius_mode']) {
$mikrotik = Mikrotik::info($routers);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::setPpoePlan($client, $name, $pool, $rate);
@@ -431,7 +431,112 @@ switch ($action) {
r2(U . 'services/pppoe-edit/' . $id, 'e', $msg);
}
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' . ' ';
+ }
+ if ($name == '') {
+ $msg .= $_L['All_field_is_required'] . ' ';
+ }
+
+ $d = ORM::for_table('tbl_plans')->where('id', $id)->find_one();
+ if ($d) {
+ } else {
+ $msg .= $_L['Data_Not_Found'] . ' ';
+ }
+ 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' . ' ';
+ }
+ if ($name == '') {
+ $msg .= $_L['All_field_is_required'] . ' ';
+ }
+
+ $d = ORM::for_table('tbl_plans')->where('name_plan', $name)->find_one();
+ if ($d) {
+ $msg .= $_L['Plan_already_exist'] . ' ';
+ }
+ 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:
echo 'action not defined';
}
diff --git a/system/controllers/settings.php b/system/controllers/settings.php
index 6a5625c6..0de22c16 100644
--- a/system/controllers/settings.php
+++ b/system/controllers/settings.php
@@ -206,13 +206,15 @@ switch ($action) {
case 'app-post':
$company = _post('company');
$footer = _post('footer');
+ $enable_balance = _post('enable_balance');
+ $allow_balance_transfer = _post('allow_balance_transfer');
$disable_voucher = _post('disable_voucher');
$telegram_bot = _post('telegram_bot');
$telegram_target_id = _post('telegram_target_id');
$sms_url = _post('sms_url');
$wa_url = _post('wa_url');
$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');
$address = _post('address');
$tawkto = _post('tawkto');
@@ -257,6 +259,28 @@ switch ($action) {
$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();
if($d){
$d->value = $telegram_bot;
@@ -312,14 +336,14 @@ switch ($action) {
$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){
- $d->value = $user_notification_expired_text;
+ $d->value = $user_notification_reminder;
$d->save();
}else{
$d = ORM::for_table('tbl_appconfig')->create();
- $d->setting = 'user_notification_expired_text';
- $d->value = $user_notification_expired_text;
+ $d->setting = 'user_notification_reminder';
+ $d->value = $user_notification_reminder;
$d->save();
}
@@ -370,6 +394,7 @@ switch ($action) {
case 'localisation-post':
$tzone = _post('tzone');
$date_format = _post('date_format');
+ $country_code_phone = _post('country_code_phone');
$lan = _post('lan');
run_hook('save_localisation'); #HOOK
if ($tzone == '' or $date_format == '' or $lan == '') {
@@ -397,6 +422,18 @@ switch ($action) {
$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'];
$d = ORM::for_table('tbl_appconfig')->where('setting', 'currency_code')->find_one();
$d->value = $currency_code;
@@ -455,7 +492,22 @@ switch ($action) {
}
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':
if ($admin['user_type'] != 'Admin') {
r2(U . "dashboard", 'e', $_L['Do_Not_Access']);
diff --git a/system/cron.php b/system/cron.php
index 13a4837f..e7774867 100644
--- a/system/cron.php
+++ b/system/cron.php
@@ -18,9 +18,15 @@ 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("system/plugin/*.php") as $filename) {
+foreach (glob("plugin/*.php") as $filename) {
include $filename;
}
@@ -55,7 +61,7 @@ foreach ($result as $value) {
}
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();
@@ -76,11 +82,26 @@ foreach ($d as $ds) {
$client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']);
Mikrotik::setHotspotLimitUptime($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
$u->status = 'off';
$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 {
$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']);
Mikrotik::disablePpoeUser($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->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";
}
}
diff --git a/system/cron_reminder.php b/system/cron_reminder.php
new file mode 100644
index 00000000..8fd04c12
--- /dev/null
+++ b/system/cron_reminder.php
@@ -0,0 +1,90 @@
+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";
+ }
+ }
+}
diff --git a/system/lan/english/common.lan.php b/system/lan/english/common.lan.php
index a72756a0..4e6ca82a 100644
--- a/system/lan/english/common.lan.php
+++ b/system/lan/english/common.lan.php
@@ -332,3 +332,36 @@ $_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_check_status_transaction_'] = 'Failed to check status transaction. ';
$_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';
+$_L['Refill_Balance'] = 'Refill Balance';
+$_L['Invoice_Footer'] = 'Invoice Footer';
diff --git a/system/lan/indonesia/common.lan.php b/system/lan/indonesia/common.lan.php
index aeaafba2..8a197d45 100644
--- a/system/lan/indonesia/common.lan.php
+++ b/system/lan/indonesia/common.lan.php
@@ -325,3 +325,16 @@ $_L['Not_Online_Login_now'] = 'Internet mati, Nyalakan?';
$_L['You_are_Online_Logout'] = 'Internet hidup, Putuskan?';
$_L['Connect_to_Internet'] = 'Koneksikan 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';
diff --git a/system/lan/spanish/common.lan.php b/system/lan/spanish/common.lan.php
index 661fb5dc..ec13dfd0 100644
--- a/system/lan/spanish/common.lan.php
+++ b/system/lan/spanish/common.lan.php
@@ -328,6 +328,16 @@ $_L['Not_Online_Login_now'] = 'Not Online, Login now?';
$_L['You_are_Online_Logout'] = 'You are Online, Logout?';
$_L['Connect_to_Internet'] = 'Connect 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';
\ No newline at end of file
diff --git a/system/lan/turkish/common.lan.php b/system/lan/turkish/common.lan.php
index ef852b7c..c21d9b8b 100755
--- a/system/lan/turkish/common.lan.php
+++ b/system/lan/turkish/common.lan.php
@@ -304,3 +304,16 @@ $_L['Not_Online_Login_now'] = 'Not Online, Login now?';
$_L['You_are_Online_Logout'] = 'You are Online, Logout?';
$_L['Connect_to_Internet'] = 'Connect 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';
\ No newline at end of file
diff --git a/system/updates.json b/system/updates.json
new file mode 100644
index 00000000..7dce27f7
--- /dev/null
+++ b/system/updates.json
@@ -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`;"
+ ]
+}
\ No newline at end of file
diff --git a/system/uploads/admin.png b/system/uploads/admin.default.png
similarity index 100%
rename from system/uploads/admin.png
rename to system/uploads/admin.default.png
diff --git a/system/uploads/logo.png b/system/uploads/logo.default.png
similarity index 100%
rename from system/uploads/logo.png
rename to system/uploads/logo.default.png
diff --git a/system/uploads/notifications.default.json b/system/uploads/notifications.default.json
new file mode 100644
index 00000000..21e9c1cc
--- /dev/null
+++ b/system/uploads/notifications.default.json
@@ -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\n[[footer]]",
+ "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\n====================\r\n[[footer]]"
+}
diff --git a/system/uploads/user.jpg b/system/uploads/user.default.jpg
similarity index 100%
rename from system/uploads/user.jpg
rename to system/uploads/user.default.jpg
diff --git a/ui/ui/app-localisation.tpl b/ui/ui/app-localisation.tpl
index ebbc960a..a5ca2ba5 100644
--- a/ui/ui/app-localisation.tpl
+++ b/ui/ui/app-localisation.tpl
@@ -1,80 +1,107 @@
{include file="sections/header.tpl"}
-
-
-
-
{$_L['Localisation']}
-
+
+
+
+
{$_L['Localisation']}
+
-
-
-
-{include file="sections/footer.tpl"}
+
+
+
+
+
+{include file="sections/footer.tpl"}
\ No newline at end of file
diff --git a/ui/ui/app-notifications.tpl b/ui/ui/app-notifications.tpl
new file mode 100644
index 00000000..6446adf1
--- /dev/null
+++ b/ui/ui/app-notifications.tpl
@@ -0,0 +1,127 @@
+{include file="sections/header.tpl"}
+
+
+{include file="sections/footer.tpl"}
\ No newline at end of file
diff --git a/ui/ui/app-settings.tpl b/ui/ui/app-settings.tpl
index f8ffb419..02e44903 100644
--- a/ui/ui/app-settings.tpl
+++ b/ui/ui/app-settings.tpl
@@ -4,31 +4,38 @@
-
{$_L['General_Settings']}
+
+
+
+
+ {$_L['General_Settings']}
+
+
Still on Testing.
+ Changing from Radius will not add existing user to Mikrotik Hotspot.
+ With Radius user can use Hotspot or PPOE.
-
Telegram Notification
+
+
+
+
+ {Lang::T('Balance System')}
+
+
+
+
+
+
+ {Lang::T('Telegram Notification')}
+
Telegram Bot Token
@@ -83,85 +130,137 @@
value="{$_c['telegram_target_id']}" placeholder="12345678">
-
You will get Payment and Error notification
+
You will get Payment and Error
+ notification
+
+
+
+
+
+ {Lang::T('SMS OTP Registration')}
-
SMS OTP Registration
-
You can use WhatsApp in here too. Free Server
+
You can use WhatsApp in here too. Free Server
+
+
+
+
+
+ {Lang::T('Whatsapp Notification')}
-
Whatsapp Notification
+
You can use WhatsApp in here too. Free Server
+
+
+
+
+
+ {Lang::T('User Notification')}
-
{Lang::T('User Notification')}
-
Tawk.to Chat Widget
+
+
+
+
+ {Lang::T('Tawk.to Chat Widget')}
+
+
+
/ip hotspot walled-garden
+ add dst-host=tawk.to
+ add dst-host=*.tawk.to
-
Invoice
+
+
+
+
+ {Lang::T('Invoice')}
+
+
@@ -173,11 +272,11 @@ add dst-host=*.tawk.to
{$_L['Save']}
-
+
/ip hotspot walled-garden
- add dst-host={$_domain}
- add dst-host=*.{$_domain}
+add dst-host={$_domain}
+add dst-host=*.{$_domain}
diff --git a/ui/ui/balance-add.tpl b/ui/ui/balance-add.tpl
new file mode 100644
index 00000000..8fa3c734
--- /dev/null
+++ b/ui/ui/balance-add.tpl
@@ -0,0 +1,48 @@
+{include file="sections/header.tpl"}
+
+
+
+{include file="sections/footer.tpl"}
diff --git a/ui/ui/balance-edit.tpl b/ui/ui/balance-edit.tpl
new file mode 100644
index 00000000..16922bfb
--- /dev/null
+++ b/ui/ui/balance-edit.tpl
@@ -0,0 +1,49 @@
+{include file="sections/header.tpl"}
+
+
+
+{include file="sections/footer.tpl"}
diff --git a/ui/ui/balance.tpl b/ui/ui/balance.tpl
new file mode 100644
index 00000000..17ace703
--- /dev/null
+++ b/ui/ui/balance.tpl
@@ -0,0 +1,56 @@
+{include file="sections/header.tpl"}
+
+
+
+
+
{Lang::T('Balance Plans')}
+
+
+
+
+
+
+ {$_L['Plan_Name']}
+ {$_L['Plan_Price']}
+ {$_L['Manage']}
+
+
+
+ {foreach $d as $ds}
+
+ {$ds['name_plan']}
+ {Lang::moneyFormat($ds['price'])}
+
+ {$_L['Edit']}
+ {$_L['Delete']}
+
+
+ {/foreach}
+
+
+
+ {$paginator['contents']}
+
+
+
+
+
+
+{include file="sections/footer.tpl"}
diff --git a/ui/ui/community.tpl b/ui/ui/community.tpl
index d4e730fe..9d673bf1 100644
--- a/ui/ui/community.tpl
+++ b/ui/ui/community.tpl
@@ -10,9 +10,9 @@
@@ -28,7 +28,7 @@
@@ -63,9 +63,9 @@
@@ -101,7 +101,7 @@
@@ -114,7 +114,7 @@
$50 Paid Support donation confirmation? Or ask any Donation Alternative
@@ -126,7 +126,7 @@
@@ -142,12 +142,24 @@
+
+
diff --git a/ui/ui/customers-add.tpl b/ui/ui/customers-add.tpl
index 0d4ecb9d..62baf313 100644
--- a/ui/ui/customers-add.tpl
+++ b/ui/ui/customers-add.tpl
@@ -9,9 +9,13 @@
{$_L['Full_Name']}
@@ -20,17 +24,34 @@
+
+
-