modified it for multiple organisations
This commit is contained in:
2
API.md
2
API.md
@@ -243,3 +243,5 @@ How it updates `messages`:
|
||||
|
||||
Missing or invalid `Authorization: Bearer <API Key>` returns a `ProblemDetail` response with `status=401`.
|
||||
|
||||
http://206.225.84.201:9990/api/clients?page=0&size=20&sort=createdAt,desc
|
||||
|
||||
|
||||
15
accounts.md
15
accounts.md
@@ -20,3 +20,18 @@
|
||||
|
||||
|
||||
http://10.199.0.11/botswana/bpc/web
|
||||
|
||||
https://smsgateway.clickmlapps.com/api/
|
||||
|
||||
## Sunking Mozambique
|
||||
{
|
||||
"id": 14,
|
||||
"name": "Sunking Mozambique",
|
||||
"email": "mozambiqueinf@sunking.com",
|
||||
"country": "Mozambique",
|
||||
"phoneNumber": "+258858480000",
|
||||
"status": "NEW",
|
||||
"createdAt": "2026-06-22T10:20:10.319231Z",
|
||||
"updatedAt": "2026-06-22T10:20:10.319244Z"
|
||||
}
|
||||
info@sunkingmozambique.com/oc4P6i@510A8U6
|
||||
18
api-change-june-22-2026.md
Normal file
18
api-change-june-22-2026.md
Normal file
@@ -0,0 +1,18 @@
|
||||
http://localhost:9990/api/ucm/reports/daily-sms-units-by-network?from={{reportDateFrom}}&to={{reportDateTo}}&ucm_org_id=701
|
||||
http://localhost:9990/api/ucm/reports/daily-sms-units-by-network?from={{reportDateFrom}}&to={{reportDateTo}}&ucm_org_id=701
|
||||
|
||||
Expected response:{
|
||||
"reportDate": "2026-02-26 to 2026-03-27",
|
||||
"orgId": 701,
|
||||
"movitelMzSmsUnits": 0,
|
||||
"tmcelMzSmsUnits": 0,
|
||||
"vodacomMzSmsUnits": 0
|
||||
}
|
||||
|
||||
{{baseUrl}}/api/ucm/reports/daily-sms-units?from={{reportDateFrom}}&to={{reportDateTo}}&ucm_org_id=629
|
||||
expected response: {
|
||||
"reportDate": "2026-02-26 to 2026-03-27",
|
||||
"orgId": 629,
|
||||
"smsUnits": 908202,
|
||||
"clientChargeTotal": 6596.267261251807
|
||||
}
|
||||
@@ -44,7 +44,6 @@ class ClientsLoginController extends Controller
|
||||
}
|
||||
public function activation(Request $request){
|
||||
$this->validate($request, [
|
||||
// 'activation_hash' => 'required',
|
||||
'password' => 'required',
|
||||
// 'password' => ['required', 'min:8', 'confirmed']
|
||||
'password' => ['required','confirmed', Password::min(8)->letters()->numbers(),]
|
||||
@@ -83,19 +82,21 @@ class ClientsLoginController extends Controller
|
||||
$logged_in = '';
|
||||
|
||||
$client = Models\ClientSession::where('email', $request->email)->first();
|
||||
// dump($client);
|
||||
if ($client == false) {
|
||||
return redirect()->back()->withErrors(['Invalid credentials']);
|
||||
}
|
||||
|
||||
$client_url = "clients/" . $client->client_id;
|
||||
$result = ApiCalls::CurlGet($client_url);
|
||||
|
||||
// dd($result);
|
||||
$result_arr = json_decode($result, true);
|
||||
$logged_in = $result_arr;
|
||||
// dd($logged_in);
|
||||
|
||||
$request->session()->regenerate(true);
|
||||
$request->session()->put('current_user.user_id', $logged_in['id']);
|
||||
$request->session()->put('current_user.org_id', $logged_in['id']);
|
||||
$request->session()->put('current_user.ucm_org_id', $client->ucm_org_id);
|
||||
$request->session()->put('current_user.name', $logged_in['name']);
|
||||
$request->session()->put('current_user.email', $logged_in['email']);
|
||||
$request->session()->put('current_user.role', $client['role']);
|
||||
|
||||
@@ -38,26 +38,36 @@ class ClientsTrafficController extends Controller
|
||||
['path' => $request->url(), 'query' => $request->query()]
|
||||
);
|
||||
}
|
||||
public function indexTest(){
|
||||
$data = ['page_title' => 'Test Page'];
|
||||
return view('client-traffic.test', $data);
|
||||
}
|
||||
public function index(){
|
||||
|
||||
$client_id = session('current_user.org_id');
|
||||
$ucm_org_id = session('current_user.ucm_org_id');
|
||||
// dd($client_id);
|
||||
$clients_url = "messages/client/$client_id?page=0&size=1000&sort=createdAt,desc";
|
||||
$result = ApiCalls::CurlGet($clients_url);
|
||||
$result_arr = json_decode($result);
|
||||
// dd($result_arr);
|
||||
|
||||
$current_date = new DateTime();
|
||||
|
||||
$start_date = $current_date->modify('-10 days');
|
||||
$start_date = $start_date->format('Y-m-d');
|
||||
$end_date = date('Y-m-d');
|
||||
$daily_smsunits_url = "ucm/reports/daily-sms-units?from=$start_date&to=$end_date";
|
||||
$daily_smsunits_url = "ucm/reports/daily-sms-units?from=$start_date&to=$end_date&ucm_org_id=$ucm_org_id";
|
||||
|
||||
$result = ApiCalls::CurlGet($daily_smsunits_url);
|
||||
$sms_units_arr = json_decode($result, true);
|
||||
|
||||
$daily_smsunits_url_split = "ucm/reports/daily-sms-units-by-network?from=$start_date&to=$end_date";
|
||||
|
||||
$daily_smsunits_url_split = "ucm/reports/daily-sms-units-by-network?from=$start_date&to=$end_date&ucm_org_id=$ucm_org_id";
|
||||
// dump($daily_smsunits_url_split);
|
||||
$result = ApiCalls::CurlGet($daily_smsunits_url_split);
|
||||
$split_sms_units_arr = json_decode($result, true);
|
||||
|
||||
// dd($split_sms_units_arr);
|
||||
$orgId = session('current_user.org_id');
|
||||
$sms_balance_url = "clients/$orgId/balance";
|
||||
$result = ApiCalls::CurlGet($sms_balance_url);
|
||||
@@ -77,14 +87,15 @@ class ClientsTrafficController extends Controller
|
||||
"TNM SMSUnits" => 18796
|
||||
*/
|
||||
// dump($split_sms_units_arr);
|
||||
|
||||
if ($ucm_org_id == 629) {
|
||||
$airtel_rate = 14;
|
||||
$tnm_rate = 18;
|
||||
$airtel_computation = $split_sms_units_arr['Airtel SMSUnits'] * $airtel_rate;
|
||||
$tnm_computation = $split_sms_units_arr['TNM SMSUnits'] * $tnm_rate;
|
||||
$charge_computation = $airtel_computation + $tnm_computation;
|
||||
|
||||
|
||||
$split_sms_units_arr['charge_computation'] = number_format($charge_computation);
|
||||
|
||||
$data = [
|
||||
'page_title' => 'SMS Traffic',
|
||||
'traffic_arr' => $result_arr,
|
||||
@@ -93,6 +104,32 @@ class ClientsTrafficController extends Controller
|
||||
'charge_computation' => $charge_computation,
|
||||
'balance_arr' => $balance_arr
|
||||
];
|
||||
}
|
||||
elseif($ucm_org_id == 701){
|
||||
// "movitelMzSmsUnits" => 0
|
||||
// "tmcelMzSmsUnits" => 0
|
||||
// "vodacomMzSmsUnits" => 1
|
||||
$movitel_rate = 0.32;
|
||||
$tmcell_rate = 0.32;
|
||||
$vodacom_rate = 0.32;
|
||||
$movitel_computation = $split_sms_units_arr['movitelMzSmsUnits'] * $movitel_rate;
|
||||
$tmcell_computation = $split_sms_units_arr['tmcelMzSmsUnits'] * $tmcell_rate;
|
||||
$vodacom_computation = $split_sms_units_arr['tmcelMzSmsUnits'] * $vodacom_rate;
|
||||
|
||||
$charge_computation = $movitel_computation + $tmcell_computation + $vodacom_computation;
|
||||
$split_sms_units_arr['charge_computation'] = number_format($charge_computation);
|
||||
$split_sms_units_arr['units_computation'] = $split_sms_units_arr['movitelMzSmsUnits'] + $split_sms_units_arr['tmcelMzSmsUnits'] + $split_sms_units_arr['vodacomMzSmsUnits'];
|
||||
$data = [
|
||||
'page_title' => 'SMS Traffic',
|
||||
'traffic_arr' => $result_arr,
|
||||
'sms_units_arr' => $sms_units_arr,
|
||||
'split_sms_units_arr' => $split_sms_units_arr,
|
||||
'charge_computation' => $charge_computation,
|
||||
'balance_arr' => $balance_arr
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
// dd($data);
|
||||
return view('client-traffic.index-main', $data);
|
||||
}
|
||||
@@ -210,19 +247,61 @@ class ClientsTrafficController extends Controller
|
||||
]);
|
||||
$start_date = $request->start_date;
|
||||
$end_date = $request->end_date;
|
||||
$client_id = session('current_user.org_id');
|
||||
$ucm_org_id = session('current_user.ucm_org_id');
|
||||
/*
|
||||
$daily_smsunits_url = "ucm/reports/daily-sms-units?from=$start_date&to=$end_date";
|
||||
$result = ApiCalls::CurlGet($daily_smsunits_url);
|
||||
\Log::info('SMS Units Response ' . $result);
|
||||
*/
|
||||
|
||||
$daily_smsunits_url_split = "ucm/reports/daily-sms-units-by-network?from=$start_date&to=$end_date";
|
||||
$daily_smsunits_url_split = "ucm/reports/daily-sms-units-by-network?from=$start_date&to=$end_date&ucm_org_id=$ucm_org_id";
|
||||
$result = ApiCalls::CurlGet($daily_smsunits_url_split);
|
||||
$split_sms_units_arr = json_decode($result, true);
|
||||
\Log::info('SMS Units Response ' . $result);
|
||||
|
||||
$data = json_decode($result, true);
|
||||
|
||||
if ($ucm_org_id == 629) {
|
||||
|
||||
$airtel_rate = 14;
|
||||
$tnm_rate = 18;
|
||||
|
||||
$airtel_computation = $split_sms_units_arr['Airtel SMSUnits'] * $airtel_rate;
|
||||
$tnm_computation = $split_sms_units_arr['TNM SMSUnits'] * $tnm_rate;
|
||||
|
||||
$charge_computation = (int)$airtel_computation + (int)$tnm_computation;
|
||||
|
||||
$data['ucm_org_id'] = $ucm_org_id;
|
||||
$data['charge_computation'] = number_format($charge_computation);
|
||||
$data['airtel_sms_units'] = number_format($split_sms_units_arr['Airtel SMSUnits']);
|
||||
$data['tnm_sms_units'] = number_format($split_sms_units_arr['TNM SMSUnits']);
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
elseif($ucm_org_id == 701){
|
||||
// "movitelMzSmsUnits" => 0
|
||||
// "tmcelMzSmsUnits" => 0
|
||||
// "vodacomMzSmsUnits" => 1
|
||||
|
||||
$movitel_rate = 0.32;
|
||||
$tmcell_rate = 0.32;
|
||||
$vodacom_rate = 0.32;
|
||||
|
||||
$movitel_computation = $split_sms_units_arr['movitelMzSmsUnits'] * $movitel_rate;
|
||||
$tmcell_computation = $split_sms_units_arr['tmcelMzSmsUnits'] * $tmcell_rate;
|
||||
$vodacom_computation = $split_sms_units_arr['tmcelMzSmsUnits'] * $vodacom_rate;
|
||||
|
||||
|
||||
$charge_computation = (int)$movitel_computation + (int)$tmcell_computation + (int)$vodacom_computation;
|
||||
|
||||
$data['ucm_org_id'] = $ucm_org_id;
|
||||
$data['charge_computation'] = number_format($charge_computation);
|
||||
$units_computation = (int)$split_sms_units_arr['movitelMzSmsUnits'] + (int)$split_sms_units_arr['tmcelMzSmsUnits'] + (int)$split_sms_units_arr['vodacomMzSmsUnits'];
|
||||
$data['units_computation'] = $units_computation;
|
||||
return response()->json($data);
|
||||
}
|
||||
/*
|
||||
$airtel_rate = 14;
|
||||
$tnm_rate = 18;
|
||||
|
||||
@@ -237,8 +316,9 @@ class ClientsTrafficController extends Controller
|
||||
$data['charge_computation'] = number_format($charge_computation);
|
||||
$data['airtel_sms_units'] = number_format($split_sms_units_arr['Airtel SMSUnits']);
|
||||
$data['tnm_sms_units'] = number_format($split_sms_units_arr['TNM SMSUnits']);
|
||||
*/
|
||||
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
public function dailySmsUnitsSplit(){
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class ApiCalls
|
||||
$api_key = $result_arr->content[0]->apiKey;
|
||||
$header_part = "Authorization: Bearer " . $api_key; //env('SUNKING_APIKEY');
|
||||
}
|
||||
// dd($header_part);
|
||||
|
||||
\Log::info('Request Params :' . $data);
|
||||
$curl = curl_init();
|
||||
curl_setopt_array($curl, array(
|
||||
|
||||
@@ -13,28 +13,7 @@
|
||||
format: 'yyyy-mm-dd'
|
||||
});
|
||||
|
||||
function sendDailySmsUnitsOld() {
|
||||
document.getElementById('loadingOverlay').style.display = 'flex';
|
||||
const endpoint = "client-dailysmsunits";
|
||||
const startDate = startDateElement.value;
|
||||
const endDate = endDateElement.value;
|
||||
fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-CSRF-TOKEN': token },
|
||||
body: 'start_date=' + encodeURIComponent(startDate) + '&end_date=' + encodeURIComponent(endDate)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// document.getElementById('loadingSpinner').style.display = 'none';
|
||||
document.getElementById('loadingOverlay').style.display = 'none';
|
||||
const theReportRange = document.getElementById('reportRange');
|
||||
const theSmsUnitsValue = document.getElementById('smsUnitsValue');
|
||||
theReportRange.innerHTML = data.reportDate;
|
||||
theSmsUnitsValue.innerHTML = "SMS Units : " + data.smsUnits + "| Charge : " + data.clientChargeTotal.toFixed(2);
|
||||
|
||||
})
|
||||
.catch(error => console.error('Error:', error));
|
||||
}
|
||||
function sendDailySmsUnits() {
|
||||
document.getElementById('loadingOverlay').style.display = 'flex';
|
||||
const endpoint = "client-dailysmsunits";
|
||||
@@ -53,17 +32,16 @@
|
||||
const theSmsChargeTotalValue = document.getElementById('smsUnitsCharge');
|
||||
theReportRange.innerHTML = data.reportDate;
|
||||
|
||||
//const formattedTNMUnits = Number(data.tnm_sms_units']).toLocaleString('en-GH');
|
||||
|
||||
// const formattedAirtelUnits = Number(data.data['airtel_sms_units']).toLocaleString('en-GH', {
|
||||
// minimumFractionDigits: 2,
|
||||
// maximumFractionDigits: 2
|
||||
// });
|
||||
|
||||
if (data.ucm_org_id === 629) {
|
||||
theSmsChargeTotalValue.innerHTML = 'SMS Charge (MWK) : <b>' + data.charge_computation + '</b>';
|
||||
console.log(data.charge_computation);
|
||||
console.log(data.airtel_sms_units);
|
||||
theSmsUnitsValue.innerHTML = 'SMS Units: Airtel <b>' + data.airtel_sms_units + '</b> | TNM: <b>' + data.tnm_sms_units + '</b>';
|
||||
}
|
||||
else {
|
||||
theSmsChargeTotalValue.innerHTML = 'SMS Charge (MZM) : <b>' + data.charge_computation + '</b>';
|
||||
theSmsUnitsValue.innerHTML = 'SMS Units: ' + data.units_computation;
|
||||
|
||||
}
|
||||
})
|
||||
.catch(error => console.error('Error:', error));
|
||||
}
|
||||
|
||||
@@ -63,9 +63,9 @@
|
||||
<h2 class="h5 mb-3">Recent activity</h2>
|
||||
|
||||
<div class="timeline-item pt-0 mt-0 border-0">
|
||||
<div class="fw-semibold">Sender ID approved</div>
|
||||
<!-- <div class="fw-semibold">Sender ID approved</div>
|
||||
<div class="muted-label">CLICKINFO added </div>
|
||||
<div class="small text-secondary mt-1">09:04</div>
|
||||
<div class="small text-secondary mt-1">09:04</div> -->
|
||||
</div>
|
||||
|
||||
<!-- <div class="timeline-item">
|
||||
@@ -75,9 +75,9 @@
|
||||
</div> -->
|
||||
|
||||
<div class="timeline-item">
|
||||
<div class="fw-semibold">Campaign completed</div>
|
||||
<!-- <div class="fw-semibold">Campaign completed</div>
|
||||
<div class="muted-label">[campaign name] batch finished</div>
|
||||
<div class="small text-secondary mt-1">08:41</div>
|
||||
<div class="small text-secondary mt-1">08:41</div> -->
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
@@ -81,9 +81,12 @@
|
||||
</div>
|
||||
<div class="muted-label mb-2">Sent Messages (last 10 days)</div>
|
||||
<!-- <div class="h3 mb-2">183,372</div> -->
|
||||
<div class="h5 mb-2 pt-1" id="smsUnitsCharge">SMS Charge(MWK) : <b>{{ $split_sms_units_arr['charge_computation'] }}</b></div>
|
||||
<div class="h5 mb-2 pt-1" id="smsUnitsCharge">SMS Charge(<?php echo (session('current_user.ucm_org_id') == 629)? "MWK" : "MZM"; ?>) : <b>{{ $split_sms_units_arr['charge_computation'] }}</b></div>
|
||||
@if(session('current_user.ucm_org_id') == 629)
|
||||
<div class="h5 mb-2 pt-1" id="smsUnitsValue">SMS Units : Airtel : <b>{{ number_format($split_sms_units_arr['Airtel SMSUnits']) }}</b> | TNM : <b>{{ number_format($split_sms_units_arr['TNM SMSUnits']) }}</b></div>
|
||||
|
||||
@else
|
||||
<div class="h5 mb-2 pt-1" id="smsUnitsValue">SMS Units : <b>{{ number_format($split_sms_units_arr['units_computation']) }}</div>
|
||||
@endif
|
||||
<div class="mini-chart"><span style="width: 57%;"></span></div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
59
resources/views/client-traffic/test.blade.php
Normal file
59
resources/views/client-traffic/test.blade.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Bootstrap 5 Starter</title>
|
||||
<!-- Bootstrap CSS CDN -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Navigation Bar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">Test Bootstrap</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="#">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Features</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content Area -->
|
||||
<div class="container mt-5">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card shadow">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h1>Welcome to the Test Page!</h1>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="lead">This is a clean, responsive section built with Bootstrap 5.
|
||||
Components like forms, cards, and navigation on the way.</p>
|
||||
<p>Grid system for layout and utility classes for styling.</p>
|
||||
<button class="btn btn-success mt-3">Get Started</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS Bundle (Place before closing body tag for best performance) -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -27,6 +27,7 @@
|
||||
</head>
|
||||
<body>
|
||||
@include('client-traffic.partials.new-app')
|
||||
<?php //dump($page_title); ?>
|
||||
<div class="container py-3 py-lg-4">
|
||||
<header class="topbar">
|
||||
<div class="topbar-card d-flex flex-column flex-lg-row align-items-lg-center justify-content-between gap-3">
|
||||
|
||||
Reference in New Issue
Block a user