Compare commits
317 Commits
Author | SHA1 | Date | |
---|---|---|---|
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 | |||
77e48dae8b | |||
0745532951 | |||
b53116d22a | |||
f7df824145 | |||
f154322f99 | |||
a76ba6ee8b | |||
61b3f5b5f5 | |||
b153e5b595 | |||
9ab0b6a0fa | |||
a7f191f058 | |||
012a1ecfab | |||
dc70a49f52 | |||
bc7380eab7 | |||
f4da09a26e | |||
de3312055a | |||
699289662b | |||
bae079f71c | |||
28f4624e8d | |||
fbd215e741 | |||
2437096473 | |||
dfeee540cf | |||
a0b9e85f38 | |||
08153e6ec1 | |||
2660f5d2d0 | |||
82e67f0b83 | |||
41dd0d86e7 | |||
c8004f1a27 | |||
61edfb932a | |||
747a67b691 | |||
b938db9e5d | |||
1ec8049068 | |||
848dcb5caf | |||
afe6b34fd6 | |||
fceb79bdc3 | |||
83457fd9fc |
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>
|
134
CHANGELOG.md
134
CHANGELOG.md
@ -2,6 +2,140 @@
|
||||
|
||||
# CHANGELOG
|
||||
|
||||
## 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
|
||||
- Add Customer Announcements by @Gerandonk
|
||||
- Add PPPOE Period Validity by @Gerandonk
|
||||
|
||||
## 2024.2.29
|
||||
|
||||
- Fix Hook Functionality
|
||||
- Change Customer Menu
|
||||
|
||||
## 2024.2.28
|
||||
|
||||
- Fix Buy Plan with Balance
|
||||
- Add Expired date for reminder
|
||||
|
||||
## 2024.2.27
|
||||
|
||||
- fix path notification
|
||||
- redirect to dashboard if already login
|
||||
|
||||
## 2024.2.26
|
||||
|
||||
- Clean Unused JS and CSS
|
||||
|
60
init.php
60
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,14 +73,17 @@ 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($root_path . $UPLOAD_PATH . DIRECTORY_SEPARATOR . "notifications.json")) {
|
||||
$_notifmsg = json_decode(file_get_contents($root_path . $UPLOAD_PATH . DIRECTORY_SEPARATOR . 'notifications.json'), true);
|
||||
if (file_exists($UPLOAD_PATH . DIRECTORY_SEPARATOR . "notifications.json")) {
|
||||
$_notifmsg = json_decode(file_get_contents($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'notifications.json'), true);
|
||||
}
|
||||
$_notifmsg_default = json_decode(file_get_contents($root_path . $UPLOAD_PATH . DIRECTORY_SEPARATOR . 'notifications.default.json'), true);
|
||||
$_notifmsg_default = json_decode(file_get_contents($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'notifications.default.json'), true);
|
||||
|
||||
//register all plugin
|
||||
foreach (glob(File::pathFixer($PLUGIN_PATH . DIRECTORY_SEPARATOR . '*.php')) as $filename) {
|
||||
@ -96,6 +100,7 @@ $result = ORM::for_table('tbl_appconfig')->find_many();
|
||||
foreach ($result as $value) {
|
||||
$config[$value['setting']] = $value['value'];
|
||||
}
|
||||
$_c = $config;
|
||||
if (empty($http_proxy) && !empty($config['http_proxy'])) {
|
||||
$http_proxy = $config['http_proxy'];
|
||||
if (empty($http_proxyauth) && !empty($config['http_proxyauth'])) {
|
||||
@ -195,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();
|
||||
}
|
||||
|
||||
@ -206,9 +222,16 @@ 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 sendTelegram($txt)
|
||||
{
|
||||
@ -227,6 +250,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;
|
||||
@ -237,9 +267,15 @@ function r2($to, $ntype = 'e', $msg = '')
|
||||
exit;
|
||||
}
|
||||
|
||||
function _alert($text, $type = 'success', $url = "home")
|
||||
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") {
|
||||
@ -250,8 +286,10 @@ function _alert($text, $type = 'success', $url = "home")
|
||||
}
|
||||
$ui->assign('text', $text);
|
||||
$ui->assign('type', $type);
|
||||
$ui->assign('time', $time);
|
||||
$ui->assign('url', $url);
|
||||
$ui->display('alert.tpl');
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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') 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`;
|
||||
@ -142,7 +145,7 @@ CREATE TABLE `tbl_users` (
|
||||
`username` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`fullname` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`password` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`user_type` enum('Admin','Sales') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`user_type` enum('SuperAdmin','Admin','Report','Agent','Sales') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`status` enum('Active','Inactive') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'Active',
|
||||
`last_login` datetime DEFAULT NULL,
|
||||
`creationdate` datetime NOT NULL
|
||||
@ -309,11 +312,13 @@ CREATE TABLE tbl_customers_fields (
|
||||
|
||||
ALTER TABLE `tbl_voucher` ADD `generated_by` INT NOT NULL DEFAULT '0' COMMENT 'id admin' AFTER `status`;
|
||||
ALTER TABLE `tbl_users` ADD `root` INT NOT NULL DEFAULT '0' COMMENT 'for sub account' AFTER `id`;
|
||||
ALTER TABLE `tbl_users` CHANGE `user_type` `user_type` ENUM('SuperAdmin','Admin','Report','Agent','Sales') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
|
||||
ALTER TABLE `tbl_users` CHANGE `password` `password` VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
|
||||
ALTER TABLE `tbl_users` ADD `phone` VARCHAR(32) NOT NULL DEFAULT '' AFTER `password`, ADD `email` VARCHAR(128) NOT NULL DEFAULT '' AFTER `phone`, ADD `city` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'kota' AFTER `email`, ADD `subdistrict` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'kecamatan' AFTER `city`, ADD `ward` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'kelurahan' AFTER `subdistrict`;
|
||||
ALTER TABLE `tbl_customers` ADD `created_by` INT NOT NULL DEFAULT '0' AFTER `auto_renewal`;
|
||||
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`;
|
@ -1 +1,3 @@
|
||||
Pengumuman!!<br>Besok libur<br><br>Announcement!!<br>Tomorrow holiday<br>
|
||||
Pengumuman!!<br>Besok libur<br><br>Announcement!!<br>Tomorrow holiday<br><br>
|
||||
<br>
|
||||
This Announcement is for Login Page.
|
8
pages_template/Announcement_Customer.html
Normal file
8
pages_template/Announcement_Customer.html
Normal file
@ -0,0 +1,8 @@
|
||||
Pengumuman Pelanggan!!<br>
|
||||
Besok libur<br>
|
||||
<br>
|
||||
Customer Announcement!!<br>
|
||||
Tomorrow holiday<br>
|
||||
<br>
|
||||
<br>
|
||||
This Announcement is for Customer Dashboard
|
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'])) {
|
||||
@ -51,7 +55,7 @@ class Admin
|
||||
if ($id) {
|
||||
return ORM::for_table('tbl_users')->find_one($id);
|
||||
} else {
|
||||
return [];
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -38,6 +38,7 @@ function register_menu($name, $admin, $function, $position, $icon = '', $label =
|
||||
$hook_registered = array();
|
||||
|
||||
function register_hook($action, $function){
|
||||
global $hook_registered;
|
||||
$hook_registered[] = [
|
||||
'action' => $action,
|
||||
'function' => $function
|
||||
|
@ -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,27 +67,93 @@ 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)
|
||||
{
|
||||
$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();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function sendPackageNotification($customer, $package, $price, $message, $via)
|
||||
{
|
||||
global $user_recharge;
|
||||
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);
|
||||
$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 ($user_recharge) {
|
||||
$msg = str_replace('[[expired_date]]', Lang::dateAndTimeFormat($user_recharge['expiration'], $user_recharge['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";
|
||||
@ -111,6 +186,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);
|
||||
@ -118,8 +196,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;
|
||||
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'];
|
||||
@ -48,8 +91,8 @@ class Package
|
||||
$t->routers = $router_name;
|
||||
$t->type = "Balance";
|
||||
if ($admin) {
|
||||
$t->admin_id = $admin['id'];
|
||||
}else{
|
||||
$t->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
} else {
|
||||
$t->admin_id = '0';
|
||||
}
|
||||
$t->save();
|
||||
@ -86,17 +129,51 @@ 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");
|
||||
|
||||
|
||||
$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-$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'));
|
||||
} else if ($p['validity_unit'] == 'Hrs') {
|
||||
@ -116,6 +193,9 @@ class Package
|
||||
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-$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'];
|
||||
@ -152,31 +232,66 @@ class Package
|
||||
$b->routers = $router_name;
|
||||
$b->type = "Hotspot";
|
||||
if ($admin) {
|
||||
$b->admin_id = $admin['id'];
|
||||
}else{
|
||||
$b->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
} else {
|
||||
$b->admin_id = '0';
|
||||
}
|
||||
$b->save();
|
||||
|
||||
// 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'];
|
||||
}else{
|
||||
$t->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
} else {
|
||||
$t->admin_id = '0';
|
||||
}
|
||||
$t->save();
|
||||
|
||||
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");
|
||||
@ -201,37 +316,71 @@ class Package
|
||||
$d->routers = $router_name;
|
||||
$d->type = "Hotspot";
|
||||
if ($admin) {
|
||||
$b->admin_id = $admin['id'];
|
||||
}else{
|
||||
$b->admin_id = '0';
|
||||
$d->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
} else {
|
||||
$d->admin_id = '0';
|
||||
}
|
||||
$d->save();
|
||||
|
||||
// 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'];
|
||||
}else{
|
||||
$t->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
} else {
|
||||
$t->admin_id = '0';
|
||||
}
|
||||
$t->save();
|
||||
|
||||
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);
|
||||
}
|
||||
Message::sendTelegram("#u$c[username] #buy #Hotspot \n" . $p['name_plan'] .
|
||||
"\nRouter: " . $router_name .
|
||||
"\nGateway: " . $gateway .
|
||||
"\nChannel: " . $channel .
|
||||
"\nPrice: " . Lang::moneyFormat($p['price']));
|
||||
} else {
|
||||
|
||||
if ($b) {
|
||||
@ -240,6 +389,9 @@ class Package
|
||||
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-$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'];
|
||||
@ -276,31 +428,65 @@ class Package
|
||||
$b->routers = $router_name;
|
||||
$b->type = "PPPOE";
|
||||
if ($admin) {
|
||||
$b->admin_id = $admin['id'];
|
||||
}else{
|
||||
$b->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
} else {
|
||||
$b->admin_id = '0';
|
||||
}
|
||||
$b->save();
|
||||
|
||||
// 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'];
|
||||
}else{
|
||||
$t->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
} else {
|
||||
$t->admin_id = '0';
|
||||
}
|
||||
$t->save();
|
||||
|
||||
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");
|
||||
@ -325,47 +511,89 @@ class Package
|
||||
$d->routers = $router_name;
|
||||
$d->type = "PPPOE";
|
||||
if ($admin) {
|
||||
$d->admin_id = $admin['id'];
|
||||
}else{
|
||||
$d->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
} else {
|
||||
$d->admin_id = '0';
|
||||
}
|
||||
$d->save();
|
||||
|
||||
// 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'];
|
||||
}else{
|
||||
$t->admin_id = ($admin['id']) ? $admin['id'] : '0';
|
||||
} else {
|
||||
$t->admin_id = '0';
|
||||
}
|
||||
$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']);
|
||||
@ -442,9 +670,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -463,7 +691,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";
|
||||
@ -475,9 +708,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') {
|
||||
@ -499,9 +754,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') {
|
||||
@ -511,6 +786,6 @@ class Package
|
||||
$invoice .= Lang::pad("", '=') . "\n";
|
||||
$invoice .= Lang::pad($config['note'], ' ', 2) . "\n";
|
||||
$ui->assign('whatsapp', urlencode("```$invoice```"));
|
||||
$ui->assign('in',$in);
|
||||
$ui->assign('in', $in);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,82 @@
|
||||
<?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();
|
||||
$next = $page + 1;
|
||||
$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 +85,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 +104,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 +171,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 +183,7 @@ class Paginator
|
||||
} else {
|
||||
$totalReq = $table->count();
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
if ($w1 != '') {
|
||||
$totalReq = ORM::for_table($table)->where($w1, $c1)->count();
|
||||
} elseif ($w2 != '') {
|
||||
@ -142,59 +210,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 +278,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 +305,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;
|
||||
|
@ -301,7 +301,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 +314,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,175 @@ 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')
|
||||
->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('plan_type')
|
||||
->select('tbl_user_recharges.routers', 'routers')
|
||||
->select('tbl_user_recharges.type', 'type')
|
||||
->select('admin_id')
|
||||
->select('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
@ -78,9 +78,9 @@ $ui->assign('_domain', str_replace('www.', '', parse_url(APP_URL, PHP_URL_HOST))
|
||||
$ui->assign('_url', APP_URL . '/index.php?_route=');
|
||||
$ui->assign('_path', __DIR__);
|
||||
$ui->assign('_c', $config);
|
||||
$ui->assign('UPLOAD_PATH', $UPLOAD_PATH);
|
||||
$ui->assign('CACHE_PATH', $CACHE_PATH);
|
||||
$ui->assign('PAGES_PATH', $PAGES_PATH);
|
||||
$ui->assign('UPLOAD_PATH', str_replace($root_path, '', $UPLOAD_PATH));
|
||||
$ui->assign('CACHE_PATH', str_replace($root_path, '', $CACHE_PATH));
|
||||
$ui->assign('PAGES_PATH', str_replace($root_path, '', $PAGES_PATH));
|
||||
$ui->assign('_system_menu', 'dashboard');
|
||||
|
||||
function _msglog($type, $msg)
|
||||
|
@ -5,6 +5,10 @@
|
||||
* by https://t.me/ibnux
|
||||
**/
|
||||
|
||||
if(Admin::getID()){
|
||||
r2(U.'dashboard', "s", Lang::T("You are already logged in"));
|
||||
}
|
||||
|
||||
if (isset($routes['1'])) {
|
||||
$do = $routes['1'];
|
||||
} else {
|
||||
@ -22,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);
|
||||
|
||||
|
@ -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,54 +12,32 @@ $ui->assign('_system_menu', 'customers');
|
||||
$action = $routes['1'];
|
||||
$ui->assign('_admin', $admin);
|
||||
|
||||
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');
|
||||
@ -68,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']);
|
||||
@ -137,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);
|
||||
@ -177,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
|
||||
@ -225,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) {
|
||||
@ -274,7 +361,8 @@ switch ($action) {
|
||||
} catch (Throwable $e) {
|
||||
}
|
||||
try {
|
||||
$c->delete();
|
||||
if ($c)
|
||||
$c->delete();
|
||||
} catch (Exception $e) {
|
||||
} catch (Throwable $e) {
|
||||
}
|
||||
@ -293,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'];
|
||||
@ -320,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
|
||||
@ -354,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) {
|
||||
@ -387,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;
|
||||
@ -416,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();
|
||||
|
||||
|
||||
@ -462,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();
|
||||
}
|
||||
}
|
||||
@ -495,12 +592,19 @@ 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
|
||||
|
||||
$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->display('customers.tpl');
|
||||
break;
|
||||
}
|
||||
|
@ -16,13 +16,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 +54,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 +68,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 +145,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();
|
||||
|
||||
|
@ -4,5 +4,10 @@
|
||||
* by https://t.me/ibnux
|
||||
**/
|
||||
|
||||
|
||||
r2(APP_URL.'/index.php?_route=dashboard');
|
||||
if(Admin::getID()){
|
||||
r2(U.'dashboard');
|
||||
}if(User::getID()){
|
||||
r2(U.'home');
|
||||
}else{
|
||||
r2(U.'login');
|
||||
}
|
||||
|
@ -62,10 +62,11 @@ switch ($action) {
|
||||
$title = ' Reports [' . $mdate . ']';
|
||||
$title = str_replace('-', ' ', $title);
|
||||
|
||||
$UPLOAD_URL_PATH = str_replace($root_path, '', $UPLOAD_PATH);
|
||||
if (file_exists($UPLOAD_PATH . '/logo.png')) {
|
||||
$logo = $UPLOAD_PATH . '/logo.png';
|
||||
$logo = $UPLOAD_URL_PATH . '/logo.png';
|
||||
} else {
|
||||
$logo = $UPLOAD_PATH . '/logo.default.png';
|
||||
$logo = $UPLOAD_URL_PATH . '/logo.default.png';
|
||||
}
|
||||
|
||||
if ($x) {
|
||||
@ -169,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';
|
||||
}
|
||||
@ -234,10 +235,12 @@ EOF;
|
||||
|
||||
$title = ' Reports [' . $mdate . ']';
|
||||
$title = str_replace('-', ' ', $title);
|
||||
|
||||
$UPLOAD_URL_PATH = str_replace($root_path, '', $UPLOAD_PATH);
|
||||
if (file_exists($UPLOAD_PATH . '/logo.png')) {
|
||||
$logo = $UPLOAD_PATH . '/logo.png';
|
||||
$logo = $UPLOAD_URL_PATH . '/logo.png';
|
||||
} else {
|
||||
$logo = $UPLOAD_PATH . '/logo.default.png';
|
||||
$logo = $UPLOAD_URL_PATH . '/logo.default.png';
|
||||
}
|
||||
|
||||
if ($x) {
|
||||
@ -341,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,40 +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($plan['allow_purchase'] != 'yes'){
|
||||
r2(U . "home", 'e', 'Cannot recharge this plan');
|
||||
}
|
||||
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) {
|
||||
@ -136,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 {
|
||||
|
@ -5,6 +5,10 @@
|
||||
* by https://t.me/ibnux
|
||||
**/
|
||||
|
||||
if(User::getID()){
|
||||
r2(U.'home');
|
||||
}
|
||||
|
||||
if (isset($routes['1'])) {
|
||||
$do = $routes['1'];
|
||||
} 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;
|
||||
|
||||
|
48
system/controllers/map.php
Normal file
48
system/controllers/map.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?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':
|
||||
|
||||
$c = ORM::for_table('tbl_customers')->find_many();
|
||||
$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('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);
|
||||
@ -142,9 +141,13 @@ switch ($action) {
|
||||
$ui->display('user-orderView.tpl');
|
||||
break;
|
||||
case 'pay':
|
||||
if ($_c['enable_balance'] != 'yes' && $config['allow_balance_transfer'] != 'yes') {
|
||||
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'] .
|
||||
@ -176,7 +178,7 @@ switch ($action) {
|
||||
}
|
||||
break;
|
||||
case 'send':
|
||||
if ($_c['enable_balance'] != 'yes') {
|
||||
if ($config['enable_balance'] != 'yes') {
|
||||
r2(U . "order/package", 'e', Lang::T("Balance not enabled"));
|
||||
}
|
||||
$ui->assign('_title', Lang::T('Buy for friend'));
|
||||
@ -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;
|
||||
@ -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) {
|
||||
@ -245,12 +245,44 @@ switch ($action) {
|
||||
$radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown;
|
||||
$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) {
|
||||
@ -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 = '';
|
||||
@ -515,11 +579,43 @@ switch ($action) {
|
||||
$radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown;
|
||||
$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) {
|
||||
@ -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,20 +25,25 @@ 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);
|
||||
if (file_exists($UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png')) {
|
||||
$logo = $UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.png?' . time();
|
||||
$logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'logo.png?' . time();
|
||||
} else {
|
||||
$logo = $UPLOAD_PATH . DIRECTORY_SEPARATOR . 'logo.default.png';
|
||||
$logo = $UPLOAD_URL_PATH . DIRECTORY_SEPARATOR . 'logo.default.png';
|
||||
}
|
||||
$ui->assign('logo', $logo);
|
||||
if ($_c['radius_enable'] && empty($_c['radius_client'])) {
|
||||
if ($config['radius_enable'] && empty($config['radius_client'])) {
|
||||
try {
|
||||
$_c['radius_client'] = Radius::getClient();
|
||||
$config['radius_client'] = Radius::getClient();
|
||||
$ui->assign('_c', $_c);
|
||||
} catch (Exception $e) {
|
||||
//ignore
|
||||
@ -114,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) {
|
||||
@ -128,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) {
|
||||
@ -275,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 = [];
|
||||
@ -344,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;
|
||||
@ -389,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':
|
||||
@ -439,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;
|
||||
|
||||
@ -458,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;
|
||||
|
||||
@ -495,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');
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ echo "Found " . count($d) . " user(s)\n";
|
||||
run_hook('cronjob'); #HOOK
|
||||
|
||||
foreach ($d as $ds) {
|
||||
if ($ds['type'] == 'Hotspot') {
|
||||
if ($ds['type'] == 'Hotspot') { # HOTSPOT
|
||||
$date_now = strtotime(date("Y-m-d H:i:s"));
|
||||
$expiration = strtotime($ds['expiration'] . ' ' . $ds['time']);
|
||||
echo $ds['expiration'] . " : " . (($isCli) ? $ds['username'] : Lang::maskText($ds['username']));
|
||||
@ -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,22 +45,28 @@ 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') {
|
||||
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'], $p['routers'], $p['id'], 'Customer', 'Balance')) {
|
||||
// if success, then get the balance
|
||||
Balance::min($ds['customer_id'], $p['price']);
|
||||
@ -82,7 +87,7 @@ foreach ($d as $ds) {
|
||||
}
|
||||
} else
|
||||
echo " : ACTIVE \r\n";
|
||||
} else {
|
||||
} else { # PPPOE
|
||||
$date_now = strtotime(date("Y-m-d H:i:s"));
|
||||
$expiration = strtotime($ds['expiration'] . ' ' . $ds['time']);
|
||||
echo $ds['expiration'] . " : " . (($isCli) ? $ds['username'] : Lang::maskText($ds['username']));
|
||||
@ -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,14 +113,20 @@ 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') {
|
||||
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'], $p['routers'], $p['id'], 'Customer', 'Balance')) {
|
||||
// if success, then get the balance
|
||||
Balance::min($ds['customer_id'], $p['price']);
|
||||
@ -134,4 +144,4 @@ foreach ($d as $ds) {
|
||||
} else
|
||||
echo " : ACTIVE \r\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",
|
||||
@ -456,5 +452,130 @@
|
||||
"Click_Here": "Click Here",
|
||||
"danger": "danger",
|
||||
"Logout_Successful": "Logout Successful",
|
||||
"warning": "warning"
|
||||
"warning": "warning",
|
||||
"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",
|
||||
"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"
|
||||
}
|
@ -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",
|
||||
|
@ -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`;",
|
||||
@ -69,5 +69,29 @@
|
||||
"2024.2.23" : [
|
||||
"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`;"
|
||||
],
|
||||
"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`;"
|
||||
]
|
||||
}
|
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/Abyssinica_SIL.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/Abyssinica_SIL.ttf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/Aegean.otf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/Aegean.otf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/Aegyptus.otf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/Aegyptus.otf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/Akkadian.otf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/Akkadian.otf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/DBSILBR.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/DBSILBR.ttf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSans-Bold.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSans-Bold.ttf
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSans.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSans.ttf
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSansMono.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSansMono.ttf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSerif-Bold.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSerif-Bold.ttf
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSerif.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/DejaVuSerif.ttf
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
99
system/vendor/mpdf/mpdf/ttfonts/DejaVuinfo.txt
vendored
99
system/vendor/mpdf/mpdf/ttfonts/DejaVuinfo.txt
vendored
@ -1,99 +0,0 @@
|
||||
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
||||
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
|
||||
|
||||
Bitstream Vera Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
|
||||
a trademark of Bitstream, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of the fonts accompanying this license ("Fonts") and associated
|
||||
documentation files (the "Font Software"), to reproduce and distribute the
|
||||
Font Software, including without limitation the rights to use, copy, merge,
|
||||
publish, distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice shall
|
||||
be included in all copies of one or more of the Font Software typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in particular
|
||||
the designs of glyphs or characters in the Fonts may be modified and
|
||||
additional glyphs or characters may be added to the Fonts, only if the fonts
|
||||
are renamed to names not containing either the words "Bitstream" or the word
|
||||
"Vera".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts or Font
|
||||
Software that has been modified and is distributed under the "Bitstream
|
||||
Vera" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but no
|
||||
copy of one or more of the Font Software typefaces may be sold by itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
||||
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
|
||||
FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
|
||||
ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
|
||||
FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the names of Gnome, the Gnome
|
||||
Foundation, and Bitstream Inc., shall not be used in advertising or
|
||||
otherwise to promote the sale, use or other dealings in this Font Software
|
||||
without prior written authorization from the Gnome Foundation or Bitstream
|
||||
Inc., respectively. For further information, contact: fonts at gnome dot
|
||||
org.
|
||||
|
||||
Arev Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the fonts accompanying this license ("Fonts") and
|
||||
associated documentation files (the "Font Software"), to reproduce
|
||||
and distribute the modifications to the Bitstream Vera Font Software,
|
||||
including without limitation the rights to use, copy, merge, publish,
|
||||
distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice
|
||||
shall be included in all copies of one or more of the Font Software
|
||||
typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in
|
||||
particular the designs of glyphs or characters in the Fonts may be
|
||||
modified and additional glyphs or characters may be added to the
|
||||
Fonts, only if the fonts are renamed to names not containing either
|
||||
the words "Tavmjong Bah" or the word "Arev".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts
|
||||
or Font Software that has been modified and is distributed under the
|
||||
"Tavmjong Bah Arev" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but
|
||||
no copy of one or more of the Font Software typefaces may be sold by
|
||||
itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
|
||||
TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Tavmjong Bah shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Font Software without prior written authorization
|
||||
from Tavmjong Bah. For further information, contact: tavmjong @ free
|
||||
. fr.
|
||||
|
||||
$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
|
BIN
system/vendor/mpdf/mpdf/ttfonts/Dhyana-Bold.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/Dhyana-Bold.ttf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/Dhyana-Regular.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/Dhyana-Regular.ttf
vendored
Binary file not shown.
94
system/vendor/mpdf/mpdf/ttfonts/DhyanaOFL.txt
vendored
94
system/vendor/mpdf/mpdf/ttfonts/DhyanaOFL.txt
vendored
@ -1,94 +0,0 @@
|
||||
Copyright (c) 2010, Vernon Adams (vern@newtypography.co.uk),
|
||||
with Reserved Font Names "Dhyana".
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeMono.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeMono.ttf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeMonoBold.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeMonoBold.ttf
vendored
Binary file not shown.
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeMonoOblique.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeMonoOblique.ttf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSans.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSans.ttf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSansBold.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSansBold.ttf
vendored
Binary file not shown.
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSansOblique.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSansOblique.ttf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSerif.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSerif.ttf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSerifBold.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSerifBold.ttf
vendored
Binary file not shown.
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSerifItalic.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/FreeSerifItalic.ttf
vendored
Binary file not shown.
108
system/vendor/mpdf/mpdf/ttfonts/GNUFreeFontinfo.txt
vendored
108
system/vendor/mpdf/mpdf/ttfonts/GNUFreeFontinfo.txt
vendored
@ -1,108 +0,0 @@
|
||||
-*-text-*-
|
||||
GNU FreeFont
|
||||
|
||||
The GNU FreeFont project aims to provide a useful set of free scalable
|
||||
(i.e., OpenType) fonts covering as much as possible of the ISO 10646/Unicode
|
||||
UCS (Universal Character Set).
|
||||
|
||||
Statement of Purpose
|
||||
--------------------
|
||||
|
||||
The practical reason for putting glyphs together in a single font face is
|
||||
to conveniently mix symbols and characters from different writing systems,
|
||||
without having to switch fonts.
|
||||
|
||||
Coverage
|
||||
--------
|
||||
|
||||
FreeFont covers the following character sets
|
||||
|
||||
* ISO 8859 parts 1-15
|
||||
* CEN MES-3 European Unicode Subset
|
||||
http://www.evertype.com/standards/iso10646/pdf/cwa13873.pdf
|
||||
* IBM/Microsoft code pages 437, 850, 852, 1250, 1252 and more
|
||||
* Microsoft/Adobe Windows Glyph List 4 (WGL4)
|
||||
http://www.microsoft.com/typography/otspec/WGL4.htm
|
||||
* KOI8-R and KOI8-RU
|
||||
* DEC VT100 graphics symbols
|
||||
* International Phonetic Alphabet
|
||||
* Arabic, Hebrew, Armenian, Georgian, Ethiopian and Thai alphabets,
|
||||
including Arabic presentation forms A/B
|
||||
* mathematical symbols, including the whole TeX repertoire of symbols
|
||||
* APL symbols
|
||||
etc.
|
||||
|
||||
Editing
|
||||
-------
|
||||
|
||||
The free outline font editor, George Williams's FontForge
|
||||
<http://fontforge.sourceforge.net/> is used for editing the fonts.
|
||||
|
||||
Design Issues
|
||||
-------------
|
||||
|
||||
Which font shapes should be made? Historical style terms like Renaissance
|
||||
or Baroque letterforms cannot be applied beyond Latin/Cyrillic/Greek
|
||||
scripts to any greater extent than Kufi or Nashki can be applied beyond
|
||||
Arabic script; "italic" is really only meaningful for Latin letters.
|
||||
|
||||
However, most modern writing systems have typographic formulations for
|
||||
contrasting uniform and modulated character stroke widths, and have some
|
||||
history with "oblique", faces. Since the advent of the typewriter, most
|
||||
have developed a typographic style with uniform-width characters.
|
||||
|
||||
Accordingly, the FreeFont family has one monospaced - FreeMono - and two
|
||||
proportional faces (one with uniform stroke - FreeSans - and one with
|
||||
modulated stroke - FreeSerif).
|
||||
|
||||
To make text from different writing systems look good side-by-side, each
|
||||
FreeFont face is meant to contain characters of similar style and weight.
|
||||
|
||||
Licensing
|
||||
---------
|
||||
|
||||
Free UCS scalable fonts is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The fonts are distributed in the hope that they will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
As a special exception, if you create a document which uses this font, and
|
||||
embed this font or unaltered portions of this font into the document, this
|
||||
font does not by itself cause the resulting document to be covered by the
|
||||
GNU General Public License. This exception does not however invalidate any
|
||||
other reasons why the document might be covered by the GNU General Public
|
||||
License. If you modify this font, you may extend this exception to your
|
||||
version of the font, but you are not obligated to do so. If you do not
|
||||
wish to do so, delete this exception statement from your version.
|
||||
|
||||
|
||||
Files and their suffixes
|
||||
------------------------
|
||||
|
||||
The files with .sfd (Spline Font Database) are in FontForge's native format.
|
||||
Please use these if you plan to modify the font files.
|
||||
|
||||
TrueType fonts for immediate consumption are the files with the .ttf
|
||||
(TrueType Font) suffix. These are ready to use in Xwindows based
|
||||
systems using FreeType, on Mac OS, and on older Windows systems.
|
||||
|
||||
OpenType fonts (with suffix .otf) are for use in Windows Vista.
|
||||
Note that although they can be installed on Linux, but many applications
|
||||
in Linux still don't support them.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Primoz Peterlin, <primoz.peterlin@biofiz.mf.uni-lj.si>
|
||||
Steve White <stevan.white@googlemail.com>
|
||||
|
||||
Free UCS scalable fonts: http://savannah.gnu.org/projects/freefont/
|
||||
$Id: README,v 1.6 2008/12/25 12:51:41 Stevan_White Exp $
|
BIN
system/vendor/mpdf/mpdf/ttfonts/Garuda-Bold.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/Garuda-Bold.ttf
vendored
Binary file not shown.
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/Garuda-Oblique.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/Garuda-Oblique.ttf
vendored
Binary file not shown.
BIN
system/vendor/mpdf/mpdf/ttfonts/Garuda.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/Garuda.ttf
vendored
Binary file not shown.
@ -1,98 +0,0 @@
|
||||
This Font Software is Copyright (c) 2006, Christopher J Fynn
|
||||
All Rights Reserved.
|
||||
|
||||
"Jomolhari" is a Reserved Font Name for this Font Software.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.0.
|
||||
No modification of the license is permitted, only verbatim copy is allowed.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.0 - 22 November 2005
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of cooperative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide an open
|
||||
framework in which fonts may be shared and improved in partnership with
|
||||
others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and sold with any software provided that the font
|
||||
names of derivative works are changed. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to any and all of the following:
|
||||
- font files
|
||||
- data files
|
||||
- source code
|
||||
- build scripts
|
||||
- documentation
|
||||
|
||||
"Reserved Font Name" refers to the Font Software name as seen by
|
||||
users and any other names as specified after the copyright statement.
|
||||
|
||||
"Standard Version" refers to the collection of Font Software
|
||||
components as distributed by the Copyright Holder.
|
||||
|
||||
"Modified Version" refers to any derivative font software made by
|
||||
adding to, deleting, or substituting -- in part or in whole --
|
||||
any of the components of the Standard Version, by changing formats
|
||||
or by porting the Font Software to a new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Standard or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Standard or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s), in part or in whole, unless explicit written permission is
|
||||
granted by the Copyright Holder. This restriction applies to all
|
||||
references stored in the Font Software, such as the font menu name and
|
||||
other font description fields, which are used to differentiate the
|
||||
font from others.
|
||||
|
||||
4) The name(s) of the Copyright Holder or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed using this license, and may not be distributed
|
||||
under any other license.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
BIN
system/vendor/mpdf/mpdf/ttfonts/Jomolhari.ttf
vendored
BIN
system/vendor/mpdf/mpdf/ttfonts/Jomolhari.ttf
vendored
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user