919 lines
40 KiB
PHP
Raw Permalink Normal View History

2017-03-11 02:51:06 +07:00
<?php
2022-09-01 15:35:54 +07:00
2017-03-11 02:51:06 +07:00
/**
2023-10-12 15:55:42 +07:00
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
* by https://t.me/ibnux
2022-09-01 15:35:54 +07:00
**/
2023-10-12 15:55:42 +07:00
2017-03-11 02:51:06 +07:00
_admin();
2024-02-13 13:54:01 +07:00
$ui->assign('_title', Lang::T('Customer'));
2017-03-11 02:51:06 +07:00
$ui->assign('_system_menu', 'customers');
$action = $routes['1'];
$ui->assign('_admin', $admin);
if (empty($action)) {
2024-02-29 11:37:54 +07:00
$action = 'list';
}
2017-03-11 02:51:06 +07:00
2024-03-22 21:21:23 +07:00
$leafletpickerHeader = <<<EOT
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css">
EOT;
2017-03-11 02:51:06 +07:00
switch ($action) {
2024-02-12 11:35:59 +07:00
case 'csv':
2024-02-16 14:52:49 +07:00
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
2024-03-14 12:14:11 +07:00
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
2024-02-16 14:52:49 +07:00
}
$csrf_token = _req('token');
if (!Csrf::check($csrf_token)) {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
}
2024-04-23 11:51:34 +07:00
2024-02-12 11:35:59 +07:00
$cs = ORM::for_table('tbl_customers')
->select('tbl_customers.id', 'id')
->select('tbl_customers.username', 'username')
2024-02-12 11:35:59 +07:00
->select('fullname')
->select('address')
2024-02-12 11:35:59 +07:00
->select('phonenumber')
->select('email')
->select('balance')
->select('service_type')
->order_by_asc('tbl_customers.id')
->find_array();
2024-04-23 11:51:34 +07:00
2024-02-12 11:35:59 +07:00
$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_customers_' . date('Y-m-d_H_i') . '.csv"');
header('Content-Transfer-Encoding: binary');
2024-04-23 11:51:34 +07:00
$headers = [
'id',
'username',
'fullname',
'address',
'phonenumber',
'email',
'balance',
'service_type',
];
2024-04-23 11:51:34 +07:00
if (!$h) {
echo '"' . implode('","', $headers) . "\"\n";
$h = true;
}
2024-04-23 11:51:34 +07:00
2024-02-12 11:35:59 +07:00
foreach ($cs as $c) {
$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
2024-04-23 11:51:34 +07:00
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')
2024-05-21 11:45:23 +07:00
->left_outer_join('tbl_user_recharges', array('tbl_customers.id', '=', 'tbl_user_recharges.customer_id'))
2024-04-23 11:51:34 +07:00
->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']
];
2024-04-23 11:51:34 +07:00
echo '"' . implode('","', $row) . "\"\n";
}
break;
2017-03-11 02:51:06 +07:00
case 'add':
2024-03-14 12:14:11 +07:00
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
2024-02-26 11:01:54 +07:00
}
2024-03-22 21:21:23 +07:00
$ui->assign('xheader', $leafletpickerHeader);
2022-09-18 00:00:40 +07:00
run_hook('view_add_customer'); #HOOK
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
2025-02-04 10:22:14 +07:00
$ui->display('admin/customers/add.tpl');
2017-03-11 02:51:06 +07:00
break;
2023-09-15 11:57:07 +07:00
case 'recharge':
2024-03-14 12:14:11 +07:00
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin', 'Agent', 'Sales'])) {
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
2024-02-26 11:01:54 +07:00
}
2024-03-18 23:25:39 +03:00
$id_customer = $routes['2'];
$plan_id = $routes['3'];
$csrf_token = _req('token');
if (!Csrf::check($csrf_token)) {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id_customer, 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
}
2024-03-15 10:38:05 +07:00
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->where('plan_id', $plan_id)->find_one();
2023-09-15 11:57:07 +07:00
if ($b) {
2024-03-14 12:14:11 +07:00
$gateway = 'Recharge';
$channel = $admin['fullname'];
$cust = User::_info($id_customer);
$plan = ORM::for_table('tbl_plans')->find_one($b['plan_id']);
$add_inv = User::getAttribute("Invoice", $id_customer);
if (!empty($add_inv)) {
$plan['price'] = $add_inv;
}
$tax_enable = isset($config['enable_tax']) ? $config['enable_tax'] : 'no';
$tax_rate_setting = isset($config['tax_rate']) ? $config['tax_rate'] : null;
$custom_tax_rate = isset($config['custom_tax_rate']) ? (float)$config['custom_tax_rate'] : null;
if ($tax_rate_setting === 'custom') {
$tax_rate = $custom_tax_rate;
} else {
$tax_rate = $tax_rate_setting;
}
if ($tax_enable === 'yes') {
$tax = Package::tax($plan['price'], $tax_rate);
} else {
$tax = 0;
}
2024-03-15 10:38:05 +07:00
list($bills, $add_cost) = User::getBills($id_customer);
2024-03-14 12:14:11 +07:00
if ($using == 'balance' && $config['enable_balance'] == 'yes') {
if (!$cust) {
2025-01-31 16:22:58 +07:00
r2(getUrl('plan/recharge'), 'e', Lang::T('Customer not found'));
2024-03-14 12:14:11 +07:00
}
if (!$plan) {
2025-01-31 16:22:58 +07:00
r2(getUrl('plan/recharge'), 'e', Lang::T('Plan not found'));
2024-03-14 12:14:11 +07:00
}
if ($cust['balance'] < ($plan['price'] + $add_cost + $tax)) {
2025-01-31 16:22:58 +07:00
r2(getUrl('plan/recharge'), 'e', Lang::T('insufficient balance'));
2024-03-14 12:14:11 +07:00
}
$gateway = 'Recharge Balance';
}
if ($using == 'zero') {
$zero = 1;
$gateway = 'Recharge Zero';
2023-09-15 11:57:07 +07:00
}
2024-05-16 16:39:45 +07:00
$usings = explode(',', $config['payment_usings']);
$usings = array_filter(array_unique($usings));
2024-05-20 09:33:37 +07:00
if (count($usings) == 0) {
2024-05-16 16:39:45 +07:00
$usings[] = Lang::T('Cash');
}
2024-09-24 10:55:07 +07:00
$abills = User::getAttributes("Bill");
if ($tax_enable === 'yes') {
$ui->assign('tax', $tax);
}
2024-05-16 16:39:45 +07:00
$ui->assign('usings', $usings);
2024-09-24 10:55:07 +07:00
$ui->assign('abills', $abills);
2024-03-14 12:14:11 +07:00
$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('plan', $plan);
$ui->assign('add_inv', $add_inv);
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
2025-02-04 17:22:11 +07:00
$ui->display('admin/plan/recharge-confirm.tpl');
2024-03-18 23:25:39 +03:00
} else {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id_customer, 'e', 'Cannot find active plan');
2023-09-15 11:57:07 +07:00
}
2024-03-15 10:38:05 +07:00
break;
2023-09-15 11:57:07 +07:00
case 'deactivate':
2024-02-16 14:52:49 +07:00
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
2024-03-14 12:14:11 +07:00
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
2024-02-16 14:52:49 +07:00
}
2024-03-18 23:25:39 +03:00
$id_customer = $routes['2'];
$plan_id = $routes['3'];
$csrf_token = _req('token');
if (!Csrf::check($csrf_token)) {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id_customer, 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
}
2024-03-15 10:38:05 +07:00
$b = ORM::for_table('tbl_user_recharges')->where('customer_id', $id_customer)->where('plan_id', $plan_id)->find_one();
2023-09-15 11:57:07 +07:00
if ($b) {
2024-03-15 10:38:05 +07:00
$p = ORM::for_table('tbl_plans')->where('id', $b['plan_id'])->find_one();
2023-10-04 15:41:48 +07:00
if ($p) {
2024-06-21 23:15:27 +07:00
$p = ORM::for_table('tbl_plans')->where('id', $b['plan_id'])->find_one();
2024-06-21 09:44:49 +07:00
$c = User::_info($id_customer);
2024-06-05 17:19:24 +07:00
$dvc = Package::getDevice($p);
2024-06-20 14:16:09 +07:00
if ($_app_stage != 'demo') {
if (file_exists($dvc)) {
require_once $dvc;
2024-06-21 09:44:49 +07:00
(new $p['device'])->remove_customer($c, $p);
2024-06-20 14:16:09 +07:00
} else {
new Exception(Lang::T("Devices Not Found"));
}
2023-10-04 15:41:48 +07:00
}
$b->status = 'off';
$b->expiration = date('Y-m-d');
$b->time = date('H:i:s');
$b->save();
_log('Admin ' . $admin['username'] . ' Deactivate ' . $b['namebp'] . ' for ' . $b['username'], 'User', $b['customer_id']);
Message::sendTelegram('Admin ' . $admin['username'] . ' Deactivate ' . $b['namebp'] . ' for u' . $b['username']);
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id_customer, 's', 'Success deactivate customer to Mikrotik');
2023-09-15 11:57:07 +07:00
}
}
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id_customer, 'e', 'Cannot find active plan');
2023-09-15 11:57:07 +07:00
break;
2023-09-15 11:33:46 +07:00
case 'sync':
2024-03-18 23:25:39 +03:00
$id_customer = $routes['2'];
$csrf_token = _req('token');
if (!Csrf::check($csrf_token)) {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id_customer, 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
}
2024-03-15 10:38:05 +07:00
$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);
2024-06-21 09:44:49 +07:00
$p = ORM::for_table('tbl_plans')->where('id', $b['plan_id'])->find_one();
2024-03-15 10:38:05 +07:00
if ($p) {
$routers[] = $b['routers'];
2024-06-05 17:19:24 +07:00
$dvc = Package::getDevice($p);
2024-06-20 14:16:09 +07:00
if ($_app_stage != 'demo') {
if (file_exists($dvc)) {
require_once $dvc;
2024-12-03 13:38:29 +07:00
if (method_exists($dvc, 'sync_customer')) {
(new $p['device'])->sync_customer($c, $p);
}else{
(new $p['device'])->add_customer($c, $p);
}
2024-06-20 14:16:09 +07:00
} else {
new Exception(Lang::T("Devices Not Found"));
}
2023-10-04 15:41:48 +07:00
}
2023-09-15 11:33:46 +07:00
}
}
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id_customer, 's', 'Sync success to ' . implode(", ", $routers));
2023-09-15 11:33:46 +07:00
}
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id_customer, 'e', 'Cannot find active plan');
2023-09-15 11:33:46 +07:00
break;
2024-10-17 15:14:39 +07:00
case 'login':
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
}
$id = $routes['2'];
$csrf_token = _req('token');
if (!Csrf::check($csrf_token)) {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id, 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
}
2024-10-17 15:14:39 +07:00
$customer = ORM::for_table('tbl_customers')->find_one($id);
if ($customer) {
2024-10-17 15:14:39 +07:00
$_SESSION['uid'] = $id;
User::setCookie($id);
_alert("You are logging in as $customer[fullname],<br>don't logout just close tab.", 'info', "home", 10);
}
_alert(Lang::T('Customer not found'), 'danger', "customers");
break;
2023-08-23 15:00:34 +07:00
case 'viewu':
$customer = ORM::for_table('tbl_customers')->where('username', $routes['2'])->find_one();
2023-08-21 17:09:44 +07:00
case 'view':
2024-03-18 23:25:39 +03:00
$id = $routes['2'];
2023-08-21 17:09:44 +07:00
run_hook('view_customer'); #HOOK
2023-09-15 11:57:07 +07:00
if (!$customer) {
2023-08-23 15:00:34 +07:00
$customer = ORM::for_table('tbl_customers')->find_one($id);
}
2023-08-21 17:09:44 +07:00
if ($customer) {
2024-02-19 09:29:11 +07:00
// Fetch the Customers Attributes values from the tbl_customer_custom_fields table
$customFields = ORM::for_table('tbl_customers_fields')
->where('customer_id', $customer['id'])
->find_many();
2024-03-18 23:25:39 +03:00
$v = $routes['3'];
if (empty($v)) {
2024-03-15 09:46:01 +07:00
$v = 'activation';
}
switch ($v) {
case 'order':
$v = 'order';
$query = ORM::for_table('tbl_payment_gateway')->where('user_id', $customer['id'])->order_by_desc('id');
$order = Paginator::findMany($query);
if (empty($order) || $order < 5) {
$query = ORM::for_table('tbl_payment_gateway')->where('username', $customer['username'])->order_by_desc('id');
$order = Paginator::findMany($query);
}
$ui->assign('order', $order);
break;
case 'activation':
$query = ORM::for_table('tbl_transactions')->where('user_id', $customer['id'])->order_by_desc('id');
$activation = Paginator::findMany($query);
if (empty($activation) || $activation < 5) {
$query = ORM::for_table('tbl_transactions')->where('username', $customer['username'])->order_by_desc('id');
$activation = Paginator::findMany($query);
}
$ui->assign('activation', $activation);
break;
2023-08-21 17:09:44 +07:00
}
2024-03-15 09:46:01 +07:00
$ui->assign('packages', User::_billing($customer['id']));
2023-08-21 17:09:44 +07:00
$ui->assign('v', $v);
$ui->assign('d', $customer);
$ui->assign('customFields', $customFields);
2024-03-23 12:56:25 +07:00
$ui->assign('xheader', $leafletpickerHeader);
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
2025-02-04 10:22:14 +07:00
$ui->display('admin/customers/view.tpl');
2023-08-21 17:09:44 +07:00
} else {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/list'), 'e', Lang::T('Account Not Found'));
2023-08-21 17:09:44 +07:00
}
break;
2017-03-11 02:51:06 +07:00
case 'edit':
2024-10-23 14:13:32 +07:00
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
2024-03-14 12:14:11 +07:00
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
2024-02-26 11:01:54 +07:00
}
2024-03-18 23:25:39 +03:00
$id = $routes['2'];
2022-09-18 00:00:40 +07:00
run_hook('edit_customer'); #HOOK
2017-03-11 02:51:06 +07:00
$d = ORM::for_table('tbl_customers')->find_one($id);
2024-02-19 09:29:11 +07:00
// Fetch the Customers Attributes values from the tbl_customers_fields table
$customFields = ORM::for_table('tbl_customers_fields')
->where('customer_id', $id)
->find_many();
2022-09-01 15:35:54 +07:00
if ($d) {
if (isset($routes['3']) && $routes['3'] == 'deletePhoto') {
if ($d['photo'] != '' && strpos($d['photo'], 'default') === false) {
if (file_exists($UPLOAD_PATH . $d['photo']) && strpos($d['photo'], 'default') === false) {
unlink($UPLOAD_PATH . $d['photo']);
if (file_exists($UPLOAD_PATH . $d['photo'] . '.thumb.jpg')) {
unlink($UPLOAD_PATH . $d['photo'] . '.thumb.jpg');
}
}
$d->photo = '/user.default.jpg';
$d->save();
$ui->assign('notify_t', 's');
$ui->assign('notify', 'You have successfully deleted the photo');
} else {
$ui->assign('notify_t', 'e');
$ui->assign('notify', 'No photo found to delete');
}
}
2022-09-01 15:35:54 +07:00
$ui->assign('d', $d);
2024-05-18 23:14:03 +07:00
$ui->assign('statuses', ORM::for_table('tbl_customers')->getEnum("status"));
$ui->assign('customFields', $customFields);
2024-03-22 21:21:23 +07:00
$ui->assign('xheader', $leafletpickerHeader);
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
2025-02-04 10:22:14 +07:00
$ui->display('admin/customers/edit.tpl');
2022-09-01 15:35:54 +07:00
} else {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/list'), 'e', Lang::T('Account Not Found'));
2017-03-11 02:51:06 +07:00
}
break;
case 'delete':
2024-02-16 14:52:49 +07:00
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
2024-03-14 12:14:11 +07:00
_alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
2024-02-16 14:52:49 +07:00
}
2024-03-18 23:25:39 +03:00
$id = $routes['2'];
$csrf_token = _req('token');
if (!Csrf::check($csrf_token)) {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id, 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
}
2022-09-18 00:00:40 +07:00
run_hook('delete_customer'); #HOOK
2024-06-21 09:44:49 +07:00
$c = ORM::for_table('tbl_customers')->find_one($id);
if ($c) {
2024-02-19 09:29:11 +07:00
// Delete the associated Customers Attributes records from tbl_customer_custom_fields table
ORM::for_table('tbl_customers_fields')->where('customer_id', $id)->delete_many();
2024-06-21 09:44:49 +07:00
//Delete active package
$turs = ORM::for_table('tbl_user_recharges')->where('username', $c['username'])->find_many();
foreach ($turs as $tur) {
2024-06-21 09:44:49 +07:00
$p = ORM::for_table('tbl_plans')->find_one($tur['plan_id']);
2024-06-20 14:16:09 +07:00
if ($p) {
2024-06-05 17:19:24 +07:00
$dvc = Package::getDevice($p);
2024-06-20 14:16:09 +07:00
if ($_app_stage != 'demo') {
if (file_exists($dvc)) {
require_once $dvc;
$p['plan_expired'] = 0;
2024-06-21 09:44:49 +07:00
(new $p['device'])->remove_customer($c, $p);
2024-06-20 14:16:09 +07:00
} else {
new Exception(Lang::T("Devices Not Found"));
}
2023-10-04 15:41:48 +07:00
}
2022-09-01 15:35:54 +07:00
}
try {
2024-06-21 09:44:49 +07:00
$tur->delete();
2022-09-01 15:35:54 +07:00
} catch (Exception $e) {
}
}
2024-06-05 17:19:24 +07:00
try {
2024-06-21 09:44:49 +07:00
$c->delete();
2024-06-05 17:19:24 +07:00
} catch (Exception $e) {
}
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/list'), 's', Lang::T('User deleted Successfully'));
2017-03-11 02:51:06 +07:00
}
break;
case 'add-post':
$csrf_token = _post('csrf_token');
if (!Csrf::check($csrf_token)) {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/add'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
}
$username = alphanumeric(_post('username'), ":+_.@-");
2017-03-11 02:51:06 +07:00
$fullname = _post('fullname');
$password = trim(_post('password'));
2024-08-05 10:50:37 +07:00
$pppoe_username = trim(_post('pppoe_username'));
$pppoe_password = trim(_post('pppoe_password'));
2024-08-05 10:50:37 +07:00
$pppoe_ip = trim(_post('pppoe_ip'));
2023-08-09 14:54:38 +07:00
$email = _post('email');
2023-12-19 09:55:55 +07:00
$address = _post('address');
2022-09-01 15:35:54 +07:00
$phonenumber = _post('phonenumber');
$service_type = _post('service_type');
2024-03-18 23:25:39 +03:00
$account_type = _post('account_type');
$coordinates = _post('coordinates');
2024-02-19 09:29:11 +07:00
//post Customers Attributes
$custom_field_names = (array) $_POST['custom_field_name'];
$custom_field_values = (array) $_POST['custom_field_value'];
//additional information
$city = _post('city');
$district = _post('district');
$state = _post('state');
$zip = _post('zip');
2022-09-18 00:00:40 +07:00
run_hook('add_customer'); #HOOK
2017-03-11 02:51:06 +07:00
$msg = '';
if (Validator::Length($username, 55, 2) == false) {
$msg .= 'Username should be between 3 to 54 characters' . '<br>';
2017-03-11 02:51:06 +07:00
}
if (Validator::Length($fullname, 36, 1) == false) {
$msg .= 'Full Name should be between 2 to 25 characters' . '<br>';
2017-03-11 02:51:06 +07:00
}
2024-02-12 09:45:44 +07:00
if (!Validator::Length($password, 36, 2)) {
2022-09-01 15:35:54 +07:00
$msg .= 'Password should be between 3 to 35 characters' . '<br>';
2017-03-11 02:51:06 +07:00
}
2022-09-01 15:35:54 +07:00
$d = ORM::for_table('tbl_customers')->where('username', $username)->find_one();
if ($d) {
2024-02-13 13:54:01 +07:00
$msg .= Lang::T('Account already axist') . '<br>';
2017-03-11 02:51:06 +07:00
}
2022-09-01 15:35:54 +07:00
if ($msg == '') {
2017-03-11 02:51:06 +07:00
$d = ORM::for_table('tbl_customers')->create();
$d->username = $username;
2017-03-11 02:51:06 +07:00
$d->password = $password;
2024-08-05 10:50:37 +07:00
$d->pppoe_username = $pppoe_username;
2023-08-14 13:21:41 +07:00
$d->pppoe_password = $pppoe_password;
2024-08-05 10:50:37 +07:00
$d->pppoe_ip = $pppoe_ip;
2023-08-09 14:54:38 +07:00
$d->email = $email;
2024-03-18 23:25:39 +03:00
$d->account_type = $account_type;
2017-03-11 02:51:06 +07:00
$d->fullname = $fullname;
$d->address = $address;
2024-02-16 14:52:49 +07:00
$d->created_by = $admin['id'];
2023-08-09 14:54:38 +07:00
$d->phonenumber = Lang::phoneFormat($phonenumber);
$d->service_type = $service_type;
$d->coordinates = $coordinates;
$d->city = $city;
$d->district = $district;
$d->state = $state;
$d->zip = $zip;
2017-03-11 02:51:06 +07:00
$d->save();
// Retrieve the customer ID of the newly created customer
$customerId = $d->id();
2024-02-19 09:29:11 +07:00
// Save Customers Attributes details
if (!empty($custom_field_names) && !empty($custom_field_values)) {
$totalFields = min(count($custom_field_names), count($custom_field_values));
for ($i = 0; $i < $totalFields; $i++) {
$name = $custom_field_names[$i];
$value = $custom_field_values[$i];
if (!empty($name)) {
2024-02-19 09:29:11 +07:00
$customField = ORM::for_table('tbl_customers_fields')->create();
$customField->customer_id = $customerId;
$customField->field_name = $name;
$customField->field_value = $value;
$customField->save();
}
}
}
// Send welcome message
if (isset($_POST['send_welcome_message']) && $_POST['send_welcome_message'] == true) {
$welcomeMessage = Lang::getNotifText('welcome_message');
2024-08-17 14:17:59 +01:00
$welcomeMessage = str_replace('[[company]]', $config['CompanyName'], $welcomeMessage);
$welcomeMessage = str_replace('[[name]]', $d['fullname'], $welcomeMessage);
$welcomeMessage = str_replace('[[username]]', $d['username'], $welcomeMessage);
$welcomeMessage = str_replace('[[password]]', $d['password'], $welcomeMessage);
2024-11-04 13:57:28 +07:00
$welcomeMessage = str_replace('[[url]]', APP_URL . '/?_route=login', $welcomeMessage);
$emailSubject = "Welcome to " . $config['CompanyName'];
$channels = [
'sms' => [
'enabled' => isset($_POST['sms']),
'method' => 'sendSMS',
'args' => [$d['phonenumber'], $welcomeMessage]
],
'whatsapp' => [
'enabled' => isset($_POST['wa']),
'method' => 'sendWhatsapp',
'args' => [$d['phonenumber'], $welcomeMessage]
],
'email' => [
'enabled' => isset($_POST['mail']),
'method' => 'Message::sendEmail',
'args' => [$d['email'], $emailSubject, $welcomeMessage, $d['email']]
]
];
foreach ($channels as $channel => $message) {
if ($message['enabled']) {
try {
call_user_func_array($message['method'], $message['args']);
} catch (Exception $e) {
// Log the error and handle the failure
_log("Failed to send welcome message via $channel: " . $e->getMessage());
}
}
}
}
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/list'), 's', Lang::T('Account Created Successfully'));
2022-09-01 15:35:54 +07:00
} else {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/add'), 'e', $msg);
2017-03-11 02:51:06 +07:00
}
break;
case 'edit-post':
$id = _post('id');
$csrf_token = _post('csrf_token');
if (!Csrf::check($csrf_token)) {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/edit/') . $id, 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
}
$username = alphanumeric(_post('username'), ":+_.@-");
2017-03-11 02:51:06 +07:00
$fullname = _post('fullname');
2024-03-18 23:25:39 +03:00
$account_type = _post('account_type');
$password = trim(_post('password'));
2024-08-05 10:50:37 +07:00
$pppoe_username = trim(_post('pppoe_username'));
$pppoe_password = trim(_post('pppoe_password'));
2024-08-05 10:50:37 +07:00
$pppoe_ip = trim(_post('pppoe_ip'));
2023-08-09 14:54:38 +07:00
$email = _post('email');
2017-03-11 02:51:06 +07:00
$address = _post('address');
2023-08-09 14:54:38 +07:00
$phonenumber = Lang::phoneFormat(_post('phonenumber'));
$service_type = _post('service_type');
$coordinates = _post('coordinates');
2024-05-17 10:59:40 +07:00
$status = _post('status');
//additional information
$city = _post('city');
$district = _post('district');
$state = _post('state');
$zip = _post('zip');
2022-09-18 00:00:40 +07:00
run_hook('edit_customer'); #HOOK
2017-03-11 02:51:06 +07:00
$msg = '';
if (Validator::Length($username, 55, 2) == false) {
$msg .= 'Username should be between 3 to 54 characters' . '<br>';
2017-03-11 02:51:06 +07:00
}
2024-02-12 09:45:44 +07:00
if (Validator::Length($fullname, 36, 1) == false) {
2023-08-09 14:54:38 +07:00
$msg .= 'Full Name should be between 2 to 25 characters' . '<br>';
2017-03-11 02:51:06 +07:00
}
2024-06-21 23:15:27 +07:00
$c = ORM::for_table('tbl_customers')->find_one($id);
if (!$c) {
$msg .= Lang::T('Data Not Found') . '<br>';
}
2024-02-19 09:29:11 +07:00
//lets find user Customers Attributes using id
$customFields = ORM::for_table('tbl_customers_fields')
->where('customer_id', $id)
->find_many();
2024-06-21 23:15:27 +07:00
$oldusername = $c['username'];
$oldPppoeUsername = $c['pppoe_username'];
$oldPppoePassword = $c['pppoe_password'];
$oldPppoeIp = $c['pppoe_ip'];
$oldPassPassword = $c['password'];
2023-10-04 15:41:48 +07:00
$userDiff = false;
$pppoeDiff = false;
$passDiff = false;
2024-08-06 15:42:57 +07:00
$pppoeIpDiff = false;
2023-10-04 15:41:48 +07:00
if ($oldusername != $username) {
if (ORM::for_table('tbl_customers')->where('username', $username)->find_one()) {
$msg .= Lang::T('Username already used by another customer') . '<br>';
}
if (ORM::for_table('tbl_customers')->where('pppoe_username', $username)->find_one()) {
$msg .= Lang::T('Username already used by another pppoe username customer') . '<br>';
2017-03-11 02:51:06 +07:00
}
2023-10-04 15:41:48 +07:00
$userDiff = true;
}
if ($oldPppoeUsername != $pppoe_username) {
// if(!empty($pppoe_username)){
// if(ORM::for_table('tbl_customers')->where('pppoe_username', $pppoe_username)->find_one()){
// $msg.= Lang::T('PPPoE Username already used by another customer') . '<br>';
// }
// if(ORM::for_table('tbl_customers')->where('username', $pppoe_username)->find_one()){
// $msg.= Lang::T('PPPoE Username already used by another customer') . '<br>';
// }
// }
$pppoeDiff = true;
2023-10-04 15:41:48 +07:00
}
2024-08-06 15:42:57 +07:00
if ($oldPppoeIp != $pppoe_ip) {
$pppoeIpDiff = true;
}
2023-10-04 15:41:48 +07:00
if ($password != '' && $oldPassPassword != $password) {
$passDiff = true;
2017-03-11 02:51:06 +07:00
}
2022-09-01 15:35:54 +07:00
if ($msg == '') {
2024-10-31 14:46:51 +07:00
if (!empty($_FILES['photo']['name']) && file_exists($_FILES['photo']['tmp_name'])) {
if (function_exists('imagecreatetruecolor')) {
$hash = md5_file($_FILES['photo']['tmp_name']);
$subfolder = substr($hash, 0, 2);
$folder = $UPLOAD_PATH . DIRECTORY_SEPARATOR . 'photos' . DIRECTORY_SEPARATOR;
if (!file_exists($folder)) {
mkdir($folder);
}
$folder = $UPLOAD_PATH . DIRECTORY_SEPARATOR . 'photos' . DIRECTORY_SEPARATOR . $subfolder . DIRECTORY_SEPARATOR;
if (!file_exists($folder)) {
mkdir($folder);
}
$imgPath = $folder . $hash . '.jpg';
if (!file_exists($imgPath)) {
File::resizeCropImage($_FILES['photo']['tmp_name'], $imgPath, 1600, 1600, 100);
}
if (!file_exists($imgPath . '.thumb.jpg')) {
if (_post('faceDetect') == 'yes') {
try {
$detector = new svay\FaceDetector();
$detector->setTimeout(5000);
$detector->faceDetect($imgPath);
$detector->cropFaceToJpeg($imgPath . '.thumb.jpg', false);
} catch (Exception $e) {
File::makeThumb($imgPath, $imgPath . '.thumb.jpg', 200);
} catch (Throwable $e) {
File::makeThumb($imgPath, $imgPath . '.thumb.jpg', 200);
}
} else {
File::makeThumb($imgPath, $imgPath . '.thumb.jpg', 200);
}
}
if (file_exists($imgPath)) {
if ($c['photo'] != '' && strpos($c['photo'], 'default') === false) {
if (file_exists($UPLOAD_PATH . $c['photo'])) {
unlink($UPLOAD_PATH . $c['photo']);
if (file_exists($UPLOAD_PATH . $c['photo'] . '.thumb.jpg')) {
unlink($UPLOAD_PATH . $c['photo'] . '.thumb.jpg');
}
}
}
$c->photo = '/photos/' . $subfolder . '/' . $hash . '.jpg';
}
if (file_exists($_FILES['photo']['tmp_name'])) unlink($_FILES['photo']['tmp_name']);
} else {
2025-01-31 16:22:58 +07:00
r2(getUrl('settings/app'), 'e', 'PHP GD is not installed');
}
}
2023-10-04 15:41:48 +07:00
if ($userDiff) {
2024-06-21 23:15:27 +07:00
$c->username = $username;
2023-10-04 15:41:48 +07:00
}
if ($password != '') {
2024-06-21 23:15:27 +07:00
$c->password = $password;
2023-10-04 15:41:48 +07:00
}
2024-08-05 10:50:37 +07:00
$c->pppoe_username = $pppoe_username;
2024-06-21 23:15:27 +07:00
$c->pppoe_password = $pppoe_password;
2024-08-05 10:50:37 +07:00
$c->pppoe_ip = $pppoe_ip;
2024-06-21 23:15:27 +07:00
$c->fullname = $fullname;
$c->email = $email;
$c->account_type = $account_type;
$c->address = $address;
$c->status = $status;
$c->phonenumber = $phonenumber;
$c->service_type = $service_type;
$c->coordinates = $coordinates;
$c->city = $city;
$c->district = $district;
$c->state = $state;
$c->zip = $zip;
$c->save();
2024-02-19 09:29:11 +07:00
// Update Customers Attributes values in tbl_customers_fields table
foreach ($customFields as $customField) {
$fieldName = $customField['field_name'];
if (isset($_POST['custom_fields'][$fieldName])) {
$customFieldValue = $_POST['custom_fields'][$fieldName];
$customField->set('field_value', $customFieldValue);
$customField->save();
}
}
2024-02-19 09:29:11 +07:00
// Add new Customers Attributess
if (isset($_POST['custom_field_name']) && isset($_POST['custom_field_value'])) {
$newCustomFieldNames = $_POST['custom_field_name'];
$newCustomFieldValues = $_POST['custom_field_value'];
// Check if the number of field names and values match
if (count($newCustomFieldNames) == count($newCustomFieldValues)) {
$numNewFields = count($newCustomFieldNames);
for ($i = 0; $i < $numNewFields; $i++) {
$fieldName = $newCustomFieldNames[$i];
$fieldValue = $newCustomFieldValues[$i];
2024-02-19 09:29:11 +07:00
// Insert the new Customers Attributes
$newCustomField = ORM::for_table('tbl_customers_fields')->create();
$newCustomField->set('customer_id', $id);
$newCustomField->set('field_name', $fieldName);
$newCustomField->set('field_value', $fieldValue);
$newCustomField->save();
}
}
}
2024-02-19 09:29:11 +07:00
// Delete Customers Attributess
if (isset($_POST['delete_custom_fields'])) {
$fieldsToDelete = $_POST['delete_custom_fields'];
foreach ($fieldsToDelete as $fieldName) {
2024-02-19 09:29:11 +07:00
// 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();
}
}
2024-08-06 15:42:57 +07:00
if ($userDiff || $pppoeDiff || $pppoeIpDiff || $passDiff) {
$turs = ORM::for_table('tbl_user_recharges')->where('customer_id', $c['id'])->findMany();
foreach ($turs as $tur) {
2024-06-21 23:15:27 +07:00
$p = ORM::for_table('tbl_plans')->find_one($tur['plan_id']);
2024-06-05 17:19:24 +07:00
$dvc = Package::getDevice($p);
2024-06-20 14:16:09 +07:00
if ($_app_stage != 'demo') {
// if has active package
if ($tur['status'] == 'on') {
if (file_exists($dvc)) {
require_once $dvc;
if ($userDiff) {
2024-07-18 09:52:53 +07:00
(new $p['device'])->change_username($p, $oldusername, $username);
}
if ($pppoeDiff && $tur['type'] == 'PPPOE') {
if (empty($oldPppoeUsername) && !empty($pppoe_username)) {
// admin just add pppoe username
(new $p['device'])->change_username($p, $username, $pppoe_username);
} else if (empty($pppoe_username) && !empty($oldPppoeUsername)) {
// admin want to use customer username
(new $p['device'])->change_username($p, $oldPppoeUsername, $username);
} else {
// regular change pppoe username
(new $p['device'])->change_username($p, $oldPppoeUsername, $pppoe_username);
}
}
(new $p['device'])->add_customer($c, $p);
} else {
new Exception(Lang::T("Devices Not Found"));
}
2024-06-20 14:16:09 +07:00
}
2022-09-01 15:35:54 +07:00
}
$tur->username = $username;
$tur->save();
2022-09-01 15:35:54 +07:00
}
}
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/view/') . $id, 's', 'User Updated Successfully');
2022-09-01 15:35:54 +07:00
} else {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers/edit/') . $id, 'e', $msg);
2017-03-11 02:51:06 +07:00
}
break;
default:
run_hook('list_customers'); #HOOK
2024-09-09 14:01:55 +07:00
$search = _req('search');
$order = _req('order', 'username');
$filter = _req('filter', 'Active');
$orderby = _req('orderby', 'asc');
2024-05-17 10:59:40 +07:00
$order_pos = [
'username' => 0,
'created_at' => 8,
2024-05-17 16:45:41 +07:00
'balance' => 3,
'status' => 7
2024-05-17 10:59:40 +07:00
];
2024-08-05 11:45:27 +07:00
$append_url = "&order=" . urlencode($order) . "&filter=" . urlencode($filter) . "&orderby=" . urlencode($orderby);
2024-05-02 16:31:25 +07:00
if ($search != '') {
$query = ORM::for_table('tbl_customers')
2024-05-20 09:33:37 +07:00
->whereRaw("username LIKE '%$search%' OR fullname LIKE '%$search%' OR address LIKE '%$search%' " .
"OR phonenumber LIKE '%$search%' OR email LIKE '%$search%' AND status='$filter'");
2024-05-02 16:31:25 +07:00
} else {
2024-05-17 10:59:40 +07:00
$query = ORM::for_table('tbl_customers');
2024-05-20 09:12:13 +07:00
$query->where("status", $filter);
2024-05-17 10:59:40 +07:00
}
if ($order == 'lastname') {
$query->order_by_expr("SUBSTR(fullname, INSTR(fullname, ' ')) $orderby");
} else {
if ($orderby == 'asc') {
$query->order_by_asc($order);
} else {
$query->order_by_desc($order);
}
2024-05-02 16:31:25 +07:00
}
2024-05-20 09:33:37 +07:00
if (_post('export', '') == 'csv') {
$csrf_token = _post('csrf_token');
if (!Csrf::check($csrf_token)) {
2025-01-31 16:22:58 +07:00
r2(getUrl('customers'), 'e', Lang::T('Invalid or Expired CSRF Token') . ".");
}
2024-08-05 11:45:27 +07:00
$d = $query->findMany();
2024-05-20 09:33:37 +07:00
$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_customers_' . $filter . '_' . date('Y-m-d_H_i') . '.csv"');
header('Content-Transfer-Encoding: binary');
$headers = [
'id',
'username',
'fullname',
'address',
'phonenumber',
'email',
'balance',
'service_type',
];
$fp = fopen('php://output', 'wb');
if (!$h) {
fputcsv($fp, $headers, ";");
$h = true;
}
2024-08-05 11:13:43 +07:00
foreach ($d as $c) {
2024-05-20 09:33:37 +07:00
$row = [
$c['id'],
$c['username'],
$c['fullname'],
str_replace("\n", " ", $c['address']),
$c['phonenumber'],
$c['email'],
$c['balance'],
$c['service_type'],
];
fputcsv($fp, $row, ";");
}
fclose($fp);
die();
}
2024-08-05 11:45:27 +07:00
$d = Paginator::findMany($query, ['search' => $search], 30, $append_url);
2024-08-05 11:13:43 +07:00
$ui->assign('d', $d);
2024-05-20 09:12:13 +07:00
$ui->assign('statuses', ORM::for_table('tbl_customers')->getEnum("status"));
$ui->assign('filter', $filter);
2024-05-02 16:31:25 +07:00
$ui->assign('search', $search);
2024-05-17 10:59:40 +07:00
$ui->assign('order', $order);
$ui->assign('order_pos', $order_pos[$order]);
$ui->assign('orderby', $orderby);
$ui->assign('csrf_token', Csrf::generateAndStoreToken());
2025-02-04 10:22:14 +07:00
$ui->display('admin/customers/list.tpl');
break;
2022-09-01 15:35:54 +07:00
}