Compare commits
318 Commits
2024.3.3.1
...
2024.5.14
Author | SHA1 | Date | |
---|---|---|---|
ae3db05649 | |||
fa45d5f4b5 | |||
895bb26b02 | |||
a5affdb674 | |||
238fc03d03 | |||
cf8e23ae88 | |||
b9132082e5 | |||
ee63abb618 | |||
060718dfda | |||
651969924c | |||
a40b2cbea3 | |||
fc73a83732 | |||
6763fe09d8 | |||
0ea9de70fc | |||
c7ec8e2d27 | |||
822acef6d8 | |||
892c6bf7f5 | |||
c0c857e735 | |||
49794b99de | |||
126212f4c2 | |||
e3de07d435 | |||
2f551b1755 | |||
f766393e52 | |||
0bd587522a | |||
47c6e90624 | |||
fc0ef5b41a | |||
dff3970ff4 | |||
4c4fe4e99f | |||
2ed3dc991a | |||
be43a5b385 | |||
61bd042b15 | |||
b6fde35eb6 | |||
980af58eb1 | |||
f7deb828ac | |||
4c1e5da601 | |||
9712d411f5 | |||
8dc7707b3a | |||
18bdf185d6 | |||
2a70236576 | |||
7b40fc850e | |||
ad411e2223 | |||
45a6085205 | |||
91fe5a4b46 | |||
c0cd197df2 | |||
3e89efcf46 | |||
31b710e03c | |||
4d6041f614 | |||
fbaf9dbe3f | |||
a4f5c1d422 | |||
d08137e0c3 | |||
961f4770c0 | |||
2d6fe9526c | |||
bebc20e39f | |||
964c141668 | |||
88bbf3ed35 | |||
bf00b21786 | |||
0e81db5ada | |||
c0382c569a | |||
c32542afda | |||
8d17cd3f90 | |||
6dafd549d9 | |||
20c4be9121 | |||
2f757f1006 | |||
0ce112dc70 | |||
ea3f5caf59 | |||
5a5032bbcc | |||
0d44fec338 | |||
7396c2f1d4 | |||
73cf67b4cb | |||
9e0f74926c | |||
09af3474a9 | |||
9b8f1fedf8 | |||
05c77df315 | |||
e88f662d8c | |||
2956cc2315 | |||
3c8b2c906d | |||
acded8eb29 | |||
b63aeb5298 | |||
115a5c81a7 | |||
ad565c15ca | |||
a0c5cec31e | |||
fb4901be9f | |||
a164b345b6 | |||
8f07c7640c | |||
8891cd5aaa | |||
854fd54834 | |||
21876601ba | |||
6955d3fd8b | |||
d6510dffa7 | |||
419595554b | |||
bcc84aed9a | |||
05caee1193 | |||
071feb3a48 | |||
a5774fe335 | |||
92a2690ec6 | |||
519bef21e0 | |||
1a40606720 | |||
eff79df39a | |||
425ed2362b | |||
1fdf1d9573 | |||
b893827463 | |||
aa756fceb1 | |||
186dd5571f | |||
14067f2917 | |||
887a0185fa | |||
88969526be | |||
eb18eebc8c | |||
e274ca82b0 | |||
9ec8b54435 | |||
9dba708c2c | |||
cbbb77b636 | |||
1733472ad1 | |||
11c111805d | |||
4c35e79a16 | |||
fc1cc54378 | |||
f62e7707a1 | |||
bab56be9c7 | |||
0422c1e9bb | |||
1f5033b471 | |||
53a309fee8 | |||
766ba59734 | |||
2e3e5d2b84 | |||
e285e53887 | |||
afd75d757e | |||
006693982b | |||
71437b9a0e | |||
eba6048abf | |||
f97651695d | |||
72c3ff6750 | |||
787f666efe | |||
5db8df0c3e | |||
f77c96f3c3 | |||
ffd9f2e524 | |||
366208d6d1 | |||
db28570610 | |||
feaf88fc00 | |||
4bd5e399de | |||
76047a6b39 | |||
68c9ab0b2e | |||
198dfee3cc | |||
5161874cf2 | |||
254fd4ccf7 | |||
ee73621c85 | |||
4bf6f9c0ac | |||
3a2e7c9192 | |||
dcbb9434d6 | |||
faca5d0359 | |||
aeddc86796 | |||
c34a34ee8e | |||
7b0bc12e98 | |||
8ff84b2c01 | |||
954a49978c | |||
773cfe0139 | |||
7eae86d861 | |||
ea9974f668 | |||
eda1750608 | |||
9a1c264173 | |||
6865b388d0 | |||
ef15ec0ae2 | |||
e0d21e6284 | |||
37a7da614e | |||
e11ab5ba01 | |||
0767c6ab23 | |||
8e90cf933b | |||
a5ffee688c | |||
36a24238ef | |||
7eda29d02c | |||
e709ea4353 | |||
18967b59e2 | |||
3c2ca66b48 | |||
63c364a6c5 | |||
338861a630 | |||
90f72852ca | |||
5426d9f35f | |||
58c4037d8c | |||
04a21d3eb2 | |||
273d98f3ad | |||
177cdef1cd | |||
ffe913cb8f | |||
75955de6c5 | |||
11d97c153f | |||
44cded581a | |||
b8ae562367 | |||
d6bcb4edfc | |||
5d16ff9484 | |||
c1f815535d | |||
37a8187f5a | |||
ec5aeedd1b | |||
7dd27e3080 | |||
93ca9fa586 | |||
de302d2656 | |||
4d8cec1a88 | |||
477dd11caa | |||
36eb5ebd3b | |||
6e2e907d85 | |||
c460cdd2d6 | |||
5b7683ae30 | |||
ea743b6db6 | |||
1a165662ca | |||
21058d5c4e | |||
af3995b421 | |||
e9240f462d | |||
5b3be79420 | |||
8f595af9a1 | |||
393a1195a5 | |||
0dd12b717d | |||
d7d6709944 | |||
ef187817cf | |||
24e45db017 | |||
0a67ea25b5 | |||
f27964dde6 | |||
5b0e782efd | |||
865df09116 | |||
f44d800400 | |||
aae5b58d57 | |||
19d60da919 | |||
7be8552784 | |||
b92efe3d30 | |||
f769e7b798 | |||
15ae5c844f | |||
0aff5f437a | |||
605fbb73a6 | |||
3d2af75e5b | |||
130451e1ae | |||
d36f39af8f | |||
518917aac6 | |||
dbc3a2623c | |||
d31edde9d6 | |||
32943b40be | |||
23790d3258 | |||
ffa55cdee5 | |||
6f5d49cd2f | |||
850581d328 | |||
1d0d3f13ab | |||
c82b6b6acf | |||
532fbf7337 | |||
c4afd6da7f | |||
a812e3a3e0 | |||
a15510e62a | |||
78d1634470 | |||
cc8d810d45 | |||
68d3c9181c | |||
e206a583fd | |||
ca27c47b75 | |||
2c67108cf1 | |||
dee4c78e93 | |||
a6c004e1cb | |||
8318bb4e6b | |||
b27e0adca9 | |||
2925d3a1e3 | |||
add28c2fca | |||
afbab3dd42 | |||
b68e4d2e68 | |||
c8f4574984 | |||
60c573821b | |||
e6e993cf21 | |||
ca0edb4e17 | |||
ed9a411095 | |||
c69fb1cae2 | |||
d30aadc5e4 | |||
b732cfd90e | |||
46a56c12e3 | |||
9b2d42610a | |||
ef85bdb02f | |||
23763ed308 | |||
9fcdf04005 | |||
60babfa7b5 | |||
4cdde32cb1 | |||
538850b323 | |||
47393b4da9 | |||
87167b7770 | |||
81572a61a4 | |||
3412ecc7de | |||
3ab38897f9 | |||
8c2471d1d2 | |||
b0937a424a | |||
171b938d3a | |||
61c1d25096 | |||
f885b8e8a3 | |||
2bb664e241 | |||
c9058769ce | |||
6d15437333 | |||
7c5958c8c1 | |||
1a4a0f2c10 | |||
629d9e8ed4 | |||
b9e987570c | |||
b95788262d | |||
3bb55320e3 | |||
7a9f937a9e | |||
c00e51adda | |||
0cc526e29a | |||
16f0642007 | |||
e1f7b324cb | |||
8f0ff3e786 | |||
9023f89456 | |||
140b756994 | |||
ca59c89e1d | |||
4e23918999 | |||
758a0a99a9 | |||
b6cf9bec0b | |||
6e07c3ae85 | |||
ef76aadc16 | |||
8e960107fc | |||
c4e702ee2f | |||
08790e7295 | |||
cfefd38a31 | |||
37a5ee8566 | |||
e5c8aae758 | |||
99d393d0c0 | |||
e6280d597b | |||
18db9cd280 | |||
6aab647f48 | |||
b8b4623078 | |||
6a79cff233 | |||
4c02283fd0 | |||
403de91fba | |||
4ee3743cf3 | |||
afe6b34fd6 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -38,4 +38,5 @@ system/lan/**
|
||||
!system/lan/spanish.json
|
||||
!system/lan/turkish.json
|
||||
!system/lan/english.json
|
||||
!system/lan/country.json
|
||||
!system/lan/country.json
|
||||
*.zip
|
14
.htaccess_firewall
Normal file
14
.htaccess_firewall
Normal file
@ -0,0 +1,14 @@
|
||||
<Files *.php>
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
</Files>
|
||||
|
||||
<Files index.php>
|
||||
Order Allow,Deny
|
||||
Allow from all
|
||||
</Files>
|
||||
|
||||
<Files update.php>
|
||||
Order Allow,Deny
|
||||
Allow from all
|
||||
</Files>
|
141
CHANGELOG.md
141
CHANGELOG.md
@ -2,6 +2,147 @@
|
||||
|
||||
# CHANGELOG
|
||||
|
||||
## 2024.5.14
|
||||
|
||||
- Show Plan and Location on expired list
|
||||
- Customizeable payment for recharge
|
||||
|
||||
## 2024.5.8
|
||||
|
||||
- Fix bugs burst by @Gerandonk
|
||||
- Fix sync for burst by @Gerandonk
|
||||
|
||||
## 2024.5.7
|
||||
|
||||
- Fix time for period Days
|
||||
- Fix Free radius attributes by @agstrxyz
|
||||
- Add Numeric Voucher Code by @pro-cms
|
||||
|
||||
## 2024.4.30
|
||||
|
||||
- CRITICAL UPDATE: last update Logic recharge not check is status on or off, it make expired customer stay in expired pool
|
||||
- Prevent double submit for recharge balance
|
||||
|
||||
## 2024.4.29
|
||||
|
||||
- Maps Pagination
|
||||
- Maps Search
|
||||
- Fix extend logic
|
||||
- Fix logic customer recharge to not delete when customer not change the plan
|
||||
|
||||
## 2024.4.23
|
||||
|
||||
- Fix Pagination Voucher
|
||||
- Fix Languange Translation
|
||||
- Fix Alert Confirmation for requesting Extend
|
||||
- Send Telegram Notification when Customer request to extend expiration
|
||||
- prepaid users export list by @freeispradius
|
||||
- fix show voucher by @agstrxyz
|
||||
|
||||
## 2024.4.21
|
||||
|
||||
- Restore old cron
|
||||
|
||||
## 2024.4.15
|
||||
|
||||
- Postpaid Customer can request extends expiration day if it enabled
|
||||
- Some Code Fixing by @ahmadhusein17 and @agstrxyz
|
||||
|
||||
## 2024.4.4
|
||||
|
||||
- Data Tables for Customers List by @Focuslinkstech
|
||||
- Add Bills to Reminder
|
||||
- Prevent double submit for recharge and renew
|
||||
|
||||
## 2024.4.3
|
||||
|
||||
- Export logs to CSV by @agstrxyz
|
||||
- Change to Username if Country code empty
|
||||
|
||||
## 2024.4.2
|
||||
|
||||
- Fix REST API
|
||||
- Fix Log IP Cloudflare by @Gerandonk
|
||||
- Show Personal or Business in customer dashboard
|
||||
|
||||
## 2024.3.26
|
||||
|
||||
- Change paginator, to make easy customization using pagination.tpl
|
||||
|
||||
## 2024.3.25
|
||||
|
||||
- Fix maps on HTTP
|
||||
- Fix Cancel payment
|
||||
|
||||
## 2024.3.23
|
||||
|
||||
- Maps full height
|
||||
- Show Get Directions instead Coordinates
|
||||
- Maps Label always show
|
||||
|
||||
## 2024.3.22
|
||||
|
||||
- Fix Broadcast Message by @Focuslinkstech
|
||||
- Add Location Picker
|
||||
|
||||
## 2024.3.20
|
||||
|
||||
- Fixing some bugs
|
||||
|
||||
## 2024.3.19
|
||||
|
||||
- Add Customer Type Personal or Bussiness by @pro-cms
|
||||
- Fix Broadcast Message by @Focuslinkstech
|
||||
- Add Customer Geolocation by @Focuslinkstech
|
||||
- Change Customer Menu
|
||||
|
||||
## 2024.3.18
|
||||
|
||||
- Add Broadcasting SMS by @Focuslinkstech
|
||||
- Fix Notification with Bills
|
||||
|
||||
## 2024.3.16
|
||||
|
||||
- Fix Zero Charging
|
||||
- Fix Disconnect Customer from Radius without loop by @Gerandonk
|
||||
|
||||
## 2024.3.15
|
||||
|
||||
- Fix Customer View to list active Plan
|
||||
- Additional Bill using Customer Attributes
|
||||
|
||||
## 2024.3.14
|
||||
|
||||
- Add Note to Invoices
|
||||
- Add Additional Bill
|
||||
- View Invoice from Customer side
|
||||
|
||||
## 2024.3.13
|
||||
|
||||
- Postpaid System
|
||||
- Additional Cost
|
||||
|
||||
## 2024.3.12
|
||||
|
||||
- Check if Validity Period, so calculate price will not affected other validity
|
||||
- Add firewall using .htaccess for apache only
|
||||
- Multiple Payment Gateway by @Focuslinkstech
|
||||
- Fix Logic Multiple Payment gateway
|
||||
- Fix delete Attribute
|
||||
- Allow Delete Payment Gateway
|
||||
- Allow Delete Plugin
|
||||
|
||||
## 2024.3.6
|
||||
|
||||
- change attributes view
|
||||
|
||||
## 2024.3.4
|
||||
|
||||
- add [[username]] for reminder
|
||||
- fix agent show when editing
|
||||
- fix password admin when sending notification
|
||||
- add file exists for pages
|
||||
|
||||
## 2024.3.3
|
||||
|
||||
- Change loading button by @Focuslinkstech
|
||||
|
75
init.php
75
init.php
@ -11,7 +11,9 @@ if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||
die();
|
||||
}
|
||||
$root_path = realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR;
|
||||
$isApi = false;
|
||||
if (!isset($isApi)) {
|
||||
$isApi = false;
|
||||
}
|
||||
// on some server, it getting error because of slash is backwards
|
||||
function _autoloader($class)
|
||||
{
|
||||
@ -37,7 +39,6 @@ function _autoloader($class)
|
||||
}
|
||||
spl_autoload_register('_autoloader');
|
||||
|
||||
|
||||
if (!file_exists($root_path . 'config.php')) {
|
||||
$root_path .= '..' . DIRECTORY_SEPARATOR;
|
||||
if (!file_exists($root_path . 'config.php')) {
|
||||
@ -72,8 +73,11 @@ ORM::configure('return_result_sets', true);
|
||||
if ($_app_stage != 'Live') {
|
||||
ORM::configure('logging', true);
|
||||
}
|
||||
|
||||
define('U', APP_URL . '/index.php?_route=');
|
||||
if ($isApi) {
|
||||
define('U', APP_URL . '/system/api.php?r=');
|
||||
} else {
|
||||
define('U', APP_URL . '/index.php?_route=');
|
||||
}
|
||||
|
||||
// notification message
|
||||
if (file_exists($UPLOAD_PATH . DIRECTORY_SEPARATOR . "notifications.json")) {
|
||||
@ -196,7 +200,18 @@ function _log($description, $type = '', $userid = '0')
|
||||
$d->type = $type;
|
||||
$d->description = $description;
|
||||
$d->userid = $userid;
|
||||
$d->ip = $_SERVER["REMOTE_ADDR"];
|
||||
if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) //to check ip is pass from cloudflare tunnel
|
||||
{
|
||||
$d->ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
|
||||
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) //to check ip is pass from proxy
|
||||
{
|
||||
$d->ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
} elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) //to check ip from share internet
|
||||
{
|
||||
$d->ip = $_SERVER['HTTP_CLIENT_IP'];
|
||||
} else {
|
||||
$d->ip = $_SERVER["REMOTE_ADDR"];
|
||||
}
|
||||
$d->save();
|
||||
}
|
||||
|
||||
@ -207,9 +222,42 @@ function Lang($key)
|
||||
|
||||
function alphanumeric($str, $tambahan = "")
|
||||
{
|
||||
return preg_replace("/[^a-zA-Z0-9" . $tambahan . "]+/", "", $str);
|
||||
return Text::alphanumeric($str, $tambahan);
|
||||
}
|
||||
|
||||
function showResult($success, $message = '', $result = [], $meta = [])
|
||||
{
|
||||
header("Content-Type: Application/json");
|
||||
$json = json_encode(['success' => $success, 'message' => $message, 'result' => $result, 'meta' => $meta]);
|
||||
echo $json;
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
function generateUniqueNumericVouchers($totalVouchers, $length = 8)
|
||||
{
|
||||
// Define characters allowed in the voucher code
|
||||
$characters = '0123456789';
|
||||
$charactersLength = strlen($characters);
|
||||
$vouchers = array();
|
||||
|
||||
// Attempt to generate unique voucher codes
|
||||
for ($j = 0; $j < $totalVouchers; $j++) {
|
||||
do {
|
||||
$voucherCode = '';
|
||||
// Generate the voucher code
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$voucherCode .= $characters[rand(0, $charactersLength - 1)];
|
||||
}
|
||||
// Check if the generated voucher code already exists in the array
|
||||
$isUnique = !in_array($voucherCode, $vouchers);
|
||||
} while (!$isUnique);
|
||||
|
||||
$vouchers[] = $voucherCode;
|
||||
}
|
||||
|
||||
return $vouchers;
|
||||
}
|
||||
|
||||
function sendTelegram($txt)
|
||||
{
|
||||
@ -228,6 +276,13 @@ function sendWhatsapp($phone, $txt)
|
||||
|
||||
function r2($to, $ntype = 'e', $msg = '')
|
||||
{
|
||||
global $isApi;
|
||||
if ($isApi) {
|
||||
showResult(
|
||||
($ntype == 's') ? true : false,
|
||||
$msg
|
||||
);
|
||||
}
|
||||
if ($msg == '') {
|
||||
header("location: $to");
|
||||
exit;
|
||||
@ -240,7 +295,13 @@ function r2($to, $ntype = 'e', $msg = '')
|
||||
|
||||
function _alert($text, $type = 'success', $url = "home", $time = 3)
|
||||
{
|
||||
global $ui;
|
||||
global $ui, $isApi;
|
||||
if ($isApi) {
|
||||
showResult(
|
||||
($type == 'success') ? true : false,
|
||||
$text
|
||||
);
|
||||
}
|
||||
if (!isset($ui)) return;
|
||||
if (strlen($url) > 4) {
|
||||
if (substr($url, 0, 4) != "http") {
|
||||
|
@ -21,13 +21,15 @@ CREATE TABLE `tbl_customers` (
|
||||
`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' COMMENT 'For PPPOE Login',
|
||||
`pppoe_password` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'For PPPOE Login',
|
||||
`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',
|
||||
`coordinates` VARCHAR(50) NOT NULL DEFAULT '' COMMENT 'Latitude and Longitude coordinates',
|
||||
`balance` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT 'For Money Deposit',
|
||||
`service_type` ENUM('Hotspot','PPPoE','Others') DEFAULT 'Others' COMMENT 'For selecting user type',
|
||||
`account_type` ENUM('Business', 'Personal') DEFAULT 'Personal' COMMENT 'For selecting account type',
|
||||
`auto_renewal` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Auto renewall using balance',
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`last_login` datetime DEFAULT NULL
|
||||
@ -79,26 +81,27 @@ CREATE TABLE `tbl_payment_gateway` (
|
||||
|
||||
DROP TABLE IF EXISTS `tbl_plans`;
|
||||
CREATE TABLE `tbl_plans` (
|
||||
`id` int(10) NOT NULL,
|
||||
`name_plan` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`id_bw` int(10) NOT NULL,
|
||||
`price` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`type` enum('Hotspot','PPPOE','Balance') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`typebp` enum('Unlimited','Limited') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`limit_type` enum('Time_Limit','Data_Limit','Both_Limit') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`time_limit` int(10) UNSIGNED DEFAULT NULL,
|
||||
`time_unit` enum('Mins','Hrs') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`data_limit` int(10) UNSIGNED DEFAULT NULL,
|
||||
`data_unit` enum('MB','GB') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`validity` int(10) NOT NULL,
|
||||
`validity_unit` enum('Mins','Hrs','Days','Months','Period') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`shared_users` int(10) DEFAULT NULL,
|
||||
`routers` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`is_radius` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1 is radius',
|
||||
`pool` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`pool_expired` varchar(40) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0 disabled\r\n',
|
||||
`allow_purchase` enum('yes','no') DEFAULT 'yes' COMMENT 'allow to show package in buy package page'
|
||||
`id` int(10) NOT NULL,
|
||||
`name_plan` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`id_bw` int(10) NOT NULL,
|
||||
`price` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`type` enum('Hotspot','PPPOE','Balance') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`typebp` enum('Unlimited','Limited') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`limit_type` enum('Time_Limit','Data_Limit','Both_Limit') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`time_limit` int(10) UNSIGNED DEFAULT NULL,
|
||||
`time_unit` enum('Mins','Hrs') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`data_limit` int(10) UNSIGNED DEFAULT NULL,
|
||||
`data_unit` enum('MB','GB') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`validity` int(10) NOT NULL,
|
||||
`validity_unit` enum('Mins','Hrs','Days','Months','Period') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`shared_users` int(10) DEFAULT NULL,
|
||||
`routers` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`is_radius` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1 is radius',
|
||||
`pool` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`pool_expired` varchar(40) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0 disabled',
|
||||
`allow_purchase` enum('yes','no') DEFAULT 'yes' COMMENT 'allow to show package in buy package page',
|
||||
`plan_type` ENUM('Business', 'Personal') DEFAULT 'Personal' COMMENT 'For switching plan according to user type'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `tbl_pool`;
|
||||
@ -315,4 +318,7 @@ ALTER TABLE `tbl_customers` ADD `created_by` INT NOT NULL DEFAULT '0' AFTER `aut
|
||||
ALTER TABLE `tbl_plans` ADD `list_expired` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'address list' AFTER `pool_expired`;
|
||||
ALTER TABLE `tbl_bandwidth` ADD `burst` VARCHAR(128) NOT NULL DEFAULT '' AFTER `rate_up_unit`;
|
||||
ALTER TABLE `tbl_transactions` ADD `admin_id` INT NOT NULL DEFAULT '1' AFTER `type`;
|
||||
ALTER TABLE `tbl_user_recharges` ADD `admin_id` INT NOT NULL DEFAULT '1' AFTER `type`;
|
||||
ALTER TABLE `tbl_user_recharges` ADD `admin_id` INT NOT NULL DEFAULT '1' AFTER `type`;
|
||||
ALTER TABLE `tbl_plans` CHANGE `allow_purchase` `prepaid` ENUM('yes','no') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'yes' COMMENT 'is prepaid';
|
||||
ALTER TABLE `tbl_transactions` ADD `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT 'for note' AFTER `type`;
|
||||
ALTER TABLE `tbl_payment_gateway` ADD `trx_invoice` VARCHAR(25) NOT NULL DEFAULT '' COMMENT 'from tbl_transactions' AFTER `paid_date`;
|
19
system/.htaccess
Normal file
19
system/.htaccess
Normal file
@ -0,0 +1,19 @@
|
||||
<Files *.php>
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
</Files>
|
||||
|
||||
<Files cron.php>
|
||||
Order Allow,Deny
|
||||
Allow from all
|
||||
</Files>
|
||||
|
||||
<Files api.php>
|
||||
Order Allow,Deny
|
||||
Allow from all
|
||||
</Files>
|
||||
|
||||
<Files cron_reminder.php>
|
||||
Order Allow,Deny
|
||||
Allow from all
|
||||
</Files>
|
118
system/api.php
118
system/api.php
@ -15,91 +15,111 @@ if ($_SERVER['REQUEST_METHOD'] === "OPTIONS" || $_SERVER['REQUEST_METHOD'] === "
|
||||
die();
|
||||
}
|
||||
|
||||
include "../init.php";
|
||||
|
||||
$isApi = true;
|
||||
|
||||
include "../init.php";
|
||||
|
||||
// Dummy Class
|
||||
$ui = new class($key)
|
||||
{
|
||||
var $assign = [];
|
||||
function display($key)
|
||||
{
|
||||
global $req;
|
||||
showResult(true, $req, $this->getAll());
|
||||
}
|
||||
function assign($key, $value)
|
||||
{
|
||||
$this->assign[$key] = $value;
|
||||
}
|
||||
|
||||
function get($key, )
|
||||
function get($key)
|
||||
{
|
||||
if(isset($this->assign[$key])){
|
||||
if (isset($this->assign[$key])) {
|
||||
return $this->assign[$key];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function getTemplateVars($key)
|
||||
{
|
||||
if (isset($this->assign[$key])) {
|
||||
return $this->assign[$key];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function getAll()
|
||||
{
|
||||
return $this->assign;
|
||||
}
|
||||
};
|
||||
|
||||
$req = _get('r');
|
||||
# a/c.id.time.md5
|
||||
# md5(a/c.id.time.$api_secret)
|
||||
$token = _get('token');
|
||||
$token = _req('token');
|
||||
$routes = explode('/', $req);
|
||||
$handler = $routes[0];
|
||||
|
||||
if(empty($token)){
|
||||
showResult(false, Lang::T("Token is invalid"));
|
||||
}
|
||||
if (!empty($token)) {
|
||||
if ($token == $config['api_key']) {
|
||||
$admin = ORM::for_table('tbl_users')->where('user_type', 'SuperAdmin')->find_one($id);
|
||||
if (empty($admin)) {
|
||||
$admin = ORM::for_table('tbl_users')->where('user_type', 'Admin')->find_one($id);
|
||||
if (empty($admin)) {
|
||||
showResult(false, Lang::T("Token is invalid"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# validate token
|
||||
list($tipe, $uid, $time, $sha1) = explode('.', $token);
|
||||
if (trim($sha1) != sha1($uid . '.' . $time . '.' . $api_secret)) {
|
||||
showResult(false, Lang::T("Token is invalid"));
|
||||
}
|
||||
|
||||
if($token == $config['api_key']){
|
||||
$admin = ORM::for_table('tbl_users')->where('user_type','SuperAdmin')->find_one($id);
|
||||
if(empty($admin)){
|
||||
$admin = ORM::for_table('tbl_users')->where('user_type','Admin')->find_one($id);
|
||||
if(empty($admin)){
|
||||
#cek token expiration
|
||||
// 3 bulan
|
||||
if ($time != 0 && time() - $time > 7776000) {
|
||||
die("$time != " . (time() - $time));
|
||||
showResult(false, Lang::T("Token Expired"), [], ['login' => true]);
|
||||
}
|
||||
|
||||
if ($tipe == 'a') {
|
||||
$_SESSION['aid'] = $uid;
|
||||
$admin = Admin::_info();
|
||||
} else if ($tipe == 'c') {
|
||||
$_SESSION['uid'] = $uid;
|
||||
} else {
|
||||
showResult(false, Lang::T("Unknown Token"), [], ['login' => true]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($handler) || empty($handler)) {
|
||||
showResult(true, Lang::T("Token is valid"));
|
||||
}
|
||||
|
||||
|
||||
if ($handler == 'isValid') {
|
||||
showResult(true, Lang::T("Token is valid"));
|
||||
}
|
||||
|
||||
if ($handler == 'me') {
|
||||
$admin = Admin::_info();
|
||||
if (!empty($admin['id'])) {
|
||||
showResult(true, "", $admin);
|
||||
} else {
|
||||
showResult(false, Lang::T("Token is invalid"));
|
||||
}
|
||||
}
|
||||
}else{
|
||||
# validate token
|
||||
list($tipe, $uid, $time, $md5) = explode('.', $token);
|
||||
if ($md5 != md5($uid . '.' . $time . '.' . $api_secret)) {
|
||||
showResult(false, Lang::T("Token is invalid"));
|
||||
}
|
||||
|
||||
#cek token expiration
|
||||
if ($time != 0 && time() > $time) {
|
||||
showResult(false, Lang::T("Token Expired"), [], ['login' => true]);
|
||||
}
|
||||
|
||||
if($tipe=='a'){
|
||||
$_SESSION['aid'] = $uid;
|
||||
}else if($tipe=='c'){
|
||||
$_SESSION['uid'] = $uid;
|
||||
}else{
|
||||
showResult(false, Lang::T("Unknown Token"), [], ['login' => true]);
|
||||
}
|
||||
}
|
||||
|
||||
if(!isset($handler) || empty($handler)){
|
||||
showResult(true, Lang::T("Token is valid"));
|
||||
}
|
||||
|
||||
|
||||
if($handler == 'isValid'){
|
||||
showResult(true, Lang::T("Token is valid"));
|
||||
}
|
||||
|
||||
function showResult($success, $message = '', $result = [], $meta = [])
|
||||
{
|
||||
header("Content-Type: Application/json; charset=utf-8");
|
||||
die(json_encode(array('success' => $success, 'message' => $message, 'result' => $result, 'meta' => $meta)));
|
||||
unset($_COOKIE);
|
||||
unset($_SESSION);
|
||||
}
|
||||
|
||||
try {
|
||||
$sys_render = File::pathFixer($root_path.'system/controllers/' . $handler . '.php');
|
||||
$sys_render = File::pathFixer($root_path . 'system/controllers/' . $handler . '.php');
|
||||
if (file_exists($sys_render)) {
|
||||
include($sys_render);
|
||||
}else{
|
||||
showResult(true, $req, $ui->getAll());
|
||||
} else {
|
||||
showResult(false, Lang::T('Command not found'));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
|
@ -32,10 +32,14 @@ class Admin
|
||||
global $db_password;
|
||||
if (isset($aid)) {
|
||||
$time = time();
|
||||
setcookie('aid', $aid . '.' . $time . '.' . sha1($aid . '.' . $time . '.' . $db_password), time() + 86400 * 7);
|
||||
$token = $aid . '.' . $time . '.' . sha1($aid . '.' . $time . '.' . $db_password);
|
||||
setcookie('aid', $token, time() + 86400 * 7);
|
||||
return $token;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
public static function removeCookie()
|
||||
{
|
||||
if (isset($_COOKIE['aid'])) {
|
||||
|
@ -10,4 +10,20 @@ class App{
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getToken(){
|
||||
return md5(microtime());
|
||||
}
|
||||
|
||||
public static function setToken($token, $value){
|
||||
$_SESSION[$token] = $value;
|
||||
}
|
||||
|
||||
public static function getTokenValue($key){
|
||||
if(isset($_SESSION[$key])){
|
||||
return $_SESSION[$key];
|
||||
}else{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -11,7 +11,9 @@ class Lang
|
||||
public static function T($key)
|
||||
{
|
||||
global $_L, $lan_file, $config;
|
||||
$_L = $_SESSION['Lang'];
|
||||
if(is_array($_SESSION['Lang'])){
|
||||
$_L = array_merge($_L, $_SESSION['Lang']);
|
||||
}
|
||||
$key = preg_replace('/\s+/', ' ', $key);
|
||||
if (!empty($_L[$key])) {
|
||||
return $_L[$key];
|
||||
|
@ -5,6 +5,12 @@
|
||||
* by https://t.me/ibnux
|
||||
**/
|
||||
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
use PHPMailer\PHPMailer\SMTP;
|
||||
require $root_path . 'system/autoload/mail/Exception.php';
|
||||
require $root_path . 'system/autoload/mail/PHPMailer.php';
|
||||
require $root_path . 'system/autoload/mail/SMTP.php';
|
||||
|
||||
class Message
|
||||
{
|
||||
@ -22,6 +28,9 @@ class Message
|
||||
public static function sendSMS($phone, $txt)
|
||||
{
|
||||
global $config;
|
||||
if(empty($txt)){
|
||||
return "";
|
||||
}
|
||||
run_hook('send_sms'); #HOOK
|
||||
if (!empty($config['sms_url'])) {
|
||||
if (strlen($config['sms_url']) > 4 && substr($config['sms_url'], 0, 4) != "http") {
|
||||
@ -58,31 +67,92 @@ class Message
|
||||
public static function sendWhatsapp($phone, $txt)
|
||||
{
|
||||
global $config;
|
||||
if(empty($txt)){
|
||||
return "";
|
||||
}
|
||||
run_hook('send_whatsapp'); #HOOK
|
||||
if (!empty($config['wa_url'])) {
|
||||
$waurl = str_replace('[number]', urlencode($phone), $config['wa_url']);
|
||||
$waurl = str_replace('[number]', urlencode(Lang::phoneFormat($phone)), $config['wa_url']);
|
||||
$waurl = str_replace('[text]', urlencode($txt), $waurl);
|
||||
return Http::getData($waurl);
|
||||
}
|
||||
}
|
||||
|
||||
public static function sendPackageNotification($phone, $name, $package, $price, $message, $via)
|
||||
public static function sendEmail($to, $subject, $body)
|
||||
{
|
||||
global $u;
|
||||
$msg = str_replace('[[name]]', $name, $message);
|
||||
global $config;
|
||||
if(empty($body)){
|
||||
return "";
|
||||
}
|
||||
run_hook('send_email'); #HOOK
|
||||
if (empty($config['smtp_host'])) {
|
||||
$attr = "";
|
||||
if (!empty($config['mail_from'])) {
|
||||
$attr .= "From: " . $config['mail_from'] . "\r\n";
|
||||
}
|
||||
if (!empty($config['mail_reply_to'])) {
|
||||
$attr .= "Reply-To: " . $config['mail_reply_to'] . "\r\n";
|
||||
}
|
||||
mail($to, $subject, $body, $attr);
|
||||
} else {
|
||||
$mail = new PHPMailer();
|
||||
$mail->isSMTP();
|
||||
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
|
||||
$mail->Host = $config['smtp_host'];
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $config['smtp_user'];
|
||||
$mail->Password = $config['smtp_pass'];
|
||||
$mail->SMTPSecure = $config['smtp_ssltls'];
|
||||
$mail->Port = $config['smtp_port'];
|
||||
if (!empty($config['mail_from'])) {
|
||||
$mail->setFrom($config['mail_from']);
|
||||
}
|
||||
if (!empty($config['mail_reply_to'])) {
|
||||
$mail->addReplyTo($config['mail_reply_to']);
|
||||
}
|
||||
$mail->isHTML(false);
|
||||
$mail->addAddress($to);
|
||||
$mail->Subject = $subject;
|
||||
$mail->Body = $body;
|
||||
$mail->send();
|
||||
}
|
||||
}
|
||||
|
||||
public static function sendPackageNotification($customer, $package, $price, $message, $via)
|
||||
{
|
||||
global $ds;
|
||||
if(empty($message)){
|
||||
return "";
|
||||
}
|
||||
$msg = str_replace('[[name]]', $customer['fullname'], $message);
|
||||
$msg = str_replace('[[username]]', $customer['username'], $msg);
|
||||
$msg = str_replace('[[plan]]', $package, $msg);
|
||||
$msg = str_replace('[[package]]', $package, $msg);
|
||||
$msg = str_replace('[[price]]', $price, $msg);
|
||||
if($u){
|
||||
$msg = str_replace('[[expired_date]]', Lang::dateAndTimeFormat($u['expiration'], $u['time']), $msg);
|
||||
$msg = str_replace('[[price]]', Lang::moneyFormat($price), $msg);
|
||||
list($bills, $add_cost) = User::getBills($customer['id']);
|
||||
if($add_cost>0){
|
||||
$note = "";
|
||||
foreach ($bills as $k => $v) {
|
||||
$note .= $k . " : " . Lang::moneyFormat($v) . "\n";
|
||||
}
|
||||
$note .= "Total : " . Lang::moneyFormat($add_cost+$price) . "\n";
|
||||
$msg = str_replace('[[bills]]', $note, $msg);
|
||||
}else{
|
||||
$msg = str_replace('[[bills]]', '', $msg);
|
||||
}
|
||||
if ($ds) {
|
||||
$msg = str_replace('[[expired_date]]', Lang::dateAndTimeFormat($ds['expiration'], $ds['time']), $msg);
|
||||
}else{
|
||||
$msg = str_replace('[[expired_date]]', "", $msg);
|
||||
}
|
||||
if (
|
||||
!empty($phone) && strlen($phone) > 5
|
||||
!empty($customer['phonenumber']) && strlen($customer['phonenumber']) > 5
|
||||
&& !empty($message) && in_array($via, ['sms', 'wa'])
|
||||
) {
|
||||
if ($via == 'sms') {
|
||||
Message::sendSMS($phone, $msg);
|
||||
echo Message::sendSMS($customer['phonenumber'], $msg);
|
||||
} else if ($via == 'wa') {
|
||||
Message::sendWhatsapp($phone, $msg);
|
||||
echo Message::sendWhatsapp($customer['phonenumber'], $msg);
|
||||
}
|
||||
}
|
||||
return "$via: $msg";
|
||||
@ -115,6 +185,9 @@ class Message
|
||||
$textInvoice = str_replace('[[phone]]', $config['phone'], $textInvoice);
|
||||
$textInvoice = str_replace('[[invoice]]', $trx['invoice'], $textInvoice);
|
||||
$textInvoice = str_replace('[[date]]', Lang::dateAndTimeFormat($trx['recharged_on'], $trx['recharged_time']), $textInvoice);
|
||||
if (!empty($trx['note'])) {
|
||||
$textInvoice = str_replace('[[note]]', $trx['note'], $textInvoice);
|
||||
}
|
||||
$gc = explode("-", $trx['method']);
|
||||
$textInvoice = str_replace('[[payment_gateway]]', trim($gc[0]), $textInvoice);
|
||||
$textInvoice = str_replace('[[payment_channel]]', trim($gc[1]), $textInvoice);
|
||||
@ -122,8 +195,11 @@ class Message
|
||||
$textInvoice = str_replace('[[plan_name]]', $trx['plan_name'], $textInvoice);
|
||||
$textInvoice = str_replace('[[plan_price]]', Lang::moneyFormat($trx['price']), $textInvoice);
|
||||
$textInvoice = str_replace('[[name]]', $cust['fullname'], $textInvoice);
|
||||
$textInvoice = str_replace('[[note]]', $cust['note'], $textInvoice);
|
||||
$textInvoice = str_replace('[[user_name]]', $trx['username'], $textInvoice);
|
||||
$textInvoice = str_replace('[[user_password]]', $cust['password'], $textInvoice);
|
||||
$textInvoice = str_replace('[[username]]', $trx['username'], $textInvoice);
|
||||
$textInvoice = str_replace('[[password]]', $cust['password'], $textInvoice);
|
||||
$textInvoice = str_replace('[[expired_date]]', Lang::dateAndTimeFormat($trx['expiration'], $trx['time']), $textInvoice);
|
||||
$textInvoice = str_replace('[[footer]]', $config['note'], $textInvoice);
|
||||
|
||||
|
@ -19,21 +19,25 @@
|
||||
/**
|
||||
* The namespace declaration.
|
||||
*/
|
||||
|
||||
namespace PEAR2\Net\RouterOS;
|
||||
|
||||
/**
|
||||
* Refers to transmitter direction constants.
|
||||
*/
|
||||
|
||||
use PEAR2\Net\Transmitter\Stream as S;
|
||||
|
||||
/**
|
||||
* Refers to the cryptography constants.
|
||||
*/
|
||||
|
||||
use PEAR2\Net\Transmitter\NetworkStream as N;
|
||||
|
||||
/**
|
||||
* Catches arbitrary exceptions at some points.
|
||||
*/
|
||||
|
||||
use Exception as E;
|
||||
|
||||
/**
|
||||
@ -108,11 +112,12 @@ class Client
|
||||
protected $registry = null;
|
||||
|
||||
/**
|
||||
* Whether to stream future responses.
|
||||
* Stream response words that are above this many bytes.
|
||||
* NULL to disable streaming completely.
|
||||
*
|
||||
* @var bool
|
||||
* @var int|null
|
||||
*/
|
||||
private $_streamingResponses = false;
|
||||
private $_streamingResponses = null;
|
||||
|
||||
/**
|
||||
* Creates a new instance of a RouterOS API client.
|
||||
@ -167,7 +172,7 @@ class Client
|
||||
: (int) $timeout;
|
||||
//Login the user if necessary
|
||||
if ((!$persist
|
||||
|| !($old = $this->com->getTransmitter()->lock(S::DIRECTION_ALL)))
|
||||
|| !($old = $this->com->getTransmitter()->lock(S::DIRECTION_ALL)))
|
||||
&& $this->com->getTransmitter()->isFresh()
|
||||
) {
|
||||
if (!static::login($this->com, $username, $password, $timeout)) {
|
||||
@ -233,7 +238,8 @@ class Client
|
||||
$password = '',
|
||||
$timeout = null
|
||||
) {
|
||||
if (null !== ($remoteCharset = $com->getCharset($com::CHARSET_REMOTE))
|
||||
if (
|
||||
null !== ($remoteCharset = $com->getCharset($com::CHARSET_REMOTE))
|
||||
&& null !== ($localCharset = $com->getCharset($com::CHARSET_LOCAL))
|
||||
) {
|
||||
$password = iconv(
|
||||
@ -256,8 +262,8 @@ class Client
|
||||
$com->getTransmitter()->lock($old, true);
|
||||
}
|
||||
throw ($e instanceof NotSupportedException
|
||||
|| $e instanceof UnexpectedValueException
|
||||
|| !$com->getTransmitter()->isDataAwaiting()) ? new SocketException(
|
||||
|| $e instanceof UnexpectedValueException
|
||||
|| !$com->getTransmitter()->isDataAwaiting()) ? new SocketException(
|
||||
'This is not a compatible RouterOS service',
|
||||
SocketException::CODE_SERVICE_INCOMPATIBLE,
|
||||
$e
|
||||
@ -287,30 +293,47 @@ class Client
|
||||
$timeout = null
|
||||
) {
|
||||
$request = new Request('/login');
|
||||
$request->send($com);
|
||||
$response = new Response($com, false, $timeout);
|
||||
$request->setArgument('name', $username);
|
||||
$request->setArgument('password', $password);
|
||||
// $request->setArgument(
|
||||
// 'response',
|
||||
// '00' . md5(
|
||||
// chr(0) . $password
|
||||
// . pack('H*', $response->getProperty('ret'))
|
||||
// )
|
||||
// );
|
||||
$oldCharset = $com->getCharset($com::CHARSET_ALL);
|
||||
$com->setCharset(null, $com::CHARSET_ALL);
|
||||
$request->verify($com)->send($com);
|
||||
|
||||
$com->setCharset($oldCharset, $com::CHARSET_ALL);
|
||||
$response = new Response($com, false, $timeout);
|
||||
if ($response->getType() === Response::TYPE_FINAL) {
|
||||
return null === $response->getProperty('ret');
|
||||
} else {
|
||||
while ($response->getType() !== Response::TYPE_FINAL
|
||||
&& $response->getType() !== Response::TYPE_FATAL
|
||||
) {
|
||||
$response = new Response($com, false, $timeout);
|
||||
if (
|
||||
$response->getType() === Response::TYPE_FINAL
|
||||
&& null === $response->getProperty('ret')
|
||||
) {
|
||||
// version >= 6.43
|
||||
return null === $response->getProperty('message');
|
||||
} elseif ($response->getType() === Response::TYPE_FINAL) {
|
||||
// version < 6.43
|
||||
$request->setArgument('password', '');
|
||||
$request->setArgument(
|
||||
'response',
|
||||
'00' . md5(
|
||||
chr(0) . $password
|
||||
. pack(
|
||||
'H*',
|
||||
is_string($response->getProperty('ret'))
|
||||
? $response->getProperty('ret')
|
||||
: stream_get_contents($response->getProperty('ret'))
|
||||
)
|
||||
)
|
||||
);
|
||||
$request->verify($com)->send($com);
|
||||
$response = new Response($com, false, $timeout);
|
||||
if ($response->getType() === Response::TYPE_FINAL) {
|
||||
return null === $response->getProperty('ret');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
while (
|
||||
$response->getType() !== Response::TYPE_FINAL
|
||||
&& $response->getType() !== Response::TYPE_FATAL
|
||||
) {
|
||||
$response = new Response($com, false, $timeout);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -322,7 +345,7 @@ class Client
|
||||
* {@link Communicator::CHARSET_REMOTE}, and when receiving,
|
||||
* {@link Communicator::CHARSET_REMOTE} is converted to
|
||||
* {@link Communicator::CHARSET_LOCAL}. Setting NULL to either charset will
|
||||
* disable charset convertion, and data will be both sent and received "as
|
||||
* disable charset conversion, and data will be both sent and received "as
|
||||
* is".
|
||||
*
|
||||
* @param mixed $charset The charset to set. If $charsetType is
|
||||
@ -387,7 +410,7 @@ class Client
|
||||
{
|
||||
//Error checking
|
||||
$tag = $request->getTag();
|
||||
if ('' == $tag) {
|
||||
if ('' === (string)$tag) {
|
||||
throw new DataFlowException(
|
||||
'Asynchonous commands must have a tag.',
|
||||
DataFlowException::CODE_TAG_REQUIRED
|
||||
@ -487,7 +510,7 @@ class Client
|
||||
$result = $hasNoTag ? array()
|
||||
: $this->extractNewResponses($tag)->toArray();
|
||||
while ((!$hasNoTag && $this->isRequestActive($tag))
|
||||
|| ($hasNoTag && 0 !== $this->getPendingRequestsCount())
|
||||
|| ($hasNoTag && 0 !== $this->getPendingRequestsCount())
|
||||
) {
|
||||
$newReply = $this->dispatchNextResponse(null);
|
||||
if ($newReply->getTag() === $tag) {
|
||||
@ -499,8 +522,8 @@ class Client
|
||||
$result = array_merge(
|
||||
$result,
|
||||
$this->isRequestActive($tag)
|
||||
? $this->extractNewResponses($tag)->toArray()
|
||||
: array()
|
||||
? $this->extractNewResponses($tag)->toArray()
|
||||
: array()
|
||||
);
|
||||
}
|
||||
break;
|
||||
@ -582,7 +605,8 @@ class Client
|
||||
}
|
||||
} else {
|
||||
list($usStart, $sStart) = explode(' ', microtime());
|
||||
while ($this->getPendingRequestsCount() !== 0
|
||||
while (
|
||||
$this->getPendingRequestsCount() !== 0
|
||||
&& ($sTimeout >= 0 || $usTimeout >= 0)
|
||||
) {
|
||||
$this->dispatchNextResponse($sTimeout, $usTimeout);
|
||||
@ -647,7 +671,7 @@ class Client
|
||||
public function cancelRequest($tag = null)
|
||||
{
|
||||
$cancelRequest = new Request('/cancel');
|
||||
$hasTag = !('' == $tag);
|
||||
$hasTag = !('' === (string)$tag);
|
||||
$hasReg = null !== $this->registry;
|
||||
if ($hasReg && !$hasTag) {
|
||||
$tags = array_merge(
|
||||
@ -703,34 +727,39 @@ class Client
|
||||
/**
|
||||
* Sets response streaming setting.
|
||||
*
|
||||
* Sets whether future responses are streamed. If responses are streamed,
|
||||
* the argument values are returned as streams instead of strings. This is
|
||||
* particularly useful if you expect a response that may contain one or more
|
||||
* very large words.
|
||||
* Sets when future response words are streamed. If a word is streamed,
|
||||
* the property value is returned a stream instead of a string, and
|
||||
* unrecognized words are returned entirely as streams instead of strings.
|
||||
* This is particularly useful if you expect a response that may contain
|
||||
* one or more very large words.
|
||||
*
|
||||
* @param bool $streamingResponses Whether to stream future responses.
|
||||
* @param int|null $threshold Threshold after which to stream
|
||||
* a word. That is, a word less than this length will not be streamed.
|
||||
* If set to 0, effectively all words are streamed.
|
||||
* NULL to disable streaming altogether.
|
||||
*
|
||||
* @return bool The previous value of the setting.
|
||||
* @return $this The client object.
|
||||
*
|
||||
* @see isStreamingResponses()
|
||||
* @see getStreamingResponses()
|
||||
*/
|
||||
public function setStreamingResponses($streamingResponses)
|
||||
public function setStreamingResponses($threshold)
|
||||
{
|
||||
$oldValue = $this->_streamingResponses;
|
||||
$this->_streamingResponses = (bool) $streamingResponses;
|
||||
return $oldValue;
|
||||
$this->_streamingResponses = $threshold === null
|
||||
? null
|
||||
: (int) $threshold;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets response streaming setting.
|
||||
*
|
||||
* Gets whether future responses are streamed.
|
||||
* Gets when future response words are streamed.
|
||||
*
|
||||
* @return bool The value of the setting.
|
||||
* @return int|null The value of the setting.
|
||||
*
|
||||
* @see setStreamingResponses()
|
||||
*/
|
||||
public function isStreamingResponses()
|
||||
public function getStreamingResponses()
|
||||
{
|
||||
return $this->_streamingResponses;
|
||||
}
|
||||
@ -822,8 +851,8 @@ class Client
|
||||
* If NULL, wait indefinitely.
|
||||
* @param int $usTimeout Microseconds to add to the waiting time.
|
||||
*
|
||||
* @return Response The dispatched response.
|
||||
* @throws SocketException When there's no response within the time limit.
|
||||
* @return Response The dispatched response.
|
||||
*/
|
||||
protected function dispatchNextResponse($sTimeout = 0, $usTimeout = 0)
|
||||
{
|
||||
@ -846,13 +875,14 @@ class Client
|
||||
$this->pendingRequestsCount--;
|
||||
}
|
||||
|
||||
if ('' != $tag) {
|
||||
if ('' !== (string)$tag) {
|
||||
if ($this->isRequestActive($tag, self::FILTER_CALLBACK)) {
|
||||
if ($this->callbacks[$tag]($response, $this)) {
|
||||
try {
|
||||
$this->cancelRequest($tag);
|
||||
} catch (DataFlowException $e) {
|
||||
if ($e->getCode() !== DataFlowException::CODE_UNKNOWN_REQUEST
|
||||
if (
|
||||
$e->getCode() !== $e::CODE_UNKNOWN_REQUEST
|
||||
) {
|
||||
throw $e;
|
||||
}
|
||||
|
@ -15,28 +15,71 @@ class Package
|
||||
* @param int $plan_id plan id for this package
|
||||
* @param string $gateway payment gateway name
|
||||
* @param string $channel channel payment gateway
|
||||
* @param array $pgids payment gateway ids
|
||||
* @return boolean
|
||||
*/
|
||||
public static function rechargeUser($id_customer, $router_name, $plan_id, $gateway, $channel)
|
||||
public static function rechargeUser($id_customer, $router_name, $plan_id, $gateway, $channel, $note = '')
|
||||
{
|
||||
global $config, $admin, $c, $p, $b, $t, $d;
|
||||
global $config, $admin, $c, $p, $b, $t, $d, $zero, $trx;
|
||||
$date_now = date("Y-m-d H:i:s");
|
||||
$date_only = date("Y-m-d");
|
||||
$time_only = date("H:i:s");
|
||||
$time = date("H:i:s");
|
||||
$inv = "";
|
||||
|
||||
if ($id_customer == '' or $router_name == '' or $plan_id == '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$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)->find_one();
|
||||
|
||||
$add_cost = 0;
|
||||
$bills = [];
|
||||
// Zero cost recharge
|
||||
if (isset($zero) && $zero == 1) {
|
||||
$p['price'] = 0;
|
||||
} else {
|
||||
// Additional cost
|
||||
list($bills, $add_cost) = User::getBills($id_customer);
|
||||
if ($add_cost > 0 && $router_name != 'balance') {
|
||||
foreach ($bills as $k => $v) {
|
||||
$note .= $k . " : " . Lang::moneyFormat($v) . "\n";
|
||||
}
|
||||
$note .= $p['name_plan'] . " : " . Lang::moneyFormat($p['price']) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!$p['enabled']) {
|
||||
if (!isset($admin) || !isset($admin['id']) || empty($admin['id'])) {
|
||||
r2(U . 'home', 'e', Lang::T('Plan Not found'));
|
||||
}
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
r2(U . 'dashboard', 'e', Lang::T('Plan Not found'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($p['validity_unit'] == 'Period') {
|
||||
$day_exp = User::getAttribute("Expired Date", $c['id']); //ORM::for_table('tbl_customers_fields')->where('field_name', 'Expired Date')->where('customer_id', $c['id'])->find_one();
|
||||
if (!$day_exp) {
|
||||
$day_exp = 20;
|
||||
// $day_exp = date('d', strtotime($c['created_at']));
|
||||
// if (empty($day_exp) || $day_exp > 28) {
|
||||
// $day_exp = 1;
|
||||
// }
|
||||
$f = ORM::for_table('tbl_customers_fields')->create();
|
||||
$f->customer_id = $c['id'];
|
||||
$f->field_name = 'Expired Date';
|
||||
$f->field_value = $day_exp;
|
||||
$f->save();
|
||||
}
|
||||
}
|
||||
|
||||
if ($router_name == 'balance') {
|
||||
// insert table transactions
|
||||
$inv = "INV-" . Package::_raid(5);
|
||||
$t = ORM::for_table('tbl_transactions')->create();
|
||||
$t->invoice = $inv;
|
||||
$t->invoice = $inv = "INV-" . Package::_raid();
|
||||
$t->username = $c['username'];
|
||||
$t->plan_name = $p['name_plan'];
|
||||
$t->price = $p['price'];
|
||||
@ -86,12 +129,31 @@ class Package
|
||||
}
|
||||
|
||||
/**
|
||||
* 1 Customer only can have 1 PPPOE and 1 Hotspot Plan
|
||||
* 1 Customer only can have 1 PPPOE and 1 Hotspot Plan, 1 prepaid and 1 postpaid
|
||||
*/
|
||||
$b = ORM::for_table('tbl_user_recharges')
|
||||
->select('tbl_user_recharges.id', 'id')
|
||||
->select('customer_id')
|
||||
->select('username')
|
||||
->select('plan_id')
|
||||
->select('namebp')
|
||||
->select('recharged_on')
|
||||
->select('recharged_time')
|
||||
->select('expiration')
|
||||
->select('time')
|
||||
->select('status')
|
||||
->select('method')
|
||||
->select('tbl_user_recharges.routers', 'routers')
|
||||
->select('tbl_user_recharges.type', 'type')
|
||||
->select('admin_id')
|
||||
->select('prepaid')
|
||||
->where('customer_id', $id_customer)
|
||||
->where('routers', $router_name)
|
||||
->where('Type', $p['type'])
|
||||
->where('tbl_user_recharges.routers', $router_name)
|
||||
->where('tbl_user_recharges.Type', $p['type'])
|
||||
# PPPOE or Hotspot only can have 1 per customer prepaid or postpaid
|
||||
# because 1 customer can have 1 PPPOE and 1 Hotspot Plan in mikrotik
|
||||
//->where('prepaid', $p['prepaid'])
|
||||
->join('tbl_plans', array('tbl_plans.id', '=', 'tbl_user_recharges.plan_id'))
|
||||
->find_one();
|
||||
|
||||
run_hook("recharge_user");
|
||||
@ -100,20 +162,22 @@ class Package
|
||||
$mikrotik = Mikrotik::info($router_name);
|
||||
if ($p['validity_unit'] == 'Months') {
|
||||
$date_exp = date("Y-m-d", strtotime('+' . $p['validity'] . ' month'));
|
||||
} else if ($p['validity_unit'] == 'Period') {
|
||||
$date_tmp = date("Y-m-20", strtotime('+' . $p['validity'] . ' month'));
|
||||
$dt1 = new DateTime("$date_only");
|
||||
$dt2 = new DateTime("$date_tmp");
|
||||
$diff = $dt2->diff($dt1);
|
||||
$sum = $diff->format("%a");// => 453
|
||||
if ($sum >= 35) {
|
||||
$date_exp = date("Y-m-20", strtotime('+0 month'));
|
||||
} else {
|
||||
$date_exp = date("Y-m-20", strtotime('+' . $p['validity'] . ' month'));
|
||||
};
|
||||
$time = date("23:59:00");
|
||||
} else if ($p['validity_unit'] == 'Period') {
|
||||
$date_tmp = date("Y-m-$day_exp", strtotime('+' . $p['validity'] . ' month'));
|
||||
$dt1 = new DateTime("$date_only");
|
||||
$dt2 = new DateTime("$date_tmp");
|
||||
$diff = $dt2->diff($dt1);
|
||||
$sum = $diff->format("%a"); // => 453
|
||||
if ($sum >= 35 * $p['validity']) {
|
||||
$date_exp = date("Y-m-$day_exp", strtotime('+0 month'));
|
||||
} else {
|
||||
$date_exp = date("Y-m-$day_exp", strtotime('+' . $p['validity'] . ' month'));
|
||||
};
|
||||
$time = date("23:59:00");
|
||||
} else if ($p['validity_unit'] == 'Days') {
|
||||
$date_exp = date("Y-m-d", strtotime('+' . $p['validity'] . ' day'));
|
||||
$datetime = explode(' ', date("Y-m-d H:i:s", strtotime('+' . $p['validity'] . ' day')));
|
||||
$date_exp = $datetime[0];
|
||||
$time = $datetime[1];
|
||||
} else if ($p['validity_unit'] == 'Hrs') {
|
||||
$datetime = explode(' ', date("Y-m-d H:i:s", strtotime('+' . $p['validity'] . ' hour')));
|
||||
$date_exp = $datetime[0];
|
||||
@ -123,17 +187,20 @@ class Package
|
||||
$date_exp = $datetime[0];
|
||||
$time = $datetime[1];
|
||||
}
|
||||
|
||||
$isChangePlan = false;
|
||||
if ($p['type'] == 'Hotspot') {
|
||||
if ($b) {
|
||||
if ($plan_id != $b['plan_id']) {
|
||||
$isChangePlan = true;
|
||||
}
|
||||
if ($b['namebp'] == $p['name_plan'] && $b['status'] == 'on') {
|
||||
// if it same internet plan, expired will extend
|
||||
if ($p['validity_unit'] == 'Months') {
|
||||
$date_exp = date("Y-m-d", strtotime($b['expiration'] . ' +' . $p['validity'] . ' months'));
|
||||
$time = $b['time'];
|
||||
} else if ($p['validity_unit'] == 'Period') {
|
||||
$date_exp = date("Y-m-20", strtotime($b['expiration'] . ' +' . $p['validity'] . ' months'));
|
||||
$time = date("23:59:00");
|
||||
} else if ($p['validity_unit'] == 'Period') {
|
||||
$date_exp = date("Y-m-$day_exp", strtotime($b['expiration'] . ' +' . $p['validity'] . ' months'));
|
||||
$time = date("23:59:00");
|
||||
} else if ($p['validity_unit'] == 'Days') {
|
||||
$date_exp = date("Y-m-d", strtotime($b['expiration'] . ' +' . $p['validity'] . ' days'));
|
||||
$time = $b['time'];
|
||||
@ -148,13 +215,15 @@ class Package
|
||||
}
|
||||
}
|
||||
|
||||
if ($p['is_radius']) {
|
||||
Radius::customerAddPlan($c, $p, "$date_exp $time");
|
||||
} else {
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::addHotspotUser($client, $p, $c);
|
||||
if ($isChangePlan || $b['status'] == 'off') {
|
||||
if ($p['is_radius']) {
|
||||
Radius::customerAddPlan($c, $p, "$date_exp $time");
|
||||
} else {
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
Mikrotik::addHotspotUser($client, $p, $c);
|
||||
}
|
||||
}
|
||||
|
||||
$b->customer_id = $id_customer;
|
||||
@ -178,16 +247,27 @@ class Package
|
||||
|
||||
// insert table transactions
|
||||
$t = ORM::for_table('tbl_transactions')->create();
|
||||
$t->invoice = "INV-" . Package::_raid(5);
|
||||
$t->invoice = $inv = "INV-" . Package::_raid();
|
||||
$t->username = $c['username'];
|
||||
$t->plan_name = $p['name_plan'];
|
||||
$t->price = $p['price'];
|
||||
if ($p['validity_unit'] == 'Period') {
|
||||
// Postpaid price from field
|
||||
$add_inv = User::getAttribute("Invoice", $id_customer);
|
||||
if (empty($add_inv) or $add_inv == 0) {
|
||||
$t->price = $p['price'] + $add_cost;
|
||||
} else {
|
||||
$t->price = $add_inv + $add_cost;
|
||||
}
|
||||
} else {
|
||||
$t->price = $p['price'] + $add_cost;
|
||||
}
|
||||
$t->recharged_on = $date_only;
|
||||
$t->recharged_time = $time_only;
|
||||
$t->expiration = $date_exp;
|
||||
$t->time = $time;
|
||||
$t->method = "$gateway - $channel";
|
||||
$t->routers = $router_name;
|
||||
$t->note = $note;
|
||||
$t->type = "Hotspot";
|
||||
if ($admin) {
|
||||
$t->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
@ -195,12 +275,30 @@ class Package
|
||||
$t->admin_id = '0';
|
||||
}
|
||||
$t->save();
|
||||
|
||||
Message::sendTelegram("#u$c[username] #recharge #Hotspot \n" . $p['name_plan'] .
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nPrice: " . Lang::moneyFormat($p['price']));
|
||||
|
||||
if ($p['validity_unit'] == 'Period') {
|
||||
// insert price to fields for invoice next month
|
||||
$fl = ORM::for_table('tbl_customers_fields')->where('field_name', 'Invoice')->where('customer_id', $c['id'])->find_one();
|
||||
if (!$fl) {
|
||||
$fl = ORM::for_table('tbl_customers_fields')->create();
|
||||
$fl->customer_id = $c['id'];
|
||||
$fl->field_name = 'Invoice';
|
||||
$fl->field_value = $p['price'];
|
||||
$fl->save();
|
||||
} else {
|
||||
$fl->customer_id = $c['id'];
|
||||
$fl->field_value = $p['price'];
|
||||
$fl->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Message::sendTelegram("#u$c[username] $c[fullname] #recharge #Hotspot \n" . $p['name_plan'] .
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nPrice: " . Lang::moneyFormat($p['price'] + $add_cost) .
|
||||
"\nNote:\n" . $note);
|
||||
} else {
|
||||
if ($p['is_radius']) {
|
||||
Radius::customerAddPlan($c, $p, "$date_exp $time");
|
||||
@ -233,16 +331,22 @@ class Package
|
||||
|
||||
// insert table transactions
|
||||
$t = ORM::for_table('tbl_transactions')->create();
|
||||
$t->invoice = "INV-" . Package::_raid(5);
|
||||
$t->invoice = $inv = "INV-" . Package::_raid();
|
||||
$t->username = $c['username'];
|
||||
$t->plan_name = $p['name_plan'];
|
||||
$t->price = $p['price'];
|
||||
if ($p['validity_unit'] == 'Period') {
|
||||
// Postpaid price always zero for first time
|
||||
$t->price = 0 + $add_cost;
|
||||
} else {
|
||||
$t->price = $p['price'] + $add_cost;
|
||||
}
|
||||
$t->recharged_on = $date_only;
|
||||
$t->recharged_time = $time_only;
|
||||
$t->expiration = $date_exp;
|
||||
$t->time = $time;
|
||||
$t->method = "$gateway - $channel";
|
||||
$t->routers = $router_name;
|
||||
$t->note = $note;
|
||||
$t->type = "Hotspot";
|
||||
if ($admin) {
|
||||
$t->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
@ -250,25 +354,54 @@ class Package
|
||||
$t->admin_id = '0';
|
||||
}
|
||||
$t->save();
|
||||
|
||||
Message::sendTelegram("#u$c[username] #buy #Hotspot \n" . $p['name_plan'] .
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nPrice: " . Lang::moneyFormat($p['price']));
|
||||
|
||||
if ($p['validity_unit'] == 'Period' && $p['price'] != 0) {
|
||||
// insert price to fields for invoice next month
|
||||
$fl = ORM::for_table('tbl_customers_fields')->where('field_name', 'Invoice')->where('customer_id', $c['id'])->find_one();
|
||||
if (!$fl) {
|
||||
$fl = ORM::for_table('tbl_customers_fields')->create();
|
||||
$fl->customer_id = $c['id'];
|
||||
$fl->field_name = 'Invoice';
|
||||
// Calculating Price
|
||||
$sd = new DateTime("$date_only");
|
||||
$ed = new DateTime("$date_exp");
|
||||
$td = $ed->diff($sd);
|
||||
$fd = $td->format("%a");
|
||||
$gi = ($p['price'] / (30 * $p['validity'])) * $fd;
|
||||
if ($gi > $p['price']) {
|
||||
$fl->field_value = $p['price'];
|
||||
} else {
|
||||
$fl->field_value = $gi;
|
||||
}
|
||||
$fl->save();
|
||||
} else {
|
||||
$fl->customer_id = $c['id'];
|
||||
$fl->field_value = $p['price'];
|
||||
$fl->save();
|
||||
}
|
||||
}
|
||||
|
||||
Message::sendTelegram("#u$c[username] $c[fullname] #buy #Hotspot \n" . $p['name_plan'] .
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nPrice: " . Lang::moneyFormat($p['price'] + $add_cost) .
|
||||
"\nNote:\n" . $note);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ($b) {
|
||||
if ($plan_id != $b['plan_id']) {
|
||||
$isChangePlan = true;
|
||||
}
|
||||
if ($b['namebp'] == $p['name_plan'] && $b['status'] == 'on') {
|
||||
// if it same internet plan, expired will extend
|
||||
if ($p['validity_unit'] == 'Months') {
|
||||
$date_exp = date("Y-m-d", strtotime($b['expiration'] . ' +' . $p['validity'] . ' months'));
|
||||
$time = $b['time'];
|
||||
} else if ($p['validity_unit'] == 'Period') {
|
||||
$date_exp = date("Y-m-20", strtotime($b['expiration'] . ' +' . $p['validity'] . ' months'));
|
||||
$time = date("23:59:00");
|
||||
} else if ($p['validity_unit'] == 'Period') {
|
||||
$date_exp = date("Y-m-$day_exp", strtotime($b['expiration'] . ' +' . $p['validity'] . ' months'));
|
||||
$time = date("23:59:00");
|
||||
} else if ($p['validity_unit'] == 'Days') {
|
||||
$date_exp = date("Y-m-d", strtotime($b['expiration'] . ' +' . $p['validity'] . ' days'));
|
||||
$time = $b['time'];
|
||||
@ -283,13 +416,15 @@ class Package
|
||||
}
|
||||
}
|
||||
|
||||
if ($p['is_radius']) {
|
||||
Radius::customerAddPlan($c, $p, "$date_exp $time");
|
||||
} else {
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::addPpoeUser($client, $p, $c);
|
||||
if ($isChangePlan || $b['status'] == 'off') {
|
||||
if ($p['is_radius']) {
|
||||
Radius::customerAddPlan($c, $p, "$date_exp $time");
|
||||
} else {
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
Mikrotik::removePpoeUser($client, $c['username']);
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
Mikrotik::addPpoeUser($client, $p, $c);
|
||||
}
|
||||
}
|
||||
|
||||
$b->customer_id = $id_customer;
|
||||
@ -313,16 +448,27 @@ class Package
|
||||
|
||||
// insert table transactions
|
||||
$t = ORM::for_table('tbl_transactions')->create();
|
||||
$t->invoice = "INV-" . Package::_raid(5);
|
||||
$t->invoice = $inv = "INV-" . Package::_raid();
|
||||
$t->username = $c['username'];
|
||||
$t->plan_name = $p['name_plan'];
|
||||
$t->price = $p['price'];
|
||||
if ($p['validity_unit'] == 'Period') {
|
||||
// Postpaid price from field
|
||||
$add_inv = User::getAttribute("Invoice", $id_customer);
|
||||
if (empty($add_inv) or $add_inv == 0) {
|
||||
$t->price = $p['price'] + $add_cost;
|
||||
} else {
|
||||
$t->price = $add_inv + $add_cost;
|
||||
}
|
||||
} else {
|
||||
$t->price = $p['price'] + $add_cost;
|
||||
}
|
||||
$t->recharged_on = $date_only;
|
||||
$t->recharged_time = $time_only;
|
||||
$t->expiration = $date_exp;
|
||||
$t->time = $time;
|
||||
$t->method = "$gateway - $channel";
|
||||
$t->routers = $router_name;
|
||||
$t->note = $note;
|
||||
$t->type = "PPPOE";
|
||||
if ($admin) {
|
||||
$t->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
@ -330,12 +476,29 @@ class Package
|
||||
$t->admin_id = '0';
|
||||
}
|
||||
$t->save();
|
||||
|
||||
Message::sendTelegram("#u$c[username] #recharge #PPPOE \n" . $p['name_plan'] .
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nPrice: " . Lang::moneyFormat($p['price']));
|
||||
|
||||
if ($p['validity_unit'] == 'Period' && $p['price'] != 0) {
|
||||
// insert price to fields for invoice next month
|
||||
$fl = ORM::for_table('tbl_customers_fields')->where('field_name', 'Invoice')->where('customer_id', $c['id'])->find_one();
|
||||
if (!$fl) {
|
||||
$fl = ORM::for_table('tbl_customers_fields')->create();
|
||||
$fl->customer_id = $c['id'];
|
||||
$fl->field_name = 'Invoice';
|
||||
$fl->field_value = $p['price'];
|
||||
$fl->save();
|
||||
} else {
|
||||
$fl->customer_id = $c['id'];
|
||||
$fl->field_value = $p['price'];
|
||||
$fl->save();
|
||||
}
|
||||
}
|
||||
|
||||
Message::sendTelegram("#u$c[username] $c[fullname] #recharge #PPPOE \n" . $p['name_plan'] .
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nPrice: " . Lang::moneyFormat($p['price'] + $add_cost) .
|
||||
"\nNote:\n" . $note);
|
||||
} else {
|
||||
if ($p['is_radius']) {
|
||||
Radius::customerAddPlan($c, $p, "$date_exp $time");
|
||||
@ -368,15 +531,23 @@ class Package
|
||||
|
||||
// insert table transactions
|
||||
$t = ORM::for_table('tbl_transactions')->create();
|
||||
$t->invoice = "INV-" . Package::_raid(5);
|
||||
$t->invoice = $inv = "INV-" . Package::_raid();
|
||||
$t->username = $c['username'];
|
||||
$t->plan_name = $p['name_plan'];
|
||||
$t->price = $p['price'];
|
||||
if ($p['validity_unit'] == 'Period') {
|
||||
// Postpaid price always zero for first time
|
||||
$note = '';
|
||||
$bills = [];
|
||||
$t->price = 0;
|
||||
} else {
|
||||
$t->price = $p['price'] + $add_cost;
|
||||
}
|
||||
$t->recharged_on = $date_only;
|
||||
$t->recharged_time = $time_only;
|
||||
$t->expiration = $date_exp;
|
||||
$t->time = $time;
|
||||
$t->method = "$gateway - $channel";
|
||||
$t->note = $note;
|
||||
$t->routers = $router_name;
|
||||
if ($admin) {
|
||||
$t->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
@ -385,24 +556,56 @@ class Package
|
||||
}
|
||||
$t->type = "PPPOE";
|
||||
$t->save();
|
||||
|
||||
Message::sendTelegram("#u$c[username] #buy #PPPOE \n" . $p['name_plan'] .
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nPrice: " . Lang::moneyFormat($p['price']));
|
||||
|
||||
if ($p['validity_unit'] == 'Period' && $p['price'] != 0) {
|
||||
// insert price to fields for invoice next month
|
||||
$fl = ORM::for_table('tbl_customers_fields')->where('field_name', 'Invoice')->where('customer_id', $c['id'])->find_one();
|
||||
if (!$fl) {
|
||||
$fl = ORM::for_table('tbl_customers_fields')->create();
|
||||
$fl->customer_id = $c['id'];
|
||||
$fl->field_name = 'Invoice';
|
||||
// Calculating Price
|
||||
$sd = new DateTime("$date_only");
|
||||
$ed = new DateTime("$date_exp");
|
||||
$td = $ed->diff($sd);
|
||||
$fd = $td->format("%a");
|
||||
$gi = ($p['price'] / (30 * $p['validity'])) * $fd;
|
||||
if ($gi > $p['price']) {
|
||||
$fl->field_value = $p['price'];
|
||||
} else {
|
||||
$fl->field_value = $gi;
|
||||
}
|
||||
$fl->save();
|
||||
} else {
|
||||
$fl->customer_id = $c['id'];
|
||||
$fl->field_value = $p['price'];
|
||||
$fl->save();
|
||||
}
|
||||
}
|
||||
|
||||
Message::sendTelegram("#u$c[username] $c[fullname] #buy #PPPOE \n" . $p['name_plan'] .
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nPrice: " . Lang::moneyFormat($p['price'] + $add_cost) .
|
||||
"\nNote:\n" . $note);
|
||||
}
|
||||
|
||||
}
|
||||
if (is_array($bills) && count($bills) > 0) {
|
||||
User::billsPaid($bills, $id_customer);
|
||||
}
|
||||
run_hook("recharge_user_finish");
|
||||
Message::sendInvoice($c, $t);
|
||||
return true;
|
||||
if ($trx) {
|
||||
$trx->trx_invoice = $inv;
|
||||
}
|
||||
return $inv;
|
||||
}
|
||||
|
||||
public static function changeTo($username, $plan_id, $from_id)
|
||||
{
|
||||
$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();
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $plan_id)->find_one();
|
||||
$b = ORM::for_table('tbl_user_recharges')->find_one($from_id);
|
||||
if ($p['routers'] == $b['routers'] && $b['routers'] != 'radius') {
|
||||
$mikrotik = Mikrotik::info($p['routers']);
|
||||
@ -479,9 +682,9 @@ class Package
|
||||
}
|
||||
|
||||
|
||||
public static function _raid($l)
|
||||
public static function _raid()
|
||||
{
|
||||
return substr(str_shuffle(str_repeat('0123456789', $l)), 0, $l);
|
||||
return ORM::for_table('tbl_transactions')->max('id') + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -500,7 +703,12 @@ class Package
|
||||
$_admin = Admin::_info($in['admin_id']);
|
||||
// if admin not deleted
|
||||
if ($_admin) $admin = $_admin;
|
||||
} else {
|
||||
$admin['fullname'] = 'Customer';
|
||||
}
|
||||
$cust = ORM::for_table('tbl_customers')->where('username', $in['username'])->findOne();
|
||||
|
||||
$note = '';
|
||||
//print
|
||||
$invoice = Lang::pad($config['CompanyName'], ' ', 2) . "\n";
|
||||
$invoice .= Lang::pad($config['address'], ' ', 2) . "\n";
|
||||
@ -512,9 +720,31 @@ class Package
|
||||
$invoice .= Lang::pad("", '=') . "\n";
|
||||
$invoice .= Lang::pads(Lang::T('Type'), $in['type'], ' ') . "\n";
|
||||
$invoice .= Lang::pads(Lang::T('Plan Name'), $in['plan_name'], ' ') . "\n";
|
||||
$invoice .= Lang::pads(Lang::T('Plan Price'), Lang::moneyFormat($in['price']), ' ') . "\n";
|
||||
$invoice .= Lang::pad($in['method'], ' ', 2) . "\n";
|
||||
|
||||
if (!empty($in['note'])) {
|
||||
$in['note'] = str_replace("\r", "", $in['note']);
|
||||
$tmp = explode("\n", $in['note']);
|
||||
foreach ($tmp as $t) {
|
||||
if (strpos($t, " : ") === false) {
|
||||
if (!empty($t)) {
|
||||
$note .= "$t\n";
|
||||
}
|
||||
} else {
|
||||
$tmp2 = explode(" : ", $t);
|
||||
$invoice .= Lang::pads($tmp2[0], $tmp2[1], ' ') . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
$invoice .= Lang::pads(Lang::T('Total'), Lang::moneyFormat($in['price']), ' ') . "\n";
|
||||
$method = explode("-", $in['method']);
|
||||
$invoice .= Lang::pads($method[0], $method[1], ' ') . "\n";
|
||||
if (!empty($note)) {
|
||||
$invoice .= Lang::pad("", '=') . "\n";
|
||||
$invoice .= Lang::pad($note, ' ', 2) . "\n";
|
||||
}
|
||||
$invoice .= Lang::pad("", '=') . "\n";
|
||||
if ($cust) {
|
||||
$invoice .= Lang::pads(Lang::T('Full Name'), $cust['fullname'], ' ') . "\n";
|
||||
}
|
||||
$invoice .= Lang::pads(Lang::T('Username'), $in['username'], ' ') . "\n";
|
||||
$invoice .= Lang::pads(Lang::T('Password'), '**********', ' ') . "\n";
|
||||
if ($in['type'] != 'Balance') {
|
||||
@ -536,9 +766,29 @@ class Package
|
||||
$invoice .= Lang::pad("", '=') . "\n";
|
||||
$invoice .= Lang::pads(Lang::T('Type'), $in['type'], ' ') . "\n";
|
||||
$invoice .= Lang::pads(Lang::T('Plan Name'), $in['plan_name'], ' ') . "\n";
|
||||
$invoice .= Lang::pads(Lang::T('Plan Price'), Lang::moneyFormat($in['price']), ' ') . "\n";
|
||||
$invoice .= Lang::pad($in['method'], ' ', 2) . "\n";
|
||||
|
||||
if (!empty($in['note'])) {
|
||||
$invoice .= Lang::pad("", '=') . "\n";
|
||||
foreach ($tmp as $t) {
|
||||
if (strpos($t, " : ") === false) {
|
||||
if (!empty($t)) {
|
||||
$invoice .= Lang::pad($t, ' ', 2) . "\n";
|
||||
}
|
||||
} else {
|
||||
$tmp2 = explode(" : ", $t);
|
||||
$invoice .= Lang::pads($tmp2[0], $tmp2[1], ' ') . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
$invoice .= Lang::pads(Lang::T('Total'), Lang::moneyFormat($in['price']), ' ') . "\n";
|
||||
$invoice .= Lang::pads($method[0], $method[1], ' ') . "\n";
|
||||
if (!empty($note)) {
|
||||
$invoice .= Lang::pad("", '=') . "\n";
|
||||
$invoice .= Lang::pad($note, ' ', 2) . "\n";
|
||||
}
|
||||
$invoice .= Lang::pad("", '=') . "\n";
|
||||
if ($cust) {
|
||||
$invoice .= Lang::pads(Lang::T('Full Name'), $cust['fullname'], ' ') . "\n";
|
||||
}
|
||||
$invoice .= Lang::pads(Lang::T('Username'), $in['username'], ' ') . "\n";
|
||||
$invoice .= Lang::pads(Lang::T('Password'), '**********', ' ') . "\n";
|
||||
if ($in['type'] != 'Balance') {
|
||||
|
@ -1,14 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
* PHP Mikrotik Billing (https://github.com/SiberTech/)
|
||||
* by https://t.me/ibnux
|
||||
**/
|
||||
|
||||
|
||||
class Paginator
|
||||
{
|
||||
public static function build($table, $colVal = [], $query='', $per_page = '10')
|
||||
public static function findMany($query, $search = [], $per_page = '10')
|
||||
{
|
||||
global $routes, $ui;
|
||||
$adjacents = "2";
|
||||
$page = _get('p', 1);
|
||||
$page = (empty($page) ? 1 : $page);
|
||||
$url = U . implode('/', $routes);
|
||||
if (count($search) > 0) {
|
||||
$url .= '&' . http_build_query($search);
|
||||
}
|
||||
$url .= '&p=';
|
||||
$totalReq = $query->count();
|
||||
$lastpage = ceil($totalReq / $per_page);
|
||||
$lpm1 = $lastpage - 1;
|
||||
$limit = $per_page;
|
||||
$startpoint = ($page * $limit) - $limit;
|
||||
if ($lastpage >= 1) {
|
||||
$pages = [];
|
||||
if ($lastpage < 7 + ($adjacents * 2)) {
|
||||
for ($counter = 1; $counter <= $lastpage; $counter++) {
|
||||
$pages[] = $counter;
|
||||
}
|
||||
} elseif ($lastpage > 5 + ($adjacents * 2)) {
|
||||
if ($page < 1 + ($adjacents * 2)) {
|
||||
for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++) {
|
||||
$pages[] = $counter;
|
||||
}
|
||||
$pages[] = "...";
|
||||
$pages[] = $lpm1;
|
||||
$pages[] = $lastpage;
|
||||
} elseif ($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2)) {
|
||||
$pages[] = "1";
|
||||
$pages[] = "2";
|
||||
$pages[] = "...";
|
||||
for ($counter = $page - $adjacents; $counter <= $page + $adjacents; $counter++) {
|
||||
$pages[] = $counter;
|
||||
}
|
||||
$pages[] = "...";
|
||||
$pages[] = $lpm1;
|
||||
$pages[] = $lastpage;
|
||||
} else {
|
||||
$pages[] = "1";
|
||||
$pages[] = "2";
|
||||
$pages[] = "...";
|
||||
for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++) {
|
||||
$pages[] = $counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = [
|
||||
'count' => $lastpage,
|
||||
'limit' => $per_page,
|
||||
'startpoint' => $startpoint,
|
||||
'url' => $url,
|
||||
'page' => $page,
|
||||
'pages' => $pages,
|
||||
'prev' => ($page > 0) ? ($page - 1) : "0",
|
||||
'next' => ($page >= $lastpage) ? $lastpage : $page + 1
|
||||
];
|
||||
if ($ui) {
|
||||
$ui->assign('paginator', $result);
|
||||
}
|
||||
return $query->offset($startpoint)->limit($per_page)->find_many();
|
||||
}
|
||||
}
|
||||
|
||||
public static function build($table, $colVal = [], $query = '', $per_page = '10')
|
||||
{
|
||||
global $routes;
|
||||
global $_L;
|
||||
@ -17,13 +84,13 @@ class Paginator
|
||||
$adjacents = "2";
|
||||
$page = (int)(empty(_get('p')) ? 1 : _get('p'));
|
||||
$pagination = "";
|
||||
foreach($colVal as $k=>$v) {
|
||||
if(!is_array($v) && strpos($v,'%') === false) {
|
||||
foreach ($colVal as $k => $v) {
|
||||
if (!is_array($v) && strpos($v, '%') === false) {
|
||||
$table = $table->where($k, $v);
|
||||
}else{
|
||||
if(is_array($v)){
|
||||
} else {
|
||||
if (is_array($v)) {
|
||||
$table = $table->where_in($k, $v);
|
||||
}else{
|
||||
} else {
|
||||
$table = $table->where_like($k, $v);
|
||||
}
|
||||
}
|
||||
@ -36,60 +103,60 @@ class Paginator
|
||||
$limit = $per_page;
|
||||
$startpoint = ($page * $limit) - $limit;
|
||||
if ($lastpage >= 1) {
|
||||
$pagination .= '<ul class="pagination pagination-sm">';
|
||||
$pagination .= '<ul class="pagination">';
|
||||
if ($lastpage < 7 + ($adjacents * 2)) {
|
||||
for ($counter = 1; $counter <= $lastpage; $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a href='javascript:void(0);'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item active'><a class='page-link' href='javascript:void(0);'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}&p=$counter&q=$query'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=$counter&q=$query'>$counter</a></li>";
|
||||
}
|
||||
} elseif ($lastpage > 5 + ($adjacents * 2)) {
|
||||
if ($page < 1 + ($adjacents * 2)) {
|
||||
for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a href='javascript:void(0);'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item active'><a class='page-link' href='javascript:void(0);'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}&p=$counter&q=$query'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=$counter&q=$query'>$counter</a></li>";
|
||||
}
|
||||
$pagination .= "<li class='disabled'><a href='#'>...</a></li>";
|
||||
$pagination .= "<li><a href='{$url}&p=$lpm1&q=$query'>$lpm1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}&p=$lastpage&q=$query'>$lastpage</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link' href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=$lpm1&q=$query'>$lpm1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=$lastpage&q=$query'>$lastpage</a></li>";
|
||||
} elseif ($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2)) {
|
||||
$pagination .= "<li><a href='{$url}&p=1&q=$query'>1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}&p=2&q=$query'>2</a></li>";
|
||||
$pagination .= "<li class='disabled'><a href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=1&q=$query'>1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=2&q=$query'>2</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link' href='#'>...</a></li>";
|
||||
for ($counter = $page - $adjacents; $counter <= $page + $adjacents; $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a href='javascript:void(0);'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item active'><a class='page-link' href='javascript:void(0);'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}&p=$counter&q=$query'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=$counter&q=$query'>$counter</a></li>";
|
||||
}
|
||||
$pagination .= "<li class='disabled'><a href='#'>...</a></li>";
|
||||
$pagination .= "<li><a href='{$url}&p=$lpm1&q=$query'>$lpm1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}&p=$lastpage&q=$query'>$lastpage</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link' href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=$lpm1&q=$query'>$lpm1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=$lastpage&q=$query'>$lastpage</a></li>";
|
||||
} else {
|
||||
$pagination .= "<li><a href='{$url}&p=1&q=$query'>1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}&p=2&q=$query'>2</a></li>";
|
||||
$pagination .= "<li><a href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=1&q=$query'>1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=2&q=$query'>2</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='#'>...</a></li>";
|
||||
for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a class='disabled'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link disabled'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}&p=$counter&q=$query'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=$counter&q=$query'>$counter</a></li>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($page < $counter - 1) {
|
||||
$pagination .= "<li><a href='{$url}&p=$next&q=$query'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li><a href='{$url}&p=$lastpage&q=$query'>" . Lang::T('Last') . "</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=$next&q=$query'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}&p=$lastpage&q=$query'>" . Lang::T('Last') . "</a></li>";
|
||||
} else {
|
||||
$pagination .= "<li class='disabled'><a class='disabled'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li class='disabled'><a class='disabled'>" . Lang::T('Last') . "</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link disabled'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link disabled'>" . Lang::T('Last') . "</a></li>";
|
||||
}
|
||||
$pagination .= "</ul>";
|
||||
|
||||
$pagination = '<nav>' . $pagination . '</nav>';
|
||||
return array("startpoint" => $startpoint, "limit" => $limit, "found" => $totalReq, "page" => $page, "lastpage" => $lastpage, "contents" => $pagination);
|
||||
}
|
||||
}
|
||||
@ -103,7 +170,7 @@ class Paginator
|
||||
$page = (int)(!isset($routes['2']) ? 1 : $routes['2']);
|
||||
$pagination = "";
|
||||
|
||||
if(is_object($table)){
|
||||
if (is_object($table)) {
|
||||
if ($w1 != '') {
|
||||
$totalReq = $table->where($w1, $c1)->count();
|
||||
} elseif ($w2 != '') {
|
||||
@ -115,7 +182,7 @@ class Paginator
|
||||
} else {
|
||||
$totalReq = $table->count();
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
if ($w1 != '') {
|
||||
$totalReq = ORM::for_table($table)->where($w1, $c1)->count();
|
||||
} elseif ($w2 != '') {
|
||||
@ -142,59 +209,60 @@ class Paginator
|
||||
$startpoint = ($page * $limit) - $limit;
|
||||
|
||||
if ($lastpage >= 1) {
|
||||
$pagination .= '<ul class="pagination pagination-sm">';
|
||||
$pagination .= '<ul class="pagination">';
|
||||
if ($lastpage < 7 + ($adjacents * 2)) {
|
||||
for ($counter = 1; $counter <= $lastpage; $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a href='javascript:void(0);'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item active'><a class='page-link' href='javascript:void(0);'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}$counter'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$counter'>$counter</a></li>";
|
||||
}
|
||||
} elseif ($lastpage > 5 + ($adjacents * 2)) {
|
||||
if ($page < 1 + ($adjacents * 2)) {
|
||||
for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a href='javascript:void(0);'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item active'><a class='page-link' href='javascript:void(0);'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}$counter'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$counter'>$counter</a></li>";
|
||||
}
|
||||
$pagination .= "<li class='disabled'><a href='#'>...</a></li>";
|
||||
$pagination .= "<li><a href='{$url}$lpm1'>$lpm1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}$lastpage'>$lastpage</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link' href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$lpm1'>$lpm1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$lastpage'>$lastpage</a></li>";
|
||||
} elseif ($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2)) {
|
||||
$pagination .= "<li><a href='{$url}1'>1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}2'>2</a></li>";
|
||||
$pagination .= "<li class='disabled'><a href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}1'>1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}2'>2</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link' href='#'>...</a></li>";
|
||||
for ($counter = $page - $adjacents; $counter <= $page + $adjacents; $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a href='javascript:void(0);'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item active'><a class='page-link' href='javascript:void(0);'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}$counter'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$counter'>$counter</a></li>";
|
||||
}
|
||||
$pagination .= "<li class='disabled'><a href='#'>...</a></li>";
|
||||
$pagination .= "<li><a href='{$url}$lpm1'>$lpm1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}$lastpage'>$lastpage</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link' href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$lpm1'>$lpm1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$lastpage'>$lastpage</a></li>";
|
||||
} else {
|
||||
$pagination .= "<li><a href='{$url}1'>1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}2'>2</a></li>";
|
||||
$pagination .= "<li><a href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}1'>1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}2'>2</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='#'>...</a></li>";
|
||||
for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a class='disabled'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link disabled'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}$counter'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$counter'>$counter</a></li>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($page < $counter - 1) {
|
||||
$pagination .= "<li><a href='{$url}$next'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li><a href='{$url}$lastpage'>" . Lang::T('Last') . "</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$next'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$lastpage'>" . Lang::T('Last') . "</a></li>";
|
||||
} else {
|
||||
$pagination .= "<li class='disabled'><a class='disabled'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li class='disabled'><a class='disabled'>" . Lang::T('Last') . "</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link disabled'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link disabled'>" . Lang::T('Last') . "</a></li>";
|
||||
}
|
||||
$pagination .= "</ul>";
|
||||
$pagination = '<nav>' . $pagination . '</nav>';
|
||||
|
||||
$gen = array("startpoint" => $startpoint, "limit" => $limit, "found" => $totalReq, "page" => $page, "lastpage" => $lastpage, "contents" => $pagination);
|
||||
return $gen;
|
||||
@ -209,13 +277,13 @@ class Paginator
|
||||
$adjacents = "2";
|
||||
$page = (int)(!isset($routes['2']) ? 1 : $routes['2']);
|
||||
$pagination = "";
|
||||
if(is_object($table)){
|
||||
if (is_object($table)) {
|
||||
if ($w1 != '') {
|
||||
$totalReq = $table->where_raw($w1, $c1)->count();
|
||||
} else {
|
||||
$totalReq = $table->count();
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
if ($w1 != '') {
|
||||
$totalReq = ORM::for_table($table)->where_raw($w1, $c1)->count();
|
||||
} else {
|
||||
@ -236,59 +304,60 @@ class Paginator
|
||||
$startpoint = ($page * $limit) - $limit;
|
||||
|
||||
if ($lastpage >= 1) {
|
||||
$pagination .= '<ul class="pagination pagination-sm">';
|
||||
$pagination .= '<ul class="pagination">';
|
||||
if ($lastpage < 7 + ($adjacents * 2)) {
|
||||
for ($counter = 1; $counter <= $lastpage; $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a href='javascript:void(0);'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item active'><a class='page-link' href='javascript:void(0);'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}$counter'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$counter'>$counter</a></li>";
|
||||
}
|
||||
} elseif ($lastpage > 5 + ($adjacents * 2)) {
|
||||
if ($page < 1 + ($adjacents * 2)) {
|
||||
for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a href='javascript:void(0);'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item active'><a class='page-link' href='javascript:void(0);'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}$counter'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$counter'>$counter</a></li>";
|
||||
}
|
||||
$pagination .= "<li class='disabled'><a href='#'>...</a></li>";
|
||||
$pagination .= "<li><a href='{$url}$lpm1'>$lpm1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}$lastpage'>$lastpage</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link' href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$lpm1'>$lpm1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$lastpage'>$lastpage</a></li>";
|
||||
} elseif ($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2)) {
|
||||
$pagination .= "<li><a href='{$url}1'>1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}2'>2</a></li>";
|
||||
$pagination .= "<li class='disabled'><a href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}1'>1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}2'>2</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link' href='#'>...</a></li>";
|
||||
for ($counter = $page - $adjacents; $counter <= $page + $adjacents; $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a href='javascript:void(0);'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item active'><a class='page-link' href='javascript:void(0);'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}$counter'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$counter'>$counter</a></li>";
|
||||
}
|
||||
$pagination .= "<li class='disabled'><a href='#'>...</a></li>";
|
||||
$pagination .= "<li><a href='{$url}$lpm1'>$lpm1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}$lastpage'>$lastpage</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-link' href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$lpm1'>$lpm1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$lastpage'>$lastpage</a></li>";
|
||||
} else {
|
||||
$pagination .= "<li><a href='{$url}1'>1</a></li>";
|
||||
$pagination .= "<li><a href='{$url}2'>2</a></li>";
|
||||
$pagination .= "<li><a href='#'>...</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}1'>1</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}2'>2</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='#'>...</a></li>";
|
||||
for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++) {
|
||||
if ($counter == $page)
|
||||
$pagination .= "<li class='active'><a class='disabled'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item active'><a class='page-item disabled'>$counter</a></li>";
|
||||
else
|
||||
$pagination .= "<li><a href='{$url}$counter'>$counter</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$counter'>$counter</a></li>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($page < $counter - 1) {
|
||||
$pagination .= "<li><a href='{$url}$next'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li><a href='{$url}$lastpage'>" . Lang::T('Last') . "</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$next'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li class='page-item'><a class='page-link' href='{$url}$lastpage'>" . Lang::T('Last') . "</a></li>";
|
||||
} else {
|
||||
$pagination .= "<li class='disabled'><a class='disabled'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li class='disabled'><a class='disabled'>" . Lang::T('Last') . "</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-item disabled'>" . Lang::T('Next') . "</a></li>";
|
||||
$pagination .= "<li class='page-item disabled'><a class='page-item disabled'>" . Lang::T('Last') . "</a></li>";
|
||||
}
|
||||
$pagination .= "</ul>";
|
||||
$pagination = '<nav>' . $pagination . '</nav>';
|
||||
|
||||
$gen = array("startpoint" => $startpoint, "limit" => $limit, "found" => $totalReq, "page" => $page, "lastpage" => $lastpage, "contents" => $pagination);
|
||||
return $gen;
|
||||
|
@ -30,7 +30,10 @@ class Radius
|
||||
{
|
||||
return ORM::for_table('nas', 'radius');
|
||||
}
|
||||
|
||||
public static function getTableAcct()
|
||||
{
|
||||
return ORM::for_table('radacct', 'radius');
|
||||
}
|
||||
public static function getTableCustomer()
|
||||
{
|
||||
return ORM::for_table('radcheck', 'radius');
|
||||
@ -88,9 +91,16 @@ class Radius
|
||||
public static function planUpSert($plan_id, $rate, $pool = null)
|
||||
{
|
||||
$rates = explode('/', $rate);
|
||||
##burst fixed
|
||||
if (strpos($rate, ' ')) {
|
||||
$ratos = $rates[0].'/'.$rates[1].' '.$rates[2].'/'.$rates[3].'/'.$rates[4].'/'.$rates[5].'/'.$rates[6];
|
||||
} else {
|
||||
$ratos = $rates[0].'/'.$rates[1];
|
||||
}
|
||||
|
||||
Radius::upsertPackage($plan_id, 'Ascend-Data-Rate', $rates[1], ':=');
|
||||
Radius::upsertPackage($plan_id, 'Ascend-Xmit-Rate', $rates[0], ':=');
|
||||
Radius::upsertPackage($plan_id, 'Mikrotik-Rate-Limit', $rate, ':=');
|
||||
Radius::upsertPackage($plan_id, 'Mikrotik-Rate-Limit', $ratos, ':=');
|
||||
// if ($pool != null) {
|
||||
// Radius::upsertPackage($plan_id, 'Framed-Pool', $pool, ':=');
|
||||
// }
|
||||
@ -161,6 +171,8 @@ class Radius
|
||||
$p = Radius::getTableUserPackage()->where_equal('username', $customer['username'])->findOne();
|
||||
if ($p) {
|
||||
// if exists
|
||||
Radius::delAtribute(Radius::getTableCustomer(), 'Max-All-Session', 'username', $customer['username']);
|
||||
Radius::delAtribute(Radius::getTableCustomer(), 'Max-Data', 'username', $customer['username']);
|
||||
$p->groupname = "plan_" . $plan['id'];
|
||||
$p->save();
|
||||
} else {
|
||||
@ -176,7 +188,7 @@ class Radius
|
||||
$timelimit = $plan['time_limit'] * 60 * 60;
|
||||
else
|
||||
$timelimit = $plan['time_limit'] * 60;
|
||||
Radius::upsertCustomer($customer['username'], 'Expire-After', $timelimit);
|
||||
Radius::upsertCustomer($customer['username'], 'Max-All-Session', $timelimit);
|
||||
} else if ($plan['limit_type'] == "Data_Limit") {
|
||||
if ($plan['data_unit'] == 'GB')
|
||||
$datalimit = $plan['data_limit'] . "000000000";
|
||||
@ -184,29 +196,40 @@ class Radius
|
||||
$datalimit = $plan['data_limit'] . "000000";
|
||||
//Radius::upsertCustomer($customer['username'], 'Max-Volume', $datalimit);
|
||||
// Mikrotik Spesific
|
||||
Radius::upsertCustomer($customer['username'], 'Mikrotik-Total-Limit', $datalimit);
|
||||
Radius::upsertCustomer($customer['username'], 'Max-Data', $datalimit);
|
||||
} else if ($plan['limit_type'] == "Both_Limit") {
|
||||
if ($plan['time_unit'] == 'Hrs')
|
||||
$timelimit = $plan['time_limit'] * 60 * 60;
|
||||
else
|
||||
$timelimit = $plan['time_limit'] . ":00";
|
||||
$timelimit = $plan['time_limit'] * 60;
|
||||
if ($plan['data_unit'] == 'GB')
|
||||
$datalimit = $plan['data_limit'] . "000000000";
|
||||
else
|
||||
$datalimit = $plan['data_limit'] . "000000";
|
||||
//Radius::upsertCustomer($customer['username'], 'Max-Volume', $datalimit);
|
||||
Radius::upsertCustomer($customer['username'], 'Expire-After', $timelimit);
|
||||
Radius::upsertCustomer($customer['username'], 'Max-All-Session', $timelimit);
|
||||
// Mikrotik Spesific
|
||||
Radius::upsertCustomer($customer['username'], 'Mikrotik-Total-Limit', $datalimit);
|
||||
Radius::upsertCustomer($customer['username'], 'Max-Data', $datalimit);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
//Radius::delAtribute(Radius::getTableCustomer(), 'Max-Volume', 'username', $customer['username']);
|
||||
Radius::delAtribute(Radius::getTableCustomer(), 'Expire-After', 'username', $customer['username']);
|
||||
Radius::delAtribute(Radius::getTableCustomer(), 'Mikrotik-Total-Limit', 'username', $customer['username']);
|
||||
Radius::delAtribute(Radius::getTableCustomer(), 'Max-All-Session', 'username', $customer['username']);
|
||||
Radius::delAtribute(Radius::getTableCustomer(), 'Max-Data', 'username', $customer['username']);
|
||||
}
|
||||
|
||||
Radius::disconnectCustomer($customer['username']);
|
||||
Radius::getTableAcct()->where_equal('username', $customer['username'])->delete_many();
|
||||
|
||||
|
||||
// expired user
|
||||
if ($expired != null) {
|
||||
//Radius::upsertCustomer($customer['username'], 'access-period', strtotime($expired) - time());
|
||||
//Radius::upsertCustomer($customer['username'], 'Max-All-Session', strtotime($expired) - time());
|
||||
Radius::upsertCustomer($customer['username'], 'expiration', date('d M Y H:i:s', strtotime($expired)));
|
||||
// Mikrotik Spesific
|
||||
Radius::upsertCustomer(
|
||||
@ -215,13 +238,15 @@ class Radius
|
||||
date('Y-m-d', strtotime($expired)) . 'T' . date('H:i:s', strtotime($expired)) . Timezone::getTimeOffset($config['timezone'])
|
||||
);
|
||||
} else {
|
||||
//Radius::delAtribute(Radius::getTableCustomer(), 'access-period', 'username', $customer['username']);
|
||||
//Radius::delAtribute(Radius::getTableCustomer(), 'Max-All-Session', 'username', $customer['username']);
|
||||
Radius::delAtribute(Radius::getTableCustomer(), 'expiration', 'username', $customer['username']);
|
||||
}
|
||||
|
||||
if ($plan['type'] == 'PPPOE') {
|
||||
Radius::upsertCustomerAttr($customer['username'], 'Framed-Pool', $plan['pool'], ':=');
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -267,7 +292,7 @@ class Radius
|
||||
/**
|
||||
* To insert or update existing customer
|
||||
*/
|
||||
private static function upsertCustomer($username, $attr, $value, $op = ':=')
|
||||
public static function upsertCustomer($username, $attr, $value, $op = ':=')
|
||||
{
|
||||
$r = Radius::getTableCustomer()->where_equal('username', $username)->whereEqual('attribute', $attr)->find_one();
|
||||
if (!$r) {
|
||||
@ -301,7 +326,11 @@ class Radius
|
||||
if ($_app_stage == 'demo') {
|
||||
return null;
|
||||
}
|
||||
$nas = Radius::getTableNas()->findMany();
|
||||
/**
|
||||
* Fix loop to all Nas but still detecting Hotspot Multylogin from other Nas
|
||||
*/
|
||||
$act = ORM::for_table('radacct')->where_raw("acctstoptime IS NULL")->where('username', $username)->find_one();
|
||||
$nas = Radius::getTableNas()->where('nasname', $act['nasipaddress'])->find_many();
|
||||
$count = count($nas) * 15;
|
||||
set_time_limit($count);
|
||||
$result = [];
|
||||
@ -310,7 +339,7 @@ class Radius
|
||||
if (!empty($n['ports'])) {
|
||||
$port = $n['ports'];
|
||||
}
|
||||
$result[] = $n['nasname'] . ': ' . @shell_exec("echo 'User-Name = $username' | " . Radius::getClient() . " " . trim($n['nasname']) . ":$port disconnect '" . $n['secret'] . "'");
|
||||
$result[] = $n['nasname'] . ': ' . @shell_exec("echo 'User-Name = $username,Framed-IP-Address = " . $act['framedipaddress'] . "' | radclient -x " . trim($n['nasname']) . ":$port disconnect '" . $n['secret'] . "'");
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
64
system/autoload/Text.php
Normal file
64
system/autoload/Text.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
* by https://t.me/ibnux
|
||||
*
|
||||
* This file is for Text Transformation
|
||||
**/
|
||||
|
||||
class Text
|
||||
{
|
||||
|
||||
public static function toHex($string)
|
||||
{
|
||||
return "\x" . implode("\x", str_split(array_shift(unpack('H*', $string)), 2));
|
||||
}
|
||||
|
||||
public static function alphanumeric($str, $tambahan = "")
|
||||
{
|
||||
return preg_replace("/[^a-zA-Z0-9" . $tambahan . "]+/", "", $str);
|
||||
}
|
||||
|
||||
public static function numeric($str)
|
||||
{
|
||||
return preg_replace("/[^0-9]+/", "", $str);
|
||||
}
|
||||
|
||||
public static function ucWords($text)
|
||||
{
|
||||
return ucwords(str_replace('_', ' ', $text));
|
||||
}
|
||||
|
||||
public static function randomUpLowCase($text)
|
||||
{
|
||||
$jml = strlen($text);
|
||||
$result = '';
|
||||
for ($i = 0; $i < $jml; $i++) {
|
||||
if (rand(0, 99) % 2) {
|
||||
$result .= strtolower(substr($text, $i, 1));
|
||||
} else {
|
||||
$result .= substr($text, $i, 1);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function maskText($text){
|
||||
$len = strlen($text);
|
||||
if($len < 3){
|
||||
return "***";
|
||||
}else if($len<5){
|
||||
return substr($text,0,1)."***".substr($text,-1,1);
|
||||
}else if($len<8){
|
||||
return substr($text,0,2)."***".substr($text,-2,2);
|
||||
}else{
|
||||
return substr($text,0,4)."******".substr($text,-3,3);
|
||||
}
|
||||
}
|
||||
|
||||
public static function sanitize($str)
|
||||
{
|
||||
return preg_replace("/[^A-Za-z0-9]/", '_', $str);;
|
||||
}
|
||||
}
|
@ -8,15 +8,16 @@
|
||||
|
||||
class User
|
||||
{
|
||||
public static function getID(){
|
||||
public static function getID()
|
||||
{
|
||||
global $db_password;
|
||||
if(isset($_SESSION['uid']) && !empty($_SESSION['uid'])){
|
||||
if (isset($_SESSION['uid']) && !empty($_SESSION['uid'])) {
|
||||
return $_SESSION['uid'];
|
||||
}else if(isset($_COOKIE['uid'])){
|
||||
} else if (isset($_COOKIE['uid'])) {
|
||||
// id.time.sha1
|
||||
$tmp = explode('.',$_COOKIE['uid']);
|
||||
if(sha1($tmp[0].'.'.$tmp[1].'.'.$db_password)==$tmp[2]){
|
||||
if(time()-$tmp[1] < 86400*30){
|
||||
$tmp = explode('.', $_COOKIE['uid']);
|
||||
if (sha1($tmp[0] . '.' . $tmp[1] . '.' . $db_password) == $tmp[2]) {
|
||||
if (time() - $tmp[1] < 86400 * 30) {
|
||||
$_SESSION['uid'] = $tmp[0];
|
||||
return $tmp[0];
|
||||
}
|
||||
@ -25,35 +26,167 @@ class User
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function setCookie($uid){
|
||||
global $db_password;
|
||||
if(isset($uid)){
|
||||
$time = time();
|
||||
setcookie('uid', $uid.'.'.$time.'.'.sha1($uid.'.'.$time.'.'.$db_password), time()+86400*30);
|
||||
}
|
||||
}
|
||||
|
||||
public static function removeCookie(){
|
||||
if(isset($_COOKIE['uid'])){
|
||||
setcookie('uid', '', time()-86400);
|
||||
}
|
||||
}
|
||||
|
||||
public static function _info()
|
||||
public static function getBills($id = 0)
|
||||
{
|
||||
$id = User::getID();
|
||||
if (!$id) {
|
||||
$id = User::getID();
|
||||
if (!$id) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
$addcost = 0;
|
||||
$bills = [];
|
||||
$attrs = User::getAttributes('Bill', $id);
|
||||
foreach ($attrs as $k => $v) {
|
||||
// if has : then its an installment
|
||||
if (strpos($v, ":") === false) {
|
||||
// Not installment
|
||||
$bills[$k] = $v;
|
||||
$addcost += $v;
|
||||
} else {
|
||||
// installment
|
||||
list($cost, $rem) = explode(":", $v);
|
||||
// :0 installment is done
|
||||
if (!empty($rem)) {
|
||||
$bills[$k] = $cost;
|
||||
$addcost += $cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
return [$bills, $addcost];
|
||||
}
|
||||
|
||||
public static function billsPaid($bills, $id = 0)
|
||||
{
|
||||
if (!$id) {
|
||||
$id = User::getID();
|
||||
if (!$id) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
foreach ($bills as $k => $v) {
|
||||
// if has : then its an installment
|
||||
$v = User::getAttribute($k, $id);
|
||||
if (strpos($v, ":") === false) {
|
||||
// Not installment, no need decrement
|
||||
} else {
|
||||
// installment
|
||||
list($cost, $rem) = explode(":", $v);
|
||||
// :0 installment is done
|
||||
if ($rem != 0) {
|
||||
User::setAttribute($k, "$cost:" . ($rem - 1), $id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function setAttribute($name, $value, $id = 0)
|
||||
{
|
||||
if (!$id) {
|
||||
$id = User::getID();
|
||||
if (!$id) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
$f = ORM::for_table('tbl_customers_fields')->where('field_name', $name)->where('customer_id', $id)->find_one();
|
||||
if (!$f) {
|
||||
$f = ORM::for_table('tbl_customers_fields')->create();
|
||||
$f->customer_id = $id;
|
||||
$f->field_name = $name;
|
||||
$f->field_value = $value;
|
||||
$f->save();
|
||||
$result = $f->id();
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
$f->field_value = $value;
|
||||
$f->save();
|
||||
return $f['id'];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function getAttribute($name, $id = 0)
|
||||
{
|
||||
if (!$id) {
|
||||
$id = User::getID();
|
||||
if (!$id) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
$f = ORM::for_table('tbl_customers_fields')->where('field_name', $name)->where('customer_id', $id)->find_one();
|
||||
if ($f) {
|
||||
return $f['field_value'];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function getAttributes($endWith, $id = 0)
|
||||
{
|
||||
if (!$id) {
|
||||
$id = User::getID();
|
||||
if (!$id) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
$attrs = [];
|
||||
$f = ORM::for_table('tbl_customers_fields')->where_like('field_name', "%$endWith")->where('customer_id', $id)->find_many();
|
||||
if ($f) {
|
||||
foreach ($f as $k) {
|
||||
$attrs[$k['field_name']] = $k['field_value'];
|
||||
}
|
||||
return $attrs;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function setCookie($uid)
|
||||
{
|
||||
global $db_password;
|
||||
if (isset($uid)) {
|
||||
$time = time();
|
||||
setcookie('uid', $uid . '.' . $time . '.' . sha1($uid . '.' . $time . '.' . $db_password), time() + 86400 * 30);
|
||||
}
|
||||
}
|
||||
|
||||
public static function removeCookie()
|
||||
{
|
||||
if (isset($_COOKIE['uid'])) {
|
||||
setcookie('uid', '', time() - 86400);
|
||||
}
|
||||
}
|
||||
|
||||
public static function _info($id = 0)
|
||||
{
|
||||
if (!$id) {
|
||||
$id = User::getID();
|
||||
}
|
||||
$d = ORM::for_table('tbl_customers')->find_one($id);
|
||||
|
||||
if(empty($d['username'])){
|
||||
if (empty($d['username'])) {
|
||||
r2(U . 'logout', 'd', '');
|
||||
}
|
||||
return $d;
|
||||
}
|
||||
|
||||
public static function _billing()
|
||||
public static function _billing($id = 0)
|
||||
{
|
||||
$id = User::getID();
|
||||
$d = ORM::for_table('tbl_user_recharges')->where('customer_id', $id)->find_many();
|
||||
if (!$id) {
|
||||
$id = User::getID();
|
||||
}
|
||||
$d = ORM::for_table('tbl_user_recharges')
|
||||
->select('tbl_user_recharges.id', 'id')
|
||||
->selects([
|
||||
'customer_id', 'username', 'plan_id', 'namebp', 'recharged_on', 'recharged_time', 'expiration', 'time',
|
||||
'status', 'method', 'plan_type',
|
||||
['tbl_user_recharges.routers', 'routers'],
|
||||
['tbl_user_recharges.type', 'type'],
|
||||
'admin_id', 'prepaid'
|
||||
])
|
||||
->where('customer_id', $id)
|
||||
->join('tbl_plans', array('tbl_plans.id', '=', 'tbl_user_recharges.plan_id'))
|
||||
->find_many();
|
||||
return $d;
|
||||
}
|
||||
}
|
||||
|
40
system/autoload/mail/Exception.php
Normal file
40
system/autoload/mail/Exception.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHPMailer Exception class.
|
||||
* PHP Version 5.5.
|
||||
*
|
||||
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||
*
|
||||
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||
* @author Brent R. Matzelle (original founder)
|
||||
* @copyright 2012 - 2020 Marcus Bointon
|
||||
* @copyright 2010 - 2012 Jim Jagielski
|
||||
* @copyright 2004 - 2009 Andy Prevost
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
namespace PHPMailer\PHPMailer;
|
||||
|
||||
/**
|
||||
* PHPMailer exception handler.
|
||||
*
|
||||
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
|
||||
*/
|
||||
class Exception extends \Exception
|
||||
{
|
||||
/**
|
||||
* Prettify error message output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function errorMessage()
|
||||
{
|
||||
return '<strong>' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "</strong><br />\n";
|
||||
}
|
||||
}
|
5252
system/autoload/mail/PHPMailer.php
Normal file
5252
system/autoload/mail/PHPMailer.php
Normal file
File diff suppressed because it is too large
Load Diff
1497
system/autoload/mail/SMTP.php
Normal file
1497
system/autoload/mail/SMTP.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
||||
**/
|
||||
|
||||
if(Admin::getID()){
|
||||
r2(U.'dashboard');
|
||||
r2(U.'dashboard', "s", Lang::T("You are already logged in"));
|
||||
}
|
||||
|
||||
if (isset($routes['1'])) {
|
||||
@ -26,20 +26,27 @@ switch ($do) {
|
||||
$d_pass = $d['password'];
|
||||
if (Password::_verify($password, $d_pass) == true) {
|
||||
$_SESSION['aid'] = $d['id'];
|
||||
Admin::setCookie($d['id']);
|
||||
$token = Admin::setCookie($d['id']);
|
||||
$d->last_login = date('Y-m-d H:i:s');
|
||||
$d->save();
|
||||
_log($username . ' ' . Lang::T('Login Successful'), $d['user_type'], $d['id']);
|
||||
if ($isApi) {
|
||||
if ($token) {
|
||||
showResult(true, Lang::T('Login Successful'), ['token' => "a.".$token]);
|
||||
} else {
|
||||
showResult(false, Lang::T('Invalid Username or Password'));
|
||||
}
|
||||
}
|
||||
_alert(Lang::T('Login Successful'),'success', "dashboard");
|
||||
} else {
|
||||
_log($username . ' ' . Lang::T('Failed Login'), $d['user_type']);
|
||||
_alert(Lang::T('Invalid Username or Password'),'danger', "admin");
|
||||
_alert(Lang::T('Invalid Username or Password').".",'danger', "admin");
|
||||
}
|
||||
} else {
|
||||
_alert(Lang::T('Invalid Username or Password'),'danger', "admin");
|
||||
_alert(Lang::T('Invalid Username or Password')."..",'danger', "admin");
|
||||
}
|
||||
} else {
|
||||
_alert(Lang::T('Invalid Username or Password'),'danger', "admin");
|
||||
_alert(Lang::T('Invalid Username or Password')."...",'danger', "admin");
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -38,10 +38,18 @@ switch ($action) {
|
||||
case 'plan':
|
||||
$server = _post('server');
|
||||
$jenis = _post('jenis');
|
||||
if($server=='radius'){
|
||||
$d = ORM::for_table('tbl_plans')->where('is_radius', 1)->where('type', $jenis)->where('enabled', '1')->find_many();
|
||||
if(in_array($admin['user_type'], array('SuperAdmin', 'Admin'))){
|
||||
if($server=='radius'){
|
||||
$d = ORM::for_table('tbl_plans')->where('is_radius', 1)->where('type', $jenis)->find_many();
|
||||
}else{
|
||||
$d = ORM::for_table('tbl_plans')->where('routers', $server)->where('type', $jenis)->find_many();
|
||||
}
|
||||
}else{
|
||||
$d = ORM::for_table('tbl_plans')->where('routers', $server)->where('type', $jenis)->where('enabled', '1')->find_many();
|
||||
if($server=='radius'){
|
||||
$d = ORM::for_table('tbl_plans')->where('is_radius', 1)->where('type', $jenis)->where('enabled', '1')->find_many();
|
||||
}else{
|
||||
$d = ORM::for_table('tbl_plans')->where('routers', $server)->where('type', $jenis)->where('enabled', '1')->find_many();
|
||||
}
|
||||
}
|
||||
$ui->assign('d', $d);
|
||||
|
||||
@ -76,7 +84,6 @@ switch ($action) {
|
||||
}
|
||||
echo json_encode(['results' => $json]);
|
||||
die();
|
||||
break;
|
||||
default:
|
||||
$ui->display('a404.tpl');
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
* by https://t.me/ibnux
|
||||
@ -12,30 +13,29 @@ $action = $routes['1'];
|
||||
$ui->assign('_admin', $admin);
|
||||
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
r2(U."dashboard",'e',Lang::T('You do not have permission to access this page'));
|
||||
r2(U . "dashboard", 'e', Lang::T('You do not have permission to access this page'));
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'list':
|
||||
$ui->assign('xfooter', '<script type="text/javascript" src="ui/lib/c/bandwidth.js"></script>');
|
||||
$ui->assign('xfooter', '<script type="text/javascript" src="ui/lib/c/bandwidth.js"></script>');
|
||||
run_hook('view_list_bandwidth'); #HOOK
|
||||
$name = _post('name');
|
||||
if ($name != ''){
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_bandwidth'), ['name_bw' => '%' . $name . '%'], $name);
|
||||
$d = ORM::for_table('tbl_bandwidth')->where_like('name_bw','%'.$name.'%')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
}else{
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_bandwidth'));
|
||||
$d = ORM::for_table('tbl_bandwidth')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
}
|
||||
$name = _post('name');
|
||||
if ($name != '') {
|
||||
$query = ORM::for_table('tbl_bandwidth')->where_like('name_bw', '%' . $name . '%')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query, ['name' => $name]);
|
||||
} else {
|
||||
$query = ORM::for_table('tbl_bandwidth')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
}
|
||||
|
||||
$ui->assign('d',$d);
|
||||
$ui->assign('paginator',$paginator);
|
||||
$ui->assign('d', $d);
|
||||
$ui->display('bandwidth.tpl');
|
||||
break;
|
||||
|
||||
case 'add':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
run_hook('view_add_bandwidth'); #HOOK
|
||||
$ui->display('bandwidth-add.tpl');
|
||||
@ -43,28 +43,28 @@ switch ($action) {
|
||||
|
||||
case 'edit':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
$id = $routes['2'];
|
||||
run_hook('view_edit_bandwith'); #HOOK
|
||||
$d = ORM::for_table('tbl_bandwidth')->find_one($id);
|
||||
if($d){
|
||||
$ui->assign('burst',explode(" ", $d['burst']));
|
||||
$ui->assign('d',$d);
|
||||
if ($d) {
|
||||
$ui->assign('burst', explode(" ", $d['burst']));
|
||||
$ui->assign('d', $d);
|
||||
$ui->display('bandwidth-edit.tpl');
|
||||
}else{
|
||||
r2(U . 'bandwidth/list', 'e', $_L['Account_Not_Found']);
|
||||
} else {
|
||||
r2(U . 'bandwidth/list', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
$id = $routes['2'];
|
||||
run_hook('delete_bandwidth'); #HOOK
|
||||
$d = ORM::for_table('tbl_bandwidth')->find_one($id);
|
||||
if($d){
|
||||
if ($d) {
|
||||
$d->delete();
|
||||
r2(U . 'bandwidth/list', 's', Lang::T('Data Deleted Successfully'));
|
||||
}
|
||||
@ -72,40 +72,48 @@ switch ($action) {
|
||||
|
||||
case 'add-post':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
$name = _post('name');
|
||||
$rate_down = _post('rate_down');
|
||||
$rate_down_unit = _post('rate_down_unit');
|
||||
$rate_up = _post('rate_up');
|
||||
$rate_up_unit = _post('rate_up_unit');
|
||||
$rate_up = _post('rate_up');
|
||||
$rate_up_unit = _post('rate_up_unit');
|
||||
run_hook('add_bandwidth'); #HOOK
|
||||
$isBurst = true;
|
||||
$burst = "";
|
||||
if(isset($_POST['burst'])){
|
||||
foreach($_POST['burst'] as $b){
|
||||
if(empty($b)){
|
||||
if (isset($_POST['burst'])) {
|
||||
foreach ($_POST['burst'] as $b) {
|
||||
if (empty($b)) {
|
||||
$isBurst = false;
|
||||
}
|
||||
}
|
||||
if($isBurst){
|
||||
if ($isBurst) {
|
||||
$burst = implode(' ', $_POST['burst']);
|
||||
};
|
||||
}
|
||||
$msg = '';
|
||||
if(Validator::Length($name,16,4) == false){
|
||||
$msg .= 'Name should be between 5 to 15 characters'. '<br>';
|
||||
if (Validator::Length($name, 16, 4) == false) {
|
||||
$msg .= 'Name should be between 5 to 15 characters' . '<br>';
|
||||
}
|
||||
|
||||
if($rate_down_unit == 'Kbps'){ $unit_rate_down = $rate_down * 1024; }else{ $unit_rate_down = $rate_down * 1048576; }
|
||||
if($rate_up_unit == 'Kbps'){ $unit_rate_up = $min_up * 1024; }else{ $unit_rate_up = $min_up * 1048576; }
|
||||
|
||||
$d = ORM::for_table('tbl_bandwidth')->where('name_bw',$name)->find_one();
|
||||
if($d){
|
||||
$msg .= Lang::T('Name Bandwidth Already Exist'). '<br>';
|
||||
if ($rate_down_unit == 'Kbps') {
|
||||
$unit_rate_down = $rate_down * 1024;
|
||||
} else {
|
||||
$unit_rate_down = $rate_down * 1048576;
|
||||
}
|
||||
if ($rate_up_unit == 'Kbps') {
|
||||
$unit_rate_up = $min_up * 1024;
|
||||
} else {
|
||||
$unit_rate_up = $min_up * 1048576;
|
||||
}
|
||||
|
||||
if($msg == ''){
|
||||
$d = ORM::for_table('tbl_bandwidth')->where('name_bw', $name)->find_one();
|
||||
if ($d) {
|
||||
$msg .= Lang::T('Name Bandwidth Already Exist') . '<br>';
|
||||
}
|
||||
|
||||
if ($msg == '') {
|
||||
$d = ORM::for_table('tbl_bandwidth')->create();
|
||||
$d->name_bw = $name;
|
||||
$d->rate_down = $rate_down;
|
||||
@ -116,53 +124,53 @@ switch ($action) {
|
||||
$d->save();
|
||||
|
||||
r2(U . 'bandwidth/list', 's', Lang::T('Data Created Successfully'));
|
||||
}else{
|
||||
} else {
|
||||
r2(U . 'bandwidth/add', 'e', $msg);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'edit-post':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
$name = _post('name');
|
||||
$rate_down = _post('rate_down');
|
||||
$rate_down_unit = _post('rate_down_unit');
|
||||
$rate_up = _post('rate_up');
|
||||
$rate_up_unit = _post('rate_up_unit');
|
||||
run_hook('edit_bandwidth'); #HOOK
|
||||
$rate_up = _post('rate_up');
|
||||
$rate_up_unit = _post('rate_up_unit');
|
||||
run_hook('edit_bandwidth'); #HOOK
|
||||
$isBurst = true;
|
||||
$burst = "";
|
||||
if(isset($_POST['burst'])){
|
||||
foreach($_POST['burst'] as $b){
|
||||
if(empty($b)){
|
||||
if (isset($_POST['burst'])) {
|
||||
foreach ($_POST['burst'] as $b) {
|
||||
if (empty($b)) {
|
||||
$isBurst = false;
|
||||
}
|
||||
}
|
||||
if($isBurst){
|
||||
if ($isBurst) {
|
||||
$burst = implode(' ', $_POST['burst']);
|
||||
};
|
||||
}
|
||||
$msg = '';
|
||||
if(Validator::Length($name,16,4) == false){
|
||||
$msg .= 'Name should be between 5 to 15 characters'. '<br>';
|
||||
if (Validator::Length($name, 16, 4) == false) {
|
||||
$msg .= 'Name should be between 5 to 15 characters' . '<br>';
|
||||
}
|
||||
|
||||
$id = _post('id');
|
||||
$d = ORM::for_table('tbl_bandwidth')->find_one($id);
|
||||
if($d){
|
||||
}else{
|
||||
$msg .= Lang::T('Data Not Found'). '<br>';
|
||||
if ($d) {
|
||||
} else {
|
||||
$msg .= Lang::T('Data Not Found') . '<br>';
|
||||
}
|
||||
|
||||
if($d['name_bw'] != $name){
|
||||
$c = ORM::for_table('tbl_bandwidth')->where('name_bw',$name)->find_one();
|
||||
if($c){
|
||||
$msg .= Lang::T('Name Bandwidth Already Exist'). '<br>';
|
||||
if ($d['name_bw'] != $name) {
|
||||
$c = ORM::for_table('tbl_bandwidth')->where('name_bw', $name)->find_one();
|
||||
if ($c) {
|
||||
$msg .= Lang::T('Name Bandwidth Already Exist') . '<br>';
|
||||
}
|
||||
}
|
||||
|
||||
if($msg == ''){
|
||||
if ($msg == '') {
|
||||
$d->name_bw = $name;
|
||||
$d->rate_down = $rate_down;
|
||||
$d->rate_down_unit = $rate_down_unit;
|
||||
@ -172,11 +180,11 @@ switch ($action) {
|
||||
$d->save();
|
||||
|
||||
r2(U . 'bandwidth/list', 's', Lang::T('Data Updated Successfully'));
|
||||
}else{
|
||||
r2(U . 'bandwidth/edit/'.$id, 'e', $msg);
|
||||
} else {
|
||||
r2(U . 'bandwidth/edit/' . $id, 'e', $msg);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$ui->display('a404.tpl');
|
||||
}
|
||||
}
|
||||
|
@ -12,57 +12,32 @@ $ui->assign('_system_menu', 'customers');
|
||||
$action = $routes['1'];
|
||||
$ui->assign('_admin', $admin);
|
||||
|
||||
if(empty($action)){
|
||||
if (empty($action)) {
|
||||
$action = 'list';
|
||||
}
|
||||
|
||||
$leafletpickerHeader = <<<EOT
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css">
|
||||
EOT;
|
||||
|
||||
switch ($action) {
|
||||
case 'list':
|
||||
$search = _post('search');
|
||||
run_hook('list_customers'); #HOOK
|
||||
if ($search != '') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_customers'), [
|
||||
'username' => '%' . $search . '%',
|
||||
'fullname' => '%' . $search . '%',
|
||||
'phonenumber' => '%' . $search . '%',
|
||||
'email' => '%' . $search . '%',
|
||||
'service_type' => '%' . $search . '%'
|
||||
], $search);
|
||||
$d = ORM::for_table('tbl_customers')
|
||||
->where_raw("(`username` LIKE '%$search%' OR `fullname` LIKE '%$search%' OR `phonenumber` LIKE '%$search%' OR `email` LIKE '%$search%')")
|
||||
->offset($paginator['startpoint'])
|
||||
->limit($paginator['limit'])
|
||||
->order_by_asc('username')
|
||||
->find_many();
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_customers'));
|
||||
$d = ORM::for_table('tbl_customers')
|
||||
->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
}
|
||||
|
||||
$ui->assign('search', htmlspecialchars($search));
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('paginator', $paginator);
|
||||
$ui->display('customers.tpl');
|
||||
break;
|
||||
|
||||
case 'csv':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
|
||||
$cs = ORM::for_table('tbl_customers')
|
||||
->select('tbl_customers.id', 'id')
|
||||
->select('tbl_customers.username', 'username')
|
||||
->select('fullname')
|
||||
->select('address')
|
||||
->select('phonenumber')
|
||||
->select('email')
|
||||
->select('balance')
|
||||
->select('namebp')
|
||||
->select('routers')
|
||||
->select('status')
|
||||
->select('method', 'Payment')
|
||||
->join('tbl_user_recharges', array('tbl_customers.id', '=', 'tbl_user_recharges.customer_id'))
|
||||
->order_by_asc('tbl_customers.id')->find_array();
|
||||
->select('service_type')
|
||||
->order_by_asc('tbl_customers.id')
|
||||
->find_array();
|
||||
|
||||
$h = false;
|
||||
set_time_limit(-1);
|
||||
header('Pragma: public');
|
||||
@ -71,49 +46,166 @@ switch ($action) {
|
||||
header("Content-type: text/csv");
|
||||
header('Content-Disposition: attachment;filename="phpnuxbill_customers_' . date('Y-m-d_H_i') . '.csv"');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
$headers = [
|
||||
'id',
|
||||
'username',
|
||||
'fullname',
|
||||
'address',
|
||||
'phonenumber',
|
||||
'email',
|
||||
'balance',
|
||||
'service_type',
|
||||
];
|
||||
|
||||
if (!$h) {
|
||||
echo '"' . implode('","', $headers) . "\"\n";
|
||||
$h = true;
|
||||
}
|
||||
|
||||
foreach ($cs as $c) {
|
||||
$ks = [];
|
||||
$vs = [];
|
||||
foreach ($c as $k => $v) {
|
||||
$ks[] = $k;
|
||||
$vs[] = $v;
|
||||
}
|
||||
if (!$h) {
|
||||
echo '"' . implode('";"', $ks) . "\"\n";
|
||||
$h = true;
|
||||
}
|
||||
echo '"' . implode('";"', $vs) . "\"\n";
|
||||
$row = [
|
||||
$c['id'],
|
||||
$c['username'],
|
||||
$c['fullname'],
|
||||
$c['address'],
|
||||
$c['phonenumber'],
|
||||
$c['email'],
|
||||
$c['balance'],
|
||||
$c['service_type'],
|
||||
];
|
||||
echo '"' . implode('","', $row) . "\"\n";
|
||||
}
|
||||
break;
|
||||
//case csv-prepaid can be moved later to (plan.php) php file dealing with prepaid users
|
||||
case 'csv-prepaid':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
|
||||
$cs = ORM::for_table('tbl_customers')
|
||||
->select('tbl_customers.id', 'id')
|
||||
->select('tbl_customers.username', 'username')
|
||||
->select('fullname')
|
||||
->select('address')
|
||||
->select('phonenumber')
|
||||
->select('email')
|
||||
->select('balance')
|
||||
->select('service_type')
|
||||
->select('namebp')
|
||||
->select('routers')
|
||||
->select('status')
|
||||
->select('method', 'Payment')
|
||||
->join('tbl_user_recharges', array('tbl_customers.id', '=', 'tbl_user_recharges.customer_id'))
|
||||
->order_by_asc('tbl_customers.id')
|
||||
->find_array();
|
||||
|
||||
$h = false;
|
||||
set_time_limit(-1);
|
||||
header('Pragma: public');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header("Content-type: text/csv");
|
||||
header('Content-Disposition: attachment;filename="phpnuxbill_prepaid_users' . date('Y-m-d_H_i') . '.csv"');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
$headers = [
|
||||
'id',
|
||||
'username',
|
||||
'fullname',
|
||||
'address',
|
||||
'phonenumber',
|
||||
'email',
|
||||
'balance',
|
||||
'service_type',
|
||||
'namebp',
|
||||
'routers',
|
||||
'status',
|
||||
'Payment'
|
||||
];
|
||||
|
||||
if (!$h) {
|
||||
echo '"' . implode('","', $headers) . "\"\n";
|
||||
$h = true;
|
||||
}
|
||||
|
||||
foreach ($cs as $c) {
|
||||
$row = [
|
||||
$c['id'],
|
||||
$c['username'],
|
||||
$c['fullname'],
|
||||
$c['address'],
|
||||
$c['phonenumber'],
|
||||
$c['email'],
|
||||
$c['balance'],
|
||||
$c['service_type'],
|
||||
$c['namebp'],
|
||||
$c['routers'],
|
||||
$c['status'],
|
||||
$c['Payment']
|
||||
];
|
||||
echo '"' . implode('","', $row) . "\"\n";
|
||||
}
|
||||
break;
|
||||
case 'add':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
$ui->assign('xheader', $leafletpickerHeader);
|
||||
run_hook('view_add_customer'); #HOOK
|
||||
$ui->display('customers-add.tpl');
|
||||
break;
|
||||
case 'recharge':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
$id_customer = $routes['2'];
|
||||
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->find_one();
|
||||
$id_customer = $routes['2'];
|
||||
$plan_id = $routes['3'];
|
||||
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->where('plan_id', $plan_id)->find_one();
|
||||
if ($b) {
|
||||
if (Package::rechargeUser($id_customer, $b['routers'], $b['plan_id'], "Recharge", $admin['fullname'])) {
|
||||
r2(U . 'customers/view/' . $id_customer, 's', 'Success Recharge Customer');
|
||||
} else {
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Customer plan is inactive');
|
||||
$gateway = 'Recharge';
|
||||
$channel = $admin['fullname'];
|
||||
$cust = User::_info($id_customer);
|
||||
$plan = ORM::for_table('tbl_plans')->find_one($b['plan_id']);
|
||||
list($bills, $add_cost) = User::getBills($id_customer);
|
||||
if ($using == 'balance' && $config['enable_balance'] == 'yes') {
|
||||
if (!$cust) {
|
||||
r2(U . 'plan/recharge', 'e', Lang::T('Customer not found'));
|
||||
}
|
||||
if (!$plan) {
|
||||
r2(U . 'plan/recharge', 'e', Lang::T('Plan not found'));
|
||||
}
|
||||
if ($cust['balance'] < ($plan['price'] + $add_cost)) {
|
||||
r2(U . 'plan/recharge', 'e', Lang::T('insufficient balance'));
|
||||
}
|
||||
$gateway = 'Recharge Balance';
|
||||
}
|
||||
if ($using == 'zero') {
|
||||
$zero = 1;
|
||||
$gateway = 'Recharge Zero';
|
||||
}
|
||||
$ui->assign('bills', $bills);
|
||||
$ui->assign('add_cost', $add_cost);
|
||||
$ui->assign('cust', $cust);
|
||||
$ui->assign('gateway', $gateway);
|
||||
$ui->assign('channel', $channel);
|
||||
$ui->assign('server', $b['routers']);
|
||||
$ui->assign('using', 'cash');
|
||||
$ui->assign('plan', $plan);
|
||||
$ui->display('recharge-confirm.tpl');
|
||||
} else {
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Cannot find active plan');
|
||||
}
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Cannot find active plan');
|
||||
break;
|
||||
case 'deactivate':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
$id_customer = $routes['2'];
|
||||
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->find_one();
|
||||
$id_customer = $routes['2'];
|
||||
$plan_id = $routes['3'];
|
||||
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->where('plan_id', $plan_id)->find_one();
|
||||
if ($b) {
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $b['plan_id'])->where('enabled', '1')->find_one();
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $b['plan_id'])->find_one();
|
||||
if ($p) {
|
||||
if ($p['is_radius']) {
|
||||
Radius::customerDeactivate($b['username']);
|
||||
@ -140,35 +232,36 @@ switch ($action) {
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Cannot find active plan');
|
||||
break;
|
||||
case 'sync':
|
||||
$id_customer = $routes['2'];
|
||||
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->where('status', 'on')->find_one();
|
||||
if ($b) {
|
||||
$c = ORM::for_table('tbl_customers')->find_one($id_customer);
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $b['plan_id'])->where('enabled', '1')->find_one();
|
||||
if ($p) {
|
||||
if ($p['is_radius']) {
|
||||
Radius::customerAddPlan($c, $p, $p['expiration'] . ' ' . $p['time']);
|
||||
r2(U . 'customers/view/' . $id_customer, 's', 'Success sync customer to Radius');
|
||||
} else {
|
||||
$mikrotik = Mikrotik::info($b['routers']);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
if ($b['type'] == 'Hotspot') {
|
||||
Mikrotik::addHotspotUser($client, $p, $c);
|
||||
} else if ($b['type'] == 'PPPOE') {
|
||||
Mikrotik::addPpoeUser($client, $p, $c);
|
||||
$id_customer = $routes['2'];
|
||||
$bs = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->where('status', 'on')->findMany();
|
||||
if ($bs) {
|
||||
$routers = [];
|
||||
foreach ($bs as $b) {
|
||||
$c = ORM::for_table('tbl_customers')->find_one($id_customer);
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $b['plan_id'])->where('enabled', '1')->find_one();
|
||||
if ($p) {
|
||||
$routers[] = $b['routers'];
|
||||
if ($p['is_radius']) {
|
||||
Radius::customerAddPlan($c, $p, $p['expiration'] . ' ' . $p['time']);
|
||||
} else {
|
||||
$mikrotik = Mikrotik::info($b['routers']);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
if ($b['type'] == 'Hotspot') {
|
||||
Mikrotik::addHotspotUser($client, $p, $c);
|
||||
} else if ($b['type'] == 'PPPOE') {
|
||||
Mikrotik::addPpoeUser($client, $p, $c);
|
||||
}
|
||||
}
|
||||
r2(U . 'customers/view/' . $id_customer, 's', 'Success sync customer to Mikrotik');
|
||||
}
|
||||
} else {
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Customer plan is inactive');
|
||||
}
|
||||
r2(U . 'customers/view/' . $id_customer, 's', 'Sync success to ' . implode(", ", $routers));
|
||||
}
|
||||
r2(U . 'customers/view/' . $id_customer, 'e', 'Cannot find active plan');
|
||||
break;
|
||||
case 'viewu':
|
||||
$customer = ORM::for_table('tbl_customers')->where('username', $routes['2'])->find_one();
|
||||
case 'view':
|
||||
$id = $routes['2'];
|
||||
$id = $routes['2'];
|
||||
run_hook('view_customer'); #HOOK
|
||||
if (!$customer) {
|
||||
$customer = ORM::for_table('tbl_customers')->find_one($id);
|
||||
@ -180,45 +273,35 @@ switch ($action) {
|
||||
$customFields = ORM::for_table('tbl_customers_fields')
|
||||
->where('customer_id', $customer['id'])
|
||||
->find_many();
|
||||
|
||||
$v = $routes['3'];
|
||||
if (empty($v) || $v == 'order') {
|
||||
$v = $routes['3'];
|
||||
if (empty($v)) {
|
||||
$v = 'activation';
|
||||
}
|
||||
if ($v == 'order') {
|
||||
$v = 'order';
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_payment_gateway'), ['username' => $customer['username']]);
|
||||
$order = ORM::for_table('tbl_payment_gateway')
|
||||
->where('username', $customer['username'])
|
||||
->offset($paginator['startpoint'])
|
||||
->limit($paginator['limit'])
|
||||
->order_by_desc('id')
|
||||
->find_many();
|
||||
$ui->assign('paginator', $paginator);
|
||||
$query = ORM::for_table('tbl_transactions')->where('username', $customer['username'])->order_by_desc('id');
|
||||
$order = Paginator::findMany($query);
|
||||
$ui->assign('order', $order);
|
||||
} else if ($v == 'activation') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_transactions'), ['username' => $customer['username']]);
|
||||
$activation = ORM::for_table('tbl_transactions')
|
||||
->where('username', $customer['username'])
|
||||
->offset($paginator['startpoint'])
|
||||
->limit($paginator['limit'])
|
||||
->order_by_desc('id')
|
||||
->find_many();
|
||||
$ui->assign('paginator', $paginator);
|
||||
$query = ORM::for_table('tbl_transactions')->where('username', $customer['username'])->order_by_desc('id');
|
||||
$activation = Paginator::findMany($query);
|
||||
$ui->assign('activation', $activation);
|
||||
}
|
||||
$package = ORM::for_table('tbl_user_recharges')->where('username', $customer['username'])->find_one();
|
||||
$ui->assign('package', $package);
|
||||
$ui->assign('packages', User::_billing($customer['id']));
|
||||
$ui->assign('v', $v);
|
||||
$ui->assign('d', $customer);
|
||||
$ui->assign('customFields', $customFields);
|
||||
$ui->assign('xheader', $leafletpickerHeader);
|
||||
$ui->display('customers-view.tpl');
|
||||
} else {
|
||||
r2(U . 'customers/list', 'e', $_L['Account_Not_Found']);
|
||||
r2(U . 'customers/list', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
break;
|
||||
case 'edit':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
$id = $routes['2'];
|
||||
$id = $routes['2'];
|
||||
run_hook('edit_customer'); #HOOK
|
||||
$d = ORM::for_table('tbl_customers')->find_one($id);
|
||||
// Fetch the Customers Attributes values from the tbl_customers_fields table
|
||||
@ -228,17 +311,18 @@ switch ($action) {
|
||||
if ($d) {
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('customFields', $customFields);
|
||||
$ui->assign('xheader', $leafletpickerHeader);
|
||||
$ui->display('customers-edit.tpl');
|
||||
} else {
|
||||
r2(U . 'customers/list', 'e', $_L['Account_Not_Found']);
|
||||
r2(U . 'customers/list', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
$id = $routes['2'];
|
||||
$id = $routes['2'];
|
||||
run_hook('delete_customer'); #HOOK
|
||||
$d = ORM::for_table('tbl_customers')->find_one($id);
|
||||
if ($d) {
|
||||
@ -277,7 +361,8 @@ switch ($action) {
|
||||
} catch (Throwable $e) {
|
||||
}
|
||||
try {
|
||||
if($c) $c->delete();
|
||||
if ($c)
|
||||
$c->delete();
|
||||
} catch (Exception $e) {
|
||||
} catch (Throwable $e) {
|
||||
}
|
||||
@ -296,6 +381,8 @@ switch ($action) {
|
||||
$address = _post('address');
|
||||
$phonenumber = _post('phonenumber');
|
||||
$service_type = _post('service_type');
|
||||
$account_type = _post('account_type');
|
||||
$coordinates = _post('coordinates');
|
||||
//post Customers Attributes
|
||||
$custom_field_names = (array) $_POST['custom_field_name'];
|
||||
$custom_field_values = (array) $_POST['custom_field_value'];
|
||||
@ -323,11 +410,13 @@ switch ($action) {
|
||||
$d->password = $password;
|
||||
$d->pppoe_password = $pppoe_password;
|
||||
$d->email = $email;
|
||||
$d->account_type = $account_type;
|
||||
$d->fullname = $fullname;
|
||||
$d->address = $address;
|
||||
$d->created_by = $admin['id'];
|
||||
$d->phonenumber = Lang::phoneFormat($phonenumber);
|
||||
$d->service_type = $service_type;
|
||||
$d->coordinates = $coordinates;
|
||||
$d->save();
|
||||
|
||||
// Retrieve the customer ID of the newly created customer
|
||||
@ -357,12 +446,14 @@ switch ($action) {
|
||||
case 'edit-post':
|
||||
$username = Lang::phoneFormat(_post('username'));
|
||||
$fullname = _post('fullname');
|
||||
$account_type = _post('account_type');
|
||||
$password = _post('password');
|
||||
$pppoe_password = _post('pppoe_password');
|
||||
$email = _post('email');
|
||||
$address = _post('address');
|
||||
$phonenumber = Lang::phoneFormat(_post('phonenumber'));
|
||||
$service_type = _post('service_type');
|
||||
$coordinates = _post('coordinates');
|
||||
run_hook('edit_customer'); #HOOK
|
||||
$msg = '';
|
||||
if (Validator::Length($username, 35, 2) == false) {
|
||||
@ -390,8 +481,8 @@ switch ($action) {
|
||||
}
|
||||
|
||||
$oldusername = $d['username'];
|
||||
$oldPppoePassword = $d['password'];
|
||||
$oldPassPassword = $d['pppoe_password'];
|
||||
$oldPppoePassword = $d['password'];
|
||||
$oldPassPassword = $d['pppoe_password'];
|
||||
$userDiff = false;
|
||||
$pppoeDiff = false;
|
||||
$passDiff = false;
|
||||
@ -419,9 +510,11 @@ switch ($action) {
|
||||
$d->pppoe_password = $pppoe_password;
|
||||
$d->fullname = $fullname;
|
||||
$d->email = $email;
|
||||
$d->account_type = $account_type;
|
||||
$d->address = $address;
|
||||
$d->phonenumber = $phonenumber;
|
||||
$d->service_type = $service_type;
|
||||
$d->coordinates = $coordinates;
|
||||
$d->save();
|
||||
|
||||
|
||||
@ -465,6 +558,7 @@ switch ($action) {
|
||||
// Delete the Customers Attributes with the given field name
|
||||
ORM::for_table('tbl_customers_fields')
|
||||
->where('field_name', $fieldName)
|
||||
->where('customer_id', $id)
|
||||
->delete_many();
|
||||
}
|
||||
}
|
||||
@ -498,12 +592,28 @@ switch ($action) {
|
||||
}
|
||||
}
|
||||
}
|
||||
r2(U . 'customers/list', 's', 'User Updated Successfully');
|
||||
r2(U . 'customers/view/' . $id, 's', 'User Updated Successfully');
|
||||
} else {
|
||||
r2(U . 'customers/edit/' . $id, 'e', $msg);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
r2(U . 'customers/list', 'e', 'action not defined');
|
||||
run_hook('list_customers'); #HOOK
|
||||
$search = _post('search');
|
||||
if ($search != '') {
|
||||
$query = ORM::for_table('tbl_customers')
|
||||
->whereRaw("username LIKE '%$search%' OR fullname LIKE '%$search%' OR address LIKE '%$search%' ".
|
||||
"OR phonenumber LIKE '%$search%' OR email LIKE '%$search%' ")
|
||||
->order_by_asc('username');
|
||||
$d = $query->findMany();
|
||||
} else {
|
||||
$query = ORM::for_table('tbl_customers')->order_by_asc('username');
|
||||
}
|
||||
$d = $query->findMany();
|
||||
$ui->assign('xheader', '<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.3/css/jquery.dataTables.min.css">');
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('search', $search);
|
||||
$ui->display('customers.tpl');
|
||||
break;
|
||||
}
|
||||
|
@ -9,6 +9,17 @@ _admin();
|
||||
$ui->assign('_title', Lang::T('Dashboard'));
|
||||
$ui->assign('_admin', $admin);
|
||||
|
||||
if(isset($_GET['refresh'])){
|
||||
$files = scandir($CACHE_PATH);
|
||||
foreach ($files as $file) {
|
||||
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
||||
if (is_file($CACHE_PATH . DIRECTORY_SEPARATOR . $file) && $ext == 'temp') {
|
||||
unlink($CACHE_PATH . DIRECTORY_SEPARATOR . $file);
|
||||
}
|
||||
}
|
||||
r2(U . 'dashboard', 's', 'Data Refreshed');
|
||||
}
|
||||
|
||||
$fdate = date('Y-m-01');
|
||||
$tdate = date('Y-m-t');
|
||||
//first day of month
|
||||
@ -16,13 +27,18 @@ $first_day_month = date('Y-m-01');
|
||||
$mdate = date('Y-m-d');
|
||||
$month_n = date('n');
|
||||
|
||||
$iday = ORM::for_table('tbl_transactions')->where('recharged_on', $mdate)->sum('price');
|
||||
$iday = ORM::for_table('tbl_transactions')
|
||||
->where('recharged_on', $mdate)
|
||||
->where_not_equal('method', 'Customer - Balance')
|
||||
->where_not_equal('method', 'Recharge Balance - Administrator')
|
||||
->sum('price');
|
||||
|
||||
if ($iday == '') {
|
||||
$iday = '0.00';
|
||||
}
|
||||
$ui->assign('iday', $iday);
|
||||
|
||||
$imonth = ORM::for_table('tbl_transactions')->where_gte('recharged_on', $first_day_month)->where_lte('recharged_on', $mdate)->sum('price');
|
||||
$imonth = ORM::for_table('tbl_transactions')->where_not_equal('method', 'Customer - Balance')->where_not_equal('method', 'Recharge Balance - Administrator')->where_gte('recharged_on', $first_day_month)->where_lte('recharged_on', $mdate)->sum('price');
|
||||
if ($imonth == '') {
|
||||
$imonth = '0.00';
|
||||
}
|
||||
@ -49,13 +65,10 @@ $ui->assign('c_all', $c_all);
|
||||
|
||||
if ($config['hide_uet'] != 'yes') {
|
||||
//user expire
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_user_recharges'));
|
||||
$expire = ORM::for_table('tbl_user_recharges')
|
||||
$query = ORM::for_table('tbl_user_recharges')
|
||||
->where_lte('expiration', $mdate)
|
||||
->offset($paginator['startpoint'])
|
||||
->limit($paginator['limit'])
|
||||
->order_by_desc('expiration')
|
||||
->find_many();
|
||||
->order_by_desc('expiration');
|
||||
$expire = Paginator::findMany($query);
|
||||
|
||||
// Get the total count of expired records for pagination
|
||||
$totalCount = ORM::for_table('tbl_user_recharges')
|
||||
@ -66,7 +79,6 @@ if ($config['hide_uet'] != 'yes') {
|
||||
$paginator['total_count'] = $totalCount;
|
||||
|
||||
// Assign the pagination HTML to the template variable
|
||||
$ui->assign('paginator', $paginator);
|
||||
$ui->assign('expire', $expire);
|
||||
}
|
||||
|
||||
@ -144,6 +156,8 @@ if (file_exists($cacheMSfile) && time() - filemtime($cacheMSfile) < 43200) {
|
||||
->select_expr('MONTH(recharged_on)', 'month')
|
||||
->select_expr('SUM(price)', 'total')
|
||||
->where_raw("YEAR(recharged_on) = YEAR(CURRENT_DATE())") // Filter by the current year
|
||||
->where_not_equal('method', 'Customer - Balance')
|
||||
->where_not_equal('method', 'Recharge Balance - Administrator')
|
||||
->group_by_expr('MONTH(recharged_on)')
|
||||
->find_many();
|
||||
|
||||
|
@ -170,7 +170,7 @@ $style
|
||||
$html
|
||||
EOF;
|
||||
$mpdf->WriteHTML($nhtml);
|
||||
$mpdf->Output(date('Y-m-d') . Package::_raid(4) . '.pdf', 'D');
|
||||
$mpdf->Output(date('Ymd_His') . '.pdf', 'D');
|
||||
} else {
|
||||
echo 'No Data';
|
||||
}
|
||||
@ -344,7 +344,7 @@ $style
|
||||
$html
|
||||
EOF;
|
||||
$mpdf->WriteHTML($nhtml);
|
||||
$mpdf->Output(date('Y-m-d') . Package::_raid(4) . '.pdf', 'D');
|
||||
$mpdf->Output(date('Ymd_His') . '.pdf', 'D');
|
||||
} else {
|
||||
echo 'No Data';
|
||||
}
|
||||
|
@ -77,37 +77,111 @@ if (_post('send') == 'balance') {
|
||||
r2(U . 'home', 'd', Lang::T('Failed, balance is not available'));
|
||||
}
|
||||
} else if (_post('send') == 'plan') {
|
||||
$active = ORM::for_table('tbl_user_recharges')
|
||||
$actives = ORM::for_table('tbl_user_recharges')
|
||||
->where('username', _post('username'))
|
||||
->find_one();
|
||||
$router = ORM::for_table('tbl_routers')->where('name', $active['routers'])->find_one();
|
||||
if ($router) {
|
||||
r2(U . "order/send/$router[id]/$active[plan_id]&u=" . trim(_post('username')), 's', Lang::T('Review package before recharge'));
|
||||
} else {
|
||||
r2(U . 'home', 'w', Lang::T('Your friend do not have active package'));
|
||||
->find_many();
|
||||
foreach ($actives as $active) {
|
||||
$router = ORM::for_table('tbl_routers')->where('name', $active['routers'])->find_one();
|
||||
if ($router) {
|
||||
r2(U . "order/send/$router[id]/$active[plan_id]&u=" . trim(_post('username')), 's', Lang::T('Review package before recharge'));
|
||||
}
|
||||
}
|
||||
r2(U . 'home', 'w', Lang::T('Your friend do not have active package'));
|
||||
}
|
||||
|
||||
$ui->assign('_bills', User::_billing());
|
||||
|
||||
if (isset($_GET['recharge']) && !empty($_GET['recharge'])) {
|
||||
if (!empty(App::getTokenValue(_get('stoken')))) {
|
||||
r2(U . "voucher/invoice/");
|
||||
die();
|
||||
}
|
||||
$bill = ORM::for_table('tbl_user_recharges')->where('id', $_GET['recharge'])->where('username', $user['username'])->findOne();
|
||||
if ($bill) {
|
||||
$router = ORM::for_table('tbl_routers')->where('name', $bill['routers'])->find_one();
|
||||
if ($bill['routers'] == 'radius') {
|
||||
$router = 'radius';
|
||||
} else {
|
||||
$routers = ORM::for_table('tbl_routers')->where('name', $bill['routers'])->find_one();
|
||||
$router = $routers['id'];
|
||||
}
|
||||
if ($config['enable_balance'] == 'yes') {
|
||||
$plan = ORM::for_table('tbl_plans')->find_one($bill['plan_id']);
|
||||
if(!$plan['enabled']){
|
||||
if (!$plan['enabled']) {
|
||||
r2(U . "home", 'e', 'Plan is not exists');
|
||||
}
|
||||
if ($user['balance'] > $plan['price']) {
|
||||
r2(U . "order/pay/$router[id]/$bill[plan_id]", 'e', 'Order Plan');
|
||||
r2(U . "order/pay/$router/$bill[plan_id]&stoken=" . _get('stoken'), 'e', 'Order Plan');
|
||||
} else {
|
||||
r2(U . "order/buy/$router[id]/$bill[plan_id]", 'e', 'Order Plan');
|
||||
r2(U . "order/buy/$router/$bill[plan_id]", 'e', 'Order Plan');
|
||||
}
|
||||
} else {
|
||||
r2(U . "order/buy/$router[id]/$bill[plan_id]", 'e', 'Order Plan');
|
||||
r2(U . "order/buy/$router/$bill[plan_id]", 'e', 'Order Plan');
|
||||
}
|
||||
}
|
||||
} else if (!empty(_get('extend'))) {
|
||||
if(!$config['extend_expired']){
|
||||
r2(U . 'home', 'e', "cannot extend");
|
||||
}
|
||||
if (!empty(App::getTokenValue(_get('stoken')))) {
|
||||
r2(U . 'home', 'e', "You already extend");
|
||||
}
|
||||
$id = _get('extend');
|
||||
$tur = ORM::for_table('tbl_user_recharges')->where('customer_id', $user['id'])->where('id', $id)->find_one();
|
||||
if ($tur) {
|
||||
$m = date("m");
|
||||
$path = $CACHE_PATH . DIRECTORY_SEPARATOR . "extends" . DIRECTORY_SEPARATOR;
|
||||
if(!file_exists($path)){
|
||||
mkdir($path);
|
||||
}
|
||||
$path .= $user['id'] . ".txt";
|
||||
if (file_exists($path)) {
|
||||
// is already extend
|
||||
$last = file_get_contents($path);
|
||||
if ($last == $m) {
|
||||
r2(U . 'home', 'e', "You already extend for this month");
|
||||
}
|
||||
}
|
||||
if ($tur['status'] != 'on') {
|
||||
if ($tur['routers'] != 'radius') {
|
||||
$mikrotik = Mikrotik::info($tur['routers']);
|
||||
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
|
||||
$router = $tur['routers'];
|
||||
}
|
||||
$p = ORM::for_table('tbl_plans')->findOne($tur['plan_id']);
|
||||
if(!$p){
|
||||
r2(U . 'home', '3', "Plan Not Found");
|
||||
}
|
||||
if ($tur['routers'] == 'radius') {
|
||||
Radius::customerAddPlan($user, $p, $tur['expiration'] . ' ' . $tur['time']);
|
||||
} else {
|
||||
if ($tur['type'] == 'Hotspot') {
|
||||
Mikrotik::removeHotspotUser($client, $user['username']);
|
||||
Mikrotik::addHotspotUser($client, $p, $user);
|
||||
} else if ($tur['type'] == 'PPPOE') {
|
||||
Mikrotik::removePpoeUser($client, $user['username']);
|
||||
Mikrotik::addPpoeUser($client, $p, $user);
|
||||
}
|
||||
}
|
||||
// make customer cannot extend again
|
||||
$days = $config['extend_days'];
|
||||
$expiration = date('Y-m-d', strtotime(" +$days day"));
|
||||
$tur->expiration = $expiration;
|
||||
$tur->status = "on";
|
||||
$tur->save();
|
||||
App::setToken(_get('stoken'), $id);
|
||||
file_put_contents($path, $m);
|
||||
_log("Customer $tur[customer_id] $tur[username] extend for $days days", "Customer", $user['id']);
|
||||
Message::sendTelegram("#u$user[username] #extend #".$p['type']." \n" . $p['name_plan'] .
|
||||
"\nLocation: " . $p['routers'] .
|
||||
"\nCustomer: " . $user['fullname'] .
|
||||
"\nNew Expired: " . Lang::dateAndTimeFormat($expiration, $tur['time']));
|
||||
r2(U . 'home', 's', "Extend until $expiration");
|
||||
}else{
|
||||
r2(U . 'home', 'e', "Plan is not expired");
|
||||
}
|
||||
} else {
|
||||
r2(U . 'home', 'e', "Plan Not Found or Not Active");
|
||||
}
|
||||
} else if (isset($_GET['deactivate']) && !empty($_GET['deactivate'])) {
|
||||
$bill = ORM::for_table('tbl_user_recharges')->where('id', $_GET['deactivate'])->where('username', $user['username'])->findOne();
|
||||
if ($bill) {
|
||||
@ -133,7 +207,7 @@ if (isset($_GET['recharge']) && !empty($_GET['recharge'])) {
|
||||
$bill->expiration = date('Y-m-d');
|
||||
$bill->time = date('H:i:s');
|
||||
$bill->save();
|
||||
_log('User ' . $bill['username'] . ' Deactivate ' . $bill['namebp'], 'User', $bill['customer_id']);
|
||||
_log('User ' . $bill['username'] . ' Deactivate ' . $bill['namebp'], 'Customer', $bill['customer_id']);
|
||||
Message::sendTelegram('User u' . $bill['username'] . ' Deactivate ' . $bill['namebp']);
|
||||
r2(U . 'home', 's', 'Success deactivate ' . $bill['namebp']);
|
||||
} else {
|
||||
|
@ -13,11 +13,73 @@ $action = $routes['1'];
|
||||
$ui->assign('_admin', $admin);
|
||||
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
|
||||
|
||||
switch ($action) {
|
||||
case 'list-csv':
|
||||
$logs = ORM::for_table('tbl_logs')
|
||||
->select('id')
|
||||
->select('date')
|
||||
->select('type')
|
||||
->select('description')
|
||||
->select('userid')
|
||||
->select('ip')
|
||||
->order_by_asc('id')->find_array();
|
||||
$h = false;
|
||||
set_time_limit(-1);
|
||||
header('Pragma: public');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header("Content-type: text/csv");
|
||||
header('Content-Disposition: attachment;filename="activity-logs_' . date('Y-m-d_H_i') . '.csv"');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
foreach ($logs as $log) {
|
||||
$ks = [];
|
||||
$vs = [];
|
||||
foreach ($log as $k => $v) {
|
||||
$ks[] = $k;
|
||||
$vs[] = $v;
|
||||
}
|
||||
if (!$h) {
|
||||
echo '"' . implode('";"', $ks) . "\"\n";
|
||||
$h = true;
|
||||
}
|
||||
echo '"' . implode('";"', $vs) . "\"\n";
|
||||
}
|
||||
break;
|
||||
case 'radius-csv':
|
||||
$logs = ORM::for_table('radpostauth')
|
||||
->select('id')
|
||||
->select('username')
|
||||
->select('pass')
|
||||
->select('reply')
|
||||
->select('authdate')
|
||||
->order_by_asc('id')->find_array();
|
||||
$h = false;
|
||||
set_time_limit(-1);
|
||||
header('Pragma: public');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header("Content-type: text/csv");
|
||||
header('Content-Disposition: attachment;filename="radius-logs_' . date('Y-m-d_H_i') . '.csv"');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
foreach ($logs as $log) {
|
||||
$ks = [];
|
||||
$vs = [];
|
||||
foreach ($log as $k => $v) {
|
||||
$ks[] = $k;
|
||||
$vs[] = $v;
|
||||
}
|
||||
if (!$h) {
|
||||
echo '"' . implode('";"', $ks) . "\"\n";
|
||||
$h = true;
|
||||
}
|
||||
echo '"' . implode('";"', $vs) . "\"\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'list':
|
||||
$q = (_post('q') ? _post('q') : _get('q'));
|
||||
$keep = _post('keep');
|
||||
@ -26,16 +88,15 @@ switch ($action) {
|
||||
r2(U . "logs/list/", 's', "Delete logs older than $keep days");
|
||||
}
|
||||
if ($q != '') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_logs'), ['description' => '%' . $q . '%'], $q);
|
||||
$d = ORM::for_table('tbl_logs')->where_like('description', '%' . $q . '%')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('tbl_logs')->where_like('description', '%' . $q . '%')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query, ['q' => $q]);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_logs'));
|
||||
$d = ORM::for_table('tbl_logs')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('tbl_logs')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
}
|
||||
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('q', $q);
|
||||
$ui->assign('paginator', $paginator);
|
||||
$ui->display('logs.tpl');
|
||||
break;
|
||||
case 'radius':
|
||||
@ -46,16 +107,15 @@ switch ($action) {
|
||||
r2(U . "logs/radius/", 's', "Delete logs older than $keep days");
|
||||
}
|
||||
if ($q != '') {
|
||||
$paginator = Paginator::build(ORM::for_table('radpostauth', 'radius'), ['username' => '%' . $q . '%'], $q);
|
||||
$d = ORM::for_table('radpostauth', 'radius')->where_like('username', '%' . $q . '%')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('radpostauth', 'radius')->where_like('username', '%' . $q . '%')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query, ['q' => $q]);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('radpostauth', 'radius'));
|
||||
$d = ORM::for_table('radpostauth', 'radius')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('radpostauth', 'radius')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
}
|
||||
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('q', $q);
|
||||
$ui->assign('paginator', $paginator);
|
||||
$ui->display('logs-radius.tpl');
|
||||
break;
|
||||
|
||||
|
54
system/controllers/map.php
Normal file
54
system/controllers/map.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
* by https://t.me/ibnux
|
||||
**/
|
||||
|
||||
_admin();
|
||||
$ui->assign('_system_menu', 'map');
|
||||
|
||||
$action = $routes['1'];
|
||||
$ui->assign('_admin', $admin);
|
||||
|
||||
if (empty($action)) {
|
||||
$action = 'customer';
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'customer':
|
||||
if(!empty(_req('search'))){
|
||||
$search = _req('search');
|
||||
$query = ORM::for_table('tbl_customers')->whereRaw("coordinates != '' AND fullname LIKE '%$search%' OR username LIKE '%$search%' OR email LIKE '%$search%' OR phonenumber LIKE '%$search%'")->order_by_desc('fullname');
|
||||
$c = Paginator::findMany($query, ['search' => $search], 50);
|
||||
}else{
|
||||
$query = ORM::for_table('tbl_customers')->where_not_equal('coordinates','');
|
||||
$c = Paginator::findMany($query, ['search'=>''], 50);
|
||||
}
|
||||
$customerData = [];
|
||||
|
||||
foreach ($c as $customer) {
|
||||
if (!empty($customer->coordinates)) {
|
||||
$customerData[] = [
|
||||
'id' => $customer->id,
|
||||
'name' => $customer->fullname,
|
||||
'balance' => $customer->balance,
|
||||
'address' => $customer->address,
|
||||
'direction' => $customer->coordinates,
|
||||
'info' => Lang::T("Username") . ": " . $customer->username . " - " . Lang::T("Full Name") . ": " . $customer->fullname . " - " . Lang::T("Email") . ": " . $customer->email . " - " . Lang::T("Phone") . ": " . $customer->phonenumber . " - " . Lang::T("Service Type") . ": " . $customer->service_type,
|
||||
'coordinates' => '[' . $customer->coordinates . ']',
|
||||
];
|
||||
}
|
||||
}
|
||||
$ui->assign('search', $search);
|
||||
$ui->assign('customers', $customerData);
|
||||
$ui->assign('xheader', '<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css">');
|
||||
$ui->assign('_title', Lang::T('Customer Geo Location Information'));
|
||||
$ui->assign('xfooter', '<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>');
|
||||
$ui->display('customers-map.tpl');
|
||||
break;
|
||||
|
||||
default:
|
||||
r2(U . 'map/customer', 'e', 'action not defined');
|
||||
break;
|
||||
}
|
238
system/controllers/message.php
Normal file
238
system/controllers/message.php
Normal file
@ -0,0 +1,238 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
* by https://t.me/ibnux
|
||||
**/
|
||||
|
||||
_admin();
|
||||
$ui->assign('_title', Lang::T('Send Message'));
|
||||
$ui->assign('_system_menu', 'message');
|
||||
|
||||
$action = $routes['1'];
|
||||
$ui->assign('_admin', $admin);
|
||||
|
||||
if (empty($action)) {
|
||||
$action = 'send';
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'send':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
|
||||
$select2_customer = <<<EOT
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
$('#personSelect').select2({
|
||||
theme: "bootstrap",
|
||||
ajax: {
|
||||
url: function(params) {
|
||||
if(params.term != undefined){
|
||||
return './index.php?_route=autoload/customer_select2&s='+params.term;
|
||||
}else{
|
||||
return './index.php?_route=autoload/customer_select2';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
EOT;
|
||||
if (isset($routes['2']) && !empty($routes['2'])) {
|
||||
$ui->assign('cust', ORM::for_table('tbl_customers')->find_one($routes['2']));
|
||||
}
|
||||
$id = $routes['2'];
|
||||
$ui->assign('id', $id);
|
||||
$ui->assign('xfooter', $select2_customer);
|
||||
$ui->display('message.tpl');
|
||||
break;
|
||||
|
||||
case 'send-post':
|
||||
// Check user permissions
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
|
||||
// Get form data
|
||||
$id_customer = $_POST['id_customer'];
|
||||
$message = $_POST['message'];
|
||||
$via = $_POST['via'];
|
||||
|
||||
// Check if fields are empty
|
||||
if ($id_customer == '' or $message == '' or $via == '') {
|
||||
r2(U . 'message/send', 'e', Lang::T('All field is required'));
|
||||
} else {
|
||||
// Get customer details from the database
|
||||
$c = ORM::for_table('tbl_customers')->find_one($id_customer);
|
||||
|
||||
// Replace placeholders in the message with actual values
|
||||
$message = str_replace('[[name]]', $c['fullname'], $message);
|
||||
$message = str_replace('[[user_name]]', $c['username'], $message);
|
||||
$message = str_replace('[[phone]]', $c['phonenumber'], $message);
|
||||
$message = str_replace('[[company_name]]', $config['CompanyName'], $message);
|
||||
|
||||
|
||||
//Send the message
|
||||
if ($via == 'sms' || $via == 'both') {
|
||||
$smsSent = Message::sendSMS($c['phonenumber'], $message);
|
||||
}
|
||||
|
||||
if ($via == 'wa' || $via == 'both') {
|
||||
$waSent = Message::sendWhatsapp($c['phonenumber'], $message);
|
||||
}
|
||||
|
||||
if (isset($smsSent) || isset($waSent)) {
|
||||
r2(U . 'message/send', 's', Lang::T('Message Sent Successfully'));
|
||||
} else {
|
||||
r2(U . 'message/send', 'e', Lang::T('Failed to send message'));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'send_bulk':
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
|
||||
// Get form data
|
||||
$group = $_POST['group'];
|
||||
$message = $_POST['message'];
|
||||
$via = $_POST['via'];
|
||||
$test = isset($_POST['test']) && $_POST['test'] === 'on' ? 'yes' : 'no';
|
||||
$batch = $_POST['batch'];
|
||||
$delay = $_POST['delay'];
|
||||
|
||||
// Initialize counters
|
||||
$totalSMSSent = 0;
|
||||
$totalSMSFailed = 0;
|
||||
$totalWhatsappSent = 0;
|
||||
$totalWhatsappFailed = 0;
|
||||
$batchStatus = [];
|
||||
|
||||
if (_req('send') == 'now') {
|
||||
// Check if fields are empty
|
||||
if ($group == '' || $message == '' || $via == '') {
|
||||
r2(U . 'message/send_bulk', 'e', Lang::T('All fields are required'));
|
||||
} else {
|
||||
// Get customer details from the database based on the selected group
|
||||
if ($group == 'all') {
|
||||
$customers = ORM::for_table('tbl_customers')->find_many()->as_array();
|
||||
} elseif ($group == 'new') {
|
||||
// Get customers created just a month ago
|
||||
$customers = ORM::for_table('tbl_customers')->where_raw("DATE(created_at) >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)")->find_many()->as_array();
|
||||
} elseif ($group == 'expired') {
|
||||
// Get expired user recharges where status is 'off'
|
||||
$expired = ORM::for_table('tbl_user_recharges')->where('status', 'off')->find_many();
|
||||
$customer_ids = [];
|
||||
foreach ($expired as $recharge) {
|
||||
$customer_ids[] = $recharge->customer_id;
|
||||
}
|
||||
$customers = ORM::for_table('tbl_customers')->where_in('id', $customer_ids)->find_many()->as_array();
|
||||
} elseif ($group == 'active') {
|
||||
// Get active user recharges where status is 'on'
|
||||
$active = ORM::for_table('tbl_user_recharges')->where('status', 'on')->find_many();
|
||||
$customer_ids = [];
|
||||
foreach ($active as $recharge) {
|
||||
$customer_ids[] = $recharge->customer_id;
|
||||
}
|
||||
$customers = ORM::for_table('tbl_customers')->where_in('id', $customer_ids)->find_many()->as_array();
|
||||
}
|
||||
|
||||
// Set the batch size
|
||||
$batchSize = $batch;
|
||||
|
||||
// Calculate the number of batches
|
||||
$totalCustomers = count($customers);
|
||||
$totalBatches = ceil($totalCustomers / $batchSize);
|
||||
|
||||
// Loop through batches
|
||||
for ($batchIndex = 0; $batchIndex < $totalBatches; $batchIndex++) {
|
||||
// Get the starting and ending index for the current batch
|
||||
$start = $batchIndex * $batchSize;
|
||||
$end = min(($batchIndex + 1) * $batchSize, $totalCustomers);
|
||||
$batchCustomers = array_slice($customers, $start, $end - $start);
|
||||
|
||||
// Loop through customers in the current batch and send messages
|
||||
foreach ($batchCustomers as $customer) {
|
||||
// Create a copy of the original message for each customer and save it as currentMessage
|
||||
$currentMessage = $message;
|
||||
$currentMessage = str_replace('[[name]]', $customer['fullname'], $currentMessage);
|
||||
$currentMessage = str_replace('[[user_name]]', $customer['username'], $currentMessage);
|
||||
$currentMessage = str_replace('[[phone]]', $customer['phonenumber'], $currentMessage);
|
||||
$currentMessage = str_replace('[[company_name]]', $config['CompanyName'], $currentMessage);
|
||||
|
||||
// Send the message based on the selected method
|
||||
if ($test === 'yes') {
|
||||
// Only for testing, do not send messages to customers
|
||||
$batchStatus[] = [
|
||||
'name' => $customer['fullname'],
|
||||
'phone' => $customer['phonenumber'],
|
||||
'message' => $currentMessage,
|
||||
'status' => 'Test Mode - Message not sent'
|
||||
];
|
||||
} else {
|
||||
// Send the actual messages
|
||||
if ($via == 'sms' || $via == 'both') {
|
||||
$smsSent = Message::sendSMS($customer['phonenumber'], $currentMessage);
|
||||
if ($smsSent) {
|
||||
$totalSMSSent++;
|
||||
$batchStatus[] = [
|
||||
'name' => $customer['fullname'],
|
||||
'phone' => $customer['phonenumber'],
|
||||
'message' => $currentMessage,
|
||||
'status' => 'SMS Message Sent'
|
||||
];
|
||||
} else {
|
||||
$totalSMSFailed++;
|
||||
$batchStatus[] = [
|
||||
'name' => $customer['fullname'],
|
||||
'phone' => $customer['phonenumber'],
|
||||
'message' => $currentMessage,
|
||||
'status' => 'SMS Message Failed'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ($via == 'wa' || $via == 'both') {
|
||||
$waSent = Message::sendWhatsapp($customer['phonenumber'], $currentMessage);
|
||||
if ($waSent) {
|
||||
$totalWhatsappSent++;
|
||||
$batchStatus[] = [
|
||||
'name' => $customer['fullname'],
|
||||
'phone' => $customer['phonenumber'],
|
||||
'message' => $currentMessage,
|
||||
'status' => 'WhatsApp Message Sent'
|
||||
];
|
||||
} else {
|
||||
$totalWhatsappFailed++;
|
||||
$batchStatus[] = [
|
||||
'name' => $customer['fullname'],
|
||||
'phone' => $customer['phonenumber'],
|
||||
'message' => $currentMessage,
|
||||
'status' => 'WhatsApp Message Failed'
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Introduce a delay between each batch
|
||||
if ($batchIndex < $totalBatches - 1) {
|
||||
sleep($delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$ui->assign('batchStatus', $batchStatus);
|
||||
$ui->assign('totalSMSSent', $totalSMSSent);
|
||||
$ui->assign('totalSMSFailed', $totalSMSFailed);
|
||||
$ui->assign('totalWhatsappSent', $totalWhatsappSent);
|
||||
$ui->assign('totalWhatsappFailed', $totalWhatsappFailed);
|
||||
$ui->display('message-bulk.tpl');
|
||||
break;
|
||||
|
||||
default:
|
||||
r2(U . 'message/send_sms', 'e', 'action not defined');
|
||||
}
|
@ -19,13 +19,8 @@ switch ($action) {
|
||||
break;
|
||||
case 'history':
|
||||
$ui->assign('_system_menu', 'history');
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_payment_gateway'), ['username' => $user['username']]);
|
||||
$d = ORM::for_table('tbl_payment_gateway')
|
||||
->where('username', $user['username'])
|
||||
->order_by_desc('id')
|
||||
->offset($paginator['startpoint'])->limit($paginator['limit'])
|
||||
->find_many();
|
||||
$ui->assign('paginator', $paginator);
|
||||
$query = ORM::for_table('tbl_payment_gateway')->where('username', $user['username'])->order_by_desc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('_title', Lang::T('Order History'));
|
||||
run_hook('customer_view_order_history'); #HOOK
|
||||
@ -37,7 +32,7 @@ switch ($action) {
|
||||
}
|
||||
$ui->assign('_title', 'Top Up');
|
||||
$ui->assign('_system_menu', 'balance');
|
||||
$plans_balance = ORM::for_table('tbl_plans')->where('enabled', '1')->where('type', 'Balance')->where('allow_purchase', 'yes')->find_many();
|
||||
$plans_balance = ORM::for_table('tbl_plans')->where('enabled', '1')->where('type', 'Balance')->where('prepaid', 'yes')->find_many();
|
||||
$ui->assign('plans_balance', $plans_balance);
|
||||
$ui->display('user-orderBalance.tpl');
|
||||
break;
|
||||
@ -47,26 +42,30 @@ switch ($action) {
|
||||
}
|
||||
$ui->assign('_title', 'Order Plan');
|
||||
$ui->assign('_system_menu', 'package');
|
||||
$account_type = $user['account_type'];
|
||||
if (empty($account_type)) {
|
||||
$account_type = 'Personal';
|
||||
}
|
||||
if (!empty($_SESSION['nux-router'])) {
|
||||
if ($_SESSION['nux-router'] == 'radius') {
|
||||
$radius_pppoe = ORM::for_table('tbl_plans')->where('enabled', '1')->where('is_radius', 1)->where('type', 'PPPOE')->where('allow_purchase', 'yes')->find_many();
|
||||
$radius_hotspot = ORM::for_table('tbl_plans')->where('enabled', '1')->where('is_radius', 1)->where('type', 'Hotspot')->where('allow_purchase', 'yes')->find_many();
|
||||
$radius_pppoe = ORM::for_table('tbl_plans')->where('plan_type', $account_type)->where('enabled', '1')->where('is_radius', 1)->where('type', 'PPPOE')->where('prepaid', 'yes')->find_many();
|
||||
$radius_hotspot = ORM::for_table('tbl_plans')->where('plan_type', $account_type)->where('enabled', '1')->where('is_radius', 1)->where('type', 'Hotspot')->where('prepaid', 'yes')->find_many();
|
||||
} else {
|
||||
$routers = ORM::for_table('tbl_routers')->where('id', $_SESSION['nux-router'])->find_many();
|
||||
$rs = [];
|
||||
foreach ($routers as $r) {
|
||||
$rs[] = $r['name'];
|
||||
}
|
||||
$plans_pppoe = ORM::for_table('tbl_plans')->where('enabled', '1')->where_in('routers', $rs)->where('is_radius', 0)->where('type', 'PPPOE')->where('allow_purchase', 'yes')->find_many();
|
||||
$plans_hotspot = ORM::for_table('tbl_plans')->where('enabled', '1')->where_in('routers', $rs)->where('is_radius', 0)->where('type', 'Hotspot')->where('allow_purchase', 'yes')->find_many();
|
||||
$plans_pppoe = ORM::for_table('tbl_plans')->where('plan_type', $account_type)->where('enabled', '1')->where_in('routers', $rs)->where('is_radius', 0)->where('type', 'PPPOE')->where('prepaid', 'yes')->find_many();
|
||||
$plans_hotspot = ORM::for_table('tbl_plans')->where('plan_type', $account_type)->where('enabled', '1')->where_in('routers', $rs)->where('is_radius', 0)->where('type', 'Hotspot')->where('prepaid', 'yes')->find_many();
|
||||
}
|
||||
} else {
|
||||
$radius_pppoe = ORM::for_table('tbl_plans')->where('enabled', '1')->where('is_radius', 1)->where('type', 'PPPOE')->where('allow_purchase', 'yes')->find_many();
|
||||
$radius_hotspot = ORM::for_table('tbl_plans')->where('enabled', '1')->where('is_radius', 1)->where('type', 'Hotspot')->where('allow_purchase', 'yes')->find_many();
|
||||
$radius_pppoe = ORM::for_table('tbl_plans')->where('plan_type', $account_type)->where('enabled', '1')->where('is_radius', 1)->where('type', 'PPPOE')->where('prepaid', 'yes')->find_many();
|
||||
$radius_hotspot = ORM::for_table('tbl_plans')->where('plan_type', $account_type)->where('enabled', '1')->where('is_radius', 1)->where('type', 'Hotspot')->where('prepaid', 'yes')->find_many();
|
||||
|
||||
$routers = ORM::for_table('tbl_routers')->find_many();
|
||||
$plans_pppoe = ORM::for_table('tbl_plans')->where('enabled', '1')->where('is_radius', 0)->where('type', 'PPPOE')->where('allow_purchase', 'yes')->find_many();
|
||||
$plans_hotspot = ORM::for_table('tbl_plans')->where('enabled', '1')->where('is_radius', 0)->where('type', 'Hotspot')->where('allow_purchase', 'yes')->find_many();
|
||||
$plans_pppoe = ORM::for_table('tbl_plans')->where('plan_type', $account_type)->where('enabled', '1')->where('is_radius', 0)->where('type', 'PPPOE')->where('prepaid', 'yes')->find_many();
|
||||
$plans_hotspot = ORM::for_table('tbl_plans')->where('plan_type', $account_type)->where('enabled', '1')->where('is_radius', 0)->where('type', 'Hotspot')->where('prepaid', 'yes')->find_many();
|
||||
}
|
||||
$ui->assign('routers', $routers);
|
||||
$ui->assign('radius_pppoe', $radius_pppoe);
|
||||
@ -103,8 +102,8 @@ switch ($action) {
|
||||
if (empty($trx)) {
|
||||
r2(U . "order/package", 'w', Lang::T("Payment not found"));
|
||||
}
|
||||
// jika url kosong, balikin ke buy
|
||||
if (empty($trx['pg_url_payment'])) {
|
||||
// jika url kosong, balikin ke buy, kecuali cancel
|
||||
if (empty($trx['pg_url_payment']) && $routes['3'] != 'cancel') {
|
||||
r2(U . "order/buy/" . (($trx['routers_id'] == 0) ? $trx['routers'] : $trx['routers_id']) . '/' . $trx['plan_id'], 'w', Lang::T("Checking payment"));
|
||||
}
|
||||
if ($routes['3'] == 'check') {
|
||||
@ -114,7 +113,7 @@ switch ($action) {
|
||||
run_hook('customer_check_payment_status'); #HOOK
|
||||
include $PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR . $trx['gateway'] . '.php';
|
||||
call_user_func($trx['gateway'] . '_validate_config');
|
||||
call_user_func($config['payment_gateway'] . '_get_status', $trx, $user);
|
||||
call_user_func($trx['gateway'] . '_get_status', $trx, $user);
|
||||
} else if ($routes['3'] == 'cancel') {
|
||||
run_hook('customer_cancel_payment'); #HOOK
|
||||
$trx->pg_paid_response = '{}';
|
||||
@ -124,16 +123,16 @@ switch ($action) {
|
||||
$trx = ORM::for_table('tbl_payment_gateway')
|
||||
->where('username', $user['username'])
|
||||
->find_one($trxid);
|
||||
if ('midtrans' == $trx['gateway']) {
|
||||
//Hapus invoice link
|
||||
}
|
||||
}
|
||||
if (empty($trx)) {
|
||||
r2(U . "order/package", 'e', Lang::T("Transaction Not found"));
|
||||
}
|
||||
$router = ORM::for_table('tbl_routers')->find_one($trx['routers_id']);
|
||||
|
||||
$router = Mikrotik::info($trx['routers']);
|
||||
$plan = ORM::for_table('tbl_plans')->find_one($trx['plan_id']);
|
||||
$bandw = ORM::for_table('tbl_bandwidth')->find_one($plan['id_bw']);
|
||||
$invoice = ORM::for_table('tbl_transactions')->where("invoice",$trx['trx_invoice'])->find_one();
|
||||
$ui->assign('invoice', $invoice);
|
||||
$ui->assign('trx', $trx);
|
||||
$ui->assign('router', $router);
|
||||
$ui->assign('plan', $plan);
|
||||
@ -145,6 +144,10 @@ switch ($action) {
|
||||
if ($config['enable_balance'] != 'yes') {
|
||||
r2(U . "order/package", 'e', Lang::T("Balance not enabled"));
|
||||
}
|
||||
if (!empty(App::getTokenValue($_GET['stoken']))) {
|
||||
r2(U . "voucher/invoice/");
|
||||
die();
|
||||
}
|
||||
$plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3']);
|
||||
if (empty($plan)) {
|
||||
r2(U . "order/package", 'e', Lang::T("Plan Not found"));
|
||||
@ -152,19 +155,18 @@ switch ($action) {
|
||||
if (!$plan['enabled']) {
|
||||
r2(U . "home", 'e', 'Plan is not exists');
|
||||
}
|
||||
if ($plan['allow_purchase'] != 'yes') {
|
||||
r2(U . "home", 'e', 'Cannot recharge this plan');
|
||||
}
|
||||
if ($routes['2'] == 'radius') {
|
||||
$router_name = 'radius';
|
||||
} else {
|
||||
$router_name = $plan['routers'];
|
||||
}
|
||||
list($bills, $add_cost) = User::getBills($id_customer);
|
||||
if ($plan && $plan['enabled'] && $user['balance'] >= $plan['price']) {
|
||||
if (Package::rechargeUser($user['id'], $router_name, $plan['id'], 'Customer', 'Balance')) {
|
||||
// if success, then get the balance
|
||||
Balance::min($user['id'], $plan['price']);
|
||||
r2(U . "home", 's', Lang::T("Success to buy package"));
|
||||
Balance::min($user['id'], $plan['price'] + $add_cost);
|
||||
App::setToken($_GET['stoken'], "success");
|
||||
r2(U . "voucher/invoice/", 's', Lang::T("Success to buy package"));
|
||||
} else {
|
||||
r2(U . "order/package", 'e', Lang::T("Failed to buy package"));
|
||||
Message::sendTelegram("Buy Package with Balance Failed\n\n#u$c[username] #buy \n" . $plan['name_plan'] .
|
||||
@ -188,9 +190,6 @@ switch ($action) {
|
||||
if (!$plan['enabled']) {
|
||||
r2(U . "home", 'e', 'Plan is not exists');
|
||||
}
|
||||
if ($plan['allow_purchase'] != 'yes') {
|
||||
r2(U . "home", 'e', 'Cannot recharge this plan');
|
||||
}
|
||||
if ($routes['2'] == 'radius') {
|
||||
$router_name = 'radius';
|
||||
} else {
|
||||
@ -198,6 +197,12 @@ switch ($action) {
|
||||
}
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'plan') {
|
||||
$target = ORM::for_table('tbl_customers')->where('username', _post('username'))->find_one();
|
||||
list($bills, $add_cost) = User::getBills($target['id']);
|
||||
if (!empty($add_cost)) {
|
||||
$ui->assign('bills', $bills);
|
||||
$ui->assign('add_cost', $add_cost);
|
||||
$plan['price'] += $add_cost;
|
||||
}
|
||||
if (!$target) {
|
||||
r2(U . 'home', 'd', Lang::T('Username not found'));
|
||||
}
|
||||
@ -215,7 +220,8 @@ switch ($action) {
|
||||
if ($active && $active['plan_id'] != $plan['id']) {
|
||||
r2(U . "order/package", 'e', Lang::T("Target has active plan, different with current plant.") . " [ <b>$active[namebp]</b> ]");
|
||||
}
|
||||
if (Package::rechargeUser($target['id'], $router_name, $plan['id'], $user['fullname'], 'Balance')) {
|
||||
$result = Package::rechargeUser($target['id'], $router_name, $plan['id'], $user['username'], 'Balance');
|
||||
if (!empty($result)) {
|
||||
// if success, then get the balance
|
||||
Balance::min($user['id'], $plan['price']);
|
||||
//sender
|
||||
@ -233,6 +239,7 @@ switch ($action) {
|
||||
$d->paid_date = date('Y-m-d H:i:s');
|
||||
$d->expired_date = date('Y-m-d H:i:s');
|
||||
$d->pg_url_payment = 'balance';
|
||||
$d->trx_invoice = $result;
|
||||
$d->status = 2;
|
||||
$d->save();
|
||||
$trx_id = $d->id();
|
||||
@ -251,6 +258,7 @@ switch ($action) {
|
||||
$d->paid_date = date('Y-m-d H:i:s');
|
||||
$d->expired_date = date('Y-m-d H:i:s');
|
||||
$d->pg_url_payment = 'balance';
|
||||
$d->trx_invoice = $result;
|
||||
$d->status = 2;
|
||||
$d->save();
|
||||
r2(U . "order/view/$trx_id", 's', Lang::T("Success to send package"));
|
||||
@ -266,19 +274,49 @@ switch ($action) {
|
||||
$ui->assign('plan', $plan);
|
||||
$ui->display('user-sendPlan.tpl');
|
||||
break;
|
||||
case 'buy':
|
||||
case 'gateway':
|
||||
$ui->assign('_title', Lang::T('Select Payment Gateway'));
|
||||
$ui->assign('_system_menu', 'package');
|
||||
if (strpos($user['email'], '@') === false) {
|
||||
r2(U . 'accounts/profile', 'e', Lang::T("Please enter your email address"));
|
||||
}
|
||||
if ($config['payment_gateway'] == 'none') {
|
||||
r2(U . 'home', 'e', Lang::T("No Payment Gateway Available"));
|
||||
$pgs = array_values(explode(',', $config['payment_gateway']));
|
||||
if (count($pgs) == 0) {
|
||||
sendTelegram("Payment Gateway not set, please set it in Settings");
|
||||
_log(Lang::T("Payment Gateway not set, please set it in Settings"));
|
||||
r2(U . "home", 'e', Lang::T("Failed to create Transaction.."));
|
||||
}
|
||||
if (!file_exists($PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR . $config['payment_gateway'] . '.php')) {
|
||||
r2(U . 'home', 'e', Lang::T("No Payment Gateway Available"));
|
||||
if (count($pgs) > 1) {
|
||||
$ui->assign('pgs', $pgs);
|
||||
//$ui->assign('pgs', $pgs);
|
||||
$ui->assign('route2', $routes[2]);
|
||||
$ui->assign('route3', $routes[3]);
|
||||
|
||||
//$ui->assign('plan', $plan);
|
||||
$ui->display('user-selectGateway.tpl');
|
||||
break;
|
||||
} else {
|
||||
if (empty($pgs[0])) {
|
||||
sendTelegram("Payment Gateway not set, please set it in Settings");
|
||||
_log(Lang::T("Payment Gateway not set, please set it in Settings"));
|
||||
r2(U . "home", 'e', Lang::T("Failed to create Transaction.."));
|
||||
} else {
|
||||
$_POST['gateway'] = $pgs[0];
|
||||
}
|
||||
}
|
||||
case 'buy':
|
||||
$gateway = _post('gateway');
|
||||
if (empty($gateway) && !empty($_SESSION['gateway'])) {
|
||||
$gateway = $_SESSION['gateway'];
|
||||
} else if (!empty($gateway)) {
|
||||
$_SESSION['gateway'] = $gateway;
|
||||
}
|
||||
if (empty($gateway)) {
|
||||
r2(U . 'order/gateway/' . $routes[2] . '/' . $routes[3], 'w', Lang::T("Please select Payment Gateway"));
|
||||
}
|
||||
run_hook('customer_buy_plan'); #HOOK
|
||||
include $PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR . $config['payment_gateway'] . '.php';
|
||||
call_user_func($config['payment_gateway'] . '_validate_config');
|
||||
include $PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR . $gateway . '.php';
|
||||
call_user_func($gateway . '_validate_config');
|
||||
|
||||
if ($routes['2'] == 'radius') {
|
||||
$router['id'] = 0;
|
||||
@ -289,7 +327,7 @@ switch ($action) {
|
||||
$router['id'] = 0;
|
||||
$router['name'] = 'balance';
|
||||
}
|
||||
$plan = ORM::for_table('tbl_plans')->where('enabled', '1')->where('allow_purchase', 'yes')->find_one($routes['3']);
|
||||
$plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3']);
|
||||
if (empty($router) || empty($plan)) {
|
||||
r2(U . "order/package", 'e', Lang::T("Plan Not found"));
|
||||
}
|
||||
@ -301,7 +339,7 @@ switch ($action) {
|
||||
if ($d['pg_url_payment']) {
|
||||
r2(U . "order/view/" . $d['id'], 'w', Lang::T("You already have unpaid transaction, cancel it or pay it."));
|
||||
} else {
|
||||
if ($config['payment_gateway'] == $d['gateway']) {
|
||||
if ($gateway == $d['gateway']) {
|
||||
$id = $d['id'];
|
||||
} else {
|
||||
$d->status = 4;
|
||||
@ -309,27 +347,53 @@ switch ($action) {
|
||||
}
|
||||
}
|
||||
}
|
||||
$add_cost = 0;
|
||||
if ($router['name'] != 'balance') {
|
||||
list($bills, $add_cost) = User::getBills($id_customer);
|
||||
}
|
||||
if (empty($id)) {
|
||||
$d = ORM::for_table('tbl_payment_gateway')->create();
|
||||
$d->username = $user['username'];
|
||||
$d->gateway = $config['payment_gateway'];
|
||||
$d->gateway = $gateway;
|
||||
$d->plan_id = $plan['id'];
|
||||
$d->plan_name = $plan['name_plan'];
|
||||
$d->routers_id = $router['id'];
|
||||
$d->routers = $router['name'];
|
||||
$d->price = $plan['price'];
|
||||
if ($plan['validity_unit'] == 'Period') {
|
||||
// Postpaid price from field
|
||||
$add_inv = User::getAttribute("Invoice", $id_customer);
|
||||
if (empty($add_inv) or $add_inv == 0) {
|
||||
$d->price = ($plan['price'] + $add_cost);
|
||||
} else {
|
||||
$d->price = ($add_inv + $add_cost);
|
||||
}
|
||||
} else {
|
||||
$d->price = ($plan['price'] + $add_cost);
|
||||
}
|
||||
//$d->price = ($plan['price'] + $add_cost);
|
||||
$d->created_date = date('Y-m-d H:i:s');
|
||||
$d->status = 1;
|
||||
$d->save();
|
||||
$id = $d->id();
|
||||
} else {
|
||||
$d->username = $user['username'];
|
||||
$d->gateway = $config['payment_gateway'];
|
||||
$d->gateway = $gateway;
|
||||
$d->plan_id = $plan['id'];
|
||||
$d->plan_name = $plan['name_plan'];
|
||||
$d->routers_id = $router['id'];
|
||||
$d->routers = $router['name'];
|
||||
$d->price = $plan['price'];
|
||||
if ($plan['validity_unit'] == 'Period') {
|
||||
// Postpaid price from field
|
||||
$add_inv = User::getAttribute("Invoice", $id_customer);
|
||||
if (empty($add_inv) or $add_inv == 0) {
|
||||
$d->price = ($plan['price'] + $add_cost);
|
||||
} else {
|
||||
$d->price = ($add_inv + $add_cost);
|
||||
}
|
||||
} else {
|
||||
$d->price = ($plan['price'] + $add_cost);
|
||||
}
|
||||
//$d->price = ($plan['price'] + $add_cost);
|
||||
$d->created_date = date('Y-m-d H:i:s');
|
||||
$d->status = 1;
|
||||
$d->save();
|
||||
@ -337,7 +401,7 @@ switch ($action) {
|
||||
if (!$id) {
|
||||
r2(U . "order/package/" . $d['id'], 'e', Lang::T("Failed to create Transaction.."));
|
||||
} else {
|
||||
call_user_func($config['payment_gateway'] . '_create_transaction', $d, $user);
|
||||
call_user_func($gateway . '_create_transaction', $d, $user);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -8,9 +8,35 @@
|
||||
_admin();
|
||||
$ui->assign('_system_menu', 'paymentgateway');
|
||||
|
||||
$action = alphanumeric($routes['1']);
|
||||
$action = alphanumeric($routes[1]);
|
||||
$ui->assign('_admin', $admin);
|
||||
|
||||
if ($action == 'delete') {
|
||||
$pg = alphanumeric($routes[2]);
|
||||
if (file_exists($PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR . $pg . '.php')) {
|
||||
deleteFile($PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR, $pg);
|
||||
}
|
||||
r2(U . 'paymentgateway', 's', Lang::T('Payment Gateway Deleted'));
|
||||
}
|
||||
|
||||
if (_post('save') == 'actives') {
|
||||
$pgs = '';
|
||||
if(is_array($_POST['pgs'])){
|
||||
$pgs = implode(',', $_POST['pgs']);
|
||||
}
|
||||
$d = ORM::for_table('tbl_appconfig')->where('setting', 'payment_gateway')->find_one();
|
||||
if ($d) {
|
||||
$d->value = $pgs;
|
||||
$d->save();
|
||||
} else {
|
||||
$d = ORM::for_table('tbl_appconfig')->create();
|
||||
$d->setting = 'payment_gateway';
|
||||
$d->value = $pgs;
|
||||
$d->save();
|
||||
}
|
||||
r2(U . 'paymentgateway', 's', Lang::T('Payment Gateway saved successfully'));
|
||||
}
|
||||
|
||||
if (file_exists($PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR . $action . '.php')) {
|
||||
include $PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR . $action . '.php';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
@ -36,22 +62,22 @@ if (file_exists($PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR . $action . '.php'))
|
||||
$pgs[] = str_replace('.php', '', $file);
|
||||
}
|
||||
}
|
||||
if (isset($_POST['payment_gateway'])) {
|
||||
$payment_gateway = _post('payment_gateway');
|
||||
$d = ORM::for_table('tbl_appconfig')->where('setting', 'payment_gateway')->find_one();
|
||||
if ($d) {
|
||||
$d->value = $payment_gateway;
|
||||
$d->save();
|
||||
} else {
|
||||
$d = ORM::for_table('tbl_appconfig')->create();
|
||||
$d->setting = 'payment_gateway';
|
||||
$d->value = $payment_gateway;
|
||||
$d->save();
|
||||
}
|
||||
r2(U . 'paymentgateway', 's', Lang::T('Payment Gateway saved successfully'));
|
||||
}
|
||||
$ui->assign('_title', 'Payment Gateway Settings');
|
||||
$ui->assign('pgs', $pgs);
|
||||
$ui->assign('actives', explode(',', $config['payment_gateway']));
|
||||
$ui->display('paymentgateway.tpl');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function deleteFile($path, $name)
|
||||
{
|
||||
$files = scandir($path);
|
||||
foreach ($files as $file) {
|
||||
if (is_file($path . $file) && strpos($file, $name) !== false) {
|
||||
unlink($path . $file);
|
||||
} else if (is_dir($path . $file) && !in_array($file, ['.', '..'])) {
|
||||
deleteFile($path . $file . DIRECTORY_SEPARATOR, $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,9 +32,55 @@ if (file_exists($cache) && time() - filemtime($cache) < (24 * 60 * 60)) {
|
||||
file_put_contents($cache, $data);
|
||||
$json = json_decode($data, true);
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'delete':
|
||||
if (!is_writeable($CACHE_PATH)) {
|
||||
r2(U . "pluginmanager", 'e', 'Folder cache/ is not writable');
|
||||
}
|
||||
if (!is_writeable($PLUGIN_PATH)) {
|
||||
r2(U . "pluginmanager", 'e', 'Folder plugin/ is not writable');
|
||||
}
|
||||
set_time_limit(-1);
|
||||
$tipe = $routes['2'];
|
||||
$plugin = $routes['3'];
|
||||
$file = $CACHE_PATH . DIRECTORY_SEPARATOR . $plugin . '.zip';
|
||||
if (file_exists($file)) unlink($file);
|
||||
if ($tipe == 'plugin') {
|
||||
foreach ($json['plugins'] as $plg) {
|
||||
if ($plg['id'] == $plugin) {
|
||||
$fp = fopen($file, 'w+');
|
||||
$ch = curl_init($plg['github'] . '/archive/refs/heads/master.zip');
|
||||
curl_setopt($ch, CURLOPT_POST, 0);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($file);
|
||||
$zip->extractTo($CACHE_PATH);
|
||||
$zip->close();
|
||||
$folder = $CACHE_PATH . File::pathFixer('/' . $plugin . '-main/');
|
||||
if (!file_exists($folder)) {
|
||||
$folder = $CACHE_PATH . File::pathFixer('/' . $plugin . '-master/');
|
||||
}
|
||||
if (!file_exists($folder)) {
|
||||
r2(U . "pluginmanager", 'e', 'Extracted Folder is unknown');
|
||||
}
|
||||
scanAndRemovePath($folder, $PLUGIN_PATH . DIRECTORY_SEPARATOR);
|
||||
File::deleteFolder($folder);
|
||||
unlink($file);
|
||||
r2(U . "pluginmanager", 's', 'Plugin ' . $plugin . ' has been deleted');
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'install':
|
||||
if (!is_writeable($CACHE_PATH)) {
|
||||
r2(U . "pluginmanager", 'e', 'Folder cache/ is not writable');
|
||||
@ -45,7 +91,7 @@ switch ($action) {
|
||||
set_time_limit(-1);
|
||||
$tipe = $routes['2'];
|
||||
$plugin = $routes['3'];
|
||||
$file = $CACHE_PATH . File::pathFixer('/') . $plugin . '.zip';
|
||||
$file = $CACHE_PATH . DIRECTORY_SEPARATOR . $plugin . '.zip';
|
||||
if (file_exists($file)) unlink($file);
|
||||
if ($tipe == 'plugin') {
|
||||
foreach ($json['plugins'] as $plg) {
|
||||
@ -127,3 +173,24 @@ switch ($action) {
|
||||
$ui->assign('pgs', $json['payment_gateway']);
|
||||
$ui->display('plugin-manager.tpl');
|
||||
}
|
||||
|
||||
|
||||
function scanAndRemovePath($source, $target)
|
||||
{
|
||||
$files = scandir($source);
|
||||
foreach ($files as $file) {
|
||||
if (is_file($source . $file)) {
|
||||
if(file_exists($target.$file)){
|
||||
unlink($target . $file);
|
||||
}
|
||||
} else if (is_dir($source . $file) && !in_array($file, ['.', '..'])) {
|
||||
scanAndRemovePath($source. $file. DIRECTORY_SEPARATOR, $target. $file. DIRECTORY_SEPARATOR);
|
||||
if(file_exists($target.$file)){
|
||||
rmdir($target . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(file_exists($target)){
|
||||
rmdir($target);
|
||||
}
|
||||
}
|
@ -23,15 +23,14 @@ switch ($action) {
|
||||
|
||||
$name = _post('name');
|
||||
if ($name != '') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_pool'), ['pool_name' => '%' . $name . '%'], $name);
|
||||
$d = ORM::for_table('tbl_pool')->where_like('pool_name', '%' . $name . '%')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('tbl_pool')->where_like('pool_name', '%' . $name . '%')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query, ['name' => $name]);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_pool'));
|
||||
$d = ORM::for_table('tbl_pool')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('tbl_pool')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
}
|
||||
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('paginator', $paginator);
|
||||
run_hook('view_pool'); #HOOK
|
||||
$ui->display('pool.tpl');
|
||||
break;
|
||||
@ -51,7 +50,7 @@ switch ($action) {
|
||||
run_hook('view_edit_pool'); #HOOK
|
||||
$ui->display('pool-edit.tpl');
|
||||
} else {
|
||||
r2(U . 'pool/list', 'e', $_L['Account_Not_Found']);
|
||||
r2(U . 'pool/list', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
|
||||
* by https://t.me/ibnux
|
||||
**/
|
||||
_admin();
|
||||
$ui->assign('_title', $_L['Plugin Manager']);
|
||||
$ui->assign('_title', Lang::T('Plugin Manager'));
|
||||
$ui->assign('_system_menu', 'settings');
|
||||
|
||||
$action = $routes['1'];
|
||||
@ -12,7 +13,7 @@ $ui->assign('_admin', $admin);
|
||||
|
||||
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
@ -79,7 +80,7 @@ switch ($action) {
|
||||
$ui->assign('d', $d);
|
||||
$ui->display('radius-nas-edit.tpl');
|
||||
} else {
|
||||
r2(U . 'radius/list', 'e', $_L['Account_Not_Found']);
|
||||
r2(U . 'radius/list', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -134,22 +135,15 @@ switch ($action) {
|
||||
$ui->assign('_title', "Network Access Server");
|
||||
$name = _post('name');
|
||||
if (empty($name)) {
|
||||
$paginator = Paginator::build(ORM::for_table('nas', 'radius'));
|
||||
$nas = ORM::for_table('nas', 'radius')->offset($paginator['startpoint'])->limit($paginator['limit'])->find_many();
|
||||
$query = ORM::for_table('nas', 'radius');
|
||||
$nas = Paginator::findMany($query);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('nas', 'radius'), [
|
||||
'nasname' => '%'.$search.'%',
|
||||
'shortname' => '%'.$search.'%',
|
||||
'description' => '%'.$search.'%'
|
||||
]);
|
||||
$nas = ORM::for_table('nas', 'radius')
|
||||
->where_like('nasname', $search)
|
||||
->where_like('shortname', $search)
|
||||
->where_like('description', $search)
|
||||
->offset($paginator['startpoint'])->limit($paginator['limit'])
|
||||
->find_many();
|
||||
$query = ORM::for_table('nas', 'radius')
|
||||
->where_like('nasname', $search)
|
||||
->where_like('shortname', $search)
|
||||
->where_like('description', $search);
|
||||
$nas = Paginator::findMany($query, ['name' => $name]);
|
||||
}
|
||||
$ui->assign('paginator', $paginator);
|
||||
$ui->assign('name', $name);
|
||||
$ui->assign('nas', $nas);
|
||||
$ui->display('radius-nas.tpl');
|
||||
|
@ -30,28 +30,26 @@ switch ($action) {
|
||||
r2(U . "logs/list/", 's', "Delete logs older than $keep days");
|
||||
}
|
||||
if ($q != '') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_transactions'), ['invoice' => '%' . $q . '%'], $q);
|
||||
$d = ORM::for_table('tbl_transactions')->where_like('invoice', '%' . $q . '%')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('tbl_transactions')->where_like('invoice', '%' . $q . '%')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query, ['q' => $q]);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_transactions'));
|
||||
$d = ORM::for_table('tbl_transactions')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('tbl_transactions')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
}
|
||||
|
||||
$ui->assign('activation', $d);
|
||||
$ui->assign('q', $q);
|
||||
$ui->assign('paginator', $paginator);
|
||||
$ui->display('reports-activation.tpl');
|
||||
break;
|
||||
case 'daily-report':
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_transactions'), ['recharged_on' => $mdate]);
|
||||
$d = ORM::for_table('tbl_transactions')->where('recharged_on', $mdate)->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$dr = ORM::for_table('tbl_transactions')->where('recharged_on', $mdate)->sum('price');
|
||||
$query = ORM::for_table('tbl_transactions')->where('recharged_on', $mdate)->order_by_desc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
$dr = $query->sum('price');
|
||||
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('dr', $dr);
|
||||
$ui->assign('mdate', $mdate);
|
||||
$ui->assign('mtime', $mtime);
|
||||
$ui->assign('paginator', $paginator);
|
||||
run_hook('view_daily_reports'); #HOOK
|
||||
$ui->display('reports-daily.tpl');
|
||||
break;
|
||||
|
@ -17,7 +17,7 @@ use PEAR2\Net\RouterOS;
|
||||
require_once 'system/autoload/PEAR2/Autoload.php';
|
||||
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
@ -26,15 +26,14 @@ switch ($action) {
|
||||
|
||||
$name = _post('name');
|
||||
if ($name != '') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_routers'), ['name' => '%' . $name . '%'], $name);
|
||||
$d = ORM::for_table('tbl_routers')->where_like('name', '%' . $name . '%')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('tbl_routers')->where_like('name', '%' . $name . '%')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query, ['name' => $name]);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_routers'));
|
||||
$d = ORM::for_table('tbl_routers')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('tbl_routers')->order_by_desc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
}
|
||||
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('paginator', $paginator);
|
||||
run_hook('view_list_routers'); #HOOK
|
||||
$ui->display('routers.tpl');
|
||||
break;
|
||||
@ -55,7 +54,7 @@ switch ($action) {
|
||||
run_hook('view_router_edit'); #HOOK
|
||||
$ui->display('routers-edit.tpl');
|
||||
} else {
|
||||
r2(U . 'routers/list', 'e', $_L['Account_Not_Found']);
|
||||
r2(U . 'routers/list', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -12,7 +12,7 @@ $action = $routes['1'];
|
||||
$ui->assign('_admin', $admin);
|
||||
|
||||
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
|
||||
_alert(Lang::T('You do not have permission to access this page'),'danger', "dashboard");
|
||||
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
|
||||
}
|
||||
|
||||
use PEAR2\Net\RouterOS;
|
||||
@ -38,7 +38,7 @@ switch ($action) {
|
||||
} else {
|
||||
$radup = '000000';
|
||||
}
|
||||
$radiusRate = $plan['rate_up'] . $radup . '/' . $plan['rate_down'] . $raddown;
|
||||
$radiusRate = $plan['rate_up'] . $radup . '/' . $plan['rate_down'] . $raddown . '/' . $plan['burst'];
|
||||
Radius::planUpSert($plan['id'], $radiusRate);
|
||||
$log .= "DONE : Radius $plan[name_plan], $plan[shared_users], $radiusRate<br>";
|
||||
} else {
|
||||
@ -83,7 +83,7 @@ switch ($action) {
|
||||
} else {
|
||||
$radup = '000000';
|
||||
}
|
||||
$radiusRate = $plan['rate_up'] . $radup . '/' . $plan['rate_down'] . $raddown;
|
||||
$radiusRate = $plan['rate_up'] . $radup . '/' . $plan['rate_down'] . $raddown . '/' . $plan['burst'];
|
||||
Radius::planUpSert($plan['id'], $radiusRate, $plan['pool']);
|
||||
$log .= "DONE : RADIUS $plan[name_plan], $plan[pool], $rate<br>";
|
||||
} else {
|
||||
@ -119,15 +119,14 @@ switch ($action) {
|
||||
|
||||
$name = _post('name');
|
||||
if ($name != '') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_plans'), ['name_plan' => '%' . $name . '%', 'type' => 'Hotspot'], $name);
|
||||
$d = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'Hotspot')->where_like('tbl_plans.name_plan', '%' . $name . '%')->offset($paginator['startpoint'])->limit($paginator['limit'])->find_many();
|
||||
$query = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'Hotspot')->where_like('tbl_plans.name_plan', '%' . $name . '%');
|
||||
$d = Paginator::findMany($query, ['name' => $name]);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_plans'), ['type' => 'Hotspot']);
|
||||
$d = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'Hotspot')->offset($paginator['startpoint'])->limit($paginator['limit'])->find_many();
|
||||
$query = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'Hotspot');
|
||||
$d = Paginator::findMany($query);
|
||||
}
|
||||
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('paginator', $paginator);
|
||||
run_hook('view_list_plans'); #HOOK
|
||||
$ui->display('hotspot.tpl');
|
||||
break;
|
||||
@ -142,7 +141,7 @@ switch ($action) {
|
||||
break;
|
||||
|
||||
case 'edit':
|
||||
$id = $routes['2'];
|
||||
$id = $routes['2'];
|
||||
$d = ORM::for_table('tbl_plans')->find_one($id);
|
||||
if ($d) {
|
||||
$ui->assign('d', $d);
|
||||
@ -153,12 +152,12 @@ switch ($action) {
|
||||
run_hook('view_edit_plan'); #HOOK
|
||||
$ui->display('hotspot-edit.tpl');
|
||||
} else {
|
||||
r2(U . 'services/hotspot', 'e', $_L['Account_Not_Found']);
|
||||
r2(U . 'services/hotspot', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
$id = $routes['2'];
|
||||
$id = $routes['2'];
|
||||
|
||||
$d = ORM::for_table('tbl_plans')->find_one($id);
|
||||
if ($d) {
|
||||
@ -185,6 +184,7 @@ switch ($action) {
|
||||
|
||||
case 'add-post':
|
||||
$name = _post('name');
|
||||
$plan_type = _post('plan_type'); //Personal / Business
|
||||
$radius = _post('radius');
|
||||
$typebp = _post('typebp');
|
||||
$limit_type = _post('limit_type');
|
||||
@ -201,7 +201,7 @@ switch ($action) {
|
||||
$pool_expired = _post('pool_expired');
|
||||
$list_expired = _post('list_expired');
|
||||
$enabled = _post('enabled');
|
||||
$allow_purchase = _post('allow_purchase');
|
||||
$prepaid = _post('prepaid');
|
||||
|
||||
$msg = '';
|
||||
if (Validator::UnsignedNumber($validity) == false) {
|
||||
@ -242,15 +242,47 @@ switch ($action) {
|
||||
$radup = '000000';
|
||||
}
|
||||
$rate = $b['rate_up'] . $unitup . "/" . $b['rate_down'] . $unitdown;
|
||||
$radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown;
|
||||
$radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown . '/' . $b['burst'];
|
||||
$rate = trim($rate . " " . $b['burst']);
|
||||
|
||||
// Check if tax is enabled in config
|
||||
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
||||
|
||||
// Default tax rate
|
||||
$default_tax_rate = 0.01; // Default tax rate 1%
|
||||
|
||||
// Check if tax rate is set to custom in config
|
||||
$tax_rate_setting = isset($config['tax_rate']) ? $config['tax_rate'] : $default_tax_rate;
|
||||
|
||||
// Check if tax rate is custom
|
||||
if ($tax_rate_setting === 'custom') {
|
||||
// Check if custom tax rate is set in config
|
||||
$custom_tax_rate = isset($config['custom_tax_rate']) ? (float)$config['custom_tax_rate'] : $default_tax_rate;
|
||||
// Convert custom tax rate to decimal
|
||||
$custom_tax_rate_decimal = $custom_tax_rate / 100;
|
||||
$tax_rate = $custom_tax_rate_decimal;
|
||||
} else {
|
||||
// Use tax rate
|
||||
$tax_rate = $tax_rate_setting;
|
||||
}
|
||||
|
||||
|
||||
// Calculate the new price with tax if tax is enabled
|
||||
if ($tax_enable === 'yes') {
|
||||
$price_with_tax = $price + ($price * $tax_rate);
|
||||
} else {
|
||||
// If tax is not enabled, use the original price
|
||||
$price_with_tax = $price;
|
||||
}
|
||||
|
||||
// Create new plan
|
||||
$d = ORM::for_table('tbl_plans')->create();
|
||||
$d->name_plan = $name;
|
||||
$d->id_bw = $id_bw;
|
||||
$d->price = $price;
|
||||
$d->price = $price_with_tax; // Set price with or without tax based on configuration
|
||||
$d->type = 'Hotspot';
|
||||
$d->typebp = $typebp;
|
||||
$d->plan_type = $plan_type;
|
||||
$d->limit_type = $limit_type;
|
||||
$d->time_limit = $time_limit;
|
||||
$d->time_unit = $time_unit;
|
||||
@ -269,7 +301,7 @@ switch ($action) {
|
||||
$d->pool_expired = $pool_expired;
|
||||
$d->list_expired = $list_expired;
|
||||
$d->enabled = $enabled;
|
||||
$d->allow_purchase = $allow_purchase;
|
||||
$d->prepaid = $prepaid;
|
||||
$d->save();
|
||||
$plan_id = $d->id();
|
||||
|
||||
@ -295,6 +327,7 @@ switch ($action) {
|
||||
case 'edit-post':
|
||||
$id = _post('id');
|
||||
$name = _post('name');
|
||||
$plan_type = _post('plan_type');
|
||||
$id_bw = _post('id_bw');
|
||||
$typebp = _post('typebp');
|
||||
$price = _post('price');
|
||||
@ -309,7 +342,7 @@ switch ($action) {
|
||||
$pool_expired = _post('pool_expired');
|
||||
$list_expired = _post('list_expired');
|
||||
$enabled = _post('enabled');
|
||||
$allow_purchase = _post('allow_purchase');
|
||||
$prepaid = _post('prepaid');
|
||||
$routers = _post('routers');
|
||||
$msg = '';
|
||||
if (Validator::UnsignedNumber($validity) == false) {
|
||||
@ -344,7 +377,7 @@ switch ($action) {
|
||||
$radup = '000000';
|
||||
}
|
||||
$rate = $b['rate_up'] . $unitup . "/" . $b['rate_down'] . $unitdown;
|
||||
$radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown;
|
||||
$radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown . '/' . $b['burst'];
|
||||
|
||||
$rate = trim($rate . " " . $b['burst']);
|
||||
|
||||
@ -359,14 +392,45 @@ switch ($action) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if tax is enabled in config
|
||||
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
||||
|
||||
// Default tax rate
|
||||
$default_tax_rate = 0.01; // Default tax rate 1%
|
||||
|
||||
// Check if tax rate is set to custom in config
|
||||
$tax_rate_setting = isset($config['tax_rate']) ? $config['tax_rate'] : $default_tax_rate;
|
||||
|
||||
// Check if tax rate is custom
|
||||
if ($tax_rate_setting === 'custom') {
|
||||
// Check if custom tax rate is set in config
|
||||
$custom_tax_rate = isset($config['custom_tax_rate']) ? (float)$config['custom_tax_rate'] : $default_tax_rate;
|
||||
// Convert custom tax rate to decimal
|
||||
$custom_tax_rate_decimal = $custom_tax_rate / 100;
|
||||
$tax_rate = $custom_tax_rate_decimal;
|
||||
} else {
|
||||
// Use tax rate
|
||||
$tax_rate = $tax_rate_setting;
|
||||
}
|
||||
|
||||
|
||||
// Calculate the new price with tax if tax is enabled
|
||||
if ($tax_enable === 'yes') {
|
||||
$price_with_tax = $price + ($price * $tax_rate);
|
||||
} else {
|
||||
// If tax is not enabled, use the original price
|
||||
$price_with_tax = $price;
|
||||
}
|
||||
|
||||
$d->name_plan = $name;
|
||||
$d->id_bw = $id_bw;
|
||||
$d->price = $price;
|
||||
$d->price = $price_with_tax; // Set price with or without tax based on configuration
|
||||
$d->typebp = $typebp;
|
||||
$d->limit_type = $limit_type;
|
||||
$d->time_limit = $time_limit;
|
||||
$d->time_unit = $time_unit;
|
||||
$d->data_limit = $data_limit;
|
||||
$d->plan_type = $plan_type;
|
||||
$d->data_unit = $data_unit;
|
||||
$d->validity = $validity;
|
||||
$d->validity_unit = $validity_unit;
|
||||
@ -374,7 +438,7 @@ switch ($action) {
|
||||
$d->pool_expired = $pool_expired;
|
||||
$d->list_expired = $list_expired;
|
||||
$d->enabled = $enabled;
|
||||
$d->allow_purchase = $allow_purchase;
|
||||
$d->prepaid = $prepaid;
|
||||
$d->save();
|
||||
|
||||
r2(U . 'services/hotspot', 's', Lang::T('Data Updated Successfully'));
|
||||
@ -389,15 +453,14 @@ switch ($action) {
|
||||
|
||||
$name = _post('name');
|
||||
if ($name != '') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_plans'), ['name_plan' => '%' . $name . '%', 'type' => 'PPPOE'], $name);
|
||||
$d = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'PPPOE')->where_like('tbl_plans.name_plan', '%' . $name . '%')->offset($paginator['startpoint'])->limit($paginator['limit'])->find_many();
|
||||
$query = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'PPPOE')->where_like('tbl_plans.name_plan', '%' . $name . '%');
|
||||
$d = Paginator::findMany($query, ['name' => $name]);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_plans'), ['type' => 'PPPOE'], $name);
|
||||
$d = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'PPPOE')->offset($paginator['startpoint'])->limit($paginator['limit'])->find_many();
|
||||
$query = ORM::for_table('tbl_bandwidth')->join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw'))->where('tbl_plans.type', 'PPPOE');
|
||||
$d = Paginator::findMany($query);
|
||||
}
|
||||
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('paginator', $paginator);
|
||||
run_hook('view_list_ppoe'); #HOOK
|
||||
$ui->display('pppoe.tpl');
|
||||
break;
|
||||
@ -414,7 +477,7 @@ switch ($action) {
|
||||
|
||||
case 'pppoe-edit':
|
||||
$ui->assign('_title', Lang::T('PPPOE Plans'));
|
||||
$id = $routes['2'];
|
||||
$id = $routes['2'];
|
||||
$d = ORM::for_table('tbl_plans')->find_one($id);
|
||||
if ($d) {
|
||||
$ui->assign('d', $d);
|
||||
@ -430,12 +493,12 @@ switch ($action) {
|
||||
run_hook('view_edit_ppoe'); #HOOK
|
||||
$ui->display('pppoe-edit.tpl');
|
||||
} else {
|
||||
r2(U . 'services/pppoe', 'e', $_L['Account_Not_Found']);
|
||||
r2(U . 'services/pppoe', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'pppoe-delete':
|
||||
$id = $routes['2'];
|
||||
$id = $routes['2'];
|
||||
|
||||
$d = ORM::for_table('tbl_plans')->find_one($id);
|
||||
if ($d) {
|
||||
@ -461,6 +524,7 @@ switch ($action) {
|
||||
|
||||
case 'pppoe-add-post':
|
||||
$name = _post('name_plan');
|
||||
$plan_type = _post('plan_type');
|
||||
$radius = _post('radius');
|
||||
$id_bw = _post('id_bw');
|
||||
$price = _post('price');
|
||||
@ -471,7 +535,7 @@ switch ($action) {
|
||||
$pool_expired = _post('pool_expired');
|
||||
$list_expired = _post('list_expired');
|
||||
$enabled = _post('enabled');
|
||||
$allow_purchase = _post('allow_purchase');
|
||||
$prepaid = _post('prepaid');
|
||||
|
||||
|
||||
$msg = '';
|
||||
@ -512,14 +576,46 @@ switch ($action) {
|
||||
$radup = '000000';
|
||||
}
|
||||
$rate = $b['rate_up'] . $unitup . "/" . $b['rate_down'] . $unitdown;
|
||||
$radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown;
|
||||
$radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown . '/' . $b['burst'];
|
||||
$rate = trim($rate . " " . $b['burst']);
|
||||
|
||||
// Check if tax is enabled in config
|
||||
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
||||
|
||||
// Default tax rate
|
||||
$default_tax_rate = 0.01; // Default tax rate 1%
|
||||
|
||||
// Check if tax rate is set to custom in config
|
||||
$tax_rate_setting = isset($config['tax_rate']) ? $config['tax_rate'] : $default_tax_rate;
|
||||
|
||||
// Check if tax rate is custom
|
||||
if ($tax_rate_setting === 'custom') {
|
||||
// Check if custom tax rate is set in config
|
||||
$custom_tax_rate = isset($config['custom_tax_rate']) ? (float)$config['custom_tax_rate'] : $default_tax_rate;
|
||||
// Convert custom tax rate to decimal
|
||||
$custom_tax_rate_decimal = $custom_tax_rate / 100;
|
||||
$tax_rate = $custom_tax_rate_decimal;
|
||||
} else {
|
||||
// Use tax rate
|
||||
$tax_rate = $tax_rate_setting;
|
||||
}
|
||||
|
||||
|
||||
// Calculate the new price with tax if tax is enabled
|
||||
if ($tax_enable === 'yes') {
|
||||
$price_with_tax = $price + ($price * $tax_rate);
|
||||
} else {
|
||||
// If tax is not enabled, use the original price
|
||||
$price_with_tax = $price;
|
||||
}
|
||||
|
||||
|
||||
$d = ORM::for_table('tbl_plans')->create();
|
||||
$d->type = 'PPPOE';
|
||||
$d->name_plan = $name;
|
||||
$d->id_bw = $id_bw;
|
||||
$d->price = $price;
|
||||
$d->price = $price_with_tax;
|
||||
$d->plan_type = $plan_type;
|
||||
$d->validity = $validity;
|
||||
$d->validity_unit = $validity_unit;
|
||||
$d->pool = $pool;
|
||||
@ -533,7 +629,7 @@ switch ($action) {
|
||||
$d->pool_expired = $pool_expired;
|
||||
$d->list_expired = $list_expired;
|
||||
$d->enabled = $enabled;
|
||||
$d->allow_purchase = $allow_purchase;
|
||||
$d->prepaid = $prepaid;
|
||||
$d->save();
|
||||
$plan_id = $d->id();
|
||||
|
||||
@ -556,6 +652,7 @@ switch ($action) {
|
||||
|
||||
case 'edit-pppoe-post':
|
||||
$id = _post('id');
|
||||
$plan_type = _post('plan_type');
|
||||
$name = _post('name_plan');
|
||||
$id_bw = _post('id_bw');
|
||||
$price = _post('price');
|
||||
@ -566,7 +663,7 @@ switch ($action) {
|
||||
$pool_expired = _post('pool_expired');
|
||||
$list_expired = _post('list_expired');
|
||||
$enabled = _post('enabled');
|
||||
$allow_purchase = _post('allow_purchase');
|
||||
$prepaid = _post('prepaid');
|
||||
|
||||
$msg = '';
|
||||
if (Validator::UnsignedNumber($validity) == false) {
|
||||
@ -602,7 +699,7 @@ switch ($action) {
|
||||
$radup = '000000';
|
||||
}
|
||||
$rate = $b['rate_up'] . $unitup . "/" . $b['rate_down'] . $unitdown;
|
||||
$radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown;
|
||||
$radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown . '/' . $b['burst'];
|
||||
$rate = trim($rate . " " . $b['burst']);
|
||||
|
||||
if ($d['is_radius']) {
|
||||
@ -616,9 +713,40 @@ switch ($action) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if tax is enabled in config
|
||||
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
||||
|
||||
// Default tax rate
|
||||
$default_tax_rate = 0.01; // Default tax rate 1%
|
||||
|
||||
// Check if tax rate is set to custom in config
|
||||
$tax_rate_setting = isset($config['tax_rate']) ? $config['tax_rate'] : $default_tax_rate;
|
||||
|
||||
// Check if tax rate is custom
|
||||
if ($tax_rate_setting === 'custom') {
|
||||
// Check if custom tax rate is set in config
|
||||
$custom_tax_rate = isset($config['custom_tax_rate']) ? (float)$config['custom_tax_rate'] : $default_tax_rate;
|
||||
// Convert custom tax rate to decimal
|
||||
$custom_tax_rate_decimal = $custom_tax_rate / 100;
|
||||
$tax_rate = $custom_tax_rate_decimal;
|
||||
} else {
|
||||
// Use tax rate
|
||||
$tax_rate = $tax_rate_setting;
|
||||
}
|
||||
|
||||
|
||||
// Calculate the new price with tax if tax is enabled
|
||||
if ($tax_enable === 'yes') {
|
||||
$price_with_tax = $price + ($price * $tax_rate);
|
||||
} else {
|
||||
// If tax is not enabled, use the original price
|
||||
$price_with_tax = $price;
|
||||
}
|
||||
|
||||
$d->name_plan = $name;
|
||||
$d->id_bw = $id_bw;
|
||||
$d->price = $price;
|
||||
$d->price = $price_with_tax;
|
||||
$d->plan_type = $plan_type;
|
||||
$d->validity = $validity;
|
||||
$d->validity_unit = $validity_unit;
|
||||
$d->routers = $routers;
|
||||
@ -626,7 +754,7 @@ switch ($action) {
|
||||
$d->pool_expired = $pool_expired;
|
||||
$d->list_expired = $list_expired;
|
||||
$d->enabled = $enabled;
|
||||
$d->allow_purchase = $allow_purchase;
|
||||
$d->prepaid = $prepaid;
|
||||
$d->save();
|
||||
|
||||
r2(U . 'services/pppoe', 's', Lang::T('Data Updated Successfully'));
|
||||
@ -638,15 +766,14 @@ switch ($action) {
|
||||
$ui->assign('_title', Lang::T('Balance Plans'));
|
||||
$name = _post('name');
|
||||
if ($name != '') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_plans'), ['name_plan' => '%' . $name . '%', 'type' => 'Balance'], $name);
|
||||
$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();
|
||||
$query = ORM::for_table('tbl_plans')->where('tbl_plans.type', 'Balance')->where_like('tbl_plans.name_plan', '%' . $name . '%');
|
||||
$d = Paginator::findMany($query, ['name' => $name]);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_plans'), ['type' => 'Balance'], $name);
|
||||
$d = ORM::for_table('tbl_plans')->where('tbl_plans.type', 'Balance')->offset($paginator['startpoint'])->limit($paginator['limit'])->find_many();
|
||||
$query = ORM::for_table('tbl_plans')->where('tbl_plans.type', 'Balance');
|
||||
$d = Paginator::findMany($query);
|
||||
}
|
||||
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('paginator', $paginator);
|
||||
run_hook('view_list_balance'); #HOOK
|
||||
$ui->display('balance.tpl');
|
||||
break;
|
||||
@ -657,14 +784,14 @@ switch ($action) {
|
||||
break;
|
||||
case 'balance-edit':
|
||||
$ui->assign('_title', Lang::T('Balance Plans'));
|
||||
$id = $routes['2'];
|
||||
$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'];
|
||||
$id = $routes['2'];
|
||||
|
||||
$d = ORM::for_table('tbl_plans')->find_one($id);
|
||||
if ($d) {
|
||||
@ -678,7 +805,7 @@ switch ($action) {
|
||||
$name = _post('name');
|
||||
$price = _post('price');
|
||||
$enabled = _post('enabled');
|
||||
$allow_purchase = _post('allow_purchase');
|
||||
$prepaid = _post('prepaid');
|
||||
|
||||
$msg = '';
|
||||
if (Validator::UnsignedNumber($price) == false) {
|
||||
@ -695,10 +822,39 @@ switch ($action) {
|
||||
}
|
||||
run_hook('edit_ppoe'); #HOOK
|
||||
if ($msg == '') {
|
||||
// Check if tax is enabled in config
|
||||
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
||||
|
||||
// Default tax rate
|
||||
$default_tax_rate = 0.01; // Default tax rate 1%
|
||||
|
||||
// Check if tax rate is set to custom in config
|
||||
$tax_rate_setting = isset($config['tax_rate']) ? $config['tax_rate'] : $default_tax_rate;
|
||||
|
||||
// Check if tax rate is custom
|
||||
if ($tax_rate_setting === 'custom') {
|
||||
// Check if custom tax rate is set in config
|
||||
$custom_tax_rate = isset($config['custom_tax_rate']) ? (float)$config['custom_tax_rate'] : $default_tax_rate;
|
||||
// Convert custom tax rate to decimal
|
||||
$custom_tax_rate_decimal = $custom_tax_rate / 100;
|
||||
$tax_rate = $custom_tax_rate_decimal;
|
||||
} else {
|
||||
// Use tax rate
|
||||
$tax_rate = $tax_rate_setting;
|
||||
}
|
||||
|
||||
|
||||
// Calculate the new price with tax if tax is enabled
|
||||
if ($tax_enable === 'yes') {
|
||||
$price_with_tax = $price + ($price * $tax_rate);
|
||||
} else {
|
||||
// If tax is not enabled, use the original price
|
||||
$price_with_tax = $price;
|
||||
}
|
||||
$d->name_plan = $name;
|
||||
$d->price = $price;
|
||||
$d->price = $price_with_tax;
|
||||
$d->enabled = $enabled;
|
||||
$d->allow_purchase = $allow_purchase;
|
||||
$d->prepaid = 'yes';
|
||||
$d->save();
|
||||
|
||||
r2(U . 'services/balance', 's', Lang::T('Data Updated Successfully'));
|
||||
@ -710,7 +866,6 @@ switch ($action) {
|
||||
$name = _post('name');
|
||||
$price = _post('price');
|
||||
$enabled = _post('enabled');
|
||||
$allow_purchase = _post('allow_purchase');
|
||||
|
||||
$msg = '';
|
||||
if (Validator::UnsignedNumber($price) == false) {
|
||||
@ -726,17 +881,49 @@ switch ($action) {
|
||||
}
|
||||
run_hook('add_ppoe'); #HOOK
|
||||
if ($msg == '') {
|
||||
|
||||
// Check if tax is enabled in config
|
||||
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
|
||||
|
||||
// Default tax rate
|
||||
$default_tax_rate = 0.01; // Default tax rate 1%
|
||||
|
||||
// Check if tax rate is set to custom in config
|
||||
$tax_rate_setting = isset($config['tax_rate']) ? $config['tax_rate'] : $default_tax_rate;
|
||||
|
||||
// Check if tax rate is custom
|
||||
if ($tax_rate_setting === 'custom') {
|
||||
// Check if custom tax rate is set in config
|
||||
$custom_tax_rate = isset($config['custom_tax_rate']) ? (float)$config['custom_tax_rate'] : $default_tax_rate;
|
||||
// Convert custom tax rate to decimal
|
||||
$custom_tax_rate_decimal = $custom_tax_rate / 100;
|
||||
$tax_rate = $custom_tax_rate_decimal;
|
||||
} else {
|
||||
// Use tax rate
|
||||
$tax_rate = $tax_rate_setting;
|
||||
}
|
||||
|
||||
|
||||
// Calculate the new price with tax if tax is enabled
|
||||
if ($tax_enable === 'yes') {
|
||||
$price_with_tax = $price + ($price * $tax_rate);
|
||||
} else {
|
||||
// If tax is not enabled, use the original price
|
||||
$price_with_tax = $price;
|
||||
}
|
||||
|
||||
|
||||
$d = ORM::for_table('tbl_plans')->create();
|
||||
$d->type = 'Balance';
|
||||
$d->name_plan = $name;
|
||||
$d->id_bw = 0;
|
||||
$d->price = $price;
|
||||
$d->price = $price_with_tax;
|
||||
$d->validity = 0;
|
||||
$d->validity_unit = 'Months';
|
||||
$d->routers = '';
|
||||
$d->pool = '';
|
||||
$d->enabled = $enabled;
|
||||
$d->allow_purchase = $allow_purchase;
|
||||
$d->prepaid = 'yes';
|
||||
$d->save();
|
||||
|
||||
r2(U . 'services/balance', 's', Lang::T('Data Created Successfully'));
|
||||
|
@ -25,12 +25,16 @@ switch ($action) {
|
||||
$result = Message::sendSMS(_get('testSms'), 'PHPNuxBill Test SMS');
|
||||
r2(U . "settings/app", 's', 'Test SMS has been send<br>Result: ' . $result);
|
||||
}
|
||||
if (!empty(_get('testEmail'))) {
|
||||
Message::sendEmail(_get('testEmail'), 'PHPNuxBill Test Email', 'PHPNuxBill Test Email Body');
|
||||
r2(U . "settings/app", 's', 'Test Email has been send');
|
||||
}
|
||||
if (!empty(_get('testTg'))) {
|
||||
$result = Message::sendTelegram('PHPNuxBill Test Telegram');
|
||||
r2(U . "settings/app", 's', 'Test Telegram has been send<br>Result: ' . $result);
|
||||
}
|
||||
|
||||
$UPLOAD_URL_PATH = str_replace($root_path,'', $UPLOAD_PATH);
|
||||
$UPLOAD_URL_PATH = str_replace($root_path, '', $UPLOAD_PATH);
|
||||
if (file_exists($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png')) {
|
||||
$logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'logo.png?' . time();
|
||||
} else {
|
||||
@ -115,7 +119,7 @@ switch ($action) {
|
||||
die();
|
||||
}
|
||||
}
|
||||
// save all settings
|
||||
// Save all settings including tax system
|
||||
foreach ($_POST as $key => $value) {
|
||||
$d = ORM::for_table('tbl_appconfig')->where('setting', $key)->find_one();
|
||||
if ($d) {
|
||||
@ -129,6 +133,33 @@ switch ($action) {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle tax system separately
|
||||
$enable_tax = isset($_POST['enable_tax']) ? $_POST['enable_tax'] : 'no';
|
||||
$tax_rate = isset($_POST['tax_rate']) ? $_POST['tax_rate'] : '0.01'; // Default tax rate 1%
|
||||
|
||||
// Save or update tax system settings
|
||||
$d_tax_enable = ORM::for_table('tbl_appconfig')->where('setting', 'enable_tax')->find_one();
|
||||
if ($d_tax_enable) {
|
||||
$d_tax_enable->value = $enable_tax;
|
||||
$d_tax_enable->save();
|
||||
} else {
|
||||
$d_tax_enable = ORM::for_table('tbl_appconfig')->create();
|
||||
$d_tax_enable->setting = 'enable_tax';
|
||||
$d_tax_enable->value = $enable_tax;
|
||||
$d_tax_enable->save();
|
||||
}
|
||||
|
||||
$d_tax_rate = ORM::for_table('tbl_appconfig')->where('setting', 'tax_rate')->find_one();
|
||||
if ($d_tax_rate) {
|
||||
$d_tax_rate->value = $tax_rate;
|
||||
$d_tax_rate->save();
|
||||
} else {
|
||||
$d_tax_rate = ORM::for_table('tbl_appconfig')->create();
|
||||
$d_tax_rate->setting = 'tax_rate';
|
||||
$d_tax_rate->value = $tax_rate;
|
||||
$d_tax_rate->save();
|
||||
}
|
||||
|
||||
//checkbox
|
||||
$checks = ['hide_mrc', 'hide_tms', 'hide_aui', 'hide_al', 'hide_uet', 'hide_vs', 'hide_pg'];
|
||||
foreach ($checks as $check) {
|
||||
@ -276,60 +307,47 @@ switch ($action) {
|
||||
$search = _req('search');
|
||||
if ($search != '') {
|
||||
if ($admin['user_type'] == 'SuperAdmin') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_users'), ['username' => '%' . $search . '%'], $search);
|
||||
$d = ORM::for_table('tbl_users')
|
||||
$query = ORM::for_table('tbl_users')
|
||||
->where_like('username', '%' . $search . '%')
|
||||
->offset($paginator['startpoint'])
|
||||
->limit($paginator['limit'])->order_by_asc('id')->findArray();
|
||||
->order_by_asc('id');
|
||||
$d = Paginator::findMany($query, ['search' => $search]);
|
||||
} else if ($admin['user_type'] == 'Admin') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_users'), [
|
||||
'username' => '%' . $search . '%',
|
||||
['user_type' => 'Report'],
|
||||
['user_type' => 'Agent'],
|
||||
['user_type' => 'Sales'],
|
||||
['id' => $admin['id']]
|
||||
], $search);
|
||||
$d = ORM::for_table('tbl_users')
|
||||
->where_like('username', '%' . $search . '%')
|
||||
->where_any_is([
|
||||
$query = ORM::for_table('tbl_users')
|
||||
->where_like('username', '%' . $search . '%')->where_any_is([
|
||||
['user_type' => 'Report'],
|
||||
['user_type' => 'Agent'],
|
||||
['user_type' => 'Sales'],
|
||||
['id' => $admin['id']]
|
||||
])
|
||||
->offset($paginator['startpoint'])
|
||||
->limit($paginator['limit'])->order_by_asc('id')->findArray();
|
||||
])->order_by_asc('id');
|
||||
$d = Paginator::findMany($query, ['search' => $search]);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_users'), ['username' => '%' . $search . '%'], $search);
|
||||
$d = ORM::for_table('tbl_users')
|
||||
$query = ORM::for_table('tbl_users')
|
||||
->where_like('username', '%' . $search . '%')
|
||||
->where_any_is([
|
||||
['id' => $admin['id']],
|
||||
['root' => $admin['id']]
|
||||
])
|
||||
->offset($paginator['startpoint'])
|
||||
->limit($paginator['limit'])->order_by_asc('id')->findArray();
|
||||
])->order_by_asc('id');
|
||||
$d = Paginator::findMany($query, ['search' => $search]);
|
||||
}
|
||||
} else {
|
||||
if ($admin['user_type'] == 'SuperAdmin') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_users'));
|
||||
$d = ORM::for_table('tbl_users')->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_asc('id')->findArray();
|
||||
$query = ORM::for_table('tbl_users')->order_by_asc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
} else if ($admin['user_type'] == 'Admin') {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_users'));
|
||||
$d = ORM::for_table('tbl_users')->where_any_is([
|
||||
$query = ORM::for_table('tbl_users')->where_any_is([
|
||||
['user_type' => 'Report'],
|
||||
['user_type' => 'Agent'],
|
||||
['user_type' => 'Sales'],
|
||||
['id' => $admin['id']]
|
||||
])->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_asc('id')->findArray();
|
||||
])->order_by_asc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
} else {
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_users'));
|
||||
$d = ORM::for_table('tbl_users')
|
||||
$query = ORM::for_table('tbl_users')
|
||||
->where_any_is([
|
||||
['id' => $admin['id']],
|
||||
['root' => $admin['id']]
|
||||
])
|
||||
->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_asc('id')->findArray();
|
||||
])->order_by_asc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
}
|
||||
}
|
||||
$admins = [];
|
||||
@ -345,16 +363,9 @@ switch ($action) {
|
||||
$admins[$adm['id']] = $adm['fullname'];
|
||||
}
|
||||
}
|
||||
if ($isApi) {
|
||||
showResult(true, $action, [
|
||||
'admins' => $d,
|
||||
'roots' => $admins
|
||||
], ['search' => $search]);
|
||||
}
|
||||
$ui->assign('admins', $admins);
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('search', $search);
|
||||
$ui->assign('paginator', $paginator);
|
||||
run_hook('view_list_admin'); #HOOK
|
||||
$ui->display('users.tpl');
|
||||
break;
|
||||
@ -390,20 +401,11 @@ switch ($action) {
|
||||
if ($d['user_type'] == 'Sales') {
|
||||
$ui->assign('agent', ORM::for_table('tbl_users')->where('id', $d['root'])->find_array()[0]);
|
||||
}
|
||||
if ($isApi) {
|
||||
unset($d['password']);
|
||||
$agent = $ui->get('agent');
|
||||
if ($agent) unset($agent['password']);
|
||||
showResult(true, $action, [
|
||||
'admin' => $d,
|
||||
'agent' => $agent
|
||||
], ['search' => $search]);
|
||||
}
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('_title', $d['username']);
|
||||
$ui->display('users-view.tpl');
|
||||
} else {
|
||||
r2(U . 'settings/users', 'e', $_L['Account_Not_Found']);
|
||||
r2(U . 'settings/users', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
break;
|
||||
case 'users-edit':
|
||||
@ -440,7 +442,7 @@ switch ($action) {
|
||||
run_hook('view_edit_admin'); #HOOK
|
||||
$ui->display('users-edit.tpl');
|
||||
} else {
|
||||
r2(U . 'settings/users', 'e', $_L['Account_Not_Found']);
|
||||
r2(U . 'settings/users', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -459,7 +461,7 @@ switch ($action) {
|
||||
$d->delete();
|
||||
r2(U . 'settings/users', 's', Lang::T('User deleted Successfully'));
|
||||
} else {
|
||||
r2(U . 'settings/users', 'e', $_L['Account_Not_Found']);
|
||||
r2(U . 'settings/users', 'e', Lang::T('Account Not Found'));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -496,11 +498,11 @@ switch ($action) {
|
||||
$date_now = date("Y-m-d H:i:s");
|
||||
run_hook('add_admin'); #HOOK
|
||||
if ($msg == '') {
|
||||
$password = Password::_crypt($password);
|
||||
$passwordC = Password::_crypt($password);
|
||||
$d = ORM::for_table('tbl_users')->create();
|
||||
$d->username = $username;
|
||||
$d->fullname = $fullname;
|
||||
$d->password = $password;
|
||||
$d->password = $passwordC;
|
||||
$d->user_type = $user_type;
|
||||
$d->phone = $phone;
|
||||
$d->email = $email;
|
||||
|
@ -40,16 +40,28 @@ switch ($action) {
|
||||
|
||||
case 'list-activated':
|
||||
$ui->assign('_system_menu', 'list-activated');
|
||||
$paginator = Paginator::build(ORM::for_table('tbl_transactions'), ['username' => $user['username']]);
|
||||
$d = ORM::for_table('tbl_transactions')->where('username', $user['username'])->offset($paginator['startpoint'])->limit($paginator['limit'])->order_by_desc('id')->find_many();
|
||||
$query = ORM::for_table('tbl_transactions')->where('username', $user['username'])->order_by_desc('id');
|
||||
$d = Paginator::findMany($query);
|
||||
|
||||
$ui->assign('d', $d);
|
||||
$ui->assign('paginator', $paginator);
|
||||
run_hook('customer_view_activation_list'); #HOOK
|
||||
$ui->display('user-activation-list.tpl');
|
||||
|
||||
break;
|
||||
|
||||
case 'invoice':
|
||||
$id = $routes[2];
|
||||
if(empty($id)){
|
||||
$in = ORM::for_table('tbl_transactions')->where('username', $user['username'])->order_by_desc('id')->find_one();
|
||||
}else{
|
||||
$in = ORM::for_table('tbl_transactions')->where('username', $user['username'])->where('id', $id)->find_one();
|
||||
}
|
||||
if($in){
|
||||
Package::createInvoice($in);
|
||||
$ui->display('invoice-customer.tpl');
|
||||
}else{
|
||||
r2(U . 'voucher/list-activated', 'e', Lang::T('Not Found'));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$ui->display('a404.tpl');
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ foreach ($d as $ds) {
|
||||
$c = ORM::for_table('tbl_customers')->where('id', $ds['customer_id'])->find_one();
|
||||
$m = Mikrotik::info($ds['routers']);
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
|
||||
$price = Lang::moneyFormat($p['price']);
|
||||
if ($p['is_radius']) {
|
||||
if (empty($p['pool_expired'])) {
|
||||
print_r(Radius::customerDeactivate($c['username']));
|
||||
@ -46,23 +45,29 @@ foreach ($d as $ds) {
|
||||
$client = Mikrotik::getClient($m['ip_address'], $m['username'], $m['password']);
|
||||
if (!empty($p['pool_expired'])) {
|
||||
Mikrotik::setHotspotUserPackage($client, $c['username'], 'EXPIRED NUXBILL ' . $p['pool_expired']);
|
||||
// }if (!empty($p['list_expired'])) {
|
||||
// $ip = Mikrotik::getIpHotspotUser($client, $ds['username']);
|
||||
// Mikrotik::addIpToAddressList($client, $ip, $p['list_expired'], $c['username']);
|
||||
// }if (!empty($p['list_expired'])) {
|
||||
// $ip = Mikrotik::getIpHotspotUser($client, $ds['username']);
|
||||
// Mikrotik::addIpToAddressList($client, $ip, $p['list_expired'], $c['username']);
|
||||
} else {
|
||||
Mikrotik::removeHotspotUser($client, $c['username']);
|
||||
}
|
||||
Mikrotik::removeHotspotActiveUser($client, $c['username']);
|
||||
}
|
||||
echo Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $price, $textExpired, $config['user_notification_expired'])."\n";
|
||||
echo Message::sendPackageNotification($c, $u['namebp'], $p['price'], $textExpired, $config['user_notification_expired']) . "\n";
|
||||
//update database user dengan status off
|
||||
$u->status = 'off';
|
||||
$u->save();
|
||||
|
||||
// autorenewal from deposit
|
||||
if ($config['enable_balance'] == 'yes' && $c['auto_renewal']) {
|
||||
if ($p && $p['enabled'] && $c['balance'] >= $p['price'] && $p['allow_purchase'] == 'yes') {
|
||||
if (Package::rechargeUser($ds['customer_id'], $p['routers'], $p['id'], 'Customer', 'Balance')) {
|
||||
list($bills, $add_cost) = User::getBills($ds['customer_id']);
|
||||
if ($add_cost > 0) {
|
||||
if (!empty($add_cost)) {
|
||||
$p['price'] += $add_cost;
|
||||
}
|
||||
}
|
||||
if ($p && $p['enabled'] && $c['balance'] >= $p['price']) {
|
||||
if (Package::rechargeUser($ds['customer_id'], $ds['routers'], $p['id'], 'Customer', 'Balance')) {
|
||||
// if success, then get the balance
|
||||
Balance::min($ds['customer_id'], $p['price']);
|
||||
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
||||
@ -92,7 +97,6 @@ foreach ($d as $ds) {
|
||||
$c = ORM::for_table('tbl_customers')->where('id', $ds['customer_id'])->find_one();
|
||||
$m = ORM::for_table('tbl_routers')->where('name', $ds['routers'])->find_one();
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
|
||||
$price = Lang::moneyFormat($p['price']);
|
||||
if ($p['is_radius']) {
|
||||
if (empty($p['pool_expired'])) {
|
||||
print_r(Radius::customerDeactivate($c['username']));
|
||||
@ -109,15 +113,21 @@ foreach ($d as $ds) {
|
||||
}
|
||||
Mikrotik::removePpoeActive($client, $c['username']);
|
||||
}
|
||||
echo Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $u['namebp'], $price, $textExpired, $config['user_notification_expired'])."\n";
|
||||
echo Message::sendPackageNotification($c, $u['namebp'], $p['price'], $textExpired, $config['user_notification_expired']) . "\n";
|
||||
|
||||
$u->status = 'off';
|
||||
$u->save();
|
||||
|
||||
// autorenewal from deposit
|
||||
if ($config['enable_balance'] == 'yes' && $c['auto_renewal']) {
|
||||
if ($p && $p['enabled'] && $c['balance'] >= $p['price'] && $p['allow_purchase'] == 'yes') {
|
||||
if (Package::rechargeUser($ds['customer_id'], $p['routers'], $p['id'], 'Customer', 'Balance')) {
|
||||
list($bills, $add_cost) = User::getBills($ds['customer_id']);
|
||||
if ($add_cost > 0) {
|
||||
if (!empty($add_cost)) {
|
||||
$p['price'] += $add_cost;
|
||||
}
|
||||
}
|
||||
if ($p && $p['enabled'] && $c['balance'] >= $p['price']) {
|
||||
if (Package::rechargeUser($ds['customer_id'], $ds['routers'], $p['id'], 'Customer', 'Balance')) {
|
||||
// if success, then get the balance
|
||||
Balance::min($ds['customer_id'], $p['price']);
|
||||
echo "plan enabled: $p[enabled] | User balance: $c[balance] | price $p[price]\n";
|
||||
|
@ -38,13 +38,23 @@ foreach ($d as $ds) {
|
||||
$u = ORM::for_table('tbl_user_recharges')->where('id', $ds['id'])->find_one();
|
||||
$p = ORM::for_table('tbl_plans')->where('id', $u['plan_id'])->find_one();
|
||||
$c = ORM::for_table('tbl_customers')->where('id', $ds['customer_id'])->find_one();
|
||||
$price = Lang::moneyFormat($p['price']);
|
||||
if ($p['validity_unit'] == 'Period') {
|
||||
// Postpaid price from field
|
||||
$add_inv = User::getAttribute("Invoice", $ds['customer_id']);
|
||||
if (empty ($add_inv) or $add_inv == 0) {
|
||||
$price = $p['price'];
|
||||
} else {
|
||||
$price = $add_inv;
|
||||
}
|
||||
} else {
|
||||
$price = $p['price'];
|
||||
}
|
||||
if ($ds['expiration'] == $day7) {
|
||||
echo Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $p['name_plan'], $price, Lang::getNotifText('reminder_7_day'), $config['user_notification_reminder']) . "\n";
|
||||
echo Message::sendPackageNotification($c, $p['name_plan'], $price, Lang::getNotifText('reminder_7_day'), $config['user_notification_reminder']) . "\n";
|
||||
} else if ($ds['expiration'] == $day3) {
|
||||
echo Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $p['name_plan'], $price, Lang::getNotifText('reminder_3_day'), $config['user_notification_reminder']) . "\n";
|
||||
echo Message::sendPackageNotification($c, $p['name_plan'], $price, Lang::getNotifText('reminder_3_day'), $config['user_notification_reminder']) . "\n";
|
||||
} else if ($ds['expiration'] == $day1) {
|
||||
echo Message::sendPackageNotification($c['phonenumber'], $c['fullname'], $p['name_plan'], $price, Lang::getNotifText('reminder_1_day'), $config['user_notification_reminder']) . "\n";
|
||||
echo Message::sendPackageNotification($c, $p['name_plan'], $price, Lang::getNotifText('reminder_1_day'), $config['user_notification_reminder']) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@
|
||||
"hebrew": "iw",
|
||||
"hindi": "hi",
|
||||
"hungarian": "hu",
|
||||
"iran": "ir",
|
||||
"icelandic": "is",
|
||||
"italian": "it",
|
||||
"japanese": "ja",
|
||||
@ -55,4 +56,4 @@
|
||||
"ukrainian": "uk",
|
||||
"vietnamese": "vi",
|
||||
"welsh": "cy"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"Log_in": "Log-in",
|
||||
"Log_in": "Login",
|
||||
"Register": "Register",
|
||||
"Announcement": "Announcement",
|
||||
"Registration_Info": "Registration Info",
|
||||
@ -100,9 +100,6 @@
|
||||
"Add_Pool": "Add Pool",
|
||||
"Edit_Pool": "Edit Pool",
|
||||
"Pool_Name_Already_Exist": "Pool Name Already Exist",
|
||||
"Prepaid": "Prepaid",
|
||||
"Prepaid_Users": "Prepaid Users",
|
||||
"Prepaid_Vouchers": "Prepaid Vouchers",
|
||||
"Refill_Account": "Refill Account",
|
||||
"Recharge_Account": "Recharge Account",
|
||||
"Select_Account": "Select Account",
|
||||
@ -384,7 +381,6 @@
|
||||
"After_Customer_activate_voucher_or_login__customer_will_be_redirected_to_this_url": "After Customer activate voucher or login, customer will be redirected to this url",
|
||||
"Voucher_Prefix": "Voucher Prefix",
|
||||
"Voucher_activation_success__now_you_can_login": "Voucher activation success, now you can login",
|
||||
"Client_Can_Purchase": "Client Can Purchase",
|
||||
"Buy_this__your_active_package_will_be_overwritten": "Buy this? your active package will be overwritten",
|
||||
"Pay_this_with_Balance__your_active_package_will_be_overwritten": "Pay this with Balance? your active package will be overwritten",
|
||||
"Buy_this__your_active_package_will_be_overwrite": "Buy this? your active package will be overwrite",
|
||||
@ -460,5 +456,129 @@
|
||||
"Users_Announcement": "Users Announcement",
|
||||
"Customer_Announcement": "Customer Announcement",
|
||||
"1_Period___1_Month__Expires_the_20th_of_each_month": "1 Period = 1 Month, Expires the 20th of each month",
|
||||
"Period": "Period"
|
||||
"Period": "Period",
|
||||
"Add": "Add",
|
||||
"Select_Payment_Gateway": "Select Payment Gateway",
|
||||
"Available_Payment_Gateway": "Available Payment Gateway",
|
||||
"Pay_Now": "Pay Now",
|
||||
"Please_select_Payment_Gateway": "Please select Payment Gateway",
|
||||
"Payment_Gateway_Deleted": "Payment Gateway Deleted",
|
||||
"Payment_Gateway_not_set__please_set_it_in_Settings": "Payment Gateway not set, please set it in Settings",
|
||||
"Failed_to_create_Transaction__": "Failed to create Transaction..",
|
||||
"Show_To_Customer": "Type",
|
||||
"Using": "Using",
|
||||
"Default": "Default",
|
||||
"Customer_Balance": "Customer Balance",
|
||||
"Vouchers": "Vouchers",
|
||||
"Refill_Customer": "Refill Customer",
|
||||
"Recharge_Customer": "Recharge Customer",
|
||||
"Plans": "Plans",
|
||||
"PPPOE": "PPPOE",
|
||||
"Bandwidth": "Bandwidth",
|
||||
"Customers": "Customers",
|
||||
"Actives": "Actives",
|
||||
"Name": "Name",
|
||||
"Confirm": "Confirm",
|
||||
"Plan": "Plan",
|
||||
"Total": "Total",
|
||||
"Current_Cycle": "Current Cycle",
|
||||
"Additional_Cost": "Additional Cost",
|
||||
"Remaining": "Remaining",
|
||||
"Not_Found": "Not Found",
|
||||
"Cash": "Cash",
|
||||
"Payment_not_found": "Payment not found",
|
||||
"If_your_friend_have_Additional_Cost__you_will_pay_for_that_too": "If your friend have Additional Cost, you will pay for that too",
|
||||
"Cache_cleared_successfully_": "Cache cleared successfully!",
|
||||
"Paid": "Paid",
|
||||
"Send_Message": "Send Message",
|
||||
"Send_Personal_Message": "Send Personal Message",
|
||||
"Send_Via": "Send Via",
|
||||
"Compose_your_message___": "Compose your message...",
|
||||
"Use_placeholders_": "Use placeholders:",
|
||||
"Customer_Name": "Customer Name",
|
||||
"Customer_Username": "Customer Username",
|
||||
"Customer_Phone": "Customer Phone",
|
||||
"Your_Company_Name": "Your Company Name",
|
||||
"Message_Sent_Successfully": "Message Sent Successfully",
|
||||
"Send_Bulk_Message": "Send Bulk Message",
|
||||
"Group": "Group",
|
||||
"All_Customers": "All Customers",
|
||||
"New_Customers": "New Customers",
|
||||
"Expired_Customers": "Expired Customers",
|
||||
"Active_Customers": "Active Customers",
|
||||
"Map": "Map",
|
||||
"Customer_Location": "Customer Location",
|
||||
"Account_Type": "Account Type",
|
||||
"Coordinates": "Coordinates",
|
||||
"Latitude_and_Longitude_coordinates_for_map_must_be_separate_with_comma____": "Latitude and Longitude coordinates for map must be separate with comma ","",
|
||||
"Customer_Geo_Location_Information": "Customer Geo Location Information",
|
||||
"List": "List",
|
||||
"Lists": "Lists",
|
||||
"Single_Customer": "Single Customer",
|
||||
"Bulk_Customers": "Bulk Customers",
|
||||
"Message_per_time": "Message per time",
|
||||
"5_Messages": "5 Messages",
|
||||
"10_Messages": "10 Messages",
|
||||
"15_Messages": "15 Messages",
|
||||
"20_Messages": "20 Messages",
|
||||
"30_Messages": "30 Messages",
|
||||
"40_Messages": "40 Messages",
|
||||
"50_Messages": "50 Messages",
|
||||
"60_Messages": "60 Messages",
|
||||
"Use_20_and_above_if_you_are_sending_to_all_customers_to_avoid_server_time_out": "Use 20 and above if you are sending to all customers to avoid server time out",
|
||||
"Delay": "Delay",
|
||||
"No_Delay": "No Delay",
|
||||
"5_Seconds": "5 Seconds",
|
||||
"10_Seconds": "10 Seconds",
|
||||
"15_Seconds": "15 Seconds",
|
||||
"20_Seconds": "20 Seconds",
|
||||
"Use_at_least_5_secs_if_you_are_sending_to_all_customers_to_avoid_being_banned_by_your_message_provider": "Use at least 5 secs if you are sending to all customers to avoid being banned by your message provider",
|
||||
"Testing__if_checked_no_real_message_is_sent_": "Testing [if checked no real message is sent]",
|
||||
"All_fields_are_required": "All fields are required",
|
||||
"Personal": "Personal",
|
||||
"Email_Notification": "Email Notification",
|
||||
"Router_Name___Location": "Router Name \/ Location",
|
||||
"Plan_Category": "Plan Category",
|
||||
"ID": "ID",
|
||||
"Internet_Plan": "Internet Plan",
|
||||
"Privacy_Policy": "Privacy Policy",
|
||||
"Terms_and_Conditions": "Terms and Conditions",
|
||||
"Contact": "Contact",
|
||||
"will_be_replaced_with_Customer_Name": "will be replaced with Customer Name",
|
||||
"will_be_replaced_with_Customer_username": "will be replaced with Customer username",
|
||||
"will_be_replaced_with_Package_name": "will be replaced with Package name",
|
||||
"will_be_replaced_with_Package_price": "will be replaced with Package price",
|
||||
"additional_bills_for_customers": "additional bills for customers",
|
||||
"will_be_replaced_with_Expiration_date": "will be replaced with Expiration date",
|
||||
"Your_Company_Name_at_Settings": "Your Company Name at Settings",
|
||||
"Your_Company_Address_at_Settings": "Your Company Address at Settings",
|
||||
"Your_Company_Phone_at_Settings": "Your Company Phone at Settings",
|
||||
"Invoice_number": "Invoice number",
|
||||
"Date_invoice_created": "Date invoice created",
|
||||
"Payment_gateway_user_paid_from": "Payment gateway user paid from",
|
||||
"Payment_channel_user_paid_from": "Payment channel user paid from",
|
||||
"is_Hotspot_or_PPPOE": "is Hotspot or PPPOE",
|
||||
"Internet_Package": "Internet Package",
|
||||
"Internet_Package_Prices": "Internet Package Prices",
|
||||
"Receiver_name": "Receiver name",
|
||||
"Username_internet": "Username internet",
|
||||
"User_password": "User password",
|
||||
"Expired_datetime": "Expired datetime",
|
||||
"For_Notes_by_admin": "For Notes by admin",
|
||||
"Transaction_datetime": "Transaction datetime",
|
||||
"Balance_Before": "Balance Before",
|
||||
"Balance_After": "Balance After",
|
||||
"how_much_balance_have_been_send": "how much balance have been send",
|
||||
"Current_Balance": "Current Balance",
|
||||
"Sender_name": "Sender name",
|
||||
"how_much_balance_have_been_received": "how much balance have been received",
|
||||
"Extend_Postpaid_Expiration": "Extend Postpaid Expiration",
|
||||
"Allow_Extend": "Allow Extend",
|
||||
"Extend_Days": "Extend Days",
|
||||
"Confirmation_Message": "Confirmation Message",
|
||||
"You_are_already_logged_in": "You are already logged in",
|
||||
"Extend": "Extend",
|
||||
"Created___Expired": "Created \/ Expired",
|
||||
"Bank_Transfer": "Bank Transfer",
|
||||
"Recharge_Using": "Recharge Using"
|
||||
}
|
@ -4,18 +4,18 @@
|
||||
"Announcement": "Pemberitahuan",
|
||||
"Registration_Info": "Info Pendaftaran",
|
||||
"Voucher_not_found__please_buy_voucher_befor_register": "Voucher tidak ditemukan, silakan beli voucher sebelum mendaftar",
|
||||
"Register_Success__You_can_login_now": "Daftar Sukses! Anda dapat masuk sekarang",
|
||||
"Register_Success__You_can_login_now": "Daftar Sukses! Anda dapat masuk sekarang",
|
||||
"Log_in_to_Member_Panel": "Masuk ke Panel Anggota",
|
||||
"Register_as_Member": "Daftar sebagai Anggota",
|
||||
"Enter_Admin_Area": "Masuk ke Admin Panel",
|
||||
"PHPNuxBill": "PHPNuxBill",
|
||||
"Username": "Nama Pengguna",
|
||||
"Password": "Kata Sandi",
|
||||
"Passwords_does_not_match": "Kata Sandi tidak cocok",
|
||||
"Passwords_does_not_match": "Kata sandi tidak cocok",
|
||||
"Account_already_axist": "Akun telah ada",
|
||||
"Manage": "Mengelola",
|
||||
"Submit": "Kirim",
|
||||
"Save_Changes": "Simpan perubahan",
|
||||
"Save_Changes": "Simpan Perubahan",
|
||||
"Cancel": "Batal",
|
||||
"Edit": "Sunting",
|
||||
"Delete": "Hapus",
|
||||
@ -25,40 +25,40 @@
|
||||
"Data_Deleted_Successfully": "Data Berhasil Dihapus",
|
||||
"Static_Pages": "Halaman Statis",
|
||||
"Failed_to_save_page__make_sure_i_can_write_to_folder_pages___i_chmod_664_pages___html_i_": "Gagal menyimpan halaman, pastikan diperbolehkan menulis file di folder pages, <i>chmod 664 pages\/*.html<i>",
|
||||
"Saving_page_success": "Menyimpan halaman sukses",
|
||||
"Saving_page_success": "Menyimpan halaman berhasil",
|
||||
"Sometimes_you_need_to_refresh_3_times_until_content_change": "Terkadang Anda perlu menyegarkan 3 kali hingga konten berubah",
|
||||
"Dashboard": "Dasbor",
|
||||
"Search_Customers___": "Cari Member...",
|
||||
"My_Account": "Akun Saya",
|
||||
"My_Profile": "Profil Saya",
|
||||
"Settings": "Pengaturan",
|
||||
"Edit_Profile": "Sunting profil",
|
||||
"Edit_Profile": "Sunting Profil",
|
||||
"Change_Password": "Ganti kata sandi",
|
||||
"Logout": "Keluar",
|
||||
"Services": "Layanan",
|
||||
"Bandwidth_Plans": "Paket Bandwidth",
|
||||
"Bandwidth_Name": "Nama Bandwidth",
|
||||
"New_Bandwidth": "Baru Bandwidth",
|
||||
"New_Bandwidth": "Bandwidth Baru",
|
||||
"Edit_Bandwidth": "Sunting Bandwidth",
|
||||
"Add_New_Bandwidth": "Tambahkan Bandwidth Baru",
|
||||
"Rate_Download": "Nilai Unduhan",
|
||||
"Rate_Upload": "Nilai Unggahan",
|
||||
"Name_Bandwidth_Already_Exist": "NamanBandwidth Sudah Ada",
|
||||
"Name_Bandwidth_Already_Exist": "Nama Bandwidth sudah ada",
|
||||
"Hotspot_Plans": "Paket Hotspot",
|
||||
"PPPOE_Plans": "Paket PPPoE",
|
||||
"Plan_Name": "Nama Paket",
|
||||
"New_Service_Plan": "Paket Layanan Baru",
|
||||
"Add_Service_Plan": "Tambah Paket Layanan",
|
||||
"Edit_Service_Plan": "Sunting Paket Layanan",
|
||||
"Name_Plan_Already_Exist": "Nama Paket Sudah Ada",
|
||||
"Name_Plan_Already_Exist": "Nama Paket sudah ada",
|
||||
"Plan_Type": "Jenis Paket",
|
||||
"Plan_Price": "Harga Paket",
|
||||
"Limit_Type": "Tipe Batas",
|
||||
"Unlimited": "Tak terbatas",
|
||||
"Unlimited": "Tak Terbatas",
|
||||
"Limited": "Terbatas",
|
||||
"Time_Limit": "Batas waktu",
|
||||
"Data_Limit": "Batas Data",
|
||||
"Both_Limit": "Keduanya Membatasi",
|
||||
"Both_Limit": "Membatasi keduanya",
|
||||
"Plan_Validity": "Waktu Paket",
|
||||
"Select_Bandwidth": "Pilih Bandwidth",
|
||||
"Shared_Users": "Berbagi Pelanggan",
|
||||
@ -69,16 +69,16 @@
|
||||
"Sales": "Sales",
|
||||
"Member": "Anggota",
|
||||
"Confirm_New_Password": "Konfirmasi sandi baru",
|
||||
"Confirm_Password": "konfirmasi sandi",
|
||||
"Confirm_Password": "Konfirmasi sandi",
|
||||
"Full_Name": "Nama Lengkap",
|
||||
"User_Type": "Tipe Pelanggan",
|
||||
"Address": "Alamat",
|
||||
"Created_On": "Dibuat pada",
|
||||
"Expires_On": "Kadaluarsa pada",
|
||||
"Expires_On": "Kedaluwarsa pada",
|
||||
"Phone_Number": "Nomor telepon",
|
||||
"User_deleted_Successfully": "Pelanggan berhasil dihapus",
|
||||
"Full_Administrator": "Administrator Penuh",
|
||||
"Keep_Blank_to_do_not_change_Password": "Biarkan Kosong apabila tidak ingin mengubah Kata Sandi",
|
||||
"Keep_Blank_to_do_not_change_Password": "Biarkan kosong apabila tidak ingin mengubah kata sandi",
|
||||
"Keep_it_blank_if_you_do_not_want_to_show_currency_code": "Kosongkan jika Anda tidak ingin menampilkan kode mata uang",
|
||||
"Theme_Style": "Gaya Tema",
|
||||
"Theme_Color": "Warna Tema",
|
||||
@ -91,28 +91,25 @@
|
||||
"Edit_Router": "Sunting Router",
|
||||
"Router_Name": "Nama Router",
|
||||
"IP_Address": "Alamat IP",
|
||||
"Router_Secret": "Rahasia Router",
|
||||
"Router_Secret": "Password Router",
|
||||
"Description": "Deskrispi",
|
||||
"IP_Router_Already_Exist": "IP Router Sudah Ada",
|
||||
"IP_Router_Already_Exist": "IP Router sudah ada",
|
||||
"Name_Pool": "Nama Pool",
|
||||
"Range_IP": "Rentang IP",
|
||||
"New_Pool": "Pool baru",
|
||||
"Add_Pool": "Tambahkan Pool",
|
||||
"Edit_Pool": "Sunting Pool",
|
||||
"Pool_Name_Already_Exist": "Nama Pool Sudah Ada",
|
||||
"Prepaid": "Prabayar",
|
||||
"Prepaid_Users": "Pengguna Prabayar",
|
||||
"Prepaid_Vouchers": "Voucher Prabayar",
|
||||
"Pool_Name_Already_Exist": "Nama Pool sudah ada",
|
||||
"Refill_Account": "Isi Ulang Akun",
|
||||
"Recharge_Account": "Isi Ulang Akun",
|
||||
"Select_Account": "Pilih Akun",
|
||||
"Service_Plan": "Paket Layanan",
|
||||
"Recharge": "Isi Ulang",
|
||||
"Method": "Metode",
|
||||
"Account_Created_Successfully": "Akun Berhasil Dibuat",
|
||||
"Account_Created_Successfully": "Akun berhasil dibuat",
|
||||
"Database_Status": "Status Database",
|
||||
"Total_Database_Size": "Ukuran Total Database",
|
||||
"Download_Database_Backup": "Unduh Cadangan Database",
|
||||
"Total_Database_Size": "Ukuran total database",
|
||||
"Download_Database_Backup": "Unduh cadangan database",
|
||||
"Table_Name": "Nama Tabel",
|
||||
"Rows": "Baris",
|
||||
"Size": "Ukuran",
|
||||
@ -126,15 +123,15 @@
|
||||
"Period_Reports": "Laporan Periode",
|
||||
"All_Transactions": "Semua Transaksi",
|
||||
"Total_Income": "Jumlah Pemasukan",
|
||||
"All_Transactions_at_Date": "Semua Transaksi pada Tanggal",
|
||||
"Export_for_Print": "Ekspor untuk Cetak",
|
||||
"All_Transactions_at_Date": "Semua transaksi pada ganggal",
|
||||
"Export_for_Print": "Ekspor untuk cetak",
|
||||
"Print": "Cetak",
|
||||
"Export_to_PDF": "Ekspor ke PDF",
|
||||
"Click_Here_to_Print": "Klik Disini untuk Mencetak",
|
||||
"You_can_use_html_tag": "Anda dapat menggunakan tag html",
|
||||
"Click_Here_to_Print": "Klik Disini untuk mencetak",
|
||||
"You_can_use_html_tag": "Anda dapat menggunakan tag HTML",
|
||||
"Date_Format": "Format tanggal",
|
||||
"Income_Today": "Pendapatan Hari Ini",
|
||||
"Income_This_Month": "Penghasilan Bulan Ini",
|
||||
"Income_Today": "Pendapatan hari ini",
|
||||
"Income_This_Month": "Penghasilan bulan ini",
|
||||
"Users_Active": "Pelanggan Aktif",
|
||||
"Total_Users": "Total Pelanggan",
|
||||
"Users": "Pelanggan",
|
||||
@ -152,11 +149,11 @@
|
||||
"Settings_Saved_Successfully": "Pengaturan Berhasil Disimpan",
|
||||
"User_Updated_Successfully": "Pengguna Berhasil Diperbarui",
|
||||
"User_Expired__Today": "Pengguna Kedaluwarsa, Hari Ini",
|
||||
"Activity_Log": "Log aktivitas",
|
||||
"Activity_Log": "Log Aktivitas",
|
||||
"View_Reports": "Lihat Laporan",
|
||||
"View_All": "Lihat semua",
|
||||
"Number_of_Vouchers": "Jumlah Voucher",
|
||||
"Length_Code": "Kode Panjang",
|
||||
"Length_Code": "Panjang Kode",
|
||||
"Code_Voucher": "Kode Voucher",
|
||||
"Voucher": "Voucher",
|
||||
"Hotspot_Voucher": "Voucher Hotspot",
|
||||
@ -177,10 +174,10 @@
|
||||
"Timezone": "Zona waktu",
|
||||
"Decimal_Point": "Titik Desimal",
|
||||
"Thousands_Separator": "Pemisah Ribuan",
|
||||
"Currency_Code": "Kode mata uang",
|
||||
"Currency_Code": "Kode Mata Uang",
|
||||
"Order_Voucher": "Pesan Voucher",
|
||||
"Voucher_Activation": "Aktivasi Voucher",
|
||||
"List_Activated_Voucher": "Daftar Voucher yang Diaktifkan",
|
||||
"List_Activated_Voucher": "Daftar Voucher yang diaktifkan",
|
||||
"Enter_voucher_code_here": "Masukkan kode voucher di sini",
|
||||
"Private_Message": "Pesan Pribadi",
|
||||
"Inbox": "Kotak Masuk",
|
||||
@ -191,17 +188,17 @@
|
||||
"Message": "Pesan",
|
||||
"Your_Account_Information": "Informasi Akun Anda",
|
||||
"Welcome_to_the_Panel_Members_page__on_this_page_you_can_": "Selamat datang di halaman Anggota Panel, di halaman ini Anda dapat:",
|
||||
"Invalid_Username_or_Password": "Nama pengguna dan kata sandi salah",
|
||||
"Invalid_Username_or_Password": "Nama pengguna atau kata sandi salah",
|
||||
"You_do_not_have_permission_to_access_this_page": "Anda tidak memiliki izin untuk mengakses halaman ini",
|
||||
"Incorrect_Current_Password": "Kata Sandi Saat Ini Salah",
|
||||
"Password_changed_successfully__Please_login_again": "Kata sandi berhasil diubah, Silakan login kembali",
|
||||
"Incorrect_Current_Password": "Kata sandi saat ini salah",
|
||||
"Password_changed_successfully__Please_login_again": "Kata sandi berhasil diubah, silakan login kembali",
|
||||
"All_field_is_required": "Semua bidang wajib diisi",
|
||||
"Voucher_Not_Valid": "Voucher Tidak Berlaku",
|
||||
"Voucher_Not_Valid": "Voucher tidak berlaku",
|
||||
"Activation_Vouchers_Successfully": "Aktivasi Voucher Berhasil",
|
||||
"Data_Not_Found": "Data Tidak Ditemukan",
|
||||
"Search_by_Username": "Cari berdasarkan Nama Pengguna",
|
||||
"Search_by_Name": "Cari berdasarkan Nama",
|
||||
"Search_by_Code_Voucher": "Cari berdasarkan Kode Voucher",
|
||||
"Data_Not_Found": "Data tidak ditemukan",
|
||||
"Search_by_Username": "Cari berdasarkan nama pengguna",
|
||||
"Search_by_Name": "Cari berdasarkan nama",
|
||||
"Search_by_Code_Voucher": "Cari berdasarkan kode voucher",
|
||||
"Search": "Mencari",
|
||||
"Select_a_customer": "Pilih pelanggan",
|
||||
"Select_Routers": "Pilih Router",
|
||||
@ -215,25 +212,25 @@
|
||||
"Language_Name": "Nama Bahasa",
|
||||
"Folder_Name": "Nama Folder",
|
||||
"Translator": "Penerjemah",
|
||||
"Language_Name_Already_Exist": "Nama Bahasa Sudah Ada",
|
||||
"Language_Name_Already_Exist": "Nama Bahasa sudah ada",
|
||||
"Payment_Gateway": "Gerbang Pembayaran",
|
||||
"Community": "Komunitas",
|
||||
"1_user_can_be_used_for_many_devices_": "1 pengguna bisa digunakan untuk banyak perangkat?",
|
||||
"Cannot_be_change_after_saved": "Tidak dapat diubah setelah disimpan",
|
||||
"Explain_Coverage_of_router": "Jelaskan Cakupan router",
|
||||
"Explain_Coverage_of_router": "Jelaskan cakupan router",
|
||||
"Name_of_Area_that_router_operated": "Nama area tempat router dioperasikan",
|
||||
"Payment_Notification_URL__Recurring_Notification_URL__Pay_Account_Notification_URL": "URL Notifikasi Pembayaran, URL Notifikasi Berulang, URL Notifikasi Akun Bayar",
|
||||
"Finish_Redirect_URL__Unfinish_Redirect_URL__Error_Redirect_URL": "Selesaikan URL Pengalihan, Selesaikan URL Pengalihan, URL Pengalihan Kesalahan",
|
||||
"Payment_Notification_URL__Recurring_Notification_URL__Pay_Account_Notification_URL": "URL notifikasi pembayaran, URL notifikasi berulang, URL notifikasi akun bayar",
|
||||
"Finish_Redirect_URL__Unfinish_Redirect_URL__Error_Redirect_URL": "Selesaikan URL pengalihan, selesaikan URL pengalihan, URL pengalihan kesalahan",
|
||||
"Status": "Status",
|
||||
"Plan_Not_found": "Paket Tidak ditemukan",
|
||||
"Plan_Not_found": "Paket tidak ditemukan",
|
||||
"Failed_to_create_transaction_": "Gagal membuat transaksi.",
|
||||
"Seller_has_not_yet_setup_Xendit_payment_gateway": "Penjual belum menyiapkan gateway pembayaran Xendit",
|
||||
"Admin_has_not_yet_setup_Xendit_payment_gateway__please_tell_admin": "Admin belum menyiapkan gerbang pembayaran Xendit, mohon beritahu admin",
|
||||
"Admin_has_not_yet_setup_Xendit_payment_gateway__please_tell_admin": "Admin belum menyiapkan gerbang pembayaran Xendit, mohon beritahu Admin",
|
||||
"Buy_this__your_active_package_will_be_overwrite": "Beli ini? Paket aktif Anda akan ditimpa",
|
||||
"You_already_have_unpaid_transaction__cancel_it_or_pay_it_": "Anda sudah memiliki transaksi yang belum dibayar, batalkan atau bayar.",
|
||||
"Transaction_Not_found": "Transaksi Tidak ditemukan",
|
||||
"Transaction_Not_found": "Transaksi tidak ditemukan",
|
||||
"Cancel_it_": "Batalkan itu?",
|
||||
"expired": "kedaluwarsa",
|
||||
"expired": "Kedaluwarsa",
|
||||
"Check_for_Payment": "Periksa Pembayaran",
|
||||
"Transaction_still_unpaid_": "Transaksi masih belum dibayar.",
|
||||
"Paid_Date": "Tanggal Pembayaran",
|
||||
@ -246,9 +243,9 @@
|
||||
"Buy_PPOE_Plan": "Beli Paket PPPoE",
|
||||
"Package": "Paket",
|
||||
"Order_Internet_Package": "Pesan Paket Internet",
|
||||
"Unknown_Command_": "Perintah Tidak Diketahui.",
|
||||
"Unknown_Command_": "Perintah tidak diketahui.",
|
||||
"Checking_payment": "Memeriksa pembayaran",
|
||||
"Create_Transaction_Success": "Transaksi Berhasil Dibuat",
|
||||
"Create_Transaction_Success": "Transaksi berhasil dibuat",
|
||||
"You_have_unpaid_transaction": "Anda memiliki transaksi yang belum dibayar",
|
||||
"TripayPayment_Channel": "Saluran Pembayaran Tripay",
|
||||
"Payment_Channel": "Saluran Pembayaran",
|
||||
@ -261,16 +258,16 @@
|
||||
"Gateway": "Gerbang",
|
||||
"Date_Done": "Tanggal Selesai",
|
||||
"Unpaid_Order": "Pesanan Belum Dibayar",
|
||||
"Payment_Gateway_Not_Found": "Gerbang Pembayaran Tidak Ditemukan",
|
||||
"Payment_Gateway_Not_Found": "Gerbang Pembayaran tidak ditemukan",
|
||||
"Payment_Gateway_saved_successfully": "Gerbang Pembayaran berhasil disimpan",
|
||||
"ORDER": "MEMESAN",
|
||||
"Package_History": "Riwayat Paket",
|
||||
"Buy_History": "Riwayat Beli",
|
||||
"Activation_History": "Riwayat Aktivasi",
|
||||
"Buy_Package": "Beli Paket",
|
||||
"Email": "Surel",
|
||||
"Email": "Email",
|
||||
"Company_Footer": "Catatan Kaki Perusahaan",
|
||||
"Will_show_below_user_pages": "Akan ditampilkan di bawah halaman pengguna",
|
||||
"Will_show_below_user_pages": "Akan ditampilkan dibawah halaman pengguna",
|
||||
"Request_OTP": "Minta OTP",
|
||||
"Verification_Code": "Kode Verifikasi",
|
||||
"SMS_Verification_Code": "Kode Verifikasi SMS",
|
||||
@ -279,7 +276,7 @@
|
||||
"Plugin": "Plugin",
|
||||
"Plugin_Manager": "Manajer Plugin",
|
||||
"User_Notification": "Pemberitahuan Pelanggan",
|
||||
"Expired_Notification": "Pemberitahuan Kedaluarsa",
|
||||
"Expired_Notification": "Pemberitahuan Kedaluwarsa",
|
||||
"User_will_get_notification_when_package_expired": "Pengguna akan mendapat notifikasi ketika paket sudah habis masa berlakunya",
|
||||
"Expired_Notification_Message": "Pesan Pemberitahuan Kedaluwarsa",
|
||||
"Payment_Notification": "Notifikasi Pembayaran",
|
||||
@ -287,15 +284,15 @@
|
||||
"Current_IP": "IP saat ini",
|
||||
"Current_MAC": "MAC saat ini",
|
||||
"Login_Status": "Status Masuk",
|
||||
"Login_Request_successfully": "Permintaan Masuk berhasil",
|
||||
"Logout_Request_successfully": "Permintaan Keluar berhasil",
|
||||
"Disconnect_Internet_": "Putuskan sambungan Internet?",
|
||||
"Not_Online__Login_now_": "Tidak , Masuk sekarang?",
|
||||
"Login_Request_successfully": "Permintaan masuk berhasil",
|
||||
"Logout_Request_successfully": "Permintaan keluar berhasil",
|
||||
"Disconnect_Internet_": "Putuskan sambungan internet?",
|
||||
"Not_Online__Login_now_": "Tidak, masuk sekarang?",
|
||||
"You_are_Online__Logout_": "Kamu sedang aktif, ingin keluar?",
|
||||
"Connect_to_Internet_": "Hubungkan ke Internet?",
|
||||
"Your_account_not_connected_to_internet": "Akun Anda tidak terhubung ke internet",
|
||||
"Failed_to_create_transaction__": "Gagal membuat transaksi. ",
|
||||
"Failed_to_check_status_transaction__": "Gagal memeriksa status transaksi. ",
|
||||
"Failed_to_check_status_transaction__": "Gagal memeriksa status transaksi.",
|
||||
"Disable_Voucher": "Nonaktifkan Voucher",
|
||||
"Balance": "Saldo",
|
||||
"Balance_System": "Saldo Sistem",
|
||||
@ -316,7 +313,7 @@
|
||||
"Reminder_3_days": "Pengingat 3 hari",
|
||||
"Reminder_1_day": "Pengingat 1 hari",
|
||||
"PPPOE_Password": "Kata sandi PPPoE",
|
||||
"User_Cannot_change_this__only_admin__if_it_Empty_it_will_use_user_password": "Pelanggan tidak dapat mengubah ini, hanya Admin. Jika kosong maka akan menggunakan kata sandi pelanggan",
|
||||
"User_Cannot_change_this__only_admin__if_it_Empty_it_will_use_user_password": "Pelanggan tidak dapat mengubah ini, hanya Admin. Jika kosong maka akan menggunakan kata sandi pelanggan",
|
||||
"Invoice_Balance_Message": "Faktur Pesan Saldo",
|
||||
"Invoice_Notification_Payment": "Faktur Pemberitahuan Pembayaran",
|
||||
"Balance_Notification_Payment": "Saldo Pemberitahuan Pembayaran",
|
||||
@ -325,9 +322,9 @@
|
||||
"Price": "Harga",
|
||||
"Validity": "Waktu",
|
||||
"Disable_auto_renewal_": "Nonaktifkan perpanjangan otomatis?",
|
||||
"Auto_Renewal_On": "Perpanjangan Otomatis Aktif",
|
||||
"Auto_Renewal_On": "Perpanjangan otomatis aktif",
|
||||
"Enable_auto_renewal_": "Aktifkan perpanjangan otomatis?",
|
||||
"Auto_Renewal_Off": "Perpanjangan Otomatis Mati",
|
||||
"Auto_Renewal_Off": "Perpanjangan otomatis mati",
|
||||
"Refill_Balance": "Isi Ulang Saldo",
|
||||
"Invoice_Footer": "Catatan Kaki Faktur",
|
||||
"Pay_With_Balance": "Bayar dengan Saldo",
|
||||
@ -337,7 +334,7 @@
|
||||
"View": "Melihat",
|
||||
"Back": "Kembali",
|
||||
"Active": "Aktif",
|
||||
"Transfer_Balance": "Kirim Saldo",
|
||||
"Transfer_Balance": "Kirim saldo",
|
||||
"Send_your_balance_": "Kirim saldo Anda?",
|
||||
"Send": "Kirim",
|
||||
"Cannot_send_to_yourself": "Tidak dapat mengirim ke diri Anda sendiri",
|
||||
@ -345,9 +342,9 @@
|
||||
"From": "Dari",
|
||||
"To": "Ke",
|
||||
"insufficient_balance": "Saldo tidak mencukupi",
|
||||
"Send_Balance": "Kirim Saldo",
|
||||
"Received_Balance": "Saldo yang Diterima",
|
||||
"Minimum_Balance_Transfer": "Minimal Transfer Saldo",
|
||||
"Send_Balance": "Kirim saldo",
|
||||
"Received_Balance": "Saldo yang diterima",
|
||||
"Minimum_Balance_Transfer": "Minimal transfer saldo",
|
||||
"Minimum_Transfer": "Minimal Transfer",
|
||||
"Company_Logo": "Logo Perusahaan",
|
||||
"Expired_IP_Pool": "IP Pool Kedaluwarsa",
|
||||
@ -364,21 +361,116 @@
|
||||
"Buy_for_friend": "Beli untuk teman",
|
||||
"Buy_this_for_friend_account_": "Beli ini untuk akun teman?",
|
||||
"Review_package_before_recharge": "Tinjau paket sebelum mengisi ulang",
|
||||
"Activate": "Mengaktifkan Paket",
|
||||
"Deactivate": "Menonaktifkan Paket",
|
||||
"Activate": "Mengaktifkan paket",
|
||||
"Deactivate": "Menonaktifkan paket",
|
||||
"Sync": "Sinkronisasi",
|
||||
"Failed_to_create_PaymeTrust_transaction_": "Gagal membuat transaksi PaymeTrust.",
|
||||
"Location": "Lokasi",
|
||||
"Radius_Plans": "Paket Radius",
|
||||
"Change_title_in_user_Plan_order": "Ubah judul dalam urutan paket pelanggan",
|
||||
"Change_title_in_user_Plan_order": "Ubah Judul dalam urutan paket pelanggan",
|
||||
"Logs": "Log",
|
||||
"Voucher_Format": "Format Voucher",
|
||||
"Resend_To_Customer": "Kirim Ulang Ke Pelanggan",
|
||||
"Service_Type": "Service Type",
|
||||
"Service_Type": "Jenis Layanan",
|
||||
"Others": "Lainnya",
|
||||
"PPPoE": "PPPoE",
|
||||
"Hotspot": "Hotspot",
|
||||
"Monthly_Registered_Customers": "Pendaftaran Pelanggan perbulan",
|
||||
"Total_Monthly_Sales": "Total penjualan Perbulan",
|
||||
"Active_Users": "Pelanggan Aktif"
|
||||
}
|
||||
"Total_Monthly_Sales": "Total penjualan perbulan",
|
||||
"Active_Users": "Pelanggan Aktif",
|
||||
"SuperAdmin": "Super Admin",
|
||||
"Lists": "Daftar",
|
||||
"Vouchers": "Voucher",
|
||||
"Refill_Customer": "Isi Ulang Pelanggan",
|
||||
"Recharge_Customer": "Isi Ulang Pelanggan",
|
||||
"Plans": "Paket",
|
||||
"PPPOE": "PPPOE",
|
||||
"Bandwidth": "Bandwidth",
|
||||
"Send_Message": "Mengirim pesan",
|
||||
"Single_Customer": "Pelanggan Tunggal",
|
||||
"Bulk_Customers": "Pelanggan Massal",
|
||||
"Radius": "Radius",
|
||||
"Radius_NAS": "Radius NAS",
|
||||
"Customer_Announcement": "Pengumuman Pelanggan",
|
||||
"Language_Editor": "Editor Bahasa",
|
||||
"Plan_Category": "Kategori Paket",
|
||||
"ID": "ID",
|
||||
"Prev": "Sebelumnya",
|
||||
"Internet_Plan": "Paket Internet",
|
||||
"Generated_By": "Dihasilkan oleh",
|
||||
"All_Users_Insights": "Semua Wawasan Pengguna",
|
||||
"year": "Tahun",
|
||||
"month": "Bulan",
|
||||
"week": "Pekan",
|
||||
"day": "Hari",
|
||||
"hour": "Jam",
|
||||
"minute": "Menit",
|
||||
"second": "Kedua",
|
||||
"Account_Type": "Jenis akun",
|
||||
"Contact": "Kontak",
|
||||
"Paid": "Dibayar",
|
||||
"Personal": "Pribadi",
|
||||
"Coordinates": "Koordinat",
|
||||
"Confirm": "Mengonfirmasi",
|
||||
"Name": "Nama",
|
||||
"Plan": "Paket",
|
||||
"Using": "Menggunakan",
|
||||
"Total": "Total",
|
||||
"Additional_Cost": "Biaya tambahan",
|
||||
"Resend": "Kirim ulang",
|
||||
"Login": "Masuk",
|
||||
"success": "Sukses",
|
||||
"Click_Here": "Klik disini",
|
||||
"Your_friend_do_not_have_active_package": "Teman Anda tidak memiliki paket aktif",
|
||||
"If_your_friend_have_Additional_Cost__you_will_pay_for_that_too": "Jika teman Anda memiliki biaya tambahan, Anda juga akan membayarnya",
|
||||
"Select_Payment_Gateway": "Pilih Gerbang Pembayaran",
|
||||
"Available_Payment_Gateway": "Gerbang Pembayaran yang tersedia",
|
||||
"Pay_Now": "Bayar sekarang",
|
||||
"Notes": "Catatan",
|
||||
"will_be_replaced_with_Customer_Name": "akan diganti dengan nama Pelanggan",
|
||||
"will_be_replaced_with_Customer_username": "akan diganti dengan nama pengguna Pelanggan",
|
||||
"will_be_replaced_with_Package_name": "akan diganti dengan nama paket",
|
||||
"will_be_replaced_with_Package_price": "akan diganti dengan harga Paket",
|
||||
"will_be_replaced_with_Expiration_date": "akan diganti dengan tanggal kedaluwarsa",
|
||||
"additional_bills_for_customers": "tagihan tambahan untuk pelanggan",
|
||||
"Your_Company_Name_at_Settings": "Nama Perusahaan Anda di pengaturan",
|
||||
"Your_Company_Address_at_Settings": "Alamat Perusahaan Anda di pengaturan",
|
||||
"Your_Company_Phone_at_Settings": "Telepon Perusahaan Anda di pengaturan",
|
||||
"Invoice_number": "Nomor faktur",
|
||||
"Date_invoice_created": "Tanggal faktur dibuat",
|
||||
"Payment_gateway_user_paid_from": "Pengguna gateway pembayaran membayar dari",
|
||||
"Payment_channel_user_paid_from": "Pengguna saluran pembayaran membayar dari",
|
||||
"is_Hotspot_or_PPPOE": "adalah Hotspot atau PPPOE",
|
||||
"Internet_Package": "Paket internet",
|
||||
"Internet_Package_Prices": "Harga paket internet",
|
||||
"Receiver_name": "Nama penerima",
|
||||
"Username_internet": "Nama pengguna internet",
|
||||
"User_password": "Kata sandi pengguna",
|
||||
"Transaction_datetime": "Tanggal waktu transaksi",
|
||||
"Balance_Before": "Saldo sebelumnya",
|
||||
"Balance_After": "Saldo setelahnya",
|
||||
"For_Notes_by_admin": "Untuk catatan oleh Admin",
|
||||
"how_much_balance_have_been_send": "berapa banyak saldo yang telah dikirim",
|
||||
"Current_Balance": "Saldo saat ini",
|
||||
"Sender_name": "Nama pengirim",
|
||||
"Customer_Balance": "Saldo Pelanggan",
|
||||
"Privacy_Policy": "Kebijakan Privasi",
|
||||
"Terms_and_Conditions": "Syarat dan Ketentuan",
|
||||
"Disable_Registration": "Nonaktifkan Pendaftaran",
|
||||
"Customer_just_Login_with_Phone_number_and_Voucher_Code__Voucher_will_be_password": "Pelanggan cukup masuk dengan nomor telepon dan kode voucher, Voucher akan menjadi kata sandi",
|
||||
"After_Customer_activate_voucher_or_login__customer_will_be_redirected_to_this_url": "Setelah Pelanggan mengaktifkan voucher atau masuk, Pelanggan akan diarahkan ke URL ini",
|
||||
"Extend_Postpaid_Expiration": "Perpanjang masa kedaluwarsa pascabayar",
|
||||
"Allow_Extend": "Izinkan Perpanjang",
|
||||
"Extend_Days": "Perpanjang Hari",
|
||||
"Confirmation_Message": "Pesan konfirmasi",
|
||||
"Email_Notification": "Pemberitahuan Email",
|
||||
"This_Token_will_act_as_SuperAdmin_Admin": "Token ini akan bertindak sebagai SuperAdmin\/Admin",
|
||||
"Miscellaneous": "Aneka ragam",
|
||||
"OTP_Required": "Diperlukan OTP",
|
||||
"OTP_is_required_when_user_want_to_change_phone_number": "OTP diperlukan ketika pengguna ingin mengganti nomor telepon",
|
||||
"OTP_Method": "Metode OTP",
|
||||
"SMS": "SMS",
|
||||
"WhatsApp": "WhatsApp",
|
||||
"SMS_and_WhatsApp": "SMS dan WhatsApp",
|
||||
"The_method_which_OTP_will_be_sent_to_user": "Metode OTP yang akan dikirimkan ke pengguna"
|
||||
}
|
||||
|
@ -100,9 +100,6 @@
|
||||
"Add_Pool": "Agregar Pool",
|
||||
"Edit_Pool": "Editar Pool",
|
||||
"Pool_Name_Already_Exist": "Nombre del Pool ya existe",
|
||||
"Prepaid": "Prepago",
|
||||
"Prepaid_Users": "Usuarios prepago",
|
||||
"Prepaid_Vouchers": "Fichas prepago",
|
||||
"Refill_Account": "Recargar Ficha",
|
||||
"Recharge_Account": "Recargar Cuenta",
|
||||
"Select_Account": "Seleccionar cuenta",
|
||||
|
@ -96,9 +96,6 @@
|
||||
"Add_Pool": "Havuz ekle",
|
||||
"Edit_Pool": "Havuzu D\u00fczenle",
|
||||
"Pool_Name_Already_Exist": "Havuz Ad\u0131 \u200b\u200bZaten Var",
|
||||
"Prepaid": "\u00d6n \u00d6demeli",
|
||||
"Prepaid_Users": "\u00d6n \u00d6demeli Kullan\u0131c\u0131lar",
|
||||
"Prepaid_Vouchers": "\u00d6n \u00d6demeli Kuponlar",
|
||||
"Refill_Account": "Hesab\u0131 Yenile",
|
||||
"Recharge_Account": "Hesab\u0131 Yeniden \u015earj Et",
|
||||
"Select_Account": "Hesap Se\u00e7",
|
||||
|
5204
system/orm.php
5204
system/orm.php
File diff suppressed because it is too large
Load Diff
@ -6,13 +6,13 @@
|
||||
"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_customers` ADD `pppoe_password` varchar(45) NOT NULL DEFAULT '' 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`;"
|
||||
],
|
||||
"2023.8.23": [
|
||||
"ALTER TABLE `tbl_customers` CHANGE `pppoe_password` `pppoe_password` VARCHAR(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT 'For PPPOE Login';"
|
||||
"ALTER TABLE `tbl_customers` CHANGE `pppoe_password` `pppoe_password` VARCHAR(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'For PPPOE Login';"
|
||||
],
|
||||
"2023.8.28": [
|
||||
"ALTER TABLE `tbl_user_recharges` ADD `recharged_time` time NOT NULL DEFAULT '00:00:00' AFTER `recharged_on`;",
|
||||
@ -72,5 +72,26 @@
|
||||
],
|
||||
"2024.3.3" : [
|
||||
"ALTER TABLE `tbl_plans` CHANGE `validity_unit` `validity_unit` ENUM('Mins','Hrs','Days','Months','Period') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;"
|
||||
],
|
||||
"2024.3.12" : [
|
||||
"ALTER TABLE `tbl_plans` CHANGE `allow_purchase` `prepaid` ENUM('yes','no') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'yes' COMMENT 'is prepaid';"
|
||||
],
|
||||
"2024.3.14" : [
|
||||
"ALTER TABLE `tbl_transactions` ADD `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT 'for note' AFTER `type`;"
|
||||
],
|
||||
"2024.3.19" : [
|
||||
"ALTER TABLE `tbl_customers` ADD `coordinates` VARCHAR(50) NOT NULL DEFAULT '' COMMENT 'Latitude and Longitude coordinates' AFTER `email`;"
|
||||
],
|
||||
"2024.3.19.1" : [
|
||||
"ALTER TABLE `tbl_customers` ADD `account_type` ENUM('Business', 'Personal') DEFAULT 'Personal' COMMENT 'For selecting account type' AFTER `coordinates`;"
|
||||
],
|
||||
"2024.3.19.2" : [
|
||||
"ALTER TABLE `tbl_plans` ADD `plan_type` ENUM('Business', 'Personal') DEFAULT 'Personal' COMMENT 'For selecting account type' ;"
|
||||
],
|
||||
"2023.3.20": [
|
||||
"ALTER TABLE `tbl_customers` CHANGE `pppoe_password` `pppoe_password` VARCHAR(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'For PPPOE Login';"
|
||||
],
|
||||
"2024.4.5" : [
|
||||
"ALTER TABLE `tbl_payment_gateway` ADD `trx_invoice` VARCHAR(25) NOT NULL DEFAULT '' COMMENT 'from tbl_transactions' AFTER `paid_date`;"
|
||||
]
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Directory access is forbidden.</p>
|
||||
</body>
|
||||
</html>
|
@ -1,9 +1,9 @@
|
||||
$(document).on("click", ".cdelete", function(e) {
|
||||
e.preventDefault();
|
||||
var id = this.id;
|
||||
bootbox.confirm("Are you sure?", function(result) {
|
||||
if(result){
|
||||
window.location.href = "index.php?_route=prepaid/delete/" + id;
|
||||
}
|
||||
});
|
||||
$(document).on("click", ".cdelete", function(e) {
|
||||
e.preventDefault();
|
||||
var id = this.id;
|
||||
bootbox.confirm("Are you sure?", function(result) {
|
||||
if(result){
|
||||
window.location.href = "index.php?_route=plan/delete/" + id;
|
||||
}
|
||||
});
|
||||
});
|
@ -3,7 +3,7 @@
|
||||
var id = this.id;
|
||||
bootbox.confirm("Are you sure?", function(result) {
|
||||
if(result){
|
||||
window.location.href = "index.php?_route=prepaid/voucher-delete/" + id;
|
||||
window.location.href = "index.php?_route=plan/voucher-delete/" + id;
|
||||
}
|
||||
});
|
||||
});
|
@ -4,19 +4,19 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>{$_title} - {Lang::T('Login')}</title>
|
||||
<title>{Lang::T('Login')} - {$_c['CompanyName']}</title>
|
||||
<link rel="shortcut icon" href="ui/ui/images/logo.png" type="image/x-icon" />
|
||||
|
||||
<link rel="stylesheet" href="ui/ui/styles/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="ui/ui/styles/modern-AdminLTE.min.css">
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="hold-transition login-page">
|
||||
<div class="login-box">
|
||||
<div class="login-logo">
|
||||
<b>Nux</b>Billing
|
||||
{$_c['CompanyName']}
|
||||
</div>
|
||||
<div class="login-box-body">
|
||||
<p class="login-box-msg">{Lang::T('Enter Admin Area')}</p>
|
||||
|
@ -17,12 +17,14 @@
|
||||
<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>
|
||||
rows="4">{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">
|
||||
<b>[[name]]</b> will be replaced with Customer Name.
|
||||
<b>[[package]]</b> will be replaced with Package name.
|
||||
<b>[[price]]</b> will be replaced with Package price.
|
||||
<b>[[name]]</b> - {Lang::T('will be replaced with Customer Name')}.<br>
|
||||
<b>[[username]]</b> - {Lang::T('will be replaced with Customer username')}.<br>
|
||||
<b>[[package]]</b> - {Lang::T('will be replaced with Package name')}.<br>
|
||||
<b>[[price]]</b> - {Lang::T('will be replaced with Package price')}.<br>
|
||||
<b>[[bills]]</b> - {Lang::T('additional bills for customers')}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -31,13 +33,15 @@
|
||||
<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>
|
||||
rows="4">{Lang::htmlspecialchars($_json['reminder_7_day'])}</textarea>
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
<b>[[name]]</b> will be replaced with Customer Name.
|
||||
<b>[[package]]</b> will be replaced with Package name.
|
||||
<b>[[price]]</b> will be replaced with Package price.
|
||||
<b>[[expired_date]]</b> will be replaced with Expiration date.
|
||||
<b>[[name]]</b> - {Lang::T('will be replaced with Customer Name')}.<br>
|
||||
<b>[[username]]</b> - {Lang::T('will be replaced with Customer username')}.<br>
|
||||
<b>[[package]]</b> - {Lang::T('will be replaced with Package name')}.<br>
|
||||
<b>[[price]]</b> - {Lang::T('will be replaced with Package price')}.<br>
|
||||
<b>[[expired_date]]</b> - {Lang::T('will be replaced with Expiration date')}.<br>
|
||||
<b>[[bills]]</b> - {Lang::T('additional bills for customers')}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -46,13 +50,15 @@
|
||||
<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>
|
||||
rows="4">{Lang::htmlspecialchars($_json['reminder_3_day'])}</textarea>
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
<b>[[name]]</b> will be replaced with Customer Name.
|
||||
<b>[[package]]</b> will be replaced with Package name.
|
||||
<b>[[price]]</b> will be replaced with Package price.
|
||||
<b>[[expired_date]]</b> will be replaced with Expiration date.
|
||||
<b>[[name]]</b> - {Lang::T('will be replaced with Customer Name')}.<br>
|
||||
<b>[[username]]</b> - {Lang::T('will be replaced with Customer username')}.<br>
|
||||
<b>[[package]]</b> - {Lang::T('will be replaced with Package name')}.<br>
|
||||
<b>[[price]]</b> - {Lang::T('will be replaced with Package price')}.<br>
|
||||
<b>[[expired_date]]</b> - {Lang::T('will be replaced with Expiration date')}.<br>
|
||||
<b>[[bills]]</b> - {Lang::T('additional bills for customers')}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -61,13 +67,15 @@
|
||||
<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>
|
||||
rows="4">{Lang::htmlspecialchars($_json['reminder_1_day'])}</textarea>
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
<b>[[name]]</b> will be replaced with Customer Name.
|
||||
<b>[[package]]</b> will be replaced with Package name.
|
||||
<b>[[price]]</b> will be replaced with Package price.
|
||||
<b>[[expired_date]]</b> will be replaced with Expiration date.
|
||||
<b>[[name]]</b> - {Lang::T('will be replaced with Customer Name')}.<br>
|
||||
<b>[[username]]</b> - {Lang::T('will be replaced with Customer username')}.<br>
|
||||
<b>[[package]]</b> - {Lang::T('will be replaced with Package name')}.<br>
|
||||
<b>[[price]]</b> - {Lang::T('will be replaced with Package price')}.<br>
|
||||
<b>[[expired_date]]</b> - {Lang::T('will be replaced with Expiration date')}.<br>
|
||||
<b>[[bills]]</b> - {Lang::T('additional bills for customers')}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -80,21 +88,22 @@
|
||||
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>[[name]]</b> Receiver name.<br>
|
||||
<b>[[user_name]]</b> Username internet.<br>
|
||||
<b>[[user_password]]</b> User password.<br>
|
||||
<b>[[expired_date]]</b> Expired datetime.<br>
|
||||
<b>[[footer]]</b> Invoice Footer.
|
||||
<b>[[company_name]]</b> {Lang::T('Your Company Name at Settings')}.<br>
|
||||
<b>[[address]]</b> {Lang::T('Your Company Address at Settings')}.<br>
|
||||
<b>[[phone]]</b> - {Lang::T('Your Company Phone at Settings')}.<br>
|
||||
<b>[[invoice]]</b> - {Lang::T('Invoice number')}.<br>
|
||||
<b>[[date]]</b> - {Lang::T('Date invoice created')}.<br>
|
||||
<b>[[payment_gateway]]</b> - {Lang::T('Payment gateway user paid from')}.<br>
|
||||
<b>[[payment_channel]]</b> - {Lang::T('Payment channel user paid from')}.<br>
|
||||
<b>[[type]]</b> - {Lang::T('is Hotspot or PPPOE')}.<br>
|
||||
<b>[[plan_name]]</b> - {Lang::T('Internet Package')}.<br>
|
||||
<b>[[plan_price]]</b> - {Lang::T('Internet Package Prices')}.<br>
|
||||
<b>[[name]]</b> - {Lang::T('Receiver name')}.<br>
|
||||
<b>[[user_name]]</b> - {Lang::T('Username internet')}.<br>
|
||||
<b>[[user_password]]</b> - {Lang::T('User password')}.<br>
|
||||
<b>[[expired_date]]</b> - {Lang::T('Expired datetime')}.<br>
|
||||
<b>[[footer]]</b> - {Lang::T('Invoice Footer')}.<br>
|
||||
<b>[[note]]</b> - {Lang::T('For Notes by admin')}.<br>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -107,54 +116,56 @@
|
||||
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>[[name]]</b> Receiver name.<br>
|
||||
<b>[[user_name]]</b> Username internet.<br>
|
||||
<b>[[user_password]]</b> User password.<br>
|
||||
<b>[[trx_date]]</b> Transaction datetime.<br>
|
||||
<b>[[balance_before]]</b> Balance Before.<br>
|
||||
<b>[[balance]]</b> Balance After.<br>
|
||||
<b>[[footer]]</b> Invoice Footer.
|
||||
<b>[[company_name]]</b> - {Lang::T('Your Company Name at Settings')}.<br>
|
||||
<b>[[address]]</b> - {Lang::T('Your Company Address at Settings')}.<br>
|
||||
<b>[[phone]]</b> - {Lang::T('Your Company Phone at Settings')}.<br>
|
||||
<b>[[invoice]]</b> - {Lang::T('Invoice number')}.<br>
|
||||
<b>[[date]]</b> - {Lang::T('Date invoice created')}.<br>
|
||||
<b>[[payment_gateway]]</b> - {Lang::T('Payment gateway user paid from')}.<br>
|
||||
<b>[[payment_channel]]</b> - {Lang::T('Payment channel user paid from')}.<br>
|
||||
<b>[[type]]</b> - {Lang::T('is Hotspot or PPPOE')}.<br>
|
||||
<b>[[plan_name]]</b> - {Lang::T('Internet Package')}.<br>
|
||||
<b>[[plan_price]]</b> - {Lang::T('Internet Package Prices')}.<br>
|
||||
<b>[[name]]</b> - {Lang::T('Receiver name')}.<br>
|
||||
<b>[[user_name]]</b> - {Lang::T('Username internet')}.<br>
|
||||
<b>[[user_password]]</b> - {Lang::T('User password')}.<br>
|
||||
<b>[[trx_date]]</b> - {Lang::T('Transaction datetime')}.<br>
|
||||
<b>[[balance_before]]</b> - {Lang::T('Balance Before')}.<br>
|
||||
<b>[[balance]]</b> - {Lang::T('Balance After')}.<br>
|
||||
<b>[[footer]]</b> - {Lang::T('Invoice Footer')}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Send Balance')}</label>
|
||||
<div class="col-md-6">
|
||||
<textarea class="form-control" id="balance_send" name="balance_send"
|
||||
rows="3">{if $_json['balance_send']}{Lang::htmlspecialchars($_json['balance_send'])}{else}{Lang::htmlspecialchars($_default['balance_send'])}{/if}</textarea>
|
||||
{if $_c['enable_balance'] == 'yes'}
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Send Balance')}</label>
|
||||
<div class="col-md-6">
|
||||
<textarea class="form-control" id="balance_send" name="balance_send"
|
||||
rows="4">{if $_json['balance_send']}{Lang::htmlspecialchars($_json['balance_send'])}{else}{Lang::htmlspecialchars($_default['balance_send'])}{/if}</textarea>
|
||||
</div>
|
||||
<p class="col-md-4 help-block">
|
||||
<b>[[name]]</b> - {Lang::T('Receiver name')}.<br>
|
||||
<b>[[balance]]</b> - {Lang::T('how much balance have been send')}.<br>
|
||||
<b>[[current_balance]]</b> - {Lang::T('Current Balance')}.
|
||||
</p>
|
||||
</div>
|
||||
<p class="col-md-4 help-block">
|
||||
<b>[[name]]</b> Receiver name.<br>
|
||||
<b>[[balance]]</b> how much balance have been send.<br>
|
||||
<b>[[current_balance]]</b> Current Balance.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Received Balance')}</label>
|
||||
<div class="col-md-6">
|
||||
<textarea class="form-control" id="balance_received" name="balance_received"
|
||||
rows="3">{if $_json['balance_received']}{Lang::htmlspecialchars($_json['balance_received'])}{else}{Lang::htmlspecialchars($_default['balance_received'])}{/if}</textarea>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Received Balance')}</label>
|
||||
<div class="col-md-6">
|
||||
<textarea class="form-control" id="balance_received" name="balance_received"
|
||||
rows="4">{if $_json['balance_received']}{Lang::htmlspecialchars($_json['balance_received'])}{else}{Lang::htmlspecialchars($_default['balance_received'])}{/if}</textarea>
|
||||
</div>
|
||||
<p class="col-md-4 help-block">
|
||||
<b>[[name]]</b> - {Lang::T('Sender name')}.<br>
|
||||
<b>[[balance]]</b> - {Lang::T('how much balance have been received')}.<br>
|
||||
<b>[[current_balance]]</b> - {Lang::T('Current Balance')}.
|
||||
</p>
|
||||
</div>
|
||||
<p class="col-md-4 help-block">
|
||||
<b>[[name]]</b> Sender name.<br>
|
||||
<b>[[balance]]</b> how much balance have been received.<br>
|
||||
<b>[[current_balance]]</b> Current Balance.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
@ -165,4 +176,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{include file="sections/footer.tpl"}
|
||||
{include file="sections/footer.tpl"}
|
||||
|
@ -77,8 +77,8 @@
|
||||
<option value="default" {if $_c['theme'] eq 'default' }selected="selected" {/if}>Default
|
||||
</option>
|
||||
{foreach $themes as $theme}
|
||||
<option value="{$theme}" {if $_c['theme'] eq $theme}selected="selected" {/if}>
|
||||
{Lang::ucWords($theme)}</option>
|
||||
<option value="{$theme}" {if $_c['theme'] eq $theme}selected="selected" {/if}>
|
||||
{Lang::ucWords($theme)}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
@ -86,6 +86,13 @@
|
||||
href="https://github.com/hotspotbilling/phpnuxbill/wiki/Themes" target="_blank">Theme
|
||||
info</a></p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Recharge Using')}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" name="payment_usings" class="form-control" value="{$_c['payment_usings']}" placeholder="{Lang::T('Cash')}, {Lang::T('Bank Transfer')}">
|
||||
</div>
|
||||
<p class="help-block col-md-4">This used for admin to select payment in recharge, using comma for every new options</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">APP URL</label>
|
||||
<div class="col-md-6">
|
||||
@ -152,38 +159,42 @@
|
||||
<option value="rand" {if $_c['voucher_format']=='rand' }selected="selected" {/if}>
|
||||
RaNdoM
|
||||
</option>
|
||||
<option value="numbers" {if $_c['voucher_format'] == 'numbers'}selected="selected"
|
||||
{/if}>
|
||||
Numbers
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">UPPERCASE lowercase RaNdoM</p>
|
||||
</div>
|
||||
{if $_c['disable_voucher'] != 'yes'}
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Disable Registration')}</label>
|
||||
<div class="col-md-6">
|
||||
<select name="disable_registration" id="disable_registration" class="form-control">
|
||||
<option value="no" {if $_c['disable_registration']=='no' }selected="selected" {/if}>No
|
||||
</option>
|
||||
<option value="yes" {if $_c['disable_registration']=='yes' }selected="selected" {/if}>
|
||||
Yes
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
{Lang::T('Customer just Login with Phone number and Voucher Code, Voucher will be
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Disable Registration')}</label>
|
||||
<div class="col-md-6">
|
||||
<select name="disable_registration" id="disable_registration" class="form-control">
|
||||
<option value="no" {if $_c['disable_registration']=='no' }selected="selected" {/if}>No
|
||||
</option>
|
||||
<option value="yes" {if $_c['disable_registration']=='yes' }selected="selected" {/if}>
|
||||
Yes
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
{Lang::T('Customer just Login with Phone number and Voucher Code, Voucher will be
|
||||
password')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">Redirect after Activation</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="voucher_redirect" name="voucher_redirect"
|
||||
placeholder="https://192.168.88.1/status" value="{$voucher_redirect}">
|
||||
</p>
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
{Lang::T('After Customer activate voucher or login, customer will be redirected to this
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">Redirect after Activation</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="voucher_redirect" name="voucher_redirect"
|
||||
placeholder="https://192.168.88.1/status" value="{$voucher_redirect}">
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
{Lang::T('After Customer activate voucher or login, customer will be redirected to this
|
||||
url')}
|
||||
</p>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="panel-heading">
|
||||
@ -213,6 +224,39 @@
|
||||
</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('Extend Postpaid Expiration')}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Allow Extend')}</label>
|
||||
<div class="col-md-6">
|
||||
<select name="extend_expired" id="extend_expired" class="form-control text-muted">
|
||||
<option value="0">No</option>
|
||||
<option value="1" {if $_c['extend_expired']}selected="selected" {/if}>Yes</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">Customer can request to extend expirations</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Extend Days')}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" name="extend_days" placeholder="3"
|
||||
value="{$_c['extend_days']}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Confirmation Message')}</label>
|
||||
<div class="col-md-6">
|
||||
<textarea type="text" rows="4" class="form-control" name="extend_confirmation"
|
||||
placeholder="i agree to extends and will paid full after this">{$_c['extend_confirmation']}</textarea>
|
||||
</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
|
||||
@ -306,8 +350,8 @@
|
||||
onchange="document.getElementById('sms_url').value = this.value">
|
||||
<option value="">Select Router</option>
|
||||
{foreach $r as $rs}
|
||||
<option value="{$rs['name']}" {if $rs['name']==$_c['sms_url']}selected{/if}>
|
||||
{$rs['name']}</option>
|
||||
<option value="{$rs['name']}" {if $rs['name']==$_c['sms_url']}selected{/if}>
|
||||
{$rs['name']}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
@ -340,6 +384,74 @@
|
||||
<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 class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-success btn-xs" style="color: black;" href="javascript:testEmail()">Test
|
||||
Email</a>
|
||||
<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('Email Notification')}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">SMTP Host : port</label>
|
||||
<div class="col-md-4">
|
||||
<input type="text" class="form-control" id="smtp_host" name="smtp_host"
|
||||
value="{$_c['smtp_host']}" placeholder="smtp.host.tld">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="number" class="form-control" id="smtp_port" name="smtp_port"
|
||||
value="{$_c['smtp_port']}" placeholder="465 587 port">
|
||||
</div>
|
||||
<p class="help-block col-md-4">Empty this to use internal mail() PHP</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">SMTP username</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="smtp_user" name="smtp_user"
|
||||
value="{$_c['smtp_user']}" placeholder="user@host.tld">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">SMTP Password</label>
|
||||
<div class="col-md-6">
|
||||
<input type="password" class="form-control" id="smtp_pass" name="smtp_pass"
|
||||
value="{$_c['smtp_pass']}" onmouseleave="this.type = 'password'"
|
||||
onmouseenter="this.type = 'text'">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">SMTP Security</label>
|
||||
<div class="col-md-6">
|
||||
<select name="smtp_ssltls" id="smtp_ssltls" class="form-control">
|
||||
<option value="" {if $_c['smtp_ssltls']=='' }selected="selected" {/if}>Not Secure
|
||||
</option>
|
||||
<option value="ssl" {if $_c['smtp_ssltls']=='ssl' }selected="selected" {/if}>SSL
|
||||
</option>
|
||||
<option value="tls" {if $_c['smtp_ssltls']=='tls' }selected="selected" {/if}>TLS
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">UPPERCASE lowercase RaNdoM</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">Mail From</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="mail_from" name="mail_from"
|
||||
value="{$_c['mail_from']}" placeholder="noreply@host.tld">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">Mail Reply To</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="mail_reply_to" name="mail_reply_to"
|
||||
value="{$_c['mail_reply_to']}" placeholder="support@host.tld">
|
||||
</div>
|
||||
<p class="help-block col-md-4">Customer will reply email to this address, empty if you want to
|
||||
use From Address</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
|
||||
@ -491,6 +603,71 @@
|
||||
<p class="help-block col-md-4">{Lang::T('The method which OTP will be sent to user')}</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('Tax System')}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Enable Tax System')}</label>
|
||||
<div class="col-md-6">
|
||||
<select name="enable_tax" id="enable_tax" class="form-control">
|
||||
<option value="no" {if $_c['enable_tax']=='no' }selected="selected" {/if}>
|
||||
{Lang::T('No')}
|
||||
</option>
|
||||
<option value="yes" {if $_c['enable_tax']=='yes' }selected="selected" {/if}>
|
||||
{Lang::T('Yes')}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">{Lang::T('Tax will be calculated in Internet Plan Price')}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Tax Rate')}</label>
|
||||
<div class="col-md-6">
|
||||
<select name="tax_rate" id="tax_rate" class="form-control">
|
||||
<option value="0.005" {if $_c['tax_rate']=='0.005' }selected="selected" {/if}>
|
||||
{Lang::T('0.5%')}
|
||||
</option>
|
||||
<option value="0.01" {if $_c['tax_rate']=='0.01' }selected="selected" {/if}>
|
||||
{Lang::T('1%')}
|
||||
</option>
|
||||
<option value="0.015" {if $_c['tax_rate']=='0.015' }selected="selected" {/if}>
|
||||
{Lang::T('1.5%')}
|
||||
</option>
|
||||
<option value="0.02" {if $_c['tax_rate']=='0.02' }selected="selected" {/if}>
|
||||
{Lang::T('2%')}
|
||||
</option>
|
||||
<option value="0.05" {if $_c['tax_rate']=='0.05' }selected="selected" {/if}>
|
||||
{Lang::T('5%')}
|
||||
</option>
|
||||
<option value="0.1" {if $_c['tax_rate']=='0.1' }selected="selected" {/if}>
|
||||
{Lang::T('10%')}
|
||||
</option>
|
||||
<!-- Custom tax rate option -->
|
||||
<option value="custom" {if $_c['tax_rate']=='custom' }selected="selected" {/if}>
|
||||
{Lang::T('Custom')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">{Lang::T('Tax Rates in percentage')}</p>
|
||||
</div>
|
||||
<!-- Custom tax rate input field (initially hidden) -->
|
||||
<div class="form-group" id="customTaxRate" style="display: none;">
|
||||
<label class="col-md-2 control-label">{Lang::T('Custom Tax Rate')}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" value="{$_c['custom_tax_rate']}" class="form-control"
|
||||
name="custom_tax_rate" id="custom_tax_rate"
|
||||
placeholder="{Lang::T('Enter Custom Tax Rate')}">
|
||||
</div>
|
||||
<p class="help-block col-md-4">{Lang::T('Enter the custom tax rate (e.g., 3.75 for 3.75%)')}</p>
|
||||
</div>
|
||||
</div> *}
|
||||
|
||||
{* <div class="panel-heading" id="envato">
|
||||
<div class="btn-group pull-right">
|
||||
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
|
||||
@ -561,8 +738,38 @@ add dst-host=*.{$_domain}</pre>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testEmail() {
|
||||
var target = prompt("Email\nSave First before Test", "");
|
||||
if (target != null) {
|
||||
window.location.href = '{$_url}settings/app&testEmail=' + target;
|
||||
}
|
||||
}
|
||||
|
||||
function testTg() {
|
||||
window.location.href = '{$_url}settings/app&testTg=test';
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Function to toggle visibility of custom tax rate input field
|
||||
function toggleCustomTaxRate() {
|
||||
var taxRateSelect = document.getElementById("tax_rate");
|
||||
var customTaxRateInput = document.getElementById("customTaxRate");
|
||||
|
||||
if (taxRateSelect.value === "custom") {
|
||||
customTaxRateInput.style.display = "block";
|
||||
} else {
|
||||
customTaxRateInput.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
// Call the function when the page loads
|
||||
toggleCustomTaxRate();
|
||||
|
||||
// Call the function whenever the tax rate dropdown value changes
|
||||
document.getElementById("tax_rate").addEventListener("change", toggleCustomTaxRate);
|
||||
});
|
||||
</script>
|
||||
{include file="sections/footer.tpl"}
|
@ -1,4 +1,9 @@
|
||||
<option value="">Select Plans</option>
|
||||
{foreach $d as $ds}
|
||||
<option value="{$ds['id']}">{$ds['name_plan']} • {Lang::moneyFormat($ds['price'])}</option>
|
||||
<option value="{$ds['id']}">
|
||||
{if $ds['enabled'] neq 1}DISABLED PLAN • {/if}
|
||||
{$ds['name_plan']} •
|
||||
{Lang::moneyFormat($ds['price'])}
|
||||
{if $ds['prepaid'] neq 'yes'} • POSTPAID {/if}
|
||||
</option>
|
||||
{/foreach}
|
@ -1,59 +1,59 @@
|
||||
{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">{Lang::T('Add Service 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">{Lang::T('Client Can Purchase')}</label>
|
||||
<div class="col-md-10">
|
||||
<label class="radio-inline warning">
|
||||
<input type="radio" checked name="allow_purchase" value="yes"> Yes
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="allow_purchase" value="no"> No
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('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">{Lang::T('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 class="row">
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30">
|
||||
<div class="panel-heading">{Lang::T('Add Service 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">{Lang::T('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">{Lang::T('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>
|
||||
{if $_c['enable_tax'] == 'yes'}
|
||||
{if $_c['tax_rate'] == 'custom'}
|
||||
<p class="help-block col-md-4">{number_format($_c['custom_tax_rate'], 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{else}
|
||||
<p class="help-block col-md-4">{number_format($_c['tax_rate'] * 100, 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Save Changes')}</button>
|
||||
Or <a href="{$_url}services/balance">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include file="sections/footer.tpl"}
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Save Changes')}</button>
|
||||
Or <a href="{$_url}services/balance">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include file="sections/footer.tpl"}
|
@ -18,18 +18,6 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Client Can Purchase')}</label>
|
||||
<div class="col-md-10">
|
||||
<label class="radio-inline warning">
|
||||
<input type="radio" {if $d['allow_purchase'] == yes}checked{/if} name="allow_purchase" value="yes"> Yes
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" {if $d['allow_purchase'] == no}checked{/if} name="allow_purchase" value="no">
|
||||
No
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Plan Name')}</label>
|
||||
<div class="col-md-6">
|
||||
@ -44,6 +32,16 @@
|
||||
<input type="number" class="form-control" name="price" value="{$d['price']}" required>
|
||||
</div>
|
||||
</div>
|
||||
{if $_c['enable_tax'] == 'yes'}
|
||||
{if $_c['tax_rate'] == 'custom'}
|
||||
<p class="help-block col-md-4">{number_format($_c['custom_tax_rate'], 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{else}
|
||||
<p class="help-block col-md-4">{number_format($_c['tax_rate'] * 100, 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
@ -46,7 +46,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,58 +1,65 @@
|
||||
{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('Bandwidth 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}bandwidth/list/">
|
||||
<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="{Lang::T('Search by Name')}...">
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Search')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<a href="{$_url}bandwidth/add" class="btn btn-primary btn-block"><i class="ion ion-android-add"> </i> {Lang::T('New Bandwidth')}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-condensed table-striped table_mobile">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{Lang::T('Bandwidth Name')}</th>
|
||||
<th>{Lang::T('Rate')}</th>
|
||||
<th>{Lang::T('Burst')}</th>
|
||||
<th>{Lang::T('Manage')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $d as $ds}
|
||||
<tr>
|
||||
<td>{$ds['name_bw']}</td>
|
||||
<td>{$ds['rate_down']} {$ds['rate_down_unit']} / {$ds['rate_up']} {$ds['rate_up_unit']}</td>
|
||||
<td>{$ds['burst']}</td>
|
||||
<td>
|
||||
<a href="{$_url}bandwidth/edit/{$ds['id']}" class="btn btn-sm btn-warning">{Lang::T('Edit')}</a>
|
||||
<a href="{$_url}bandwidth/delete/{$ds['id']}" id="{$ds['id']}" class="btn btn-danger btn-sm" onclick="return confirm('{Lang::T('Delete')}?')" ><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">{Lang::T('Bandwidth 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}bandwidth/list/">
|
||||
<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="{Lang::T('Search by Name')}...">
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Search')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<a href="{$_url}bandwidth/add" class="btn btn-primary btn-block"><i class="ion ion-android-add">
|
||||
</i> {Lang::T('New Bandwidth')}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-condensed table-striped table_mobile">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{Lang::T('Bandwidth Name')}</th>
|
||||
<th>{Lang::T('Rate')}</th>
|
||||
<th>{Lang::T('Burst')}</th>
|
||||
<th>{Lang::T('Manage')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $d as $ds}
|
||||
<tr>
|
||||
<td>{$ds['name_bw']}</td>
|
||||
<td>{$ds['rate_down']} {$ds['rate_down_unit']} / {$ds['rate_up']} {$ds['rate_up_unit']}
|
||||
</td>
|
||||
<td>{$ds['burst']}</td>
|
||||
<td>
|
||||
<a href="{$_url}bandwidth/edit/{$ds['id']}"
|
||||
class="btn btn-sm btn-warning">{Lang::T('Edit')}</a>
|
||||
<a href="{$_url}bandwidth/delete/{$ds['id']}" id="{$ds['id']}"
|
||||
class="btn btn-danger btn-sm"
|
||||
onclick="return confirm('{Lang::T('Delete')}?')"><i
|
||||
class="glyphicon glyphicon-trash"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include file="sections/footer.tpl"}
|
@ -1,48 +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">{Lang::T('Add New Contact')}</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}customers/add-post">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}customers/add-post">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30">
|
||||
<div class="panel-heading">{Lang::T('Add New Contact')}</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Username')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Username')}</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
{if $_c['country_code_phone']!= ''}
|
||||
<span class="input-group-addon" id="basic-addon1">+</span>
|
||||
{if $_c['country_code_phone'] != ''}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-phone-alt"></i></span>
|
||||
{else}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-phone-alt"></i></span>
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-user"></i></span>
|
||||
{/if}
|
||||
<input type="text" class="form-control" name="username" required
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']} {Lang::T('Phone Number')}{else}{Lang::T('Username')}{/if}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Full Name')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Full Name')}</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" required class="form-control" id="fullname" name="fullname">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Email')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Email')}</label>
|
||||
<div class="col-md-9">
|
||||
<input type="email" class="form-control" id="email" name="email">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Phone Number')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Phone Number')}</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
{if $_c['country_code_phone']!= ''}
|
||||
<span class="input-group-addon" id="basic-addon1">+</span>
|
||||
<span class="input-group-addon" id="basic-addon1">+</span>
|
||||
{else}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-phone-alt"></i></span>
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-phone-alt"></i></span>
|
||||
{/if}
|
||||
<input type="text" class="form-control" name="phonenumber"
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
|
||||
@ -50,15 +50,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Password')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Password')}</label>
|
||||
<div class="col-md-9">
|
||||
<input type="password" class="form-control" autocomplete="off" required id="password"
|
||||
name="password" onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'">
|
||||
value="{rand(000000,999999)}" name="password" onmouseleave="this.type = 'password'"
|
||||
onmouseenter="this.type = 'text'">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('PPPOE Password')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('PPPOE Password')}</label>
|
||||
<div class="col-md-9">
|
||||
<input type="password" class="form-control" id="pppoe_password" name="pppoe_password"
|
||||
value="{$d['pppoe_password']}" onmouseleave="this.type = 'password'"
|
||||
onmouseenter="this.type = 'text'">
|
||||
@ -68,80 +69,134 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Address')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Address')}</label>
|
||||
<div class="col-md-9">
|
||||
<textarea name="address" id="address" class="form-control"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Service Type')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Service Type')}</label>
|
||||
<div class="col-md-9">
|
||||
<select class="form-control" id="service_type" name="service_type">
|
||||
<option value="Hotspot" {if $d['service_type'] eq 'Hotspot' }selected{/if}>Hotspot
|
||||
<option value="Hotspot">Hotspot
|
||||
</option>
|
||||
<option value="PPPoE" {if $d['service_type'] eq 'PPPoE' }selected{/if}>PPPoE</option>
|
||||
<option value="Others" {if $d['service_type'] eq 'Others' }selected{/if}>Others</option>
|
||||
<option value="PPPoE">PPPoE</option>
|
||||
<option value="Others">Others</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Customers Attributes add start -->
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Attributes')}</label>
|
||||
<div id="custom-fields-container" class="col-md-6">
|
||||
<button class="btn btn-success btn-sm" type="button"
|
||||
id="add-custom-field">+</button>
|
||||
<label class="col-md-3 control-label">{Lang::T('Account Type')}</label>
|
||||
<div class="col-md-9">
|
||||
<select class="form-control" id="account_type" name="account_type">
|
||||
<option value="Personal">Personal
|
||||
</option>
|
||||
<option value="Business">Business</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">{Lang::T('Coordinates')}</label>
|
||||
<div class="col-md-9">
|
||||
<input name="coordinates" id="coordinates" class="form-control" value=""
|
||||
placeholder="6.465422, 3.406448">
|
||||
<div id="map" style="width: '100%'; height: 200px; min-height: 150px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30">
|
||||
<div class="panel-heading">{Lang::T('Attributes')}</div>
|
||||
<div class="panel-body">
|
||||
<!-- Customers Attributes add start -->
|
||||
<div id="custom-fields-container">
|
||||
</div>
|
||||
<!-- Customers Attributes add end -->
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-primary" type="submit">
|
||||
{Lang::T('Save Changes')}
|
||||
</button>
|
||||
Or <a href="{$_url}customers/list">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<button class="btn btn-success btn-block" type="button"
|
||||
id="add-custom-field">{Lang::T('Add')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<center>
|
||||
<button class="btn btn-primary" type="submit">
|
||||
{Lang::T('Save Changes')}
|
||||
</button>
|
||||
<br><a href="{$_url}customers/list" class="btn btn-link">{Lang::T('Cancel')}</a>
|
||||
</center>
|
||||
</form>
|
||||
{literal}
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var customFieldsContainer = document.getElementById('custom-fields-container');
|
||||
var addCustomFieldButton = document.getElementById('add-custom-field');
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var customFieldsContainer = document.getElementById('custom-fields-container');
|
||||
var addCustomFieldButton = document.getElementById('add-custom-field');
|
||||
|
||||
addCustomFieldButton.addEventListener('click', function() {
|
||||
var fieldIndex = customFieldsContainer.children.length;
|
||||
var newField = document.createElement('div');
|
||||
newField.className = 'form-group';
|
||||
newField.innerHTML = `
|
||||
<label class="col-md-2 control-label">Name:</label>
|
||||
<div class="col-md-3">
|
||||
addCustomFieldButton.addEventListener('click', function() {
|
||||
var fieldIndex = customFieldsContainer.children.length;
|
||||
var newField = document.createElement('div');
|
||||
newField.className = 'form-group';
|
||||
newField.innerHTML = `
|
||||
<div class="col-md-4">
|
||||
<input type="text" class="form-control" name="custom_field_name[]" placeholder="Name">
|
||||
</div>
|
||||
<label class="col-md-2 control-label">Value:</label>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" name="custom_field_value[]" placeholder="Value">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="button" class="remove-custom-field btn btn-danger btn-sm">-</button>
|
||||
</div>
|
||||
`;
|
||||
customFieldsContainer.appendChild(newField);
|
||||
});
|
||||
customFieldsContainer.appendChild(newField);
|
||||
});
|
||||
|
||||
customFieldsContainer.addEventListener('click', function(event) {
|
||||
if (event.target.classList.contains('remove-custom-field')) {
|
||||
var fieldContainer = event.target.parentNode.parentNode;
|
||||
fieldContainer.parentNode.removeChild(fieldContainer);
|
||||
}
|
||||
customFieldsContainer.addEventListener('click', function(event) {
|
||||
if (event.target.classList.contains('remove-custom-field')) {
|
||||
var fieldContainer = event.target.parentNode.parentNode;
|
||||
fieldContainer.parentNode.removeChild(fieldContainer);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
|
||||
<script>
|
||||
function getLocation() {
|
||||
if (window.location.protocol == "https:" && navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(showPosition);
|
||||
} else {
|
||||
setupMap(51.505, -0.09);
|
||||
}
|
||||
}
|
||||
|
||||
function showPosition(position) {
|
||||
setupMap(position.coords.latitude, position.coords.longitude);
|
||||
}
|
||||
|
||||
function setupMap(lat, lon) {
|
||||
var map = L.map('map').setView([lat, lon], 13);
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/light_all/{z}/{x}/{y}.png', {
|
||||
attribution:
|
||||
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
||||
subdomains: 'abcd',
|
||||
maxZoom: 20
|
||||
}).addTo(map);
|
||||
var marker = L.marker([lat, lon]).addTo(map);
|
||||
map.on('click', function(e){
|
||||
var coord = e.latlng;
|
||||
var lat = coord.lat;
|
||||
var lng = coord.lng;
|
||||
var newLatLng = new L.LatLng(lat, lng);
|
||||
marker.setLatLng(newLatLng);
|
||||
$('#coordinates').val(lat + ',' + lng);
|
||||
});
|
||||
}
|
||||
window.onload = function() {
|
||||
getLocation();
|
||||
}
|
||||
</script>
|
||||
{/literal}
|
||||
|
||||
|
||||
|
@ -1,45 +1,45 @@
|
||||
{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">{Lang::T('Edit Contact')}</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}customers/edit-post">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}customers/edit-post">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30">
|
||||
<div class="panel-heading">{Lang::T('Edit Contact')}</div>
|
||||
<div class="panel-body">
|
||||
<input type="hidden" name="id" value="{$d['id']}">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Username')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Username')}</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
{if $_c['country_code_phone']!= ''}
|
||||
<span class="input-group-addon" id="basic-addon1">+</span>
|
||||
{else}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-phone-alt"></i></span>
|
||||
{else}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-user"></i></span>
|
||||
{/if}
|
||||
<input type="text" class="form-control" name="username" value="{$d['username']}"
|
||||
required
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']} {Lang::T('Phone Number')}{else}{Lang::T('Username')}{/if}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Full Name')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Full Name')}</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" id="fullname" name="fullname"
|
||||
value="{$d['fullname']}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Email')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Email')}</label>
|
||||
<div class="col-md-9">
|
||||
<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">{Lang::T('Phone Number')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Phone Number')}</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
{if $_c['country_code_phone']!= ''}
|
||||
<span class="input-group-addon" id="basic-addon1">+</span>
|
||||
@ -53,8 +53,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Password')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Password')}</label>
|
||||
<div class="col-md-9">
|
||||
<input type="password" autocomplete="off" class="form-control" id="password" name="password"
|
||||
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'"
|
||||
value="{$d['password']}">
|
||||
@ -62,8 +62,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('PPPOE Password')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('PPPOE Password')}</label>
|
||||
<div class="col-md-9">
|
||||
<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'">
|
||||
@ -73,14 +73,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Address')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Address')}</label>
|
||||
<div class="col-md-9">
|
||||
<textarea name="address" id="address" class="form-control">{$d['address']}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Service Type')}</label>
|
||||
<div class="col-md-6">
|
||||
<label class="col-md-3 control-label">{Lang::T('Service Type')}</label>
|
||||
<div class="col-md-9">
|
||||
<select class="form-control" id="service_type" name="service_type">
|
||||
<option value="Hotspot" {if $d['service_type'] eq 'Hotspot' }selected{/if}>Hotspot
|
||||
</option>
|
||||
@ -89,43 +89,69 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">{Lang::T('Account Type')}</label>
|
||||
<div class="col-md-9">
|
||||
<select class="form-control" id="account_type" name="account_type">
|
||||
<option value="Personal" {if $d['account_type'] eq 'Personal' }selected{/if}>Personal
|
||||
</option>
|
||||
<option value="Business" {if $d['account_type'] eq 'Business' }selected{/if}>Business
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">{Lang::T('Coordinates')}</label>
|
||||
<div class="col-md-9">
|
||||
<input name="coordinates" id="coordinates" class="form-control" value="{$d['coordinates']}"
|
||||
placeholder="6.465422, 3.406448">
|
||||
<div id="map" style="width: '100%'; height: 200px; min-height: 150px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30">
|
||||
<div class="panel-heading">{Lang::T('Attributes')}</div>
|
||||
<div class="panel-body">
|
||||
<!--Customers Attributes edit start -->
|
||||
{if $customFields}
|
||||
{foreach $customFields as $customField}
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"
|
||||
<label class="col-md-4 control-label"
|
||||
for="{$customField.field_name}">{$customField.field_name}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" name="custom_fields[{$customField.field_name}]"
|
||||
id="{$customField.field_name}" value="{$customField.field_value}">
|
||||
</div>
|
||||
<input type="checkbox" name="delete_custom_fields[]" value="{$customField.field_name}"> Delete
|
||||
<label class="col-md-2">
|
||||
<input type="checkbox" name="delete_custom_fields[]" value="{$customField.field_name}">
|
||||
Delete
|
||||
</label>
|
||||
</div>
|
||||
{/foreach}
|
||||
{/if}
|
||||
<!--Customers Attributes edit end -->
|
||||
<!--Customers Attributes add start -->
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Attributes')}</label>
|
||||
<div id="custom-fields-container" class="col-md-6">
|
||||
<button class="btn btn-success btn-sm" type="button" id="add-custom-field">+</button>
|
||||
</div>
|
||||
<!-- Customers Attributes add start -->
|
||||
<div id="custom-fields-container">
|
||||
</div>
|
||||
<!--Customers Attributes add end -->
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-primary" type="submit">
|
||||
{Lang::T('Save Changes')}
|
||||
</button>
|
||||
Or <a href="{$_url}customers/list">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<!-- Customers Attributes add end -->
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<button class="btn btn-success btn-block" type="button"
|
||||
id="add-custom-field">{Lang::T('Add')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<center>
|
||||
<button class="btn btn-primary" type="submit">
|
||||
{Lang::T('Save Changes')}
|
||||
</button>
|
||||
<br><a href="{$_url}customers/list" class="btn btn-link">{Lang::T('Cancel')}</a>
|
||||
</center>
|
||||
</form>
|
||||
|
||||
{literal}
|
||||
<script type="text/javascript">
|
||||
@ -138,12 +164,10 @@
|
||||
var newField = document.createElement('div');
|
||||
newField.className = 'form-group';
|
||||
newField.innerHTML = `
|
||||
<label class="col-md-2 control-label">Name:</label>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-4">
|
||||
<input type="text" class="form-control" name="custom_field_name[]" placeholder="Name">
|
||||
</div>
|
||||
<label class="col-md-2 control-label">Value:</label>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" name="custom_field_value[]" placeholder="Value">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
@ -161,6 +185,47 @@
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
|
||||
<script>
|
||||
function getLocation() {
|
||||
if (window.location.protocol == "https:" && navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(showPosition);
|
||||
} else {
|
||||
setupMap(51.505, -0.09);
|
||||
}
|
||||
}
|
||||
|
||||
function showPosition(position) {
|
||||
setupMap(position.coords.latitude, position.coords.longitude);
|
||||
}
|
||||
|
||||
function setupMap(lat, lon) {
|
||||
var map = L.map('map').setView([lat, lon], 13);
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/light_all/{z}/{x}/{y}.png', {
|
||||
attribution:
|
||||
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
||||
subdomains: 'abcd',
|
||||
maxZoom: 20
|
||||
}).addTo(map);
|
||||
var marker = L.marker([lat, lon]).addTo(map);
|
||||
map.on('click', function(e) {
|
||||
var coord = e.latlng;
|
||||
var lat = coord.lat;
|
||||
var lng = coord.lng;
|
||||
var newLatLng = new L.LatLng(lat, lng);
|
||||
marker.setLatLng(newLatLng);
|
||||
$('#coordinates').val(lat + ',' + lng);
|
||||
});
|
||||
}
|
||||
window.onload = function() {
|
||||
{/literal}{if $d['coordinates']}
|
||||
setupMap({$d['coordinates']});
|
||||
{else}
|
||||
getLocation();
|
||||
{/if}{literal}
|
||||
}
|
||||
</script>
|
||||
{/literal}
|
||||
|
||||
{include file="sections/footer.tpl"}
|
79
ui/ui/customers-map.tpl
Normal file
79
ui/ui/customers-map.tpl
Normal file
@ -0,0 +1,79 @@
|
||||
{include file="sections/header.tpl"}
|
||||
|
||||
|
||||
<form id="site-search" method="post" action="{$_url}map/customer/">
|
||||
<input type="hidden" name="_route" value="map/customer">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">
|
||||
<span class="fa fa-search"></span>
|
||||
</div>
|
||||
<input type="text" name="search" class="form-control" value="{$search}"
|
||||
placeholder="{Lang::T('Search')}...">
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Search')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Map container div -->
|
||||
<div id="map" class="well" style="width: '100%'; height: 70vh; margin: 20px auto"></div>
|
||||
|
||||
{include file="pagination.tpl"}
|
||||
|
||||
{literal}
|
||||
<script>
|
||||
function getLocation() {
|
||||
if (window.location.protocol == "https:" && navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(showPosition);
|
||||
} else {
|
||||
setupMap(51.505, -0.09);
|
||||
}
|
||||
}
|
||||
|
||||
function showPosition(position) {
|
||||
setupMap(position.coords.latitude, position.coords.longitude);
|
||||
}
|
||||
|
||||
function setupMap(lat, lon) {
|
||||
var map = L.map('map').setView([lat, lon], 13);
|
||||
var group = L.featureGroup().addTo(map);
|
||||
|
||||
var customers = {/literal}{$customers|json_encode}{literal};
|
||||
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/light_all/{z}/{x}/{y}.png', {
|
||||
attribution:
|
||||
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
||||
subdomains: 'abcd',
|
||||
maxZoom: 20
|
||||
}).addTo(map);
|
||||
|
||||
customers.forEach(function(customer) {
|
||||
var name = customer.id;
|
||||
var name = customer.name;
|
||||
var info = customer.info;
|
||||
var direction = customer.direction;
|
||||
var coordinates = customer.coordinates;
|
||||
var balance = customer.balance;
|
||||
var address = customer.address;
|
||||
|
||||
// Create a popup for the marker
|
||||
var popupContent = "<strong>Name</strong>: " + name + "<br>" +
|
||||
"<strong>Info</strong>: " + info + "<br>" +
|
||||
"<strong>Balance</strong>: " + balance + "<br>" +
|
||||
"<strong>Address</strong>: " + address + "<br>" +
|
||||
"<a href='{/literal}{$_url}{literal}customers/view/"+ customer.id +"'>More Info</a> • " +
|
||||
"<a href='https://www.google.com/maps/dir//" + direction + "' target='maps'>Get Direction</a><br>";
|
||||
|
||||
// Add marker to map
|
||||
var marker = L.marker(JSON.parse(coordinates)).addTo(group);
|
||||
marker.bindTooltip(name, { permanent: true }).bindPopup(popupContent);
|
||||
});
|
||||
|
||||
map.fitBounds(group.getBounds());
|
||||
}
|
||||
window.onload = function() {
|
||||
getLocation();
|
||||
}
|
||||
</script>
|
||||
{/literal}
|
||||
{include file="sections/footer.tpl"}
|
@ -30,31 +30,41 @@
|
||||
onclick="this.select()">
|
||||
</li>
|
||||
{if $d['pppoe_password'] != ''}
|
||||
<li class="list-group-item">
|
||||
<b>PPPOE {Lang::T('Password')}</b> <input type="password" value="{$d['pppoe_password']}"
|
||||
style=" border: 0px; text-align: right;" class="pull-right"
|
||||
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'"
|
||||
onclick="this.select()">
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>PPPOE {Lang::T('Password')}</b> <input type="password" value="{$d['pppoe_password']}"
|
||||
style=" border: 0px; text-align: right;" class="pull-right"
|
||||
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'"
|
||||
onclick="this.select()">
|
||||
</li>
|
||||
{/if}
|
||||
<!--Customers Attributes view start -->
|
||||
{if $customFields}
|
||||
{foreach $customFields as $customField}
|
||||
<li class="list-group-item">
|
||||
<b>{$customField.field_name}</b> <span class="pull-right">{$customField.field_value}</span>
|
||||
</li>
|
||||
{/foreach}
|
||||
{foreach $customFields as $customField}
|
||||
<li class="list-group-item">
|
||||
<b>{$customField.field_name}</b> <span class="pull-right">
|
||||
{if strpos($customField.field_value, ':0') === false}
|
||||
{$customField.field_value}
|
||||
{else}
|
||||
<b>{Lang::T('Paid')}</b>
|
||||
{/if}
|
||||
</span>
|
||||
</li>
|
||||
{/foreach}
|
||||
{/if}
|
||||
<!--Customers Attributes view end -->
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Service Type')}</b> <span class="pull-right">{Lang::T($d['service_type'])}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Account Type')}</b> <span class="pull-right">{Lang::T($d['account_type'])}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Balance')}</b> <span class="pull-right">{Lang::moneyFormat($d['balance'])}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Auto Renewal')}</b> <span class="pull-right">{if
|
||||
$d['auto_renewal']}yes{else}no{/if}</span>
|
||||
$d['auto_renewal']}yes{else}no
|
||||
{/if}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Created On')}</b> <span
|
||||
@ -64,6 +74,16 @@
|
||||
<b>{Lang::T('Last Login')}</b> <span
|
||||
class="pull-right">{Lang::dateTimeFormat($d['last_login'])}</span>
|
||||
</li>
|
||||
{if $d['coordinates']}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Coordinates')}</b> <span class="pull-right">
|
||||
<i class="glyphicon glyphicon-road"></i> <a style="color: black;"
|
||||
href="https://www.google.com/maps/dir//{$d['coordinates']}/" target="_blank">Get
|
||||
Directions</a>
|
||||
</span>
|
||||
<div id="map" style="width: '100%'; height: 100px;"></div>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
<div class="row">
|
||||
<div class="col-xs-4">
|
||||
@ -78,22 +98,26 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{if $package}
|
||||
<div class="box box-{if $package['status']=='on'}success{else}danger{/if}">
|
||||
<div class="box-body box-profile">
|
||||
<h4 class="text-center">{$package['type']} - {$package['namebp']}</h4>
|
||||
<ul class="list-group list-group-unbordered">
|
||||
{foreach $packages as $package}
|
||||
<div class="box box-{if $package['status']=='on'}success{else}danger{/if}">
|
||||
<div class="box-body box-profile">
|
||||
<h4 class="text-center">{$package['type']} - {$package['namebp']}</h4>
|
||||
<ul class="list-group list-group-unbordered">
|
||||
<li class="list-group-item">
|
||||
{Lang::T('Active')} <span class="pull-right">{if
|
||||
$package['status']=='on'}yes{else}no
|
||||
{/if}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
{Lang::T('Active')} <span class="pull-right">{if
|
||||
$package['status']=='on'}yes{else}no{/if}</span>
|
||||
{Lang::T('Type')} <span class="pull-right">
|
||||
{if $package['prepaid'] eq yes}Prepaid{else}<b>Postpaid</b>{/if}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
{Lang::T('Created On')} <span
|
||||
class="pull-right">{Lang::dateAndTimeFormat($package['recharged_on'],$package['recharged_time'])}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
{Lang::T('Expires On')} <span
|
||||
class="pull-right">{Lang::dateAndTimeFormat($package['expiration'],
|
||||
{Lang::T('Expires On')} <span class="pull-right">{Lang::dateAndTimeFormat($package['expiration'],
|
||||
$package['time'])}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
@ -102,28 +126,32 @@
|
||||
</ul>
|
||||
<div class="row">
|
||||
<div class="col-xs-4">
|
||||
<a href="{$_url}customers/deactivate/{$d['id']}" id="{$d['id']}"
|
||||
<a href="{$_url}customers/deactivate/{$d['id']}/{$package['plan_id']}" id="{$d['id']}"
|
||||
class="btn btn-danger btn-block btn-sm"
|
||||
onclick="return confirm('This will deactivate Customer Plan, and make it expired')">{Lang::T('Deactivate')}</a>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<a href="{$_url}customers/recharge/{$d['id']}"
|
||||
onclick="return confirm('This will extend Customer plan, same as recharge')"
|
||||
<div class="col-xs-8">
|
||||
<a href="{$_url}customers/recharge/{$d['id']}/{$package['plan_id']}"
|
||||
class="btn btn-success btn-sm btn-block">{Lang::T('Recharge')}</a>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<a href="{$_url}customers/sync/{$d['id']}"
|
||||
onclick="return confirm('This will sync Customer to Mikrotik?')"
|
||||
class="btn btn-primary btn-sm btn-block">{Lang::T('Sync')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{else}
|
||||
<a href="{$_url}prepaid/recharge/{$d['id']}"
|
||||
class="btn btn-success btn-sm btn-block mt-1">{Lang::T('Recharge')}</a><br>
|
||||
{/if}
|
||||
<a href="{$_url}customers/list" class="btn btn-primary btn-sm btn-block mt-1">{Lang::T('Back')}</a><br>
|
||||
{/foreach}
|
||||
<div class="row">
|
||||
<div class="col-xs-4">
|
||||
<a href="{$_url}customers/list" class="btn btn-primary btn-sm btn-block">{Lang::T('Back')}</a>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<a href="{$_url}customers/sync/{$d['id']}"
|
||||
onclick="return confirm('This will sync Customer to Mikrotik?')"
|
||||
class="btn btn-info btn-sm btn-block">{Lang::T('Sync')}</a>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<a href="{$_url}message/send/{$d['id']}" class="btn btn-success btn-sm btn-block">{Lang::T('Send
|
||||
Message')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-8 col-md-8">
|
||||
<ul class="nav nav-tabs">
|
||||
@ -135,73 +163,93 @@
|
||||
<div class="table-responsive" style="background-color: white;">
|
||||
<table id="datatable" class="table table-bordered table-striped">
|
||||
{if Lang::arrayCount($activation)}
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{Lang::T('Invoice')}</th>
|
||||
<th>{Lang::T('Username')}</th>
|
||||
<th>{Lang::T('Plan Name')}</th>
|
||||
<th>{Lang::T('Plan Price')}</th>
|
||||
<th>{Lang::T('Type')}</th>
|
||||
<th>{Lang::T('Created On')}</th>
|
||||
<th>{Lang::T('Expires On')}</th>
|
||||
<th>{Lang::T('Method')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $activation as $ds}
|
||||
<tr onclick="window.location.href = '{$_url}prepaid/view/{$ds['id']}'" style="cursor:pointer;">
|
||||
<td>{$ds['invoice']}</td>
|
||||
<td>{$ds['username']}</td>
|
||||
<td>{$ds['plan_name']}</td>
|
||||
<td>{Lang::moneyFormat($ds['price'])}</td>
|
||||
<td>{$ds['type']}</td>
|
||||
<td class="text-success">{Lang::dateAndTimeFormat($ds['recharged_on'],$ds['recharged_time'])}
|
||||
</td>
|
||||
<td class="text-danger">{Lang::dateAndTimeFormat($ds['expiration'],$ds['time'])}</td>
|
||||
<td>{$ds['method']}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{Lang::T('Invoice')}</th>
|
||||
<th>{Lang::T('Username')}</th>
|
||||
<th>{Lang::T('Plan Name')}</th>
|
||||
<th>{Lang::T('Plan Price')}</th>
|
||||
<th>{Lang::T('Type')}</th>
|
||||
<th>{Lang::T('Created On')}</th>
|
||||
<th>{Lang::T('Expires On')}</th>
|
||||
<th>{Lang::T('Method')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $activation as $ds}
|
||||
<tr onclick="window.location.href = '{$_url}plan/view/{$ds['id']}'" style="cursor:pointer;">
|
||||
<td>{$ds['invoice']}</td>
|
||||
<td>{$ds['username']}</td>
|
||||
<td>{$ds['plan_name']}</td>
|
||||
<td>{Lang::moneyFormat($ds['price'])}</td>
|
||||
<td>{$ds['type']}</td>
|
||||
<td class="text-success">{Lang::dateAndTimeFormat($ds['recharged_on'],$ds['recharged_time'])}
|
||||
</td>
|
||||
<td class="text-danger">{Lang::dateAndTimeFormat($ds['expiration'],$ds['time'])}</td>
|
||||
<td>{$ds['method']}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
{/if}
|
||||
{if Lang::arrayCount($order)}
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{Lang::T('Plan Name')}</th>
|
||||
<th>{Lang::T('Gateway')}</th>
|
||||
<th>{Lang::T('Routers')}</th>
|
||||
<th>{Lang::T('Type')}</th>
|
||||
<th>{Lang::T('Plan Price')}</th>
|
||||
<th>{Lang::T('Created On')}</th>
|
||||
<th>{Lang::T('Expires On')}</th>
|
||||
<th>{Lang::T('Date Done')}</th>
|
||||
<th>{Lang::T('Method')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $order as $ds}
|
||||
<tr>
|
||||
<td>{$ds['plan_name']}</td>
|
||||
<td>{$ds['gateway']}</td>
|
||||
<td>{$ds['routers']}</td>
|
||||
<td>{$ds['payment_channel']}</td>
|
||||
<td>{Lang::moneyFormat($ds['price'])}</td>
|
||||
<td class="text-primary">{Lang::dateTimeFormat($ds['created_date'])}</td>
|
||||
<td class="text-danger">{Lang::dateTimeFormat($ds['expired_date'])}</td>
|
||||
<td class="text-success">{if $ds['status']!=1}{Lang::dateTimeFormat($ds['paid_date'])}{/if}</td>
|
||||
<td>{if $ds['status']==1}{Lang::T('UNPAID')}
|
||||
{elseif $ds['status']==2}{Lang::T('PAID')}
|
||||
{elseif $ds['status']==3}{$_L['FAILED']}
|
||||
{elseif $ds['status']==4}{Lang::T('CANCELED')}
|
||||
{elseif $ds['status']==5}{Lang::T('UNKNOWN')}
|
||||
{/if}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{Lang::T('Plan Name')}</th>
|
||||
<th>{Lang::T('Gateway')}</th>
|
||||
<th>{Lang::T('Routers')}</th>
|
||||
<th>{Lang::T('Type')}</th>
|
||||
<th>{Lang::T('Plan Price')}</th>
|
||||
<th>{Lang::T('Created On')}</th>
|
||||
<th>{Lang::T('Expires On')}</th>
|
||||
<th>{Lang::T('Date Done')}</th>
|
||||
<th>{Lang::T('Method')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $order as $ds}
|
||||
<tr>
|
||||
<td>{$ds['plan_name']}</td>
|
||||
<td>{$ds['gateway']}</td>
|
||||
<td>{$ds['routers']}</td>
|
||||
<td>{$ds['payment_channel']}</td>
|
||||
<td>{Lang::moneyFormat($ds['price'])}</td>
|
||||
<td class="text-primary">{Lang::dateTimeFormat($ds['created_date'])}</td>
|
||||
<td class="text-danger">{Lang::dateTimeFormat($ds['expired_date'])}</td>
|
||||
<td class="text-success">{if $ds['status']!=1}{Lang::dateTimeFormat($ds['paid_date'])}{/if}</td>
|
||||
<td>{if $ds['status']==1}{Lang::T('UNPAID')}
|
||||
{elseif $ds['status']==2}{Lang::T('PAID')}
|
||||
{elseif $ds['status']==3}{$_L['FAILED']}
|
||||
{elseif $ds['status']==4}{Lang::T('CANCELED')}
|
||||
{elseif $ds['status']==5}{Lang::T('UNKNOWN')}
|
||||
{/if}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
{/if}
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if $d['coordinates']}
|
||||
{literal}
|
||||
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
|
||||
<script>
|
||||
function setupMap(lat, lon) {
|
||||
var map = L.map('map').setView([lat, lon], 17);
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/light_all/{z}/{x}/{y}.png', {
|
||||
attribution:
|
||||
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
||||
subdomains: 'abcd',
|
||||
maxZoom: 20
|
||||
}).addTo(map);
|
||||
var marker = L.marker([lat, lon]).addTo(map);
|
||||
}
|
||||
window.onload = function() {
|
||||
{/literal}setupMap({$d['coordinates']});{literal}
|
||||
}
|
||||
</script>
|
||||
{/literal}
|
||||
{/if}
|
||||
{include file="sections/footer.tpl"}
|
@ -1,46 +1,59 @@
|
||||
{include file="sections/header.tpl"}
|
||||
<style>
|
||||
.dataTables_wrapper .dataTables_paginate .paginate_button {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
margin-right: 5px;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-primary btn-xs" title="save" href="{$_url}customers/csv"
|
||||
onclick="return confirm('This will export to CSV?')"><span class="glyphicon glyphicon-download"
|
||||
aria-hidden="true"></span> CSV</a>
|
||||
</div>
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-primary btn-xs" title="save" href="{$_url}customers/csv"
|
||||
onclick="return confirm('This will export to CSV?')"><span class="glyphicon glyphicon-download"
|
||||
aria-hidden="true"></span> CSV</a>
|
||||
</div>
|
||||
{/if}
|
||||
{Lang::T('Manage Contact')}
|
||||
</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}customers/list/">
|
||||
<form id="site-search" method="post" action="{$_url}customers">
|
||||
<div class="input-group">
|
||||
<input type="text" name="search" value="{$search}" class="form-control"
|
||||
placeholder="{Lang::T('Search')}...">
|
||||
<div class="input-group-addon">
|
||||
<span class="fa fa-search"></span>
|
||||
</div>
|
||||
<input type="text" name="search" class="form-control"
|
||||
placeholder="{Lang::T('Search')}..." value="{$search}">
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-success" type="submit"><span
|
||||
class="fa fa-search"></span></button>
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Search')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<a href="{$_url}customers/add" class="btn btn-primary btn-block"><i
|
||||
class="ion ion-android-add"> </i> {Lang::T('Add New Contact')}</a>
|
||||
<a href="{$_url}customers/add" class="btn btn-primary btn-block"><i class="ion ion-android-add">
|
||||
</i> {Lang::T('Add New Contact')}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive table_mobile">
|
||||
<table class="table table-bordered table-striped table-condensed">
|
||||
<table id="customerTable" class="table table-bordered table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{Lang::T('Username')}</th>
|
||||
<th>{Lang::T('Account Type')}</th>
|
||||
<th>{Lang::T('Full Name')}</th>
|
||||
<th>{Lang::T('Balance')}</th>
|
||||
<th>{Lang::T('Phone Number')}</th>
|
||||
<th>{Lang::T('Email')}</th>
|
||||
<th>{Lang::T('Contact')}</th>
|
||||
<th>{Lang::T('Package')}</th>
|
||||
<th>{Lang::T('Service Type')}</th>
|
||||
<th>{Lang::T('Created On')}</th>
|
||||
@ -49,34 +62,65 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $d as $ds}
|
||||
<tr>
|
||||
<td onclick="window.location.href = '{$_url}customers/view/{$ds['id']}'"
|
||||
style="cursor:pointer;">{$ds['username']}</td>
|
||||
<td onclick="window.location.href = '{$_url}customers/view/{$ds['id']}'"
|
||||
style="cursor: pointer;">{$ds['fullname']}</td>
|
||||
<td>{Lang::moneyFormat($ds['balance'])}</td>
|
||||
<td>{$ds['phonenumber']}</td>
|
||||
<td>{$ds['email']}</td>
|
||||
<td align="center" api-get-text="{$_url}autoload/customer_is_active/{$ds['id']}">
|
||||
<span class="label label-default">•</span>
|
||||
</td>
|
||||
<td>{$ds['service_type']}</td>
|
||||
<td>{Lang::dateTimeFormat($ds['created_at'])}</td>
|
||||
<td align="center">
|
||||
<a href="{$_url}customers/view/{$ds['id']}" id="{$ds['id']}" style="margin: 0px;"
|
||||
class="btn btn-success btn-xs"> {Lang::T('View')} </a>
|
||||
<a href="{$_url}prepaid/recharge/{$ds['id']}" id="{$ds['id']}" style="margin: 0px;"
|
||||
class="btn btn-primary btn-xs">{Lang::T('Recharge')}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td onclick="window.location.href = '{$_url}customers/view/{$ds['id']}'"
|
||||
style="cursor:pointer;">{$ds['username']}</td>
|
||||
<td>{$ds['account_type']}</td>
|
||||
<td onclick="window.location.href = '{$_url}customers/view/{$ds['id']}'"
|
||||
style="cursor: pointer;">{$ds['fullname']}</td>
|
||||
<td>{Lang::moneyFormat($ds['balance'])}</td>
|
||||
<td align="center">
|
||||
{if $ds['phonenumber']}
|
||||
<a href="tel:{$ds['phonenumber']}" class="btn btn-default btn-xs"
|
||||
title="{$ds['phonenumber']}"><i class="glyphicon glyphicon-earphone"></i></a>
|
||||
{/if}
|
||||
{if $ds['email']}
|
||||
<a href="mailto:{$ds['email']}" class="btn btn-default btn-xs"
|
||||
title="{$ds['email']}"><i class="glyphicon glyphicon-envelope"></i></a>
|
||||
{/if}
|
||||
{if $ds['coordinates']}
|
||||
<a href="https://www.google.com/maps/dir//{$ds['coordinates']}/" target="_blank"
|
||||
class="btn btn-default btn-xs" title="{$ds['coordinates']}"><i
|
||||
class="glyphicon glyphicon-map-marker"></i></a>
|
||||
{/if}
|
||||
</td>
|
||||
<td align="center" api-get-text="{$_url}autoload/customer_is_active/{$ds['id']}">
|
||||
<span class="label label-default">•</span>
|
||||
</td>
|
||||
<td>{$ds['service_type']}</td>
|
||||
<td>{Lang::dateTimeFormat($ds['created_at'])}</td>
|
||||
<td align="center">
|
||||
<a href="{$_url}customers/view/{$ds['id']}" id="{$ds['id']}"
|
||||
style="margin: 0px; color:black"
|
||||
class="btn btn-success btn-xs"> {Lang::T('View')} </a>
|
||||
<a href="{$_url}customers/edit/{$ds['id']}" id="{$ds['id']}"
|
||||
style="margin: 0px; color:black"
|
||||
class="btn btn-info btn-xs"> {Lang::T('Edit')} </a>
|
||||
<a href="{$_url}plan/recharge/{$ds['id']}" id="{$ds['id']}" style="margin: 0px;"
|
||||
class="btn btn-primary btn-xs">{Lang::T('Recharge')}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
|
||||
<script>
|
||||
var $j = jQuery.noConflict();
|
||||
|
||||
$j(document).ready(function () {
|
||||
$j('#customerTable').DataTable({
|
||||
"pagingType": "full_numbers",
|
||||
"lengthMenu": [ [5, 10, 25, 50, 100, -1], [5, 10, 25, 50, 100, "All"] ],
|
||||
"pageLength": 5
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{include file="sections/footer.tpl"}
|
@ -41,7 +41,7 @@
|
||||
<div class="icon">
|
||||
<i class="ion ion-person"></i>
|
||||
</div>
|
||||
<a href="{$_url}prepaid/list" class="small-box-footer">{Lang::T('View All')} <i
|
||||
<a href="{$_url}plan/list" class="small-box-footer">{Lang::T('View All')} <i
|
||||
class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
@ -74,8 +74,7 @@
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn bg-teal btn-sm" data-widget="collapse"><i class="fa fa-minus"></i>
|
||||
</button>
|
||||
<a href="{$_url}settings/app#hide_dashboard_content" class="btn bg-teal btn-sm"><i
|
||||
class="fa fa-times"></i>
|
||||
<a href="{$_url}dashboard&refresh" class="btn bg-teal btn-sm"><i class="fa fa-refresh"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -96,8 +95,7 @@
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn bg-teal btn-sm" data-widget="collapse"><i class="fa fa-minus"></i>
|
||||
</button>
|
||||
<a href="{$_url}settings/app#hide_dashboard_content" class="btn bg-teal btn-sm"><i
|
||||
class="fa fa-times"></i>
|
||||
<a href="{$_url}dashboard&refresh" class="btn bg-teal btn-sm"><i class="fa fa-refresh"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -146,24 +144,30 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{Lang::T('Username')}</th>
|
||||
<th>{Lang::T('Created On')}</th>
|
||||
<th>{Lang::T('Expires On')}</th>
|
||||
<th>{Lang::T('Created / Expired')}</th>
|
||||
<th>{Lang::T('Internet Plan')}</th>
|
||||
<th>{Lang::T('Location')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $expire as $expired}
|
||||
{assign var="rem_exp" value="{$expired['expiration']} {$expired['time']}"}
|
||||
{assign var="rem_started" value="{$expired['recharged_on']} {$expired['recharged_time']}"}
|
||||
<tr>
|
||||
<td><a href="{$_url}customers/viewu/{$expired['username']}">{$expired['username']}</a></td>
|
||||
<td>{Lang::dateAndTimeFormat($expired['recharged_on'],$expired['recharged_time'])}
|
||||
</td>
|
||||
<td>{Lang::dateAndTimeFormat($expired['expiration'],$expired['time'])}
|
||||
<td><small data-toggle="tooltip" data-placement="top"
|
||||
title="{Lang::dateAndTimeFormat($expired['recharged_on'],$expired['recharged_time'])}">{Lang::timeElapsed($rem_started)}</small> /
|
||||
<span data-toggle="tooltip" data-placement="top"
|
||||
title="{Lang::dateAndTimeFormat($expired['expiration'],$expired['time'])}">{Lang::timeElapsed($rem_exp)}</span>
|
||||
</td>
|
||||
<td>{$expired['namebp']}</td>
|
||||
<td>{$expired['routers']}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{/foreach}
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@ -381,6 +385,21 @@
|
||||
var latestVersion = data.version;
|
||||
if (localVersion !== latestVersion) {
|
||||
$('#version').html('Latest Version: ' + latestVersion);
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
title: "New Version Available\nVersion: "+latestVersion,
|
||||
toast: true,
|
||||
position: 'bottom-right',
|
||||
showConfirmButton: true,
|
||||
showCloseButton: true,
|
||||
timer: 30000,
|
||||
confirmButtonText: '<a href="{$_url}community#latestVersion" style="color: white;">Update Now</a>',
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.addEventListener('mouseenter', Swal.stopTimer)
|
||||
toast.addEventListener('mouseleave', Swal.resumeTimer)
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -5,7 +5,8 @@
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30">
|
||||
<div class="panel-heading">{Lang::T('Refill Balance')}</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}prepaid/deposit-post">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}plan/deposit-post">
|
||||
<input type="hidden" name="stoken" value="{App::getToken()}">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Select Account')}</label>
|
||||
<div class="col-md-6">
|
||||
@ -21,7 +22,7 @@
|
||||
data-placeholder="{Lang::T('Select Plans')}...">
|
||||
<option></option>
|
||||
{foreach $p as $pl}
|
||||
<option value="{$pl['id']}">{$pl['name_plan']} - {Lang::moneyFormat($pl['price'])}</option>
|
||||
<option value="{$pl['id']}">{if $pl['enabled'] neq 1}DISABLED PLAN • {/if}{$pl['name_plan']} - {Lang::moneyFormat($pl['price'])}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -14,10 +14,18 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Client Can Purchase')}</label>
|
||||
<label class="col-md-2 control-label">{Lang::T('Type')}</label>
|
||||
<div class="col-md-10">
|
||||
<input type="radio" name="allow_purchase" value="yes" checked> Yes
|
||||
<input type="radio" name="allow_purchase" value="no"> No
|
||||
<input type="radio" name="prepaid" onclick="prePaid()" value="yes" checked> Prepaid
|
||||
<input type="radio" name="prepaid" onclick="postPaid()" value="no"> Postpaid
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Plan Type')}</label>
|
||||
<div class="col-md-10">
|
||||
<input type="radio" name="plan_type" value="Personal" checked> Personal
|
||||
<input type="radio" name="plan_type" value="Business"> Business
|
||||
</div>
|
||||
</div>
|
||||
{if $_c['radius_enable']}
|
||||
@ -106,6 +114,16 @@
|
||||
<input type="number" class="form-control" name="price" required>
|
||||
</div>
|
||||
</div>
|
||||
{if $_c['enable_tax'] == 'yes'}
|
||||
{if $_c['tax_rate'] == 'custom'}
|
||||
<p class="help-block col-md-4">{number_format($_c['custom_tax_rate'], 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{else}
|
||||
<p class="help-block col-md-4">{number_format($_c['tax_rate'] * 100, 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Shared Users')}</label>
|
||||
@ -121,16 +139,9 @@
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select class="form-control" id="validity_unit" name="validity_unit">
|
||||
<option value="Mins" {if $d['validity_unit'] eq 'Mins'} selected {/if}>{Lang::T('Mins')}
|
||||
</option>
|
||||
<option value="Hrs" {if $d['validity_unit'] eq 'Hrs'} selected {/if}>{Lang::T('Hrs')}
|
||||
</option>
|
||||
<option value="Days" {if $d['validity_unit'] eq 'Days'} selected {/if}>{Lang::T('Days')}
|
||||
</option>
|
||||
<option value="Months" {if $d['validity_unit'] eq 'Months'} selected {/if}>
|
||||
{Lang::T('Months')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">{Lang::T('1 Period = 1 Month, Expires the 20th of each month')}</p>
|
||||
</div>
|
||||
<span id="routerChoose" class="">
|
||||
<div class="form-group">
|
||||
@ -165,8 +176,7 @@
|
||||
</div> *}
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-10">
|
||||
<button class="btn btn-success"
|
||||
type="submit">{Lang::T('Save Changes')}</button>
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Save Changes')}</button>
|
||||
Or <a href="{$_url}services/hotspot">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -175,6 +185,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var preOpt = `<option value="Mins">{Lang::T('Mins')}</option>
|
||||
<option value="Hrs">{Lang::T('Hrs')}</option>
|
||||
<option value="Days">{Lang::T('Days')}</option>
|
||||
<option value="Months">{Lang::T('Months')}</option>`;
|
||||
var postOpt = `<option value="Period">{Lang::T('Period')}</option>`;
|
||||
function prePaid() {
|
||||
$("#validity_unit").html(preOpt);
|
||||
}
|
||||
|
||||
function postPaid() {
|
||||
$("#validity_unit").html(postOpt);
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
prePaid()
|
||||
})
|
||||
</script>
|
||||
{if $_c['radius_enable']}
|
||||
{literal}
|
||||
<script>
|
||||
|
@ -10,17 +10,35 @@
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Status')}</label>
|
||||
<div class="col-md-10">
|
||||
<input type="radio" name="enabled" value="1" {if $d['enabled'] == 1}checked{/if}> Enable
|
||||
<input type="radio" name="enabled" value="0" {if $d['enabled'] == 0}checked{/if}> Disable
|
||||
<input type="radio" name="enabled" value="1" {if $d['enabled'] == 1}checked{/if}> Enable
|
||||
<input type="radio" name="enabled" value="0" {if $d['enabled'] == 0}checked{/if}> Disable
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Client Can Purchase')}</label>
|
||||
<label class="col-md-2 control-label">{Lang::T('Type')}</label>
|
||||
<div class="col-md-10">
|
||||
<input type="radio" name="allow_purchase" value="yes" {if $d['allow_purchase'] == yes}checked{/if}> Yes
|
||||
<input type="radio" name="allow_purchase" value="no" {if $d['allow_purchase'] == no}checked{/if}> No
|
||||
<input type="radio" name="prepaid" onclick="prePaid()" value="yes"
|
||||
{if $d['prepaid'] == yes}checked{/if}>
|
||||
Prepaid
|
||||
<input type="radio" name="prepaid" onclick="postPaid()" value="no"
|
||||
{if $d['prepaid'] == no}checked{/if}> Postpaid
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Plan Type')}</label>
|
||||
<div class="col-md-10">
|
||||
<input type="radio" name="plan_type" value="Personal"
|
||||
{if $d['plan_type'] == 'Personal'}checked{/if}>
|
||||
Personal
|
||||
<input type="radio" name="plan_type" value="Business"
|
||||
{if $d['plan_type'] == 'Business'}checked{/if}> Business
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{if $_c['radius_enable'] and $d['is_radius']}
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">Radius</label>
|
||||
@ -41,7 +59,7 @@
|
||||
<div class="col-md-10">
|
||||
<input type="radio" id="Unlimited" name="typebp" value="Unlimited"
|
||||
{if $d['typebp'] eq 'Unlimited'} checked {/if}> {Lang::T('Unlimited')}
|
||||
<input type="radio" id="Limited" {if $_c['radius_enable'] and $d['is_radius']}disabled{/if}
|
||||
<input type="radio" id="Limited"
|
||||
name="typebp" value="Limited" {if $d['typebp'] eq 'Limited'} checked {/if}>
|
||||
{Lang::T('Limited')}
|
||||
</div>
|
||||
@ -115,6 +133,16 @@
|
||||
<input type="number" class="form-control" name="price" value="{$d['price']}" required>
|
||||
</div>
|
||||
</div>
|
||||
{if $_c['enable_tax'] == 'yes'}
|
||||
{if $_c['tax_rate'] == 'custom'}
|
||||
<p class="help-block col-md-4">{number_format($_c['custom_tax_rate'], 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{else}
|
||||
<p class="help-block col-md-4">{number_format($_c['tax_rate'] * 100, 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Shared Users')}</label>
|
||||
@ -131,16 +159,23 @@
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select class="form-control" id="validity_unit" name="validity_unit">
|
||||
<option value="Mins" {if $d['validity_unit'] eq 'Mins'} selected {/if}>{Lang::T('Mins')}
|
||||
</option>
|
||||
<option value="Hrs" {if $d['validity_unit'] eq 'Hrs'} selected {/if}>{Lang::T('Hrs')}
|
||||
</option>
|
||||
<option value="Days" {if $d['validity_unit'] eq 'Days'} selected {/if}>{Lang::T('Days')}
|
||||
</option>
|
||||
<option value="Months" {if $d['validity_unit'] eq 'Months'} selected {/if}>
|
||||
{Lang::T('Months')}</option>
|
||||
{if $d['prepaid'] == yes}
|
||||
<option value="Mins" {if $d['validity_unit'] eq 'Mins'} selected {/if}>{Lang::T('Mins')}
|
||||
</option>
|
||||
<option value="Hrs" {if $d['validity_unit'] eq 'Hrs'} selected {/if}>{Lang::T('Hrs')}
|
||||
</option>
|
||||
<option value="Days" {if $d['validity_unit'] eq 'Days'} selected {/if}>{Lang::T('Days')}
|
||||
</option>
|
||||
<option value="Months" {if $d['validity_unit'] eq 'Months'} selected {/if}>
|
||||
{Lang::T('Months')}</option>
|
||||
{else}
|
||||
<option value="Period" {if $d['validity_unit'] eq 'Period'} selected {/if}>
|
||||
{Lang::T('Period')}</option>
|
||||
{/if}
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">{Lang::T('1 Period = 1 Month, Expires the 20th of each month')}
|
||||
</p>
|
||||
</div>
|
||||
<span id="routerChoose" class="{if $d['is_radius']}hidden{/if}">
|
||||
<div class="form-group">
|
||||
@ -174,8 +209,7 @@
|
||||
</div> *}
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-10">
|
||||
<button class="btn btn-success"
|
||||
type="submit">{Lang::T('Save Changes')}</button>
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Save Changes')}</button>
|
||||
Or <a href="{$_url}services/hotspot">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -186,6 +220,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var preOpt = `<option value="Mins">{Lang::T('Mins')}</option>
|
||||
<option value="Hrs">{Lang::T('Hrs')}</option>
|
||||
<option value="Days">{Lang::T('Days')}</option>
|
||||
<option value="Months">{Lang::T('Months')}</option>`;
|
||||
var postOpt = `<option value="Period">{Lang::T('Period')}</option>`;
|
||||
function prePaid() {
|
||||
$("#validity_unit").html(preOpt);
|
||||
}
|
||||
|
||||
function postPaid() {
|
||||
$("#validity_unit").html(postOpt);
|
||||
}
|
||||
</script>
|
||||
|
||||
{if $_c['radius_enable'] && $d['is_radius']}
|
||||
{literal}
|
||||
<script>
|
||||
@ -213,4 +262,4 @@
|
||||
</script>
|
||||
{/literal}
|
||||
{/if}
|
||||
{include file="sections/footer.tpl"}
|
||||
{include file="sections/footer.tpl"}
|
@ -27,8 +27,8 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<a href="{$_url}services/add" class="btn btn-primary btn-block"><i
|
||||
class="ion ion-android-add"> </i> {Lang::T('New Service Plan')}</a>
|
||||
<a href="{$_url}services/add" class="btn btn-primary btn-block"><i class="ion ion-android-add">
|
||||
</i> {Lang::T('New Service Plan')}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
@ -38,52 +38,54 @@
|
||||
<th>{Lang::T('Plan Name')}</th>
|
||||
<th>{Lang::T('Plan Type')}</th>
|
||||
<th>{Lang::T('Bandwidth Plans')}</th>
|
||||
<th>{Lang::T('Plan Category')}</th>
|
||||
<th>{Lang::T('Plan Price')}</th>
|
||||
<th>{Lang::T('Time Limit')}</th>
|
||||
<th>{Lang::T('Data Limit')}</th>
|
||||
<th>{Lang::T('Plan Validity')}</th>
|
||||
<th>{Lang::T('Routers')}</th>
|
||||
<th>{Lang::T('Expired IP Pool')}</th>
|
||||
<th>{Lang::T('ID')}</th>
|
||||
<th>{Lang::T('Manage')}</th>
|
||||
<th>ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $d as $ds}
|
||||
<tr {if $ds['enabled'] != 1}class="danger" title="disabled"
|
||||
{elseif $ds['allow_purchase'] != 'yes'}class="warning" title="Customer can't purchase" {/if}>
|
||||
<td class="headcol">{$ds['name_plan']}</td>
|
||||
<td>{$ds['typebp']}</td>
|
||||
<td>{$ds['name_bw']}</td>
|
||||
<td>{Lang::moneyFormat($ds['price'])}</td>
|
||||
<td>{$ds['time_limit']} {$ds['time_unit']}</td>
|
||||
<td>{$ds['data_limit']} {$ds['data_unit']}</td>
|
||||
<td>{$ds['validity']} {$ds['validity_unit']}</td>
|
||||
<td>
|
||||
{if $ds['is_radius']}
|
||||
<span class="label label-primary">RADIUS</span>
|
||||
{else}
|
||||
{if $ds['routers']!=''}
|
||||
<a href="{$_url}routers/edit/0&name={$ds['routers']}">{$ds['routers']}</a>
|
||||
{/if}
|
||||
{/if}
|
||||
</td>
|
||||
<td>{$ds['pool_expired']}{if $ds['list_expired']}{if $ds['pool_expired']} | {/if}{$ds['list_expired']}{/if}</td>
|
||||
<td>
|
||||
<a href="{$_url}services/edit/{$ds['id']}"
|
||||
class="btn btn-info btn-xs">{Lang::T('Edit')}</a>
|
||||
<a href="{$_url}services/delete/{$ds['id']}" id="{$ds['id']}"
|
||||
onclick="return confirm('{Lang::T('Delete')}?')"
|
||||
class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</td>
|
||||
<td>{$ds['id']}</td>
|
||||
</tr>
|
||||
<tr {if $ds['enabled'] !=1}class="danger" title="disabled" {elseif $ds['prepaid'] !='yes'
|
||||
}class="warning" title="Postpaid" {/if}>
|
||||
<td class="headcol">{$ds['name_plan']}</td>
|
||||
<td>{$ds['plan_type']}</td>
|
||||
<td>{$ds['name_bw']}</td>
|
||||
<td>{$ds['typebp']}</td>
|
||||
<td>{Lang::moneyFormat($ds['price'])}</td>
|
||||
<td>{$ds['time_limit']} {$ds['time_unit']}</td>
|
||||
<td>{$ds['data_limit']} {$ds['data_unit']}</td>
|
||||
<td>{$ds['validity']} {$ds['validity_unit']}</td>
|
||||
<td>
|
||||
{if $ds['is_radius']}
|
||||
<span class="label label-primary">RADIUS</span>
|
||||
{else}
|
||||
{if $ds['routers']!=''}
|
||||
<a href="{$_url}routers/edit/0&name={$ds['routers']}">{$ds['routers']}</a>
|
||||
{/if}
|
||||
{/if}
|
||||
</td>
|
||||
<td>{$ds['pool_expired']}{if $ds['list_expired']}{if $ds['pool_expired']} |
|
||||
{/if}{$ds['list_expired']}{/if}</td>
|
||||
<td>{$ds['id']}</td>
|
||||
<td>
|
||||
<a href="{$_url}services/edit/{$ds['id']}"
|
||||
class="btn btn-info btn-xs">{Lang::T('Edit')}</a>
|
||||
<a href="{$_url}services/delete/{$ds['id']}" id="{$ds['id']}"
|
||||
onclick="return confirm('{Lang::T('Delete')}?')"
|
||||
class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
21
ui/ui/invoice-customer.tpl
Normal file
21
ui/ui/invoice-customer.tpl
Normal file
@ -0,0 +1,21 @@
|
||||
{include file="sections/user-header.tpl"}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-md-offset-2">
|
||||
<div class="panel panel-hovered panel-primary panel-stacked mb30">
|
||||
<div class="panel-heading">{$in['invoice']}</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="post" action="{$_url}plan/print" target="_blank">
|
||||
<pre id="content">{$invoice}</pre>
|
||||
<input type="hidden" name="id" value="{$in['id']}">
|
||||
<a href="{$_url}voucher/list-activated" class="btn btn-default btn-sm"><i
|
||||
class="ion-reply-all"></i>{Lang::T('Finish')}</a>
|
||||
<a href="https://api.whatsapp.com/send/?text={$whatsapp}" target="_blank"
|
||||
class="btn btn-primary btn-sm">
|
||||
<i class="glyphicon glyphicon-share"></i> WhatsApp</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include file="sections/user-footer.tpl"}
|
@ -5,16 +5,16 @@
|
||||
<div class="panel panel-hovered panel-primary panel-stacked mb30">
|
||||
<div class="panel-heading">{$in['invoice']}</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="post" action="{$_url}prepaid/print" target="_blank">
|
||||
<form class="form-horizontal" method="post" action="{$_url}plan/print" target="_blank">
|
||||
<pre id="content"></pre>
|
||||
<textarea class="hidden" id="formcontent" name="content">{$invoice}</textarea>
|
||||
<input type="hidden" name="id" value="{$in['id']}">
|
||||
<a href="{$_url}prepaid/list" class="btn btn-default btn-sm"><i
|
||||
<a href="{$_url}plan/list" class="btn btn-default btn-sm"><i
|
||||
class="ion-reply-all"></i>{Lang::T('Finish')}</a>
|
||||
<a href="https://api.whatsapp.com/send/?text={$whatsapp}" target="_blank"
|
||||
class="btn btn-primary btn-sm">
|
||||
<i class="glyphicon glyphicon-share"></i> WhatsApp</a>
|
||||
<a href="{$_url}prepaid/view/{$in['id']}/send" class="btn btn-info text-black btn-sm"><i
|
||||
<a href="{$_url}plan/view/{$in['id']}/send" class="btn btn-info text-black btn-sm"><i
|
||||
class="glyphicon glyphicon-envelope"></i> {Lang::T("Resend")}</a>
|
||||
<button type="submit" class="btn btn-info text-black btn-sm"><i class="glyphicon glyphicon-print"></i>
|
||||
Print</button>
|
||||
|
@ -4,6 +4,13 @@
|
||||
<div class="col-sm-12">
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-primary btn-xs" title="save" href="{$_url}logs/radius-csv"
|
||||
onclick="return confirm('This will export to CSV?')"><span class="glyphicon glyphicon-download"
|
||||
aria-hidden="true"></span> CSV</a>
|
||||
</div>
|
||||
{/if}
|
||||
Radius
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@ -53,7 +60,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,6 +4,13 @@
|
||||
<div class="col-sm-12">
|
||||
<div class="panel panel-hovered mb20 panel-primary">
|
||||
<div class="panel-heading">
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-primary btn-xs" title="save" href="{$_url}logs/list-csv"
|
||||
onclick="return confirm('This will export to CSV?')"><span class="glyphicon glyphicon-download"
|
||||
aria-hidden="true"></span> CSV</a>
|
||||
</div>
|
||||
{/if}
|
||||
Activity Log
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@ -50,7 +57,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
142
ui/ui/message-bulk.tpl
Normal file
142
ui/ui/message-bulk.tpl
Normal file
@ -0,0 +1,142 @@
|
||||
{include file="sections/header.tpl"}
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.3/css/jquery.dataTables.min.css">
|
||||
|
||||
|
||||
<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">{Lang::T('Send Bulk Message')}</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="post" role="form" id="bulkMessageForm" action="">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Group')}</label>
|
||||
<div class="col-md-6">
|
||||
<select class="form-control" name="group" id="group">
|
||||
<option value="all" selected>{Lang::T('All Customers')}</option>
|
||||
<option value="new">{Lang::T('New Customers')}</option>
|
||||
<option value="expired">{Lang::T('Expired Customers')}</option>
|
||||
<option value="active">{Lang::T('Active Customers')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Send Via')}</label>
|
||||
<div class="col-md-6">
|
||||
<select class="form-control" name="via" id="via">
|
||||
<option value="sms" selected>{Lang::T('SMS')}</option>
|
||||
<option value="wa">{Lang::T('WhatsApp')}</option>
|
||||
<option value="both">{Lang::T('SMS and WhatsApp')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Message per time')}</label>
|
||||
<div class="col-md-6">
|
||||
<select class="form-control" name="batch" id="batch">
|
||||
<option value="5">{Lang::T('5 Messages')}</option>
|
||||
<option value="10" selected>{Lang::T('10 Messages')}</option>
|
||||
<option value="15">{Lang::T('15 Messages')}</option>
|
||||
<option value="20">{Lang::T('20 Messages')}</option>
|
||||
<option value="20">{Lang::T('30 Messages')}</option>
|
||||
<option value="20">{Lang::T('40 Messages')}</option>
|
||||
<option value="20">{Lang::T('50 Messages')}</option>
|
||||
<option value="20">{Lang::T('60 Messages')}</option>
|
||||
</select>{Lang::T('Use 20 and above if you are sending to all customers to avoid server time out')}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Delay')}</label>
|
||||
<div class="col-md-6">
|
||||
<select class="form-control" name="delay" id="delay">
|
||||
<option value="0" selected>{Lang::T('No Delay')}</option>
|
||||
<option value="5">{Lang::T('5 Seconds')}</option>
|
||||
<option value="10">{Lang::T('10 Seconds')}</option>
|
||||
<option value="15">{Lang::T('15 Seconds')}</option>
|
||||
<option value="20">{Lang::T('20 Seconds')}</option>
|
||||
</select>{Lang::T('Use at least 5 secs if you are sending to all customers to avoid being banned by your message provider')}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Message')}</label>
|
||||
<div class="col-md-6">
|
||||
<textarea class="form-control" id="message" name="message"
|
||||
placeholder="{Lang::T('Compose your message...')}" rows="5"></textarea>
|
||||
<input name="test" type="checkbox"> {Lang::T('Testing [if checked no real message is sent]')}
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
{Lang::T('Use placeholders:')}
|
||||
<br>
|
||||
<b>[[name]]</b> - {Lang::T('Customer Name')}
|
||||
<br>
|
||||
<b>[[user_name]]</b> - {Lang::T('Customer Username')}
|
||||
<br>
|
||||
<b>[[phone]]</b> - {Lang::T('Customer Phone')}
|
||||
<br>
|
||||
<b>[[company_name]]</b> - {Lang::T('Your Company Name')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-success" type="submit" name=send value=now>
|
||||
{Lang::T('Send Message')}</button>
|
||||
<a href="{$_url}dashboard" class="btn btn-default">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if $batchStatus}
|
||||
<p><span class="label label-success">Total SMS Sent: {$totalSMSSent}</span> <span class="label label-danger">Total SMS
|
||||
Failed: {$totalSMSFailed}</span> <span class="label label-success">Total WhatsApp Sent:
|
||||
{$totalWhatsappSent}</span> <span class="label label-danger">Total WhatsApp Failed:
|
||||
{$totalWhatsappFailed}</span></p>
|
||||
{/if}
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">Message Results</h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<div class="box-body">
|
||||
<table id="messageResultsTable" class="table table-bordered table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Phone</th>
|
||||
<th>Message</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $batchStatus as $customer}
|
||||
<tr>
|
||||
<td>{$customer.name}</td>
|
||||
<td>{$customer.phone}</td>
|
||||
<td>{$customer.message}</td>
|
||||
<td>{$customer.status}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
|
||||
<script>
|
||||
var $j = jQuery.noConflict();
|
||||
|
||||
$j(document).ready(function () {
|
||||
$j('#messageResultsTable').DataTable();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
{include file="sections/footer.tpl"}
|
64
ui/ui/message.tpl
Normal file
64
ui/ui/message.tpl
Normal file
@ -0,0 +1,64 @@
|
||||
{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">{Lang::T('Send Personal Message')}</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}message/send-post">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Customer')}</label>
|
||||
<div class="col-md-6">
|
||||
<select {if $cust}{else}id="personSelect" {/if} class="form-control select2"
|
||||
name="id_customer" style="width: 100%"
|
||||
data-placeholder="{Lang::T('Select a customer')}...">
|
||||
{if $cust}
|
||||
<option value="{$cust['id']}">{$cust['username']} • {$cust['fullname']} •
|
||||
{$cust['email']}</option>
|
||||
{/if}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Send Via')}</label>
|
||||
<div class="col-md-6">
|
||||
<select class="form-control" name="via" id="via">
|
||||
<option value="sms" selected> {Lang::T('SMS')}</option>
|
||||
<option value="wa"> {Lang::T('WhatsApp')}</option>
|
||||
<option value="both"> {Lang::T('SMS and WhatsApp')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Message')}</label>
|
||||
<div class="col-md-6">
|
||||
<textarea class="form-control" id="message" name="message"
|
||||
placeholder="{Lang::T('Compose your message...')}" rows="5"></textarea>
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
{Lang::T('Use placeholders:')}
|
||||
<br>
|
||||
<b>[[name]]</b> - {Lang::T('Customer Name')}
|
||||
<br>
|
||||
<b>[[user_name]]</b> - {Lang::T('Customer Username')}
|
||||
<br>
|
||||
<b>[[phone]]</b> - {Lang::T('Customer Phone')}
|
||||
<br>
|
||||
<b>[[company_name]]</b> - {Lang::T('Your Company Name')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Send Message')}</button>
|
||||
<a href="{$_url}dashboard" class="btn btn-default">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{include file="sections/footer.tpl"}
|
20
ui/ui/pagination.tpl
Normal file
20
ui/ui/pagination.tpl
Normal file
@ -0,0 +1,20 @@
|
||||
{if $paginator}
|
||||
<nav aria-label="Page navigation pagination-sm">
|
||||
<ul class="pagination">
|
||||
<li {if empty($paginator['prev'])}class="disabled" {/if}>
|
||||
<a href="{$paginator['url']}{$paginator['prev']}" aria-label="Previous">
|
||||
<span aria-hidden="true">{Lang::T('Prev')}</span>
|
||||
</a>
|
||||
</li>
|
||||
{foreach $paginator['pages'] as $page}
|
||||
<li class="{if $paginator['page'] == $page}active{elseif $page == '...'}disabled{/if}"><a
|
||||
href="{$paginator['url']}{$page}">{$page}</a></li>
|
||||
{/foreach}
|
||||
<li {if $paginator['page']>=$paginator['count']}class="disabled" {/if}>
|
||||
<a href="{$paginator['url']}{$paginator['next']}" aria-label="Next">
|
||||
<span aria-hidden="true">{Lang::T('Next')}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{/if}
|
@ -1,34 +1,31 @@
|
||||
{include file="sections/header.tpl"}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="panel panel-info panel-hovered">
|
||||
<div class="panel-heading">{Lang::T('Payment Gateway')}</div>
|
||||
<div class="panel-body row">
|
||||
{foreach $pgs as $pg}
|
||||
<div class="col-sm-4 mb20">
|
||||
<a href="{$_url}paymentgateway/{$pg}"
|
||||
class="btn btn-block btn-{if $pg==$_c['payment_gateway']}success{else}default{/if}">{ucwords($pg)}</a>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<form method="post">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-2 control-label">Payment Gateway</label>
|
||||
<div class="col-md-8">
|
||||
<select name="payment_gateway" id="payment_gateway" class="form-control">
|
||||
<option value="none">None</option>
|
||||
<div class="panel-heading">{Lang::T('Payment Gateway')}</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-condensed">
|
||||
<tbody>
|
||||
{foreach $pgs as $pg}
|
||||
<option value="{$pg}" {if $_c['payment_gateway'] eq {$pg}}selected="selected" {/if}>{ucwords($pg)}</option>
|
||||
<tr>
|
||||
<td width="10" align="center" valign="center"><input type="checkbox" name="pgs[]"
|
||||
{if in_array($pg, $actives)}checked{/if} value="{$pg}"></td>
|
||||
<td><a href="{$_url}paymentgateway/{$pg}"
|
||||
class="btn btn-block btn-{if in_array($pg, $actives)}info{else}default{/if} text-left">{ucwords($pg)}</a>
|
||||
</td>
|
||||
<td width="10"><a href="{$_url}paymentgateway/delete/{$pg}"
|
||||
onclick="return confirm('{Lang::T('Delete')} {$pg}?')" class="btn btn-danger"><i
|
||||
class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button class="btn btn-block btn-primary" type="submit">{Lang::T('Save Changes')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel-footer"><button type="submit" class="btn btn-primary btn-block" name="save"
|
||||
value="actives">{Lang::T('Save Changes')}</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include file="sections/footer.tpl"}
|
||||
</form>
|
||||
{include file="sections/footer.tpl"}
|
@ -7,7 +7,7 @@
|
||||
<h3 class="panel-title">Edit Plan</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}prepaid/edit-post">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}plan/edit-post">
|
||||
<input type="hidden" name="id" value="{$d['id']}">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Select Account')}</label>
|
||||
@ -23,7 +23,8 @@
|
||||
<select id="id_plan" name="id_plan" class="form-control select2">
|
||||
{foreach $p as $ps}
|
||||
<option value="{$ps['id']}" {if $d['plan_id'] eq $ps['id']} selected {/if}>
|
||||
{if $ps['is_radius']=='1'}Radius{else}{$ps['routers']}{/if} - {$ps['name_plan']}</option>
|
||||
{if $ps['enabled'] neq 1}DISABLED PLAN • {/if}
|
||||
{if $ps['is_radius']=='1'}Radius{else}{$ps['routers']}{/if} • {$ps['name_plan']}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
@ -55,7 +56,7 @@
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-success"
|
||||
type="submit">{Lang::T('Edit')}</button>
|
||||
Or <a href="{$_url}prepaid/list">{Lang::T('Cancel')}</a>
|
||||
Or <a href="{$_url}plan/list">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -6,22 +6,22 @@
|
||||
<div class="panel-heading">
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-primary btn-xs" title="save" href="{$_url}prepaid/sync"
|
||||
<a class="btn btn-primary btn-xs" title="save" href="{$_url}plan/sync"
|
||||
onclick="return confirm('This will sync/send Caustomer active plan to Mikrotik?')"><span
|
||||
class="glyphicon glyphicon-refresh" aria-hidden="true"></span> sync</a>
|
||||
</div>
|
||||
<div class="btn-group pull-right">
|
||||
<a class="btn btn-info btn-xs" title="save" href="{$_url}customers/csv"
|
||||
<a class="btn btn-info btn-xs" title="save" href="{$_url}customers/csv-prepaid"
|
||||
onclick="return confirm('This will export to CSV?')"><span class="glyphicon glyphicon-download"
|
||||
aria-hidden="true"></span> CSV</a>
|
||||
</div>
|
||||
{/if}
|
||||
{Lang::T('Prepaid Users')}
|
||||
|
||||
</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}prepaid/list/">
|
||||
<form id="site-search" method="post" action="{$_url}plan/list/">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">
|
||||
<span class="fa fa-search"></span>
|
||||
@ -35,7 +35,7 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<a href="{$_url}prepaid/recharge" class="btn btn-primary btn-block"><i
|
||||
<a href="{$_url}plan/recharge" class="btn btn-primary btn-block"><i
|
||||
class="ion ion-android-add"> </i> {Lang::T('Recharge Account')}</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -64,24 +64,38 @@
|
||||
<td>{$ds['method']}</td>
|
||||
<td>{$ds['routers']}</td>
|
||||
<td>
|
||||
<a href="{$_url}prepaid/edit/{$ds['id']}"
|
||||
class="btn btn-warning btn-xs">{Lang::T('Edit')}</a>
|
||||
<a href="{$_url}plan/edit/{$ds['id']}"
|
||||
class="btn btn-warning btn-xs" style="color: black;">{Lang::T('Edit')}</a>
|
||||
{if in_array($_admin['user_type'],['SuperAdmin','Admin'])}
|
||||
<a href="{$_url}prepaid/delete/{$ds['id']}" id="{$ds['id']}"
|
||||
<a href="{$_url}plan/delete/{$ds['id']}" id="{$ds['id']}"
|
||||
onclick="return confirm('{Lang::T('Delete')}?')"
|
||||
class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{/if}
|
||||
{if $ds['status']=='off' && $_c['extend_expired']}
|
||||
<a href="javascript:extend('{$ds['id']}')"
|
||||
class="btn btn-info btn-xs">{Lang::T('Extend')}</a>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function extend(idP){
|
||||
var res = prompt("Extend for many days?", "3");
|
||||
if(res){
|
||||
if(confirm("Extend for "+res+" days?")){
|
||||
window.location.href = "{$_url}plan/extend/"+idP+"/"+res+"&stoken={App::getToken()}";
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{include file="sections/footer.tpl"}
|
||||
{include file="sections/footer.tpl"}
|
@ -14,17 +14,22 @@
|
||||
<div style="max-height: 50px; min-height: 50px;">{$plugin['description']}</div>
|
||||
</div>
|
||||
<div class="box-footer ">
|
||||
<center><small><i>@{$plugin['author']} Last update: {$plugin['last_update']}</i></small></center>
|
||||
<center><small><i>@{$plugin['author']} Last update: {$plugin['last_update']}</i></small>
|
||||
</center>
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<a href="{$plugin['url']}" target="_blank" class="btn btn-primary"><i
|
||||
class="ion ion-chatboxes"></i> Website</a>
|
||||
<a href="{$plugin['github']}" target="_blank" class="btn btn-success"><i
|
||||
class="ion ion-chatboxes"></i> Github</a>
|
||||
<a href="{$plugin['url']}" target="_blank" style="color: black;" class="btn btn-primary"><i
|
||||
class="glyphicon glyphicon-globe"></i> Web</a>
|
||||
<a href="{$plugin['github']}" target="_blank" style="color: black;" class="btn btn-info"><i
|
||||
class="glyphicon glyphicon-align-left"></i> Source</a>
|
||||
</div>
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<a href="{$_url}pluginmanager/delete/plugin/{$plugin['id']}" onclick="return confirm('{Lang::T('Delete')}?')" class="btn btn-danger"><i
|
||||
class="glyphicon glyphicon-trash"></i> Delete</a>
|
||||
<a {if $zipExt } href="{$_url}pluginmanager/install/plugin/{$plugin['id']}"
|
||||
onclick="return confirm('Installing plugin will take some time to complete, do not close the page while it loading to install the plugin')"
|
||||
{else} href="#" onclick="alert('PHP ZIP extension is not installed')"
|
||||
{/if}
|
||||
class="btn btn-warning"><i class="ion ion-chatboxes"></i> Install</a>
|
||||
{else} href="#" onclick="alert('PHP ZIP extension is not installed')"
|
||||
{/if} style="color: black;"
|
||||
class="btn btn-success"><i class="glyphicon glyphicon-circle-arrow-down"></i> Install</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -47,15 +52,15 @@
|
||||
<div class="box-footer ">
|
||||
<center><small><i>@{$pg['author']} Last update: {$pg['last_update']}</i></small></center>
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<a href="{$pg['url']}" target="_blank" class="btn btn-primary"><i
|
||||
class="ion ion-chatboxes"></i> Website</a>
|
||||
<a href="{$pg['github']}" target="_blank" class="btn btn-success"><i
|
||||
class="ion ion-chatboxes"></i> Github</a>
|
||||
<a href="{$pg['url']}" target="_blank" style="color: black;" class="btn btn-primary"><i
|
||||
class="glyphicon glyphicon-globe"></i> Web</a>
|
||||
<a href="{$pg['github']}" target="_blank" style="color: black;" class="btn btn-info"><i
|
||||
class="glyphicon glyphicon-align-left"></i> Source</a>
|
||||
<a {if $zipExt } href="{$_url}pluginmanager/install/payment/{$pg['id']}"
|
||||
onclick="return confirm('Installing plugin will take some time to complete, do not close the page while it loading to install the plugin')"
|
||||
{else} href="#" onclick="alert('PHP ZIP extension is not available')"
|
||||
{/if}
|
||||
class="btn btn-warning"><i class="ion ion-chatboxes"></i> Install</a>
|
||||
{else} href="#" onclick="alert('PHP ZIP extension is not available')"
|
||||
{/if} style="color: black;"
|
||||
class="btn btn-success"><i class="glyphicon glyphicon-circle-arrow-down"></i> Install</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -61,7 +61,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -14,12 +14,21 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Client Can Purchase')}</label>
|
||||
<label class="col-md-2 control-label">{Lang::T('Type')}</label>
|
||||
<div class="col-md-10">
|
||||
<input type="radio" checked name="allow_purchase" value="yes"> Yes
|
||||
<input type="radio" name="allow_purchase" value="no"> No
|
||||
<input type="radio" name="prepaid" onclick="prePaid()" value="yes" checked> Prepaid
|
||||
<input type="radio" name="prepaid" onclick="postPaid()" value="no"> Postpaid
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Plan Type')}</label>
|
||||
<div class="col-md-10">
|
||||
<input type="radio" name="plan_type" value="Personal" checked> Personal
|
||||
<input type="radio" name="plan_type" value="Business"> Business
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if $_c['radius_enable']}
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">Radius</label>
|
||||
@ -55,22 +64,26 @@
|
||||
<input type="number" class="form-control" name="price" required>
|
||||
</div>
|
||||
</div>
|
||||
{if $_c['enable_tax'] == 'yes'}
|
||||
{if $_c['tax_rate'] == 'custom'}
|
||||
<p class="help-block col-md-4">{number_format($_c['custom_tax_rate'], 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{else}
|
||||
<p class="help-block col-md-4">{number_format($_c['tax_rate'] * 100, 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Plan Validity')}</label>
|
||||
<div class="col-md-4">
|
||||
<input type="text" class="form-control" id="validity" name="validity">
|
||||
<p class="help-block">{Lang::T('1 Period = 1 Month, Expires the 20th of each month')}</p>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select class="form-control" id="validity_unit" name="validity_unit">
|
||||
<option value="Mins">{Lang::T('Mins')}</option>
|
||||
<option value="Hrs">{Lang::T('Hrs')}</option>
|
||||
<option value="Days">{Lang::T('Days')}</option>
|
||||
<option value="Months">{Lang::T('Months')}</option>
|
||||
<option value="Period">{Lang::T('Period')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">{Lang::T('1 Period = 1 Month, Expires the 20th of each month')}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"><a
|
||||
@ -121,6 +134,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var preOpt = `<option value="Mins">{Lang::T('Mins')}</option>
|
||||
<option value="Hrs">{Lang::T('Hrs')}</option>
|
||||
<option value="Days">{Lang::T('Days')}</option>
|
||||
<option value="Months">{Lang::T('Months')}</option>`;
|
||||
var postOpt = `<option value="Period">{Lang::T('Period')}</option>`;
|
||||
function prePaid() {
|
||||
$("#validity_unit").html(preOpt);
|
||||
}
|
||||
|
||||
function postPaid() {
|
||||
$("#validity_unit").html(postOpt);
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
prePaid()
|
||||
})
|
||||
</script>
|
||||
{if $_c['radius_enable']}
|
||||
{literal}
|
||||
<script>
|
||||
|
@ -15,12 +15,24 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Client Can Purchase')}</label>
|
||||
<label class="col-md-2 control-label">{Lang::T('Type')}</label>
|
||||
<div class="col-md-10">
|
||||
<input type="radio" name="allow_purchase" value="yes" {if $d['allow_purchase'] == yes}checked{/if}> Yes
|
||||
<input type="radio" name="allow_purchase" value="no" {if $d['allow_purchase'] == no}checked{/if}> No
|
||||
<input type="radio" name="prepaid" onclick="prePaid()" value="yes" {if $d['prepaid'] == yes}checked{/if}>
|
||||
Prepaid
|
||||
<input type="radio" name="prepaid" onclick="postPaid()" value="no" {if $d['prepaid'] == no}checked{/if}> Postpaid
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Plan Type')}</label>
|
||||
<div class="col-md-10">
|
||||
<input type="radio" name="plan_type" value="Personal"
|
||||
{if $d['plan_type'] == 'Personal'}checked{/if}>
|
||||
Personal
|
||||
<input type="radio" name="plan_type" value="Business"
|
||||
{if $d['plan_type'] == 'Business'}checked{/if}> Business
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if $_c['radius_enable'] and $d['is_radius']}
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">Radius</label>
|
||||
@ -56,27 +68,42 @@
|
||||
<input type="number" class="form-control" name="price" required value="{$d['price']}">
|
||||
</div>
|
||||
</div>
|
||||
{if $_c['enable_tax'] == 'yes'}
|
||||
{if $_c['tax_rate'] == 'custom'}
|
||||
<p class="help-block col-md-4">{number_format($_c['custom_tax_rate'], 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{else}
|
||||
<p class="help-block col-md-4">{number_format($_c['tax_rate'] * 100, 2)} % {Lang::T('Tax Rates
|
||||
will be added')}</p>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Plan Validity')}</label>
|
||||
<div class="col-md-4">
|
||||
<input type="text" class="form-control" id="validity" name="validity"
|
||||
value="{$d['validity']}">
|
||||
<p class="help-block">{Lang::T('1 Period = 30 Month, Expires the 20th of each month')}</p>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select class="form-control" id="validity_unit" name="validity_unit">
|
||||
<option value="Mins" {if $d['validity_unit'] eq 'Mins'} selected {/if}>{Lang::T('Mins')}
|
||||
</option>
|
||||
<option value="Hrs" {if $d['validity_unit'] eq 'Hrs'} selected {/if}>{Lang::T('Hrs')}
|
||||
</option>
|
||||
<option value="Days" {if $d['validity_unit'] eq 'Days'} selected {/if}>{Lang::T('Days')}
|
||||
</option>
|
||||
<option value="Months" {if $d['validity_unit'] eq 'Months'} selected {/if}>
|
||||
{Lang::T('Months')}</option>
|
||||
<option value="Period" {if $d['validity_unit'] eq 'Period'} selected {/if}>{Lang::T('Period')}</option>
|
||||
{if $d['prepaid'] == yes}
|
||||
<option value="Mins" {if $d['validity_unit'] eq 'Mins'} selected {/if}>{Lang::T('Mins')}
|
||||
</option>
|
||||
<option value="Hrs" {if $d['validity_unit'] eq 'Hrs'} selected {/if}>{Lang::T('Hrs')}
|
||||
</option>
|
||||
<option value="Days" {if $d['validity_unit'] eq 'Days'} selected {/if}>{Lang::T('Days')}
|
||||
</option>
|
||||
<option value="Months" {if $d['validity_unit'] eq 'Months'} selected {/if}>
|
||||
{Lang::T('Months')}</option>
|
||||
{else}
|
||||
<option value="Period" {if $d['validity_unit'] eq 'Period'} selected {/if}>
|
||||
{Lang::T('Period')}</option>
|
||||
{/if}
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">
|
||||
{Lang::T('1 Period = 1 Month, Expires the 20th of each month')}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"><a href="{$_url}pool/add">{Lang::T('IP Pool')}</a></label>
|
||||
@ -118,8 +145,7 @@
|
||||
</div> *}
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-success"
|
||||
type="submit">{Lang::T('Save Changes')}</button>
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Save Changes')}</button>
|
||||
Or <a href="{$_url}services/pppoe">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -129,6 +155,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
var preOpt = `<option value="Mins">{Lang::T('Mins')}</option>
|
||||
<option value="Hrs">{Lang::T('Hrs')}</option>
|
||||
<option value="Days">{Lang::T('Days')}</option>
|
||||
<option value="Months">{Lang::T('Months')}</option>`;
|
||||
var postOpt = `<option value="Period">{Lang::T('Period')}</option>`;
|
||||
function prePaid() {
|
||||
$("#validity_unit").html(preOpt);
|
||||
}
|
||||
|
||||
function postPaid() {
|
||||
$("#validity_unit").html(postOpt);
|
||||
}
|
||||
</script>
|
||||
{if $_c['radius_enable'] && $d['is_radius']}
|
||||
{literal}
|
||||
<script>
|
||||
@ -147,4 +188,4 @@
|
||||
</script>
|
||||
{/literal}
|
||||
{/if}
|
||||
{include file="sections/footer.tpl"}
|
||||
{include file="sections/footer.tpl"}
|
@ -36,6 +36,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{Lang::T('Plan Name')}</th>
|
||||
<th>{Lang::T('Plan Type')}</th>
|
||||
<th>{Lang::T('Bandwidth Plans')}</th>
|
||||
<th>{Lang::T('Plan Price')}</th>
|
||||
<th>{Lang::T('Plan Validity')}</th>
|
||||
@ -48,22 +49,26 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $d as $ds}
|
||||
<tr {if $ds['enabled'] != 1}class="danger" title="disabled"
|
||||
{elseif $ds['allow_purchase'] != 'yes'}class="warning" title="Customer can't purchase" {/if}>
|
||||
<tr {if $ds['enabled'] != 1}class="danger" title="disabled"{/if}>
|
||||
<td>{$ds['name_plan']}</td>
|
||||
<td>{$ds['plan_type']} {if $ds['prepaid'] != 'yes'}<b>Postpaid</b>{else}Prepaid{/if}</td>
|
||||
<td>{$ds['name_bw']}</td>
|
||||
<td>{Lang::moneyFormat($ds['price'])}</td>
|
||||
<td>{$ds['validity']} {$ds['validity_unit']}</td>
|
||||
<td>{$ds['pool']}</td>
|
||||
<td>{$ds['pool_expired']}{if $ds['list_expired']}{if $ds['pool_expired']} | {/if}{$ds['list_expired']}{/if}</td>
|
||||
<td>{$ds['pool_expired']}{if $ds['list_expired']}
|
||||
{if $ds['pool_expired']} |
|
||||
{/if}{$ds['list_expired']}
|
||||
{/if}</td>
|
||||
<td>
|
||||
{if $ds['is_radius']}
|
||||
<span class="label label-primary">RADIUS</span>
|
||||
{else}
|
||||
{if $ds['routers']!=''}
|
||||
<a href="{$_url}routers/edit/0&name={$ds['routers']}">{$ds['routers']}</a>
|
||||
{if $ds['is_radius']}
|
||||
<span class="label label-primary">RADIUS</span>
|
||||
{else}
|
||||
{if $ds['routers']!=''}
|
||||
<a href="{$_url}routers/edit/0&name={$ds['routers']}">{$ds['routers']}</a>
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}</td>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{$_url}services/pppoe-edit/{$ds['id']}"
|
||||
class="btn btn-info btn-xs">{Lang::T('Edit')}</a>
|
||||
@ -77,7 +82,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -60,7 +60,7 @@
|
||||
|
||||
<body>
|
||||
<page size="A4">
|
||||
<form method="post" action="{$_url}prepaid/print-voucher/" class="no-print">
|
||||
<form method="post" action="{$_url}plan/print-voucher/" class="no-print">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="1" class="btn btn-default btn-sm">
|
||||
<tr>
|
||||
<td>From ID > <input type="text" name="from_id" style="width:40px" value="{$from_id}"> limit
|
||||
|
@ -64,7 +64,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
95
ui/ui/recharge-confirm.tpl
Normal file
95
ui/ui/recharge-confirm.tpl
Normal file
@ -0,0 +1,95 @@
|
||||
{include file="sections/header.tpl"}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30">
|
||||
<div class="panel-heading">{Lang::T('Confirm')}</div>
|
||||
<div class="panel-body">
|
||||
<center><b>{Lang::T('Customer')}</b></center>
|
||||
<ul class="list-group list-group-unbordered">
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Username')}</b> <span class="pull-right">{$cust['username']}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Name')}</b> <span class="pull-right">{$cust['fullname']}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Phone Number')}</b> <span class="pull-right">{$cust['phonenumber']}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Email')}</b> <span class="pull-right">{$cust['email']}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Address')}</b> <span class="pull-right">{$cust['address']}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Balance')}</b> <span
|
||||
class="pull-right">{Lang::moneyFormat($cust['balance'])}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<center><b>{Lang::T('Plan')}</b></center>
|
||||
<ul class="list-group list-group-unbordered">
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Plan Name')}</b> <span class="pull-right">{$plan['name_plan']}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Location')}</b> <span
|
||||
class="pull-right">{if $plan['is_radius']}Radius{else}{$plan['routers']}{/if}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Type')}</b> <span
|
||||
class="pull-right">{if $plan['prepaid'] eq 'yes'}Prepaid{else}Postpaid{/if}
|
||||
{$plan['type']}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Plan Price')}</b> <span
|
||||
class="pull-right">{if $using eq 'zero'}{Lang::moneyFormat(0)}{else}{Lang::moneyFormat($plan['price'])}{/if}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Plan Validity')}</b> <span class="pull-right">{$plan['validity']}
|
||||
{$plan['validity_unit']}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Using')}</b> <span class="pull-right">{ucwords($using)}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<center><b>{Lang::T('Total')}</b></center>
|
||||
<ul class="list-group list-group-unbordered">
|
||||
{if $using neq 'zero' and $add_cost>0}
|
||||
{foreach $bills as $k => $v}
|
||||
<li class="list-group-item">
|
||||
<b>{$k}</b> <span class="pull-right">{Lang::moneyFormat($v)}</span>
|
||||
</li>
|
||||
{/foreach}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Additional Cost')}</b> <span
|
||||
class="pull-right">{Lang::moneyFormat($add_cost)}</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Total')}</b> <small>({Lang::T('Plan Price')} +{Lang::T('Additional Cost')})</small><span class="pull-right"
|
||||
style="font-size: large; font-weight:bolder; font-family: 'Courier New', Courier, monospace; ">{Lang::moneyFormat($plan['price']+$add_cost)}</span>
|
||||
</li>
|
||||
{else}
|
||||
<li class="list-group-item">
|
||||
<b>{Lang::T('Total')}</b> <span class="pull-right"
|
||||
style="font-size: large; font-weight:bolder; font-family: 'Courier New', Courier, monospace; ">{if $using eq 'zero'}{Lang::moneyFormat(0)}{else}{Lang::moneyFormat($plan['price'])}{/if}</span>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}plan/recharge-post">
|
||||
<input type="hidden" name="id_customer" value="{$cust['id']}">
|
||||
<input type="hidden" name="plan" value="{$plan['id']}">
|
||||
<input type="hidden" name="server" value="{$server}">
|
||||
<input type="hidden" name="using" value="{$using}">
|
||||
<input type="hidden" name="stoken" value="{App::getToken()}">
|
||||
<center>
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Recharge')}</button><br>
|
||||
<a class="btn btn-link" href="{$_url}plan/recharge">{Lang::T('Cancel')}</a>
|
||||
</center>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include file="sections/footer.tpl"}
|
@ -1,62 +0,0 @@
|
||||
{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">{Lang::T('Recharge Account')}</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}prepaid/recharge-post" >
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Select Account')}</label>
|
||||
<div class="col-md-6">
|
||||
<select id="personSelect" class="form-control select2" name="id_customer" style="width: 100%" data-placeholder="Select a customer...">
|
||||
<option></option>
|
||||
{foreach $c as $cs}
|
||||
{if $id eq $cs['id']}
|
||||
<option value="{$cs['id']}" selected>{$cs['username']}</option>
|
||||
{else}
|
||||
<option value="{$cs['id']}">{$cs['username']}</option>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Type')}</label>
|
||||
<div class="col-md-6">
|
||||
<label><input type="radio" id="Hot" name="type" value="Hotspot"> {Lang::T('Hotspot Plans')}</label>
|
||||
<label><input type="radio" id="POE" name="type" value="PPPOE"> {Lang::T('PPPOE Plans')}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Routers')}</label>
|
||||
<div class="col-md-6">
|
||||
<select id="server" name="server" class="form-control select2">
|
||||
<option value=''>Select Routers</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Service Plan')}</label>
|
||||
<div class="col-md-6">
|
||||
<select id="plan" name="plan" class="form-control select2">
|
||||
<option value=''>Select Plans</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Recharge')}</button>
|
||||
Or <a href="{$_url}customers/list">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{include file="sections/footer.tpl"}
|
@ -5,7 +5,7 @@
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30">
|
||||
<div class="panel-heading">{Lang::T('Recharge Account')}</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}prepaid/recharge-post">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}plan/recharge-confirm">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Select Account')}</label>
|
||||
<div class="col-md-6">
|
||||
@ -27,7 +27,7 @@
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Routers')}</label>
|
||||
<div class="col-md-6">
|
||||
<select id="server" name="server" class="form-control select2">
|
||||
<select id="server" data-type="server" name="server" class="form-control select2">
|
||||
<option value=''>{Lang::T('Select Routers')}</option>
|
||||
</select>
|
||||
</div>
|
||||
@ -41,7 +41,21 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Using')}</label>
|
||||
<div class="col-md-6">
|
||||
<select name="using" class="form-control">
|
||||
{foreach $usings as $using}
|
||||
<option value="{trim(ucWords($using))}">{trim(ucWords($using))}</option>
|
||||
{/foreach}
|
||||
{if $_c['enable_balance'] eq 'yes'}
|
||||
<option value="balance">{Lang::T('Customer Balance')}</option>
|
||||
{/if}
|
||||
<option value="zero">{$_c['currency_code']} 0</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="help-block col-md-4">Postpaid Recharge for the first time use {$_c['currency_code']} 0</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-lg-offset-2 col-lg-10">
|
||||
<button class="btn btn-success"
|
||||
|
@ -5,7 +5,7 @@
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30">
|
||||
<div class="panel-heading">{Lang::T('Refill Account')}</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}prepaid/refill-post">
|
||||
<form class="form-horizontal" method="post" role="form" action="{$_url}plan/refill-post">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Select Account')}</label>
|
||||
<div class="col-md-6">
|
||||
|
@ -26,22 +26,22 @@
|
||||
<hr>
|
||||
</div>
|
||||
{if isset($notify)}
|
||||
<script>
|
||||
// Display SweetAlert toast notification
|
||||
Swal.fire({
|
||||
icon: '{if $notify_t == "s"}success{else}warning{/if}',
|
||||
title: '{$notify}',
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 5000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.addEventListener('mouseenter', Swal.stopTimer)
|
||||
toast.addEventListener('mouseleave', Swal.resumeTimer)
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// Display SweetAlert toast notification
|
||||
Swal.fire({
|
||||
icon: '{if $notify_t == "s"}success{else}warning{/if}',
|
||||
title: '{$notify}',
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 5000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.addEventListener('mouseenter', Swal.stopTimer)
|
||||
toast.addEventListener('mouseleave', Swal.resumeTimer)
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{/if}
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
@ -59,16 +59,17 @@
|
||||
<div class="panel-body">
|
||||
<div class="form-container">
|
||||
<div class="form-group">
|
||||
<label>{Lang::T('Phone Number')}</label>
|
||||
<label>{if $_c['country_code_phone']!= ''}{Lang::T('Phone Number')}{else}{Lang::T('Username')}{/if}</label>
|
||||
<div class="input-group">
|
||||
{if $_c['country_code_phone']!= ''}
|
||||
<span class="input-group-addon" id="basic-addon1">+</span>
|
||||
{else}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-phone-alt"></i></span>
|
||||
{else}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-user"></i></span>
|
||||
{/if}
|
||||
<input type="text" class="form-control" name="username" value="{$username}"
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']} {Lang::T('Phone Number')}{else}{Lang::T('Username')}{/if}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -83,7 +84,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{Lang::T('Email')}</label>
|
||||
<input type="text" required class="form-control" placeholder="xxxxxx@xxx.xx"
|
||||
<input type="text" class="form-control" placeholder="xxxxxx@xxx.xx"
|
||||
id="email" value="{$email}" name="email">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -111,8 +112,7 @@
|
||||
</div>
|
||||
<div class="btn-group btn-group-justified mb15">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary"
|
||||
type="submit">{Lang::T('Register')}</button>
|
||||
<button class="btn btn-primary" type="submit">{Lang::T('Register')}</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a href="{$_url}register" class="btn btn-success">{Lang::T('Cancel')}</a>
|
||||
|
@ -25,22 +25,22 @@
|
||||
<hr>
|
||||
</div>
|
||||
{if isset($notify)}
|
||||
<script>
|
||||
// Display SweetAlert toast notification
|
||||
Swal.fire({
|
||||
icon: '{if $notify_t == "s"}success{else}warning{/if}',
|
||||
title: '{$notify}',
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 5000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.addEventListener('mouseenter', Swal.stopTimer)
|
||||
toast.addEventListener('mouseleave', Swal.resumeTimer)
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// Display SweetAlert toast notification
|
||||
Swal.fire({
|
||||
icon: '{if $notify_t == "s"}success{else}warning{/if}',
|
||||
title: '{$notify}',
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 5000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.addEventListener('mouseenter', Swal.stopTimer)
|
||||
toast.addEventListener('mouseleave', Swal.resumeTimer)
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{/if}
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
@ -59,16 +59,17 @@
|
||||
<div class="panel-heading">1. {Lang::T('Register as Member')}</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label>{Lang::T('Phone Number')}</label>
|
||||
<label>{if $_c['country_code_phone']!= ''}{Lang::T('Phone Number')}{else}{Lang::T('Username')}{/if}</label>
|
||||
<div class="input-group">
|
||||
{if $_c['country_code_phone']!= ''}
|
||||
<span class="input-group-addon" id="basic-addon1">+</span>
|
||||
{else}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-phone-alt"></i></span>
|
||||
{else}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-user"></i></span>
|
||||
{/if}
|
||||
<input type="text" class="form-control" name="username"
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']} {Lang::T('Phone Number')}{else}{Lang::T('Username')}{/if}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group btn-group-justified mb15">
|
||||
@ -76,8 +77,7 @@
|
||||
<a href="{$_url}login" class="btn btn-warning">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-success"
|
||||
type="submit">{Lang::T('Request OTP')}</button>
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Request OTP')}</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
@ -26,22 +26,22 @@
|
||||
<hr>
|
||||
</div>
|
||||
{if isset($notify)}
|
||||
<script>
|
||||
// Display SweetAlert toast notification
|
||||
Swal.fire({
|
||||
icon: '{if $notify_t == "s"}success{else}warning{/if}',
|
||||
title: '{$notify}',
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 5000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.addEventListener('mouseenter', Swal.stopTimer)
|
||||
toast.addEventListener('mouseleave', Swal.resumeTimer)
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// Display SweetAlert toast notification
|
||||
Swal.fire({
|
||||
icon: '{if $notify_t == "s"}success{else}warning{/if}',
|
||||
title: '{$notify}',
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 5000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.addEventListener('mouseenter', Swal.stopTimer)
|
||||
toast.addEventListener('mouseleave', Swal.resumeTimer)
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{/if}
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
@ -59,11 +59,17 @@
|
||||
<div class="panel-body">
|
||||
<div class="form-container">
|
||||
<div class="md-input-container">
|
||||
<label>{Lang::T('Phone Number')}</label>
|
||||
<label>{if $_c['country_code_phone']!= ''}{Lang::T('Phone Number')}{else}{Lang::T('Username')}{/if}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" id="basic-addon1">+</span>
|
||||
{if $_c['country_code_phone']!= ''}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-phone-alt"></i></span>
|
||||
{else}
|
||||
<span class="input-group-addon" id="basic-addon1"><i
|
||||
class="glyphicon glyphicon-user"></i></span>
|
||||
{/if}
|
||||
<input type="text" class="form-control" name="username"
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
|
||||
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']} {Lang::T('Phone Number')}{else}{Lang::T('Username')}{/if}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-input-container md-float-label">
|
||||
@ -73,8 +79,8 @@
|
||||
</div>
|
||||
<div class="md-input-container md-float-label">
|
||||
<label>{Lang::T('Email')}</label>
|
||||
<input type="text" required class="form-control" id="email"
|
||||
placeholder="xxxxxxx@xxxx.xx" value="{$email}" name="email">
|
||||
<input type="text" class="form-control" id="email" placeholder="xxxxxxx@xxxx.xx"
|
||||
value="{$email}" name="email">
|
||||
</div>
|
||||
<div class="md-input-container md-float-label">
|
||||
<label>{Lang::T('Address')}</label>
|
||||
@ -105,8 +111,7 @@
|
||||
<a href="{$_url}login" class="btn btn-warning">{Lang::T('Cancel')}</a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-success"
|
||||
type="submit">{Lang::T('Register')}</button>
|
||||
<button class="btn btn-success" type="submit">{Lang::T('Register')}</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
@ -44,7 +44,7 @@
|
||||
<tbody>
|
||||
{foreach $activation as $ds}
|
||||
<tr>
|
||||
<td onclick="window.location.href = '{$_url}prepaid/view/{$ds['id']}'"
|
||||
<td onclick="window.location.href = '{$_url}plan/view/{$ds['id']}'"
|
||||
style="cursor:pointer;">{$ds['invoice']}</td>
|
||||
<td onclick="window.location.href = '{$_url}customers/viewu/{$ds['username']}'"
|
||||
style="cursor:pointer;">{$ds['username']}</td>
|
||||
@ -61,7 +61,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -51,7 +51,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{$paginator['contents']}
|
||||
{include file="pagination.tpl"}
|
||||
|
||||
<div class="clearfix text-right total-sum mb10">
|
||||
<h4 class="text-uppercase text-bold">{Lang::T('Total Income')}:</h4>
|
||||
|
@ -54,17 +54,18 @@
|
||||
<li>Make sure your hosting not blocking port to external</li>
|
||||
<li>Make sure your Mikrotik accessible from PHPNuxBill</li>
|
||||
</ul>
|
||||
If you just update PHPNuxBill from upload files, try click Update Database
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<a href="./update.php?step=4" class="btn btn-info btn-sm btn-block">Update Database</a>
|
||||
<a href="{$_url}community#update" class="btn btn-success btn-sm btn-block">Update
|
||||
<a href="./update.php?step=4" style="color: black;" class="btn btn-info btn-sm btn-block">Update Database</a>
|
||||
<a href="{$_url}community#update" style="color: black;" class="btn btn-success btn-sm btn-block">Update
|
||||
PHPNuxBill</a>
|
||||
</div>
|
||||
<br>
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<a href="https://github.com/hotspotbilling/phpnuxbill/discussions" target="_blank"
|
||||
class="btn btn-success btn-sm btn-block">Ask Github Community</a>
|
||||
class="btn btn-success btn-sm btn-block" style="color: black;">Ask Github Community</a>
|
||||
<a href="https://t.me/phpnuxbill" target="_blank"
|
||||
class="btn btn-primary btn-sm btn-block">Ask Telegram Community</a>
|
||||
</div>
|
||||
|
@ -20,7 +20,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Router Name')}</label>
|
||||
<label class="col-md-2 control-label">{Lang::T('Router Name / Location')}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="name" name="name" maxlength="32">
|
||||
<p class="help-block">{Lang::T('Name of Area that router operated')}</p>
|
||||
|
@ -20,7 +20,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">{Lang::T('Router Name')}</label>
|
||||
<label class="col-md-2 control-label">{Lang::T('Router Name / Location')}</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="name" name="name" maxlength="32" value="{$d['name']}">
|
||||
<p class="help-block">{Lang::T('Name of Area that router operated')}</p>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user