Initial commit
This commit is contained in:
26
app/Http/Controllers/ActivityController.php
Normal file
26
app/Http/Controllers/ActivityController.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\ActivityLog;
|
||||
|
||||
class ActivityController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
$activities = ActivityLog::with('admin')->where('user_type', 'admin')->orderBy('created_at', 'desc')->paginate(30);
|
||||
$data = [
|
||||
'activities' => $activities,
|
||||
'page_title' => 'Admin Activity Log'
|
||||
];
|
||||
return view('activity.index', $data);
|
||||
}
|
||||
|
||||
}
|
||||
383
app/Http/Controllers/AdminController.php
Normal file
383
app/Http/Controllers/AdminController.php
Normal file
@@ -0,0 +1,383 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models;
|
||||
use Session;
|
||||
use DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use App\ActivityLog;
|
||||
use App\Libs\Smsgateway;
|
||||
|
||||
class AdminController extends Controller
|
||||
{
|
||||
public function index(){
|
||||
$dealers = Models\OrgUser::latest()->paginate(20);
|
||||
$data = [
|
||||
'organisations' => $dealers,
|
||||
'page_title' => 'Dealers'
|
||||
];
|
||||
return view('super_admin.organisations',$data);
|
||||
}
|
||||
public function merchant_index(){
|
||||
$merchants = Models\Merchant::paginate(20);
|
||||
$data = [
|
||||
'merchants' => $merchants,
|
||||
'page_title' => 'Merchants'
|
||||
];
|
||||
return view('super_admin.merchants',$data);
|
||||
}
|
||||
public function createOrg(){ //create a dealer
|
||||
$data = [
|
||||
'page_title' => 'New Dealer'
|
||||
];
|
||||
return view('super_admin.create-org', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created merchant in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request){ // save merchant in the DB
|
||||
|
||||
$this->validate($request, [
|
||||
'fullname' => 'required',
|
||||
'phone_number'=> 'required|unique:merchants,phone',
|
||||
'language' => 'required'
|
||||
]);
|
||||
|
||||
$check_phone = $this->validatePhoneNumber($request->phone_number);
|
||||
if ($check_phone == false) {
|
||||
return redirect()->back()->withInput()->with('admin-error', 'Invalid phone number!');
|
||||
}
|
||||
|
||||
|
||||
$fullname = $request->input('fullname');
|
||||
$phone_number = $request->input('phone_number');
|
||||
$pin = rand(1000,9999);
|
||||
|
||||
$merchant = Models\Merchant::create([
|
||||
'fullname' => $fullname,
|
||||
'phone' => $check_phone,
|
||||
'pin' => md5($pin),
|
||||
'language' => $request->language
|
||||
]);
|
||||
|
||||
|
||||
$desc = [
|
||||
'title' => 'Created a merchant',
|
||||
'data' => $fullname,
|
||||
'type' => 'merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = Auth::user()->id;
|
||||
$activity->user_type = 'admin';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
// TODO: send sms with PIN to merchant phone -
|
||||
$msg = "You have been Successfully registered as an Airtime sales merchant. Your 4-digit PIN is $pin. You wull need it for all your activities. Dial *349# to begin.";
|
||||
$smsgateway = new Smsgateway;
|
||||
if (env('APP_ENV') != 'local') {
|
||||
$result = $smsgateway->sendSmsNew($check_phone, $msg);
|
||||
}
|
||||
// $result = $smsgateway->sendSmsNew($check_phone, $msg);
|
||||
\Log::info($msg);
|
||||
return redirect()->to('/admin/merchant')->with('admin-sucsess', 'Successfully Added New Merchant');
|
||||
|
||||
}
|
||||
public function organisationStore(Request $request){
|
||||
$this->validate($request, [
|
||||
'user_phone' => 'required',
|
||||
'user_email' => 'required',
|
||||
'user_name' => 'required',
|
||||
'country' => 'required',
|
||||
'currency' => 'required'
|
||||
]);
|
||||
|
||||
|
||||
$generated_password = $this->randomPassword();
|
||||
|
||||
$org_user_results = Models\OrgUser::create([
|
||||
'name' => $request->user_name,
|
||||
'phone' => $request->user_phone,
|
||||
'email' => $request->user_email,
|
||||
'country' => $request->country,
|
||||
'currency' => $request->currency,
|
||||
'added_by' => \Auth::user()->name,
|
||||
'password' => Hash::make($generated_password),
|
||||
]);
|
||||
|
||||
|
||||
$desc = [
|
||||
'title' => 'New Dealer',
|
||||
'data' => \Auth::user()->name . ' added a new dealer with name ' . $request->name,
|
||||
'type' => 'store',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = \Auth::user()->id;
|
||||
$activity->user_type = 'admin';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
$login_url = env('MAIN_WEB_URL') . "/organisation";
|
||||
|
||||
// TODO: send sms with Password to merchant phone -
|
||||
$msg = "Hello ($request->name), you have successfully been registered as an Airtime Sales Dealer. Your Password is $generated_password. You will need it for all your activities. \r\nLogin Here : $login_url";
|
||||
$smsgateway = new Smsgateway;
|
||||
if (env('APP_ENV') != 'local') {
|
||||
$result = $smsgateway->sendSmsNew($check_user_phone, $msg);
|
||||
}
|
||||
\Log::info($msg);
|
||||
Session::flash('success_message', 'Dealer Successfully added!');
|
||||
return redirect()->to('/admin/organisations');
|
||||
}
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//
|
||||
$dealer = Models\OrgUser::findOrfail($id);
|
||||
if (!$dealer) {
|
||||
return redirect()->back()->with('admin-error', 'Dealer not found!');
|
||||
}
|
||||
// check if the user is allowed to edit this organisation
|
||||
$data = [
|
||||
'organisation' => $dealer,
|
||||
'page_title' => 'Edit Dealer',
|
||||
];
|
||||
return view('super_admin.organisation_edit',$data);
|
||||
}
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
$dealer = Models\OrgUser::findOrfail($id);
|
||||
if (!$dealer) {
|
||||
return redirect()->back()->with('admin-error', 'Dealer not found!');
|
||||
}
|
||||
// check if the user is allowed to edit this organisation
|
||||
$data = [
|
||||
'organisation' => $dealer,
|
||||
'page_title' => 'Dealer Details',
|
||||
];
|
||||
return view('super_admin.organisation_show', $data);
|
||||
}
|
||||
public function merchant_edit($id){
|
||||
|
||||
$merchant = Models\Merchant::findOrfail($id);
|
||||
if (!$merchant) {
|
||||
return redirect()->back()->with('admin-error', 'Merchant not found!');
|
||||
}
|
||||
$data = [
|
||||
'merchant' => $merchant,
|
||||
'page_title' => 'Edit Merchant Details',
|
||||
];
|
||||
return view('super_admin.merchant_edit',$data);
|
||||
}
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => 'required',
|
||||
'email' => 'required',
|
||||
'country' => 'required',
|
||||
'currency' => 'required',
|
||||
'phone' => [
|
||||
'required',
|
||||
'string',
|
||||
'regex:/^\+?[0-9\s\-\(\)]{7,15}$/', // Allows optional leading '+' and 7 to 15 digits/formatting characters
|
||||
],
|
||||
|
||||
]);
|
||||
|
||||
|
||||
|
||||
// dd($request->all());
|
||||
|
||||
Models\OrgUser::where('id', $id)->update([
|
||||
'name' => $request->name,
|
||||
'phone' => $request->phone,
|
||||
'email' => $request->email,
|
||||
'last_modified_user_id' => \Auth::user()->id,
|
||||
'status' => $request->status,
|
||||
]);
|
||||
|
||||
$desc = [
|
||||
'title' =>'Updated Dealer details',
|
||||
'data' => $request->all(),
|
||||
'type' => 'update',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = \Auth::user()->id; //session('current_org_user.id');// organisation user ID
|
||||
$activity->user_type = 'super_admin';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
// dd('Activity logged');
|
||||
return redirect()->to('admin/organisations')->with('admin-success', 'Successfully Updated Dealer details');
|
||||
}
|
||||
public function merchant_update(Request $request, $id)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'fullname' => 'required',
|
||||
'phone'=> 'required',
|
||||
// 'email' => 'required',
|
||||
'language' => 'required',
|
||||
'status' => 'required',
|
||||
// 'user_name' => 'required',
|
||||
]);
|
||||
|
||||
$check_phone = $this->validatePhoneNumber($request->phone);
|
||||
if ($check_phone == false) {
|
||||
return redirect()->back()->withInput()->with('admin-error', 'Invalid phone number!');
|
||||
}
|
||||
|
||||
// dd($request->all());
|
||||
|
||||
Models\Merchant::where('id', $id)->update([
|
||||
'fullname' => $request->fullname,
|
||||
'phone' => $check_phone,
|
||||
'language' => $request->language,
|
||||
// 'last_modified_user_id' => \Auth::user()->id,
|
||||
'status' => $request->status,
|
||||
// 'user_email' => $request->user_email,
|
||||
// 'user_name' => $request->user_name
|
||||
]);
|
||||
|
||||
$desc = [
|
||||
'title' =>'Updated Dealer details',
|
||||
'data' => $request->all(),
|
||||
'type' => 'Merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = \Auth::user()->id; //session('current_org_user.id');// organisation user ID
|
||||
$activity->user_type = 'merchant';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
// dd('Activity logged');
|
||||
return redirect()->to('admin/merchants')->with('admin-success', 'Successfully Updated merchant details');
|
||||
}
|
||||
|
||||
public function getMerchantSales(){
|
||||
// sales from merchants to end users
|
||||
$merchant_sales = Models\Transaction::with('merchant')->latest()->paginate(30);
|
||||
$data = [
|
||||
'merchant_sales' => $merchant_sales,
|
||||
'page_title' => 'Merchant Sales'
|
||||
];
|
||||
return view('super_admin.merchant_sales', $data);
|
||||
}
|
||||
public function getDealerSales(){
|
||||
// sales from dealers to merchants
|
||||
$dealer_sales = Models\MerchantTopUp::with('merchantInfo', 'orgInfo')->latest()->paginate(20);
|
||||
// dd($dealer_sales);
|
||||
$data = [
|
||||
'dealer_sales' => $dealer_sales,
|
||||
'page_title' => 'Dealer Sales'
|
||||
];
|
||||
return view('super_admin.dealer_sales', $data);
|
||||
}
|
||||
public function AdminTransactions(){
|
||||
$data = [
|
||||
'page_title' => 'Admin Transactions'
|
||||
];
|
||||
return view('super_admin.admin-transactions', $data);
|
||||
}
|
||||
public function getTransactionsJson(Request $request)
|
||||
{
|
||||
//$this->log_query();
|
||||
$transactions_arr = \DB::table('merchant_top_ups')
|
||||
->join('org_users', 'merchant_top_ups.org_user_id', '=', 'org_users.id')
|
||||
->select('merchant_top_ups.id', 'merchant_top_ups.status', 'org_users.name', 'merchant_top_ups.payment_method', 'merchant_top_ups.org_user_id', 'merchant_top_ups.amount', 'merchant_top_ups.created_at')
|
||||
->orderBy('merchant_top_ups.created_at', 'DESC')
|
||||
->paginate(10);
|
||||
|
||||
if($request->has('keyword')){
|
||||
$queries = [];
|
||||
$keyword = $request->keyword;
|
||||
$queries['keyword'] = $keyword;
|
||||
$transactions_arr = \DB::table('merchant_top_ups')
|
||||
->join('org_users', 'merchant_top_ups.org_user_id', '=', 'org_users.id')
|
||||
->select('merchant_top_ups.id', 'merchant_top_ups.status', 'org_users.name', 'merchant_top_ups.payment_method', 'merchant_top_ups.org_user_id', 'merchant_top_ups.amount', 'merchant_top_ups.created_at')
|
||||
->whereRaw("org_user.name LIKE '%$keyword%' OR merchant_top_ups.status LIKE '%$keyword%' OR merchant_top_ups.payment_method LIKE '%$keyword%' OR merchant_top_ups.amount LIKE '%$keyword%' OR merchant_top_ups.created_at LIKE '%$keyword%'")
|
||||
->orderBy('merchant_top_ups.created_at', 'DESC')
|
||||
->paginate(10)->appends($queries);
|
||||
}
|
||||
return response()->json($transactions_arr);
|
||||
}
|
||||
public function getAdminTransactionsJson(Request $request)
|
||||
{
|
||||
|
||||
|
||||
|
||||
$query = \DB::table('organisation_top_ups')
|
||||
->join('users', 'users.id', '=', 'organisation_top_ups.user_id')
|
||||
->join('organisations', 'organisations.id', '=', 'organisation_top_ups.org_id')
|
||||
->select(
|
||||
'organisation_top_ups.id', 'organisation_top_ups.current_balance', 'organisations.balance',
|
||||
'organisation_top_ups.amount', 'organisation_top_ups.status', 'users.name AS admin_name',
|
||||
'organisation_top_ups.created_at', 'users.name', 'organisations.name AS dealer_name'
|
||||
);
|
||||
|
||||
if ($request->has('filter')) {
|
||||
$filters = $request->input('filter');
|
||||
|
||||
// Map the Tabulator JS fields to the actual database table columns
|
||||
$columnMap = [
|
||||
'admin_name' => 'users.name',
|
||||
'balance' => 'organisations.balance',
|
||||
'current_balance' => 'organisation_top_ups.current_balance',
|
||||
'amount' => 'organisation_top_ups.amount',
|
||||
'dealer_name' => 'organisations.name'
|
||||
];
|
||||
|
||||
foreach ($filters as $filter) {
|
||||
$field = $filter['field'];
|
||||
$value = $filter['value'];
|
||||
|
||||
// Determine the correct DB column. Default to sender_ids table to avoid 'ambiguous column' errors
|
||||
$dbColumn = $columnMap[$field] ?? 'organisation_top_ups.' . $field;
|
||||
|
||||
// Securely bind the value using Laravel's active record (prevents SQL injection)
|
||||
$query->where($dbColumn, 'LIKE', '%' . $value . '%');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$query->orderBy('organisation_top_ups.created_at', 'DESC');
|
||||
|
||||
$perPage = $request->input('size', 15);
|
||||
$senderid_arr = $query->paginate($perPage);
|
||||
|
||||
// If using the global keyword, append it to the pagination links
|
||||
if ($request->has('keyword')) {
|
||||
$senderid_arr->appends(['keyword' => $request->keyword]);
|
||||
}
|
||||
return response()->json($senderid_arr);
|
||||
}
|
||||
public function randomPassword() {
|
||||
$alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
|
||||
$pass = array(); //remember to declare $pass as an array
|
||||
$alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$n = rand(0, $alphaLength);
|
||||
$pass[] = $alphabet[$n];
|
||||
}
|
||||
return implode($pass); //turn the array into a string
|
||||
}
|
||||
}
|
||||
313
app/Http/Controllers/ApiDealersController.php
Normal file
313
app/Http/Controllers/ApiDealersController.php
Normal file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
// use Illuminate\Support\Facades\Validator;
|
||||
use Validator;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models;
|
||||
use App\ActivityLog;
|
||||
use App\Libs\Smsgateway;
|
||||
|
||||
class ApiDealersController extends Controller
|
||||
{
|
||||
public function handleLogin(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'email' => 'required|email',
|
||||
'password' => 'required'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Email and password are required.',
|
||||
'errors' => $validator->errors()
|
||||
], 422);
|
||||
}
|
||||
|
||||
$org_user = Models\OrgUser::where('email', $request->email)->first();
|
||||
|
||||
if (!$org_user || !Hash::check($request->password, $org_user->password)) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Email or password incorrect.'
|
||||
], 401);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$desc = [
|
||||
'title' => 'Login',
|
||||
'data' => $org_user->name . ' Successful login'
|
||||
];
|
||||
|
||||
$activity = new ActivityLog();
|
||||
$activity->user_id = $org_user->id;
|
||||
$activity->user_type = 'organisation';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'message' => 'Login successful.',
|
||||
'data' => [
|
||||
'user' => $org_user,
|
||||
]
|
||||
]);
|
||||
}
|
||||
public function getBalance(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'dealer_id' => 'required|integer|exists:org_users,id'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Validation error.',
|
||||
'errors' => $validator->errors()
|
||||
], 422);
|
||||
}
|
||||
|
||||
$dealer_id = $request->dealer_id;
|
||||
|
||||
$org_user = Models\OrgUser::find($dealer_id);
|
||||
|
||||
if (!$org_user || !Hash::check($request->password, $org_user->password)) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Email or password incorrect.'
|
||||
], 401);
|
||||
}
|
||||
$desc = [
|
||||
'title' => 'Login',
|
||||
'data' => $org_user->name . ' Successful login'
|
||||
];
|
||||
|
||||
$activity = new ActivityLog();
|
||||
$activity->user_id = $org_user->id;
|
||||
$activity->user_type = 'organisation';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'message' => 'Balance check successful',
|
||||
'data' => [
|
||||
'balance' => $org_user->balance,
|
||||
]
|
||||
]);
|
||||
}
|
||||
public function getTransactionsJson(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'dealer_id' => 'required|integer|exists:org_users,id'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Validation error.',
|
||||
'errors' => $validator->errors()
|
||||
], 422);
|
||||
}
|
||||
|
||||
$dealer_id = $request->dealer_id;
|
||||
|
||||
$query = DB::table('merchant_top_ups')
|
||||
->join('org_users', 'merchant_top_ups.org_user_id', '=', 'org_users.id')
|
||||
->join('merchants', 'merchant_top_ups.merchant_id', '=', 'merchants.id')
|
||||
->select('merchant_top_ups.id', 'merchant_top_ups.status', 'merchants.phone', 'merchants.fullname', 'merchant_top_ups.payment_method', 'merchant_top_ups.org_user_id', 'merchant_top_ups.amount', 'merchant_top_ups.created_at')
|
||||
->where('merchant_top_ups.org_user_id', $dealer_id);
|
||||
|
||||
if ($request->has('keyword')) {
|
||||
$keyword = $request->keyword;
|
||||
$query->where(function($q) use ($keyword) {
|
||||
$q->where('merchants.fullname', 'LIKE', "%{$keyword}%")
|
||||
->orWhere('merchants.phone', 'LIKE', "%{$keyword}%")
|
||||
->orWhere('merchant_top_ups.status', 'LIKE', "%{$keyword}%")
|
||||
->orWhere('merchant_top_ups.payment_method', 'LIKE', "%{$keyword}%")
|
||||
->orWhere('merchant_top_ups.amount', 'LIKE', "%{$keyword}%")
|
||||
->orWhere('merchant_top_ups.created_at', 'LIKE', "%{$keyword}%");
|
||||
});
|
||||
}
|
||||
|
||||
$transactions_arr = $query->orderBy('merchant_top_ups.created_at', 'DESC')->paginate(10);
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'data' => $transactions_arr
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMyTopUpsJson(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'dealer_id' => 'required|integer|exists:org_users,id'
|
||||
]);
|
||||
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Validation error.',
|
||||
'errors' => $validator->errors()
|
||||
], 422);
|
||||
}
|
||||
|
||||
$dealer_id = $request->dealer_id;
|
||||
|
||||
$query = DB::table('organisation_top_ups')
|
||||
->join('org_users', 'organisation_top_ups.org_id', '=', 'org_users.org_id')
|
||||
->join('users', 'organisation_top_ups.user_id', '=', 'users.id')
|
||||
->select('organisation_top_ups.id', 'organisation_top_ups.status', 'org_users.phone', 'users.name', 'organisation_top_ups.payment_method', 'organisation_top_ups.org_id', 'organisation_top_ups.amount', 'organisation_top_ups.created_at')
|
||||
->where('organisation_top_ups.org_user_id', $dealer_id);
|
||||
|
||||
if ($request->has('keyword')) {
|
||||
$keyword = $request->keyword;
|
||||
$query->where(function($q) use ($keyword) {
|
||||
$q->where('org_users.name', 'LIKE', "%{$keyword}%")
|
||||
->orWhere('org_users.phone', 'LIKE', "%{$keyword}%")
|
||||
->orWhere('organisation_top_ups.status', 'LIKE', "%{$keyword}%")
|
||||
->orWhere('organisation_top_ups.payment_method', 'LIKE', "%{$keyword}%")
|
||||
->orWhere('organisation_top_ups.amount', 'LIKE', "%{$keyword}%")
|
||||
->orWhere('organisation_top_ups.created_at', 'LIKE', "%{$keyword}%");
|
||||
});
|
||||
}
|
||||
|
||||
$transactions_arr = $query->orderBy('organisation_top_ups.created_at', 'DESC')->paginate(10);
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'data' => $transactions_arr
|
||||
]);
|
||||
}
|
||||
|
||||
public function merchantTopupStore(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'merchant_id' => 'required|integer|exists:merchants,id',
|
||||
'amount' => 'required|numeric|min:1',
|
||||
'dealer_id' => 'required|integer|exists:org_users,id'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'code' => 3,
|
||||
'status' => 'failed',
|
||||
'message' => 'Validation error.',
|
||||
'errors' => $validator->errors()
|
||||
], 422);
|
||||
}
|
||||
|
||||
|
||||
$dealer_id = $request->dealer_id;
|
||||
$merchant_id = $request->merchant_id;
|
||||
|
||||
$amount = (float) $request->amount;
|
||||
|
||||
$dealer = Models\OrgUser::findOrFail($dealer_id);
|
||||
$merchant = Models\Merchant::findOrFail($merchant_id);
|
||||
|
||||
if ($amount > $dealer->balance) {
|
||||
return response()->json([
|
||||
'code' => 3,
|
||||
'status' => 'failed',
|
||||
'message' => 'Insufficient Balance.',
|
||||
'balance' => $dealer->balance
|
||||
], 400);
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
Models\MerchantTopUp::create([
|
||||
'merchant_id' => $merchant_id,
|
||||
'amount' => $amount,
|
||||
'transaction_id' => 'MCH-' . Str::uuid(),
|
||||
'org_user_id' => $dealer_id,
|
||||
'created_by' => $dealer_id,
|
||||
'payment_method' => 'cash'
|
||||
]);
|
||||
|
||||
$merchant->increment('balance', $amount);
|
||||
$dealer->decrement('balance', $amount);
|
||||
|
||||
DB::commit();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
\Log::error($e);
|
||||
|
||||
return response()->json([
|
||||
'code' => 3,
|
||||
'status' => 'failed',
|
||||
'message' => 'Merchant Top Up failed.'
|
||||
], 500);
|
||||
}
|
||||
|
||||
ActivityLog::create([
|
||||
'user_id' => $dealer_id,
|
||||
'user_type' => 'Dealer',
|
||||
'description' => json_encode([
|
||||
'title' => 'Dealer to Merchant Top Up',
|
||||
'data' => 'MWK ' . number_format($amount, 2) . ' for ' . $merchant->fullname,
|
||||
'type' => 'dealer topup'
|
||||
])
|
||||
]);
|
||||
|
||||
$merchant->refresh();
|
||||
|
||||
try {
|
||||
if (!app()->environment('local')) {
|
||||
(new Smsgateway())->sendSmsNew(
|
||||
$merchant->phone,
|
||||
"Hello {$merchant->fullname}, your account has been credited with MWK {$amount}. Your new balance is MWK {$merchant->balance}."
|
||||
);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'code' => 1,
|
||||
'status' => 'success',
|
||||
'message' => 'Merchant Top Up Successfully completed.'
|
||||
]);
|
||||
}
|
||||
|
||||
public function getActivity(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'dealer_id' => 'required|integer|exists:org_users,id'
|
||||
]);
|
||||
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Validation error.',
|
||||
'errors' => $validator->errors()
|
||||
], 422);
|
||||
}
|
||||
|
||||
$dealer_id = $request->dealer_id;
|
||||
|
||||
$activities = ActivityLog::with('admin')
|
||||
->where('user_type', 'organisation')
|
||||
->where('user_id', $dealer_id)
|
||||
->orderBy('created_at', 'desc')
|
||||
->paginate(20);
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'data' => $activities
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
///http://206.225.87.174:8131/dealer/topupmerchant
|
||||
552
app/Http/Controllers/ApiMerchantsController.php
Normal file
552
app/Http/Controllers/ApiMerchantsController.php
Normal file
@@ -0,0 +1,552 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Models\Merchant;
|
||||
use App\Models\Transaction;
|
||||
use App\ActivityLog;
|
||||
use App\Libs\Smsgateway;
|
||||
|
||||
class ApiMerchantsController extends Controller{
|
||||
public function merchant_login(Request $request){
|
||||
$this->validate($request, [
|
||||
'phone_number' => 'required',
|
||||
'pin' => 'required'
|
||||
]);
|
||||
$phone_number = $this->validatePhoneNumber($request->phone_number);
|
||||
|
||||
if ($phone_number === false) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Phone Number/PIN is incorrect!'
|
||||
], 401);
|
||||
}
|
||||
|
||||
$pin = md5($request->input('pin'));
|
||||
|
||||
$merchant = Models\Merchant::where('phone', $phone_number)->where('pin', $pin)->first();
|
||||
|
||||
if ($merchant === null) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Phone Number/PIN incorrect!'
|
||||
], 401);
|
||||
}
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Login successful',
|
||||
'merchant' => [
|
||||
'id' => $merchant->id,
|
||||
'phone' => $merchant->phone,
|
||||
'balance' => $merchant->balance,
|
||||
'status' => $merchant->status,
|
||||
'fullname' => $merchant->fullname,
|
||||
'country' => $merchant->country
|
||||
]
|
||||
], 200);
|
||||
}
|
||||
|
||||
|
||||
public function get_transactions(Request $request)
|
||||
{
|
||||
// POST body params: merchant_id (required), keyword (optional), start_date, end_date, per_page
|
||||
$merchantId = $request->input('merchant_id');
|
||||
|
||||
if (!$merchantId) {
|
||||
return response()->json(['success' => false, 'message' => 'merchant_id is required'], 422);
|
||||
}
|
||||
$merchant = Models\Merchant::find($merchantId);
|
||||
if (!$merchant) {
|
||||
return response()->json(['success' => false, 'message' => 'merchant not found'], 404);
|
||||
}
|
||||
|
||||
$perPage = (int) $request->input('per_page', 20);
|
||||
|
||||
$query = \DB::table('transactions')
|
||||
->join('merchants', 'transactions.merchant_id', '=', 'merchants.id')
|
||||
->select(
|
||||
'merchants.fullname',
|
||||
'transactions.id',
|
||||
'transactions.status',
|
||||
'transactions.msisdn',
|
||||
'transactions.amount',
|
||||
'transactions.created_at'
|
||||
)
|
||||
->where('transactions.merchant_id', $merchantId);
|
||||
|
||||
if ($request->filled('keyword')) {
|
||||
$keyword = $request->input('keyword');
|
||||
$like = "%{$keyword}%";
|
||||
$query->where(function ($q) use ($like) {
|
||||
$q->where('merchants.fullname', 'like', $like)
|
||||
->orWhere('transactions.msisdn', 'like', $like)
|
||||
->orWhere('transactions.status', 'like', $like)
|
||||
->orWhere('transactions.amount', 'like', $like)
|
||||
->orWhere('transactions.created_at', 'like', $like);
|
||||
});
|
||||
}
|
||||
|
||||
if ($request->filled('start_date') || $request->filled('end_date')) {
|
||||
try {
|
||||
$start = $request->filled('start_date') ? \Carbon\Carbon::parse($request->input('start_date'))->startOfDay() : null;
|
||||
$end = $request->filled('end_date') ? \Carbon\Carbon::parse($request->input('end_date'))->endOfDay() : null;
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['success' => false, 'message' => 'Invalid date format'], 422);
|
||||
}
|
||||
|
||||
if ($start && $end) {
|
||||
$query->whereBetween('transactions.created_at', [$start, $end]);
|
||||
} elseif ($start) {
|
||||
$query->where('transactions.created_at', '>=', $start);
|
||||
} else {
|
||||
$query->where('transactions.created_at', '<=', $end);
|
||||
}
|
||||
}
|
||||
|
||||
$query->orderBy('transactions.created_at', 'desc');
|
||||
|
||||
$paginator = $query->paginate($perPage)->appends($request->except('page'));
|
||||
|
||||
return response()->json($paginator);
|
||||
}
|
||||
public function get_dealers(Request $request){
|
||||
$perPage = (int) $request->input('per_page', 20);
|
||||
|
||||
#$dealer_arr = \DB::table('organisations')->orderBy('organisations.created_at', 'DESC')->paginate(20);
|
||||
|
||||
$query = \DB::table('organisations')->select('organisations.id', 'organisations.name', 'organisations.email', 'organisations.phone', 'organisations.status');
|
||||
|
||||
if ($request->filled('keyword')) {
|
||||
$keyword = $request->input('keyword');
|
||||
$like = "%{$keyword}%";
|
||||
$query->where(function ($q) use ($like) {
|
||||
$q->where('organisations.name', 'like', $like)
|
||||
->orWhere('organisations.phone', 'like', $like)
|
||||
->orWhere('organisations.email', 'like', $like)
|
||||
->orWhere('organisations.status', 'like', $like)
|
||||
->orWhere('organisations.created_at', 'like', $like);
|
||||
});
|
||||
}
|
||||
$paginator = $query->paginate($perPage)->appends($request->except('page'));
|
||||
|
||||
return response()->json($paginator);
|
||||
}
|
||||
|
||||
public function getDealerTransactionsJson(Request $request){
|
||||
$merchant_id = session('merchant.id');
|
||||
// dd($merchant_id);
|
||||
$transactions_arr = \DB::table('merchant_top_ups')
|
||||
->join('merchants', 'merchant_top_ups.merchant_id', '=', 'merchants.id')
|
||||
->join('org_users', 'merchant_top_ups.org_user_id', '=', 'org_users.id')
|
||||
->select('merchants.fullname', 'org_users.phone', 'org_users.name', 'merchant_top_ups.id', 'merchant_top_ups.status', 'merchant_top_ups.amount', 'merchant_top_ups.created_at')
|
||||
->whereRaw('merchant_top_ups.merchant_id = '. $merchant_id)
|
||||
->orderBy('merchant_top_ups.created_at', 'DESC')
|
||||
->paginate(20);
|
||||
|
||||
if($request->has('keyword')){
|
||||
$queries = [];
|
||||
$keyword = $request->keyword;
|
||||
$queries['keyword'] = $keyword;
|
||||
$transactions_arr = \DB::table('merchant_top_ups')
|
||||
->join('merchants', 'merchant_top_ups.merchant_id', '=', 'merchants.id')
|
||||
->join('org_users', 'merchant_top_ups.org_user_id', '=', 'org_users.id')
|
||||
->select('merchants.fullname', 'org_users.phone', 'org_users.name', 'merchant_top_ups.id', 'merchant_top_ups.status', 'merchant_top_ups.amount', 'merchant_top_ups.created_at')
|
||||
->whereRaw("org_users.phone LIKE '%$keyword%' OR org_users.name LIKE '%$keyword%' OR merchants.fullname LIKE '%$keyword%' OR merchant_top_ups.status LIKE '%$keyword%' OR merchant_top_ups.amount LIKE '%$keyword%' OR merchant_top_ups.created_at LIKE '%$keyword%'")
|
||||
->whereRaw('merchant_top_ups.merchant_id = '. $merchant_id)
|
||||
->orderBy('merchant_top_ups.created_at', 'DESC')
|
||||
->paginate(20)->appends($queries);
|
||||
}
|
||||
return response()->json($transactions_arr);
|
||||
}
|
||||
|
||||
|
||||
public function merchant_transactions($merchant){
|
||||
|
||||
$transactions = Models\Transaction::where('merchant_id', $merchant->id)
|
||||
->select('id', 'created_at')->get()
|
||||
->groupBy(function($date) {
|
||||
return Carbon::parse($date->created_at)->format('m'); // grouping by months
|
||||
});
|
||||
$transactionmcount = [];
|
||||
$transactionArr = [];
|
||||
|
||||
|
||||
|
||||
$pp = 1;
|
||||
$trans = [];
|
||||
foreach ($transactions as $value) {
|
||||
if ($pp == $value) {
|
||||
$trans[$pp]= $value;
|
||||
}
|
||||
else{
|
||||
$trans[$pp] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
foreach ($transactions as $key => $value) {
|
||||
$transactionmcount[(int)$key] = count($value);
|
||||
}
|
||||
for($i = 1; $i <= 12; $i++){
|
||||
if(!empty($transactionmcount[$i])){
|
||||
$transactionArr[$i] = $transactionmcount[$i];
|
||||
}else{
|
||||
$transactionArr[$i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$transactions = '';
|
||||
foreach ($transactionArr as $tran) {
|
||||
$transactions = $transactions.','.$tran;
|
||||
}
|
||||
return response()->json(['transactions' => $transactions]);
|
||||
}
|
||||
public function customerTopupStoreOld(Request $request){
|
||||
$this->validate($request, [
|
||||
'phone_number'=> 'required|numeric',
|
||||
'amount' => 'required|numeric|min:1',
|
||||
'merchant_id' => 'required|numeric'
|
||||
]);
|
||||
$phone_number = preg_replace('/\s+/', '', $request->phone_number);
|
||||
$check_phone = $this->validatePhoneNumber($phone_number);
|
||||
if ($check_phone == false) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Invalid phone number!'
|
||||
], 401);
|
||||
}
|
||||
$merchant = Models\Merchant::with('orgInfo')->find($request->merchant_id);
|
||||
if ($merchant == false) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'merchant not found!'
|
||||
], 401);
|
||||
}
|
||||
$difference = $merchant->balance - $request->amount;
|
||||
if ($merchant->balance < $request->amount) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Insufficient balance!'
|
||||
], 401);
|
||||
}
|
||||
$prev_balance = $merchant->balance;
|
||||
$extRefId = uniqid() . '-' . date('YmdHis');
|
||||
$transaction_arr = [
|
||||
'msisdn' => $check_phone,
|
||||
'amount' => $request->amount,
|
||||
'merchant_id' => $merchant->id,
|
||||
'session_id' => $extRefId
|
||||
];
|
||||
// dd($transaction_arr);
|
||||
$trans_result = Models\Transaction::create($transaction_arr);
|
||||
$transaction_id = $trans_result->id;
|
||||
|
||||
$click_params = [
|
||||
"msisdn" => $check_phone,
|
||||
"amount" => $request->amount,
|
||||
"extRefId" => $extRefId
|
||||
];
|
||||
\Log::info($click_params);
|
||||
|
||||
$topup_result = $this->ClickADPHttp($click_params);
|
||||
|
||||
\Log::info($topup_result);
|
||||
|
||||
$this->sendNtfy($topup_result);
|
||||
$topup_result_arr = json_decode($topup_result, TRUE);
|
||||
|
||||
\Log::info($topup_result_arr);
|
||||
if ($topup_result == false) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Top Up Could not be processed at this time. Try again later.'
|
||||
], 401);
|
||||
}
|
||||
$log_data = [
|
||||
'msisdn' => $check_phone,
|
||||
'amount' => $request->tamount,
|
||||
'user_id' => $merchant->id,
|
||||
'merchant_balance' => $merchant->balance,
|
||||
'session_id' => $extRefId,
|
||||
'status' => $topup_result_arr,
|
||||
'network' => 'n.a'
|
||||
];
|
||||
$desc = [
|
||||
'title' =>'customer top up by Merchant ID ' . $merchant->id,
|
||||
'data' => $log_data,
|
||||
'type' => 'merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $merchant->id;
|
||||
$activity->user_type = 'merchant';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
|
||||
if ($topup_result_arr['code'] == 1) {
|
||||
|
||||
$merchant_update = Models\Merchant::find($merchant->id);
|
||||
$merchant_update->balance = $prev_balance - $request->amount;
|
||||
$merchant_update->save();
|
||||
$desc = [
|
||||
'title' =>'Successful customer top up by Merchant ID ' . $merchant->id,
|
||||
'data' => ['previous_balance' => $merchant->balance, 'current_balance' => $merchant->balance - $request->amount],
|
||||
'type' => 'merchant',
|
||||
];
|
||||
#update transactions
|
||||
$transaction = Models\Transaction::find($transaction_id);
|
||||
$transaction->status = $topup_result_arr['message'];
|
||||
$transaction->save();
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $merchant->id;
|
||||
$activity->user_type = 'merchant';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Top Up Successfully processed!'
|
||||
], 200);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function customerTopupStore(Request $request){
|
||||
$request->validate([
|
||||
'phone_number' => 'required|string',
|
||||
'amount' => 'required|numeric|min:1',
|
||||
'merchant_id' => 'required|integer|exists:merchants,id'
|
||||
]);
|
||||
|
||||
|
||||
$phone_number = preg_replace('/\s+/', '', $request->phone_number);
|
||||
$check_phone = $this->validatePhoneNumber($phone_number);
|
||||
|
||||
|
||||
if (!$check_phone) {
|
||||
return response()->json(['success' => false, 'message' => 'Invalid phone number!'], 422);
|
||||
}
|
||||
|
||||
$merchant = Models\Merchant::find($request->merchant_id);
|
||||
$country_prefix = substr($check_phone, 0, 3);
|
||||
$country = '';
|
||||
switch ($country_prefix) {
|
||||
case '265':
|
||||
$country = 'MALAWI';
|
||||
break;
|
||||
case '260':
|
||||
$country = 'ZAMBIA';
|
||||
break;
|
||||
|
||||
default:
|
||||
$country = '';
|
||||
break;
|
||||
}
|
||||
if ($merchant->country !== $country) {
|
||||
// find out from team
|
||||
return response()->json(['success' => false, 'message' => 'Country not allowed!'], 400);
|
||||
}
|
||||
$extRefId = uniqid() . '-' . date('YmdHis');
|
||||
$topup_result_arr = null;
|
||||
|
||||
try {
|
||||
$topup_result = DB::transaction(function () use ($request, $check_phone, $extRefId, &$topup_result_arr) {
|
||||
|
||||
|
||||
$merchant = Merchant::lockForUpdate()->find($request->merchant_id);
|
||||
|
||||
if ($merchant->balance < $request->amount) {
|
||||
throw new \Exception('Insufficient balance!', 400);
|
||||
}
|
||||
|
||||
|
||||
$prev_balance = $merchant->balance;
|
||||
$merchant->balance -= $request->amount;
|
||||
$merchant->save();
|
||||
|
||||
|
||||
$transaction = Transaction::create([
|
||||
'msisdn' => $check_phone,
|
||||
'amount' => $request->amount,
|
||||
'merchant_id' => $merchant->id,
|
||||
'session_id' => $extRefId,
|
||||
'status' => 'PENDING'
|
||||
]);
|
||||
|
||||
|
||||
$click_params = [
|
||||
"msisdn" => $check_phone,
|
||||
"amount" => $request->amount,
|
||||
"extRefId" => $extRefId
|
||||
];
|
||||
Log::info('ClickADP Request:', $click_params);
|
||||
|
||||
$api_response = $this->ClickADPHttp($click_params);
|
||||
Log::info('ClickADP Response: ' . $api_response);
|
||||
|
||||
$this->sendNtfy($api_response);
|
||||
$topup_result_arr = json_decode($api_response, true);
|
||||
|
||||
if (!$api_response || !isset($topup_result_arr['code'])) {
|
||||
throw new \Exception('Top Up Could not be processed at this time. Try again later.', 502);
|
||||
}
|
||||
|
||||
if ($topup_result_arr['code'] != 1) {
|
||||
throw new \Exception($topup_result_arr['message'] ?? 'Provider failed to process topup.', 422);
|
||||
}
|
||||
|
||||
$transaction->update(['status' => $topup_result_arr['message'] ?? 'SUCCESS']);
|
||||
|
||||
ActivityLog::create([
|
||||
'user_id' => $merchant->id,
|
||||
'user_type' => 'merchant',
|
||||
'description' => json_encode([
|
||||
'title' => 'Successful customer top up by Merchant ID ' . $merchant->id,
|
||||
'data' => [
|
||||
'msisdn' => $check_phone,
|
||||
'amount' => $request->amount,
|
||||
'previous_balance' => $prev_balance,
|
||||
'current_balance' => $merchant->balance,
|
||||
'session_id' => $extRefId,
|
||||
'status' => $topup_result_arr,
|
||||
'network' => 'n.a'
|
||||
],
|
||||
'type' => 'merchant',
|
||||
])
|
||||
]);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Top Up Successfully processed!'
|
||||
], 200);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
|
||||
Log::error('Topup Failed: ' . $e->getMessage());
|
||||
try {
|
||||
ActivityLog::create([
|
||||
'user_id' => $request->merchant_id,
|
||||
'user_type' => 'merchant',
|
||||
'description' => json_encode([
|
||||
'title' => 'Failed customer top up attempt',
|
||||
'error' => $e->getMessage(),
|
||||
'data' => ['msisdn' => $check_phone, 'amount' => $request->amount]
|
||||
])
|
||||
]);
|
||||
|
||||
// $activity = new ActivityLog;
|
||||
// $activity->user_id = $merchant->id;
|
||||
// $activity->user_type = 'merchant';
|
||||
// $activity->description = json_encode($desc);
|
||||
// $activity->save();
|
||||
|
||||
} catch (\Exception $logEx) {
|
||||
Log::error('Failed to write failure activity log: ' . $logEx->getMessage());
|
||||
}
|
||||
|
||||
$code = ($e->getCode() >= 400 && $e->getCode() <= 505) ? $e->getCode() : 500;
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => $e->getMessage()
|
||||
], $code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make sure to import your Models and Smsgateway at the top of the file
|
||||
|
||||
public function merchantToDealerRefund(Request $request){
|
||||
$this->validate($request, [
|
||||
'transaction_id' => 'required|string',
|
||||
'reason' => 'required|string',
|
||||
]);
|
||||
$transaction = Models\MerchantTopUp::with('merchantInfo', 'orgInfo')->where('status', 'success')->where('transaction_id', $request->transaction_id)->first();
|
||||
if ($transaction == null) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Transaction not found.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
|
||||
$dealer = $transaction->orgInfo;
|
||||
|
||||
if ($transaction->merchantInfo->balance < $request->amount) {
|
||||
//ask team to confirm if merchant can have a negative balance
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Insufficient merchant balance to process this refund.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
$merchant_name = $transaction->merchantInfo->fullname;
|
||||
$dealer_name = $transaction->orgInfo->name;
|
||||
$merchant = Models\Merchant::find($transaction->merchantInfo->id);
|
||||
$organisation = Models\Organisation::find($transaction->orgInfo->id);
|
||||
try {
|
||||
//todo : remove one of organisation or dealer
|
||||
DB::transaction(function () use ($request, $merchant, $organisation, $dealer, $transaction) {
|
||||
Models\MerchantToDealerRefund::create([
|
||||
'dealer_id' => $transaction->org_user_id,
|
||||
'transaction_id'=> $request->transaction_id,
|
||||
'merchant_id' => $transaction->merchant_id,
|
||||
'amount' => $transaction->amount,
|
||||
'dealer_msisdn' => $transaction->orgInfo->phone,
|
||||
'reason' => $request->reason,
|
||||
]);
|
||||
$merchant->decrement('balance', $transaction->amount);
|
||||
$organisation->increment('balance', $transaction->amount);
|
||||
|
||||
$desc = [
|
||||
'title' => 'Dealer Refund',
|
||||
'data' => "Refunded a dealer with an amount of " . $transaction->amount, // Typo fixed
|
||||
'type' => 'merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $transaction->merchant_id;
|
||||
$activity->user_type = 'merchant';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
$transaction->status = 'refunded';
|
||||
$transaction->save();
|
||||
});
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("API : Refund Transaction Failed: " . $e->getMessage());
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => "API XX Refund Transaction Failed: " . $e->getMessage()
|
||||
], 400);
|
||||
}
|
||||
$msg = "You have successfully refunded a dealer ($dealer_name) with an amount of $transaction->amount.";
|
||||
$dealer_msg = "You have received a refund amount of $transaction->amount from Airtime Merchant ($merchant_name).";
|
||||
|
||||
if (env('APP_ENV') !== 'local') {
|
||||
try {
|
||||
$smsgateway = new Smsgateway;
|
||||
$smsgateway->sendSmsNew($merchant->phone, $msg);
|
||||
$smsgateway->sendSmsNew($organisation->phone, $dealer_msg);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("API: Failed to send SMS for refund: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
\Log::info("API :" . $msg);
|
||||
\Log::info("API :" . $dealer_msg);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => "Dealer Refund successfully processed! "
|
||||
], 200);
|
||||
}
|
||||
|
||||
}
|
||||
54
app/Http/Controllers/Auth/AuthenticatedSessionController.php
Normal file
54
app/Http/Controllers/Auth/AuthenticatedSessionController.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Auth\LoginRequest;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AuthenticatedSessionController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the login view.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming authentication request.
|
||||
*
|
||||
* @param \App\Http\Requests\Auth\LoginRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(LoginRequest $request)
|
||||
{
|
||||
$request->authenticate();
|
||||
|
||||
$request->session()->regenerate();
|
||||
|
||||
return redirect()->intended(RouteServiceProvider::HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy an authenticated session.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
Auth::guard('web')->logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
44
app/Http/Controllers/Auth/ConfirmablePasswordController.php
Normal file
44
app/Http/Controllers/Auth/ConfirmablePasswordController.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class ConfirmablePasswordController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the confirm password view.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show()
|
||||
{
|
||||
return view('auth.confirm-password');
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm the user's password.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
if (! Auth::guard('web')->validate([
|
||||
'email' => $request->user()->email,
|
||||
'password' => $request->password,
|
||||
])) {
|
||||
throw ValidationException::withMessages([
|
||||
'password' => __('auth.password'),
|
||||
]);
|
||||
}
|
||||
|
||||
$request->session()->put('auth.password_confirmed_at', time());
|
||||
|
||||
return redirect()->intended(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EmailVerificationNotificationController extends Controller
|
||||
{
|
||||
/**
|
||||
* Send a new email verification notification.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
if ($request->user()->hasVerifiedEmail()) {
|
||||
return redirect()->intended(RouteServiceProvider::HOME);
|
||||
}
|
||||
|
||||
$request->user()->sendEmailVerificationNotification();
|
||||
|
||||
return back()->with('status', 'verification-link-sent');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EmailVerificationPromptController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the email verification prompt.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
return $request->user()->hasVerifiedEmail()
|
||||
? redirect()->intended(RouteServiceProvider::HOME)
|
||||
: view('auth.verify-email');
|
||||
}
|
||||
}
|
||||
65
app/Http/Controllers/Auth/NewPasswordController.php
Normal file
65
app/Http/Controllers/Auth/NewPasswordController.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rules;
|
||||
|
||||
class NewPasswordController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the password reset view.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
return view('auth.reset-password', ['request' => $request]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming new password request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'token' => ['required'],
|
||||
'email' => ['required', 'email'],
|
||||
'password' => ['required', 'confirmed', Rules\Password::defaults()],
|
||||
]);
|
||||
|
||||
// Here we will attempt to reset the user's password. If it is successful we
|
||||
// will update the password on an actual user model and persist it to the
|
||||
// database. Otherwise we will parse the error and return the response.
|
||||
$status = Password::reset(
|
||||
$request->only('email', 'password', 'password_confirmation', 'token'),
|
||||
function ($user) use ($request) {
|
||||
$user->forceFill([
|
||||
'password' => Hash::make($request->password),
|
||||
'remember_token' => Str::random(60),
|
||||
])->save();
|
||||
|
||||
event(new PasswordReset($user));
|
||||
}
|
||||
);
|
||||
|
||||
// If the password was successfully reset, we will redirect the user back to
|
||||
// the application's home authenticated view. If there is an error we can
|
||||
// redirect them back to where they came from with their error message.
|
||||
return $status == Password::PASSWORD_RESET
|
||||
? redirect()->route('login')->with('status', __($status))
|
||||
: back()->withInput($request->only('email'))
|
||||
->withErrors(['email' => __($status)]);
|
||||
}
|
||||
}
|
||||
47
app/Http/Controllers/Auth/PasswordResetLinkController.php
Normal file
47
app/Http/Controllers/Auth/PasswordResetLinkController.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
|
||||
class PasswordResetLinkController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the password reset link request view.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('auth.forgot-password');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming password reset link request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'email' => ['required', 'email'],
|
||||
]);
|
||||
|
||||
// We will send the password reset link to this user. Once we have attempted
|
||||
// to send the link, we will examine the response then see the message we
|
||||
// need to show to the user. Finally, we'll send out a proper response.
|
||||
$status = Password::sendResetLink(
|
||||
$request->only('email')
|
||||
);
|
||||
|
||||
return $status == Password::RESET_LINK_SENT
|
||||
? back()->with('status', __($status))
|
||||
: back()->withInput($request->only('email'))
|
||||
->withErrors(['email' => __($status)]);
|
||||
}
|
||||
}
|
||||
54
app/Http/Controllers/Auth/RegisteredUserController.php
Normal file
54
app/Http/Controllers/Auth/RegisteredUserController.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\Rules;
|
||||
|
||||
class RegisteredUserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the registration view.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('auth.register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming registration request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'confirmed', Rules\Password::defaults()],
|
||||
]);
|
||||
|
||||
$user = User::create([
|
||||
'name' => $request->name,
|
||||
'email' => $request->email,
|
||||
'password' => Hash::make($request->password),
|
||||
]);
|
||||
|
||||
event(new Registered($user));
|
||||
|
||||
Auth::login($user);
|
||||
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
30
app/Http/Controllers/Auth/VerifyEmailController.php
Normal file
30
app/Http/Controllers/Auth/VerifyEmailController.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Auth\Events\Verified;
|
||||
use Illuminate\Foundation\Auth\EmailVerificationRequest;
|
||||
|
||||
class VerifyEmailController extends Controller
|
||||
{
|
||||
/**
|
||||
* Mark the authenticated user's email address as verified.
|
||||
*
|
||||
* @param \Illuminate\Foundation\Auth\EmailVerificationRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function __invoke(EmailVerificationRequest $request)
|
||||
{
|
||||
if ($request->user()->hasVerifiedEmail()) {
|
||||
return redirect()->intended(RouteServiceProvider::HOME.'?verified=1');
|
||||
}
|
||||
|
||||
if ($request->user()->markEmailAsVerified()) {
|
||||
event(new Verified($request->user()));
|
||||
}
|
||||
|
||||
return redirect()->intended(RouteServiceProvider::HOME.'?verified=1');
|
||||
}
|
||||
}
|
||||
30
app/Http/Controllers/AuthController.php
Normal file
30
app/Http/Controllers/AuthController.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
public function login(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'email' => 'required|email',
|
||||
'password' => 'required',
|
||||
]);
|
||||
|
||||
if (!\Auth::attempt($request->only('email', 'password'))) {
|
||||
return response()->json(['message' => 'Invalid credentials'], 401);
|
||||
}
|
||||
|
||||
$user = \Auth::user();
|
||||
|
||||
// Create token
|
||||
$token = $user->createToken('api-token')->plainTextToken;
|
||||
|
||||
return response()->json([
|
||||
'user' => $user,
|
||||
'token' => $token,
|
||||
]);
|
||||
}
|
||||
}
|
||||
117
app/Http/Controllers/Controller.php
Normal file
117
app/Http/Controllers/Controller.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
|
||||
public function log_query() {
|
||||
// , $binding, $timing 'bindings' => $binding)
|
||||
\DB::listen(function ($sql) {
|
||||
\Log::info('Showing query', array('sql' => $sql));
|
||||
//$encoded_sql = json_encode($sql);
|
||||
//$this->sendNtfy("Showing Query : " . $encoded_sql);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function validatePhoneNumber($phone){
|
||||
//265998109217
|
||||
//265881161942
|
||||
//265881161942
|
||||
//0881161942
|
||||
$phone = str_replace(' ', '', $phone);
|
||||
$phone = str_replace('+', '', $phone);
|
||||
$pattern = "/^\+?(265|0)?[89]\d{8}$/i";
|
||||
$retval = preg_match($pattern, $phone, $matches, PREG_OFFSET_CAPTURE);
|
||||
if (count($matches) < 1) {
|
||||
return false;
|
||||
}
|
||||
elseif (strlen($phone) == 9) {
|
||||
$msisdn = "265" . $phone;
|
||||
}
|
||||
elseif (strlen($phone) == 10) {
|
||||
$phone = ltrim($phone, 0);
|
||||
$msisdn = "265" . $phone;
|
||||
}
|
||||
elseif (strlen($phone) == 12) {
|
||||
$msisdn = $phone;
|
||||
}
|
||||
if (!isset($msisdn)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$prefix = substr($msisdn, 0, 4);
|
||||
|
||||
if ($prefix == '2658') {
|
||||
$network = 'tnm';
|
||||
}
|
||||
elseif ($prefix == '2659' ) {
|
||||
$network = 'airtel';
|
||||
}
|
||||
else{
|
||||
return FALSE;
|
||||
}
|
||||
return $msisdn;
|
||||
}
|
||||
public function sendNtfy($data){
|
||||
$url = 'https://ntfy.sh/airtimeSalesPortal';
|
||||
$curl = curl_init();
|
||||
curl_setopt_array($curl, array(
|
||||
CURLOPT_HTTPHEADER => array(
|
||||
'Content-Type: application/json'
|
||||
),
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_ENCODING => '',
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_TIMEOUT => 0,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
||||
CURLOPT_POSTFIELDS => $data
|
||||
));
|
||||
$response = curl_exec($curl);
|
||||
return $response;
|
||||
|
||||
}
|
||||
public function ClickADPHttp($params){
|
||||
//$api_email, $api_token
|
||||
$token = "54efd476-8d6e-483b-8b2a-c7904a8b4a6b";
|
||||
$email = "srwb.airtime@clickairtime.com";
|
||||
$X_Click_Airtime_Token = "54efd476-8d6e-483b-8b2a-c7904a8b4a6b";
|
||||
$X_Click_Airtime_Email = "reseller@clickairtime.com";
|
||||
$curl = curl_init();
|
||||
|
||||
|
||||
curl_setopt_array($curl, array(
|
||||
CURLOPT_URL => "https://api.clickairtime.com/adp",// "http://localhost:4646/api/request",
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_ENCODING => "",
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_TIMEOUT => 0,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
CURLOPT_CUSTOMREQUEST => "POST",
|
||||
CURLOPT_POSTFIELDS => json_encode($params),
|
||||
CURLOPT_HTTPHEADER => array(
|
||||
"X-Click-Airtime-Email: " . $X_Click_Airtime_Email,
|
||||
"X-Click-Airtime-Token: " . $X_Click_Airtime_Token,
|
||||
"Content-Type: application/json"
|
||||
),
|
||||
));
|
||||
|
||||
$response = curl_exec($curl);
|
||||
\Log::info(curl_getinfo($curl));
|
||||
|
||||
curl_close($curl);
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
123
app/Http/Controllers/DashboardController.php
Normal file
123
app/Http/Controllers/DashboardController.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\ActivityLog;
|
||||
use App\Models\Topup;
|
||||
use IlluminateAgnostic\Arr\Support\Carbon;
|
||||
use App\Models;
|
||||
use DB;
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
//
|
||||
public function index(){
|
||||
## DB Tables
|
||||
/*
|
||||
- merchant_top_ups - from dealers to merchants
|
||||
- organisation_top_us - from Admin to dealers
|
||||
- transactions - from merchants to end users
|
||||
*/
|
||||
|
||||
$merchant = Models\Merchant::all()->count();
|
||||
$dealers = Models\OrgUser::all()->count();
|
||||
$activities = ActivityLog::with('admin')->orderBy('created_at', 'desc')->get()->take(10);
|
||||
$dealer_topups = Models\OrganisationTopUp::with('orgInfo','userInfo')->orderBy('created_at','desc')->get();
|
||||
$merchant_topups = Models\MerchantTopUp::with('merchantInfo','orgUserInfo')->orderBy('created_at','desc')->get();
|
||||
// dd($merchant_topups);
|
||||
$current_year_transactions = Models\Transaction::whereYear('created_at', date('Y'))->get();
|
||||
$current_weeek_transactions = Models\Transaction::whereBetween('created_at', [now()->startOfWeek(), now()->endOfWeek()])->get();
|
||||
$last_weeek_transactions = Models\Transaction::whereBetween('created_at', [now()->subWeek()->startOfWeek(), now()->subWeek()->endOfWeek()])->get();
|
||||
$current_month_transactions = Models\Transaction::whereMonth('created_at', date('m'))->get();
|
||||
$current_day_transactions = Models\Transaction::whereDate('created_at', date('Y-m-d'))->get();
|
||||
#$top_merchants = Models\Transaction::select('merchant_id', 'amount')->with('merchant')->groupBy('amount', 'merchant_id')->orderByRaw('SUM(amount) DESC')->limit(4)->get();
|
||||
$top_merchants = DB::table('transactions')
|
||||
->select('transactions.merchant_id', 'merchants.fullname', DB::raw('SUM(amount) as total_amount'))
|
||||
->join('merchants', 'transactions.merchant_id', '=', 'merchants.id')
|
||||
->groupBy('fullname', 'merchant_id', 'amount')
|
||||
->orderByRaw('SUM(amount) DESC')
|
||||
->limit(4)
|
||||
->get();
|
||||
// dd($top_merchants);
|
||||
// $top_merchants_by_sales = Models\Merchant::with('transactions')->orderBy('transactions', 'desc')->get();
|
||||
// $top_dealers = Models\Organisation::with('transactions')->orderBy('transactions', 'desc')->get();
|
||||
$data = [
|
||||
'merchant_count' => $merchant,
|
||||
'dealer_count' => $dealers,
|
||||
'activities' => $activities,
|
||||
'dealer_topup_count' =>$dealer_topups->count(),
|
||||
'dealer_topup_sum' =>$dealer_topups->sum('amount'),
|
||||
'dealer_topups' => $dealer_topups->take(5),
|
||||
'merchant_topups' => $merchant_topups->take(10),
|
||||
'merchant_topup_count' => $merchant_topups->count(),
|
||||
'merchant_topup_sum' => $merchant_topups->sum('amount'),
|
||||
'current_weeek_transactions' => $current_weeek_transactions->sum('amount'),
|
||||
'current_month_transactions' => $current_month_transactions->sum('amount'),
|
||||
'last_weeek_transactions' => $last_weeek_transactions->sum('amount'),
|
||||
'current_day_transactions' => $current_day_transactions->sum('amount'),
|
||||
'top_merchants' => $top_merchants->take(5),
|
||||
// 'top_dealers' => $top_dealers->take(5),
|
||||
'transactions' => $this->transactions(),
|
||||
'current_year_transactions_sum' => $current_year_transactions->sum('amount'),
|
||||
'page_title' => 'Dashboard'
|
||||
];
|
||||
// dd($data['top_merchants']);
|
||||
return view('dashboard.index', $data);
|
||||
}
|
||||
public function transactions(){
|
||||
$transactions = \DB::table('transactions')
|
||||
->select(\DB::raw('SUM(amount) as total_sales, MONTH(created_at) as theMonth'))
|
||||
->groupByRaw('month(created_at)')
|
||||
->get();
|
||||
|
||||
/*
|
||||
$transactions = Transaction::select('id', 'created_at')->get()
|
||||
->groupBy(function($date) {
|
||||
//return Carbon::parse($date->created_at)->format('Y'); // grouping by years
|
||||
return Carbon::parse($date->created_at)->format('m'); // grouping by months
|
||||
});
|
||||
|
||||
dd($transactions);
|
||||
|
||||
$transactionmcount = [];
|
||||
$transactionArr = [];
|
||||
|
||||
foreach ($transactions as $key => $value) {
|
||||
$transactionmcount[(int)$key] = count($value);
|
||||
}
|
||||
|
||||
|
||||
for($i = 1; $i <= 12; $i++){
|
||||
if(!empty($transactionmcount[$i])){
|
||||
$transactionArr[$i] = $transactionmcount[$i];
|
||||
}else{
|
||||
$transactionArr[$i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$transactions = '';
|
||||
foreach ($transactionArr as $tran) {
|
||||
$transactions = $transactions.','.$tran;
|
||||
}
|
||||
*/
|
||||
return $transactions; //response()->json($transactions);
|
||||
|
||||
}
|
||||
public function merchant(){
|
||||
$merchant_session = session('merchant');
|
||||
$merchant = Models\Merchant::find($merchant_session->id);
|
||||
$merchant_trans = Models\Transaction::where('merchant_id',$merchant->id)->orderBy('id', 'DESC')->get();
|
||||
$data = [
|
||||
'transaction_count' => $merchant_trans->count(),
|
||||
'transactions' => $merchant_trans->take(5),
|
||||
'current_balance' => $merchant['balance'],
|
||||
'transactions_graph' => $this->merchant_transactions($merchant),
|
||||
];
|
||||
// dd($data);
|
||||
return view('dashboard.merchant',$data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
12
app/Http/Controllers/ExcelProcessingController.php
Normal file
12
app/Http/Controllers/ExcelProcessingController.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ExcelProcessingController extends Controller
|
||||
{
|
||||
public function index(){
|
||||
dd("foo bar");
|
||||
}
|
||||
}
|
||||
16
app/Http/Controllers/LandingPageController.php
Normal file
16
app/Http/Controllers/LandingPageController.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LandingPageController extends Controller
|
||||
{
|
||||
public function index(){
|
||||
$data = [
|
||||
'page_title' => 'Airtime Sales Portal',
|
||||
];
|
||||
// dd($data);
|
||||
return view('landing.index', $data);
|
||||
}
|
||||
}
|
||||
327
app/Http/Controllers/LoginController.php
Normal file
327
app/Http/Controllers/LoginController.php
Normal file
@@ -0,0 +1,327 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Validator;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
use App\Models;
|
||||
use Carbon\Carbon;
|
||||
use App\ActivityLog;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use App\Mail\ResetPassword;
|
||||
use App\Models\Merchant;
|
||||
use Session;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
|
||||
//Login page
|
||||
public function login_page(Request $request){
|
||||
// dd($request->headers->get('referer'));
|
||||
// session(['previous_page' => $request->headers->get('referer')]);
|
||||
// dd(session());
|
||||
return view('login.admin.index');
|
||||
}
|
||||
|
||||
//Login user
|
||||
public function login_user(Request $request){
|
||||
|
||||
$this->validate($request, ['email' => 'required', 'password' => 'required']);
|
||||
$email = $request->input('email');
|
||||
$password = $request->input('password');
|
||||
|
||||
$login = auth()->attempt(['email' => $email, 'password' => $password]);
|
||||
|
||||
if ($login) {
|
||||
$user = auth()->user();
|
||||
Auth::login($user, true);
|
||||
if (Auth::user()->deleted_at !== null) {
|
||||
return redirect()->back()->with('login-error', 'Account Suspended!');
|
||||
}
|
||||
|
||||
$desc = [
|
||||
'title'=>'Login',
|
||||
'data'=>$user->name,
|
||||
'type'=>'login',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = Auth::user()->id;
|
||||
$activity->user_type = 'admin';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
return redirect(url('admin'));
|
||||
}
|
||||
else {
|
||||
|
||||
return redirect()->back()->with('login-error', 'Email/Password incorrect!');
|
||||
}
|
||||
}
|
||||
|
||||
//Logout User
|
||||
public function logout(){
|
||||
|
||||
auth()->logout();
|
||||
return redirect()->to('/login');
|
||||
|
||||
}
|
||||
|
||||
//Add user
|
||||
public function add_user(){
|
||||
|
||||
$password = bcrypt('kweku20');
|
||||
|
||||
$user = new User;
|
||||
$user->name = 'Kweku Debrah';
|
||||
// $user->lastname = 'Debrah';
|
||||
$user->email='kweku.debrah.emma@gmail.com';
|
||||
$user->password = $password;
|
||||
|
||||
$save = $user->save();
|
||||
|
||||
}
|
||||
public function show_merchant_register(){
|
||||
|
||||
$data = [
|
||||
'page_title' => 'Merchant Registration',
|
||||
|
||||
];
|
||||
|
||||
return view('login.merchant.register', $data);
|
||||
}
|
||||
public function merchant_register(Request $request){
|
||||
|
||||
// $this->validate($request, [
|
||||
// 'fullname' => 'required',
|
||||
// 'phone'=> 'required|unique:merchants,phone',
|
||||
// 'language' => 'required'
|
||||
// ]);
|
||||
|
||||
$request->validate([
|
||||
'fullname' => 'required',
|
||||
'phone'=> 'required|unique:merchants,phone',
|
||||
// 'language' => 'required',
|
||||
'country_iso' => 'required', Rule::in(['MW', 'ZM'])
|
||||
], [
|
||||
'country_iso.exists' => 'Sorry, we do not currently support accounts from this country.',
|
||||
]);
|
||||
$merchant_arr = $request->except('_token');
|
||||
/*
|
||||
$phone = $this->validatePhoneNumber($request->phone);
|
||||
if ($phone == false) {
|
||||
Session::flash('error_message', 'Invalid phone number format. Check and try again');
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
*/
|
||||
//todo : make the currency and country dynamic
|
||||
$country = ($request->country_iso == 'MW') ? "MALAWI" : 'ZAMBIA';
|
||||
$currency = ($request->country_iso == 'MW') ? "MWK" : 'ZMW';
|
||||
$phone = str_replace('+', '', $request->phone);
|
||||
$merchant_arr['phone'] = $phone;
|
||||
$merchant_arr['language'] = 'english';
|
||||
$merchant_arr['country'] = $country;
|
||||
$merchant_arr['currency'] = $currency;
|
||||
$result = Models\Merchant::create($merchant_arr);
|
||||
|
||||
if ($result == null) {
|
||||
Session::flash('error_message', 'Your request could not be handled at this time. Try again later');
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
return redirect('merchant/register-success');
|
||||
}
|
||||
public function register_success(){
|
||||
$data = ['page_title' => 'Merchant Sign Successful'];
|
||||
return view('login.merchant.register-success',$data);
|
||||
}
|
||||
public function register_page(Request $request){
|
||||
|
||||
// $email = $request->input('email');
|
||||
|
||||
// $user = User::where('email', $email)->first();
|
||||
|
||||
// if ($user== null) {
|
||||
|
||||
// abort(404);
|
||||
// }
|
||||
|
||||
$data = [
|
||||
// 'user'=>$user,
|
||||
];
|
||||
return view('login.register', $data);
|
||||
}
|
||||
|
||||
public function reset_password(Request $request){
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'user' => 'required',
|
||||
'password'=>'required',
|
||||
'cpassword'=>'required',
|
||||
]);
|
||||
|
||||
if($validator->fails()){
|
||||
|
||||
return redirect()->back()->with('login-error', 'Enter required data!');
|
||||
|
||||
}
|
||||
|
||||
if ($request->input('password') !== $request->input('cpassword')) {
|
||||
|
||||
return redirect()->back()->with('login-error', 'Password dont Match!');
|
||||
|
||||
}
|
||||
|
||||
$user = $request->input('user');
|
||||
$password = $request->input('password');
|
||||
|
||||
$user = User::where('id',$user)->update([
|
||||
'password'=>bcrypt($password),
|
||||
]);
|
||||
|
||||
return redirect()->to('/login')->with('login-success', 'Password Changed Successfully, Login to continue');
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function forgot_page(){
|
||||
|
||||
return view('login.forgot');
|
||||
|
||||
}
|
||||
|
||||
public function sendResetMail(Request $request){
|
||||
|
||||
// dd($request->all());
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
|
||||
'email' => 'required',
|
||||
|
||||
]);
|
||||
|
||||
if($validator->fails()){
|
||||
|
||||
return redirect()->back()->with('login-error', 'Enter required data!');
|
||||
|
||||
}
|
||||
|
||||
$email = $request->input('email');
|
||||
|
||||
$user = User::where('email', $email)->first();
|
||||
|
||||
if ($user == null ) {
|
||||
|
||||
return redirect()->back()->with('login-error', 'Email Doesnt Exist!');
|
||||
|
||||
|
||||
}
|
||||
|
||||
$newUser = [
|
||||
|
||||
'name' => $user->name,
|
||||
'email' => $email,
|
||||
|
||||
];
|
||||
|
||||
Mail::to($email)->send(new ResetPassword($newUser));
|
||||
|
||||
return redirect()->to('/confirm-mail');
|
||||
|
||||
}
|
||||
|
||||
public function confirmMail()
|
||||
{
|
||||
return view('login.confirm');
|
||||
}
|
||||
|
||||
/**
|
||||
* Merchant Login Section
|
||||
*/
|
||||
|
||||
public function merchant_login_page(){
|
||||
|
||||
return view('login.merchant.index');
|
||||
|
||||
}
|
||||
|
||||
public function merchant_login(Request $request){
|
||||
$request->validate([
|
||||
'phone_number' => 'required|string',
|
||||
'pin' => 'required|string',
|
||||
'country_iso' => 'required', Rule::in(['MW', 'ZM'])
|
||||
], [
|
||||
'country_iso.exists' => 'Sorry, we do not currently support accounts from this country.',
|
||||
]);
|
||||
|
||||
// if($validator->fails()){
|
||||
// return redirect()->back()->with('login-error', 'Phone Number/PIN is required!');
|
||||
// }
|
||||
/*
|
||||
$phone_number = $this->validatePhoneNumber($request->phone_number);
|
||||
|
||||
if($phone_number == false){
|
||||
return redirect()->back()->with('login-error', 'Phone Number/PIN is incorrect!');
|
||||
}
|
||||
*/
|
||||
// $phone_number = $request->input('phone_number'); | use hashing
|
||||
$pin = md5($request->input('pin'));
|
||||
// dump($request->all());
|
||||
|
||||
$phone_number = str_replace('+', '', $request->phone_number);
|
||||
|
||||
$merchant = Merchant::where('phone', $phone_number)->where('pin', $pin)->first();
|
||||
// dd($merchant);
|
||||
if($merchant == null){
|
||||
return redirect()->back()->with('login-error', 'Phone Number/PIN incorrect!');
|
||||
}
|
||||
session(['merchant' => $merchant]);
|
||||
return redirect()->to('merchant/landing');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function merchant_logout(){
|
||||
|
||||
session(['merchant' => null]);
|
||||
|
||||
// return redirect()->to('/merchant/login');
|
||||
return redirect()->to('/');
|
||||
}
|
||||
|
||||
public function checkSupportedCountry(Request $request){
|
||||
$request->validate([
|
||||
'iso_code' => 'required|string|size:2'
|
||||
]);
|
||||
|
||||
$isoCode = strtoupper($request->iso_code);
|
||||
//todo retrieve this from the DB later
|
||||
// $isSupported = DB::table('supported_countries')->where('iso_code', $isoCode)->exists();
|
||||
|
||||
$supported_arr = ['MW', 'ZM'];
|
||||
|
||||
if (in_array($isoCode, $supported_arr)) {
|
||||
return response()->json(['supported' => true]);
|
||||
} else {
|
||||
return response()->json([
|
||||
'supported' => false,
|
||||
'message' => 'Sorry, we currently do not support accounts from this country.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
785
app/Http/Controllers/MerchantController.php
Normal file
785
app/Http/Controllers/MerchantController.php
Normal file
@@ -0,0 +1,785 @@
|
||||
<?php
|
||||
//this is a comment
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Merchant;
|
||||
use App\Models\Organisation;
|
||||
use App\Models\MerchantToDealerRefund;
|
||||
use App\User;
|
||||
use App\Models;
|
||||
use PragmaRX\Countries\Package\Countries;
|
||||
use Illuminate\Http\Request;
|
||||
use Carbon\Carbon;
|
||||
use App\ActivityLog;
|
||||
use Validator;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Models\Topup;
|
||||
use App\Models\Transaction;
|
||||
use App\Libs\Smsgateway;
|
||||
use Session;
|
||||
use App\Rules\PhoneValidationRule;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class MerchantController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
dd('index');
|
||||
$merchants = Models\Merchant::latest()->paginate(10);
|
||||
$data = [
|
||||
'merchants'=>$merchants,
|
||||
'merchants_list' => Models\Merchant::get(),
|
||||
'page_title' => 'merchant_list'
|
||||
];
|
||||
return view('organisation.merchants',$data);
|
||||
}
|
||||
|
||||
public function landing(){
|
||||
$merchant_session = session('merchant');
|
||||
$merchant = Models\Merchant::find($merchant_session->id);
|
||||
// dd($merchant);
|
||||
$merchant_trans = Models\Transaction::where('merchant_id', $merchant->id)->orderBy('id', 'DESC')->get();
|
||||
$data = [
|
||||
'transaction_count' => $merchant_trans->count(),
|
||||
'transaction_sum' => $merchant_trans->sum('amount'),
|
||||
'transactions' => $merchant_trans->take(15),
|
||||
'current_balance' => $merchant['balance'],
|
||||
'transactions_graph' => $this->merchant_transactions($merchant),
|
||||
'merchant' => $merchant,
|
||||
'page_title' => 'Merchant Dashboard',
|
||||
];
|
||||
// dd($data['transactions_graph']);
|
||||
return view('merchants.landing',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create(){
|
||||
$data = [
|
||||
'page_title' => 'Merchant Registration',
|
||||
];
|
||||
return view('organisation.create_merchant', $data);
|
||||
}
|
||||
|
||||
public function showrefund(){
|
||||
$merchant = session('merchant');
|
||||
$dealers = Models\Organisation::get();
|
||||
$recent_refunds = Models\MerchantToDealerRefund::with('orgInfo')->orderBy('id', 'DESC')->paginate(15);
|
||||
$data = [
|
||||
'page_title' => 'Merchant Refund',
|
||||
'dealers_arr' => $dealers,
|
||||
'recent_refunds' => $recent_refunds,
|
||||
'merchant' => $merchant
|
||||
];
|
||||
// dd($data);
|
||||
return view('merchants.refund', $data);
|
||||
}
|
||||
public function showchangepin(){
|
||||
$merchant = session('merchant');
|
||||
$data = [
|
||||
'page_title' => 'Merchant Refund',
|
||||
'merchant' => $merchant
|
||||
];
|
||||
return view('merchants.showchangepin', $data);
|
||||
}
|
||||
|
||||
public function refundStore(Request $request){
|
||||
$this->validate($request, [
|
||||
// 'dealer_id' => 'required|integer',
|
||||
// 'merchant_id' => 'required|integer',
|
||||
// 'amount' => 'required|numeric|min:0.01',
|
||||
'transaction_id' => 'required|string',
|
||||
'reason' => 'required|string',
|
||||
]);
|
||||
/*
|
||||
$merchant = Models\Merchant::find($request->merchant_id);
|
||||
if ($merchant == null) {
|
||||
return redirect()->to('merchant/refunds')->with('error_message', 'Merchant not found');
|
||||
}
|
||||
*/
|
||||
/*
|
||||
$organisation = Models\Organisation::find($request->dealer_id);
|
||||
if ($organisation == null) {
|
||||
return redirect()->to('merchant/refunds')->with('error_message', 'Dealer not found');
|
||||
}
|
||||
*/
|
||||
$transaction = Models\MerchantTopUp::with('merchantInfo', 'orgInfo')->where('status', 'success')->where('transaction_id', $request->transaction_id)->first();
|
||||
if ($transaction == null) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Transaction not found.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
|
||||
$dealer = $transaction->orgInfo; #Models\OrgUser::findOrFail($request->dealer_id);
|
||||
|
||||
if ($transaction->merchantInfo->balance < $request->amount) {
|
||||
//ask team to confirm if merchant can have a negative balance
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Insufficient merchant balance to process this refund.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
$merchant_name = $transaction->merchantInfo->fullname;
|
||||
$dealer_name = $transaction->orgInfo->name;
|
||||
$merchant = Models\Merchant::find($transaction->merchantInfo->id);
|
||||
$organisation = Models\Organisation::find($transaction->orgInfo->id);
|
||||
try {
|
||||
//todo : remove one of organisation or dealer
|
||||
DB::transaction(function () use ($request, $merchant, $organisation, $dealer, $transaction) {
|
||||
Models\MerchantToDealerRefund::create([
|
||||
'dealer_id' => $organisation->org_id,
|
||||
'merchant_id' => $transaction->merchant_id,
|
||||
'amount' => $transaction->amount,
|
||||
'dealer_msisdn' => $transaction->orgInfo->phone,
|
||||
'reason' => $request->reason,
|
||||
]);
|
||||
$merchant->decrement('balance', $transaction->amount);
|
||||
$organisation->increment('balance', $transaction->amount);
|
||||
|
||||
$desc = [
|
||||
'title' => 'Dealer Refund',
|
||||
'data' => "Refunded a dealer with an amount of " . $transaction->amount, // Typo fixed
|
||||
'type' => 'merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $request->session()->get('current_merchant.id');
|
||||
$activity->user_type = 'merchant';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
$transaction->status = 'refunded';
|
||||
$transaction->save();
|
||||
});
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("Refund Transaction Failed: " . $e->getMessage());
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => "Refund Transaction Failed: " . $e->getMessage()
|
||||
], 400);
|
||||
}
|
||||
$msg = "You have successfully refunded a dealer ($dealer_name) with an amount of $transaction->amount.";
|
||||
$dealer_msg = "You have received a refund amount of $transaction->amount from Airtime Merchant ($merchant_name).";
|
||||
|
||||
if (env('APP_ENV') !== 'local') {
|
||||
try {
|
||||
$smsgateway = new Smsgateway;
|
||||
$smsgateway->sendSmsNew($merchant->phone, $msg);
|
||||
$smsgateway->sendSmsNew($organisation->phone, $dealer_msg);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("Failed to send SMS for refund: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
\Log::info($msg);
|
||||
\Log::info($dealer_msg);
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => "Dealer Refund successfully processed! "
|
||||
], 200);
|
||||
|
||||
}
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request){
|
||||
$validatedData = $request->validate([
|
||||
'fullname' => 'required',
|
||||
// 'phone_number'=> 'required|unique:merchants,phone',
|
||||
'phone_number' => ['required', 'unique:merchants,phone', new PhoneValidationRule],
|
||||
'language' => 'required'
|
||||
]);
|
||||
/*
|
||||
$check_phone = $this->validatePhoneNumber($request->phone_number);
|
||||
if ($check_phone == false) {
|
||||
if($request->ajax()){
|
||||
return response()->json([
|
||||
'code' => 3,
|
||||
'status' => 'fail',
|
||||
'message' => 'Invalid phone number'
|
||||
]);
|
||||
}
|
||||
else{
|
||||
return redirect()->back()->withInput()->with('error_message', 'Invalid phone number!');
|
||||
}
|
||||
}
|
||||
*/
|
||||
$fullname = $request->input('fullname');
|
||||
$phone_number = $request->input('phone_number');
|
||||
$pin = rand(1000, 9999);
|
||||
|
||||
$merchant = Models\Merchant::create([
|
||||
'fullname' => $fullname,
|
||||
'phone' => $request->phone_number, // $check_phone,
|
||||
'pin' => md5($pin),
|
||||
'org_id' => session('current_org_user.org_id'),
|
||||
'language' => 'english'
|
||||
]);
|
||||
$desc = [
|
||||
'title' => 'Created a merchant',
|
||||
'data' => $fullname,
|
||||
'type' => 'merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $request->session()->get('current_org_user.id'); // org_user_id ;
|
||||
$activity->user_type = 'organisation';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
// TODO: send sms with PIN to merchant phone -
|
||||
$msg = "You have been Successfully registered as an Airtime sales merchant. Your 4-digit PIN is $pin. You will need it for all your activities. Dial *349# to begin.";
|
||||
$smsgateway = new Smsgateway;
|
||||
if(env('APP_ENV') !== 'local'){
|
||||
$result = $smsgateway->sendSmsNew($check_phone, $msg);
|
||||
}
|
||||
\Log::info($msg);
|
||||
$this->sendNtfy($msg);
|
||||
if($request->ajax()){
|
||||
return response()->json([
|
||||
'code' => 1,
|
||||
'status' => 'success',
|
||||
'message' => 'Merchant Created Successfully'
|
||||
]);
|
||||
}
|
||||
else{
|
||||
return redirect()->to('organisation/merchants')->with('success_message', 'Successfully Added New Merchant');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
// dd($id);
|
||||
// $merchant = Merchant::where('id',$id)->with('transactions')->get()[0];
|
||||
$merchant = Merchant::with('transactions')->find($id);
|
||||
$merchants = Models\Merchant::get();
|
||||
$merchant_topups = Models\MerchantTopUp::where('merchant_id', $id)->latest()->paginate(20);
|
||||
$data = [
|
||||
'merchant' => $merchant,
|
||||
'merchants_list' => $merchants,
|
||||
'page_title' => 'Merchant Details | ' . $merchant->fullname,
|
||||
'merchant_topups' => $merchant_topups,
|
||||
'merchant_id' => $id,
|
||||
];
|
||||
return view('organisation.merchant_show',$data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//
|
||||
$merchant = Models\Merchant::findOrfail($id);
|
||||
// $countries = Countries::all();
|
||||
$data = [
|
||||
'merchant' => $merchant,
|
||||
'page_title' => 'Merchant Edit',
|
||||
];
|
||||
// dd($data);
|
||||
return view('organisation.merchant_edit', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'fullname' => 'required',
|
||||
'phone'=> 'required',
|
||||
'status' => 'required',
|
||||
'language' => 'required'
|
||||
]);
|
||||
|
||||
$check_phone = $this->validatePhoneNumber($request->phone);
|
||||
if ($check_phone == false) {
|
||||
return redirect()->back()->withInput()->with('admin-error', 'Invalid phone number!');
|
||||
}
|
||||
|
||||
// dd($request->all());
|
||||
|
||||
Merchant::where('id', $id)->update([
|
||||
'fullname' => $request->fullname,
|
||||
'phone' => $check_phone,
|
||||
'language' => $request->language,
|
||||
'status' => $request->status
|
||||
]);
|
||||
|
||||
$desc = [
|
||||
'title' =>'Updated merchant',
|
||||
'data' => $request->fullname,
|
||||
'type' => 'merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = session('current_org_user.id');// organisation user ID
|
||||
$activity->user_type = 'organisation';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
return redirect()->to('organisation/merchants')->with('admin-success', 'Successfully Updated Merchant details');
|
||||
}
|
||||
|
||||
public function changePin(Request $request)
|
||||
{
|
||||
// dd($request->ajax());
|
||||
$this->validate($request, [
|
||||
'current_pin' => 'required',
|
||||
'new_pin'=> 'required',
|
||||
'merchant_id' => 'required'
|
||||
]);
|
||||
|
||||
// verify current PIN | 81dc9bdb52d04dc20036dbd8313ed055
|
||||
$current_pin = trim($request->current_pin);
|
||||
$merchant = Merchant::find($request->merchant_id);
|
||||
if(md5($current_pin) !== $merchant->pin){
|
||||
return response()->json([
|
||||
'code' => 3,
|
||||
'status' => 'failed',
|
||||
'message' => 'Current PIN is incorrect, check and try again!'
|
||||
]);
|
||||
}
|
||||
$new_pin = md5($request->new_pin);
|
||||
Merchant::where('id', $request->merchant_id)->update(['pin' => $new_pin]);
|
||||
|
||||
$desc = [
|
||||
'title' =>'Merchant PIN change',
|
||||
'data' => "PIN successfully changed for merchant ID: " . $request->merchant_id,
|
||||
'type' => 'merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = session('current_org_user.id');// organisation user ID
|
||||
$activity->user_type = 'organisation';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
return response()->json([
|
||||
'code' => 1,
|
||||
'status' => 'success',
|
||||
'message' => 'PIN Successfully Changed!'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
|
||||
Models\Merchant::where('id', $id)->update([
|
||||
'status' => 'disabled',
|
||||
]);
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = session('current_org_user.id'); // organisation user ID
|
||||
$activity->user_type = 'organisation';
|
||||
$activity->description = 'disabled a merchant with ID : ' . $id ;
|
||||
$activity->save();
|
||||
|
||||
return redirect()->to('organisation/merchant')->with('admin-sucsess', 'Successfully Disabled Merchant');
|
||||
}
|
||||
public function enable($id)
|
||||
{
|
||||
|
||||
Models\Merchant::where('id', $id)->update([
|
||||
'status'=>'active',
|
||||
]);
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = session('current_org_user.id');
|
||||
$activity->user_type = 'organisation';
|
||||
$activity->description = 'enable a merchant with ID : ' . $id ;
|
||||
$activity->save();
|
||||
|
||||
return redirect()->to('/organisation/merchant')->with('admin-sucsess', 'Successfully Enabled Merchant');
|
||||
}
|
||||
|
||||
|
||||
public function addTopUp(Request $request){
|
||||
|
||||
// dd($request->all());
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
|
||||
'amount' => 'required',
|
||||
'payment'=>'required',
|
||||
'merchant'=>'required',
|
||||
|
||||
]);
|
||||
|
||||
if($validator->fails()){
|
||||
return redirect()->back()->with('admin-error', 'Enter required data!');
|
||||
}
|
||||
|
||||
$amount = $request->input('amount');
|
||||
$payment = $request->input('payment');
|
||||
$merchant = $request->input('merchant');
|
||||
|
||||
$topup = new TopUp;
|
||||
$topup->amount = $amount;
|
||||
$topup->merchant_id = $merchant;
|
||||
$topup->created_by = $request->session()->get('current_org_user.id');
|
||||
$topup->payment_method = $payment;
|
||||
$save = $topup->save();
|
||||
|
||||
//Update Merchant Amt //
|
||||
Models\Merchant::where('id', $merchant)->increment('balance', $amount);
|
||||
|
||||
if ($save) {
|
||||
|
||||
$merchant = Models\Merchant::find($merchant);
|
||||
|
||||
$desc = [
|
||||
'title'=>'Added new Top Up',
|
||||
'data'=>'K ' .$topup->amount.' for '.$merchant->fullname.' payment by '.$payment,
|
||||
'type'=>'topup',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $request->session()->get('current_org_user.id');
|
||||
$activity->user_type = 'organisation';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
return redirect()->to('/organisation/merchant/'.$merchant->id)->with('admin-sucsess', 'Successfully Added Top Up');
|
||||
|
||||
} else {
|
||||
|
||||
return redirect()->back()->with('admin-error', 'Error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function transactions(){
|
||||
$merchant = session('merchant');
|
||||
// $transactions = Transaction::where('merchant_id', $merchant->id)->latest()->paginate(20);
|
||||
$data = [
|
||||
// 'transactions'=>$transactions,
|
||||
'merchant' => $merchant,
|
||||
'page_title' => 'Merchant Transactions',
|
||||
];
|
||||
return view('merchants.transactions',$data);
|
||||
}
|
||||
public function getTransactionsJson(Request $request){
|
||||
$merchant_id = session('merchant.id');
|
||||
$transactions_arr = \DB::table('transactions')
|
||||
->join('merchants', 'transactions.merchant_id', '=', 'merchants.id')
|
||||
->select('merchants.fullname', 'transactions.id', 'transactions.status', 'transactions.msisdn', 'transactions.amount', 'transactions.created_at')
|
||||
->whereRaw('transactions.merchant_id = '. $merchant_id)
|
||||
->orderBy('transactions.created_at', 'DESC')
|
||||
->paginate(20);
|
||||
|
||||
if($request->has('keyword')){
|
||||
$queries = [];
|
||||
$keyword = $request->keyword;
|
||||
$queries['keyword'] = $keyword;
|
||||
$transactions_arr = \DB::table('transactions')
|
||||
// ->join('org_users', 'transactions.org_user_id', '=', 'org_users.id')
|
||||
->join('merchants', 'transactions.merchant_id', '=', 'merchants.id')
|
||||
->select('merchants.fullname', 'transactions.id', 'transactions.status', 'transactions.msisdn', 'transactions.amount', 'transactions.created_at')
|
||||
->whereRaw("merchants.fullname LIKE '%$keyword%' OR transactions.msisdn LIKE '%$keyword%' OR transactions.status LIKE '%$keyword%' OR transactions.amount LIKE '%$keyword%' OR transactions.created_at LIKE '%$keyword%'")
|
||||
->whereRaw('transactions.merchant_id = '. $merchant_id)
|
||||
->orderBy('transactions.created_at', 'DESC')
|
||||
->paginate(20)->appends($queries);
|
||||
}
|
||||
return response()->json($transactions_arr);
|
||||
}
|
||||
|
||||
public function dealer_transactions(){
|
||||
$merchant = session('merchant');
|
||||
$data = [
|
||||
'merchant' => $merchant,
|
||||
'page_title' => 'Dealer Transactions',
|
||||
];
|
||||
// dd($data);
|
||||
return view('merchants.dealer-transactions',$data);
|
||||
}
|
||||
public function getDealerListJson(Request $request){
|
||||
$merchant_id = session('merchant.id');
|
||||
$dealer_arr = \DB::table('organisations')->orderBy('organisations.created_at', 'DESC')->paginate(20);
|
||||
|
||||
if($request->has('keyword')){
|
||||
$queries = [];
|
||||
$keyword = $request->keyword;
|
||||
$queries['keyword'] = $keyword;
|
||||
$dealer_arr = \DB::table('organisations')
|
||||
->whereRaw("name LIKE '%$keyword%' OR phone LIKE '%$keyword%' OR status LIKE '%$keyword%' OR email LIKE '%$keyword%' OR created_at LIKE '%$keyword%'")
|
||||
->orderBy('created_at', 'DESC')
|
||||
->paginate(20)->appends($queries);
|
||||
}
|
||||
return response()->json($dealer_arr);
|
||||
}
|
||||
public function get_dealers(){
|
||||
$merchant = session('merchant');
|
||||
$data = [
|
||||
'merchant' => $merchant,
|
||||
'page_title' => 'Dealers',
|
||||
];
|
||||
return view('merchants.dealer-list', $data);
|
||||
}
|
||||
public function getDealerTransactionsJson(Request $request){
|
||||
$merchantId = session('merchant.id');
|
||||
|
||||
$query = \DB::table('merchant_top_ups')
|
||||
->join('merchants', 'merchant_top_ups.merchant_id', '=', 'merchants.id')
|
||||
->join('org_users', 'merchant_top_ups.org_user_id', '=', 'org_users.id')
|
||||
->select([
|
||||
'merchants.fullname',
|
||||
'org_users.phone',
|
||||
'org_users.name',
|
||||
// 'merchant_top_ups.id',
|
||||
'merchant_top_ups.transaction_id',
|
||||
'merchant_top_ups.status',
|
||||
'merchant_top_ups.amount',
|
||||
'merchant_top_ups.created_at',
|
||||
])
|
||||
->where('merchant_top_ups.merchant_id', $merchantId)
|
||||
->orderByDesc('merchant_top_ups.created_at');
|
||||
|
||||
if ($request->filled('keyword')) {
|
||||
$keyword = $request->input('keyword');
|
||||
$like = '%' . $keyword . '%';
|
||||
|
||||
$query->where(function ($q) use ($like, $keyword) {
|
||||
$q->where('org_users.phone', 'like', $like)
|
||||
->orWhere('org_users.name', 'like', $like)
|
||||
->orWhere('merchants.fullname', 'like', $like)
|
||||
->orWhere('merchant_top_ups.status', 'like', $like)
|
||||
->orWhere('merchant_top_ups.amount', 'like', $like)
|
||||
->orWhere('merchant_top_ups.created_at', 'like', $like);
|
||||
});
|
||||
}
|
||||
|
||||
$transactions = $query->paginate(20);
|
||||
|
||||
if ($request->filled('keyword')) {
|
||||
$transactions->appends(['keyword' => $request->input('keyword')]);
|
||||
}
|
||||
|
||||
return response()->json($transactions);
|
||||
}
|
||||
|
||||
public function showCustomerTopForm(){
|
||||
|
||||
//$merchant = Merchant::where('id',$id)->with('transactions')->get()[0];
|
||||
$data = [
|
||||
'page_title' => 'Customer Top Up',
|
||||
'page_title' => 'merchant_topups'
|
||||
];
|
||||
return view('merchant.customer-topup',$data);
|
||||
}
|
||||
|
||||
public function customerTopupStore(Request $request){
|
||||
$this->validate($request, [
|
||||
'phone_number'=> 'required|numeric',
|
||||
'amount' => 'required|numeric|min:1'
|
||||
]);
|
||||
$phone_number = preg_replace('/[+\s]+/', '', $request->phone_number); // preg_replace('/\s+/', '', $request->phone_number);
|
||||
/*
|
||||
$check_phone = $this->validatePhoneNumber($phone_number);
|
||||
if ($check_phone == false) {
|
||||
return redirect()->back()->withInput()->with('admin-error', 'Invalid phone number!');
|
||||
}
|
||||
*/
|
||||
$merchant_session = session('merchant');
|
||||
$merchant = Models\Merchant::find($merchant_session['id']);
|
||||
// dd($merchant);
|
||||
$country_prefix = substr($phone_number, 0, 3);
|
||||
// dd($country_prefix);
|
||||
$country = '';
|
||||
switch ($country_prefix) {
|
||||
case '265':
|
||||
$country = 'MALAWI';
|
||||
break;
|
||||
case '260':
|
||||
$country = 'ZAMBIA';
|
||||
break;
|
||||
|
||||
default:
|
||||
$country = '';
|
||||
break;
|
||||
}
|
||||
if ($merchant->country !== $country) {
|
||||
// find out from team
|
||||
return redirect()->back()->withInput()->with('admin-error', 'Country not allowed!');
|
||||
}
|
||||
$difference = $merchant->balance - $request->amount;
|
||||
if ($merchant->balance < $request->amount) {
|
||||
return redirect()->back()->withInput()->with('admin-error', 'Insufficient balance!');
|
||||
}
|
||||
$prev_balance = $merchant->balance;
|
||||
|
||||
//get merchant ID, amount, msisdn,
|
||||
$extRefId = uniqid() . '-' . date('YmdHis');
|
||||
#$last_insert_id = saveTransaction($session_data['top_up_phone'], $session_data['top_up_amount'], $session_data['merchant_id'], $extRefId);
|
||||
$transaction_arr = [
|
||||
'msisdn' => $phone_number,
|
||||
'amount' => $request->amount,
|
||||
'merchant_id' => $merchant->id,
|
||||
'session_id' => $extRefId
|
||||
];
|
||||
// dd($transaction_arr);
|
||||
$trans_result = Models\Transaction::create($transaction_arr);
|
||||
$transaction_id = $trans_result->id;
|
||||
|
||||
$click_params = [
|
||||
"msisdn" => $phone_number,
|
||||
"amount" => $request->amount,
|
||||
"extRefId" => $extRefId
|
||||
];
|
||||
\Log::info($click_params);
|
||||
//$merchant->orgInfo->api_email, $merchant->orgInfo->api_token
|
||||
$topup_result = $this->ClickADPHttp($click_params); // Click ADP
|
||||
|
||||
\Log::info($topup_result);
|
||||
|
||||
$this->sendNtfy($topup_result);
|
||||
$topup_result_arr = json_decode($topup_result, TRUE);
|
||||
|
||||
\Log::info($topup_result_arr);
|
||||
if ($topup_result == false) {
|
||||
return redirect()->back()->withInput()->with('admin-error', 'Top Up Could not be processed at this time. Try again later!');
|
||||
}
|
||||
$log_data = [
|
||||
'msisdn' => $phone_number,
|
||||
'amount' => $request->tamount,
|
||||
'user_id' => $merchant->id,
|
||||
'merchant_balance' => $merchant->balance,
|
||||
'session_id' => $extRefId,
|
||||
'status' => $topup_result_arr,
|
||||
'network' => 'n.a'
|
||||
];
|
||||
$desc = [
|
||||
'title' =>'customer top up by Merchant ID ' . $merchant->id,
|
||||
'data' => $log_data,
|
||||
'type' => 'merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $merchant->id;
|
||||
$activity->user_type = 'merchant';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
|
||||
if ($topup_result_arr['code'] == 1) {
|
||||
|
||||
$merchant_update = Models\Merchant::find($merchant->id);
|
||||
$merchant_update->balance = $prev_balance - $request->amount;
|
||||
$merchant_update->save();
|
||||
$desc = [
|
||||
'title' =>'Successful customer top up by Merchant ID ' . $merchant->id,
|
||||
'data' => ['previous_balance' => $merchant->balance, 'current_balance' => $merchant->balance - $request->amount],
|
||||
'type' => 'merchant',
|
||||
];
|
||||
#update transactions
|
||||
$transaction = Models\Transaction::find($transaction_id);
|
||||
$transaction->status = $topup_result_arr['message'];
|
||||
$transaction->save();
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $merchant->id;
|
||||
$activity->user_type = 'merchant';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
Session::flash('success_message', 'Top Up Successfully processed!');
|
||||
return redirect('merchant');
|
||||
}
|
||||
return redirect('merchant/transactions');
|
||||
}
|
||||
|
||||
public function merchant_transactions($merchant){
|
||||
|
||||
$transactions = Models\Transaction::where('merchant_id', $merchant->id)->select('id', 'created_at')->get()
|
||||
->groupBy(function($date) {
|
||||
//return Carbon::parse($date->created_at)->format('Y'); // grouping by years
|
||||
return Carbon::parse($date->created_at)->format('m'); // grouping by months
|
||||
});
|
||||
$transactionmcount = [];
|
||||
$transactionArr = [];
|
||||
|
||||
return response()->json(['transactions' => $transactions]);
|
||||
|
||||
$pp = 1;
|
||||
$trans = [];
|
||||
foreach ($transactions as $value) {
|
||||
if ($pp == $value) {
|
||||
$trans[$pp]= $value;
|
||||
}
|
||||
else{
|
||||
$trans[$pp] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
foreach ($transactions as $key => $value) {
|
||||
$transactionmcount[(int)$key] = count($value);
|
||||
}
|
||||
for($i = 1; $i <= 12; $i++){
|
||||
if(!empty($transactionmcount[$i])){
|
||||
$transactionArr[$i] = $transactionmcount[$i];
|
||||
}else{
|
||||
$transactionArr[$i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$transactions = '';
|
||||
foreach ($transactionArr as $tran) {
|
||||
$transactions = $transactions.','.$tran;
|
||||
}
|
||||
return $transactions;
|
||||
}
|
||||
public function merchant_transactions_graph($merchant_id = 1){
|
||||
$transactions = Models\Transaction::where('merchant_id', $merchant_id)->pluck('amount', 'created_at');
|
||||
// return response()->json($transactions);
|
||||
// dump($transactions);
|
||||
return $transactions;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getActivity()
|
||||
{
|
||||
//
|
||||
$merchant = session('merchant');
|
||||
$activities = ActivityLog::with('admin')->where('user_type', 'merchant')->where('user_id', $merchant->id)
|
||||
->orderBy('created_at', 'desc')->paginate(30);
|
||||
$data = [
|
||||
'activities' => $activities,
|
||||
'merchant' => $merchant,
|
||||
'page_title' => 'Merchant Activity Log'
|
||||
];
|
||||
return view('merchants.activity', $data);
|
||||
}
|
||||
}
|
||||
202
app/Http/Controllers/OrganisationLoginController.php
Normal file
202
app/Http/Controllers/OrganisationLoginController.php
Normal file
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\User;
|
||||
use Carbon\Carbon;
|
||||
use App\ActivityLog;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use App\Mail\ResetPassword;
|
||||
use App\Models\Merchant;
|
||||
use Validator;
|
||||
use App\Models;
|
||||
use Session;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
|
||||
class OrganisationLoginController extends Controller
|
||||
{
|
||||
|
||||
public function login_page(Request $request){
|
||||
|
||||
session(['pre_page' => $request->headers->get('referer')]);
|
||||
|
||||
return view('login.organisation.index');
|
||||
}
|
||||
//Add user
|
||||
public function add_user(){
|
||||
dd('foo bar');
|
||||
// $password = bcrypt('kweku20');
|
||||
|
||||
// $user = new User;
|
||||
// $user->name = 'Kweku Debrah';
|
||||
// // $user->lastname = 'Debrah';
|
||||
// $user->email='kweku.debrah.emma@gmail.com';
|
||||
// $user->password = $password;
|
||||
|
||||
$save = $user->save();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function register_page(){
|
||||
$data = ['page_title' => 'Dealer Sign Up'];
|
||||
return view('login.organisation.register',$data);
|
||||
}
|
||||
public function register_success(){
|
||||
$data = ['page_title' => 'Dealer Sign Successful'];
|
||||
return view('login.organisation.register-success',$data);
|
||||
}
|
||||
public function register(Request $request){
|
||||
$this->validate($request, [
|
||||
'name' => 'required',
|
||||
'phone'=> 'required|unique:organisations,phone',
|
||||
'email' => 'required'
|
||||
]);
|
||||
$org_arr = $request->except('_token');
|
||||
$phone = $this->validatePhoneNumber($request->phone);
|
||||
// dd($phone);
|
||||
if ($phone == false) {
|
||||
Session::flash('error_message', 'Invalid phone number format. Check and try again');
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
$org_arr['phone'] = $phone;
|
||||
$result = Models\Organisation::create($org_arr);
|
||||
|
||||
if ($result == null) {
|
||||
Session::flash('error_message', 'Your request could not be handled at this time. Try again later');
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
return redirect('dealer/register-success');
|
||||
}
|
||||
|
||||
public function resetpassword(Request $request){
|
||||
|
||||
$this->validate($request, [
|
||||
'user_id' => 'required',
|
||||
'current_password' => 'required',
|
||||
'new_password' => 'required',
|
||||
'confirm_password' => 'required'
|
||||
]);
|
||||
|
||||
|
||||
// if($validator->fails()){
|
||||
// return redirect()->back()->with('login-error', 'Enter required data!');
|
||||
// }
|
||||
|
||||
$org_user = Models\OrgUser::find($request->user_id);
|
||||
if (!Hash::check($request->current_password, $org_user->password)) {
|
||||
return redirect()->back()->with('login-error', 'Incorrect current password!');
|
||||
}
|
||||
if ($request->input('new_password') !== $request->input('confirm_password')) {
|
||||
return redirect()->back()->with('login-error', 'New Passwords do not match!');
|
||||
}
|
||||
$new_password = Hash::make($request->new_password);
|
||||
$user = Models\OrgUser::where('id', $request->user_id)->update([
|
||||
'password' => $new_password,
|
||||
]);
|
||||
return redirect()->to('organisation/reset-password')->with('login-success', 'Password Changed Successfully, Login to continue');
|
||||
|
||||
}
|
||||
|
||||
public function forgot_page(){
|
||||
return view('login.forgot');
|
||||
}
|
||||
public function resetCreate(){
|
||||
$user = session('current_org_user');
|
||||
|
||||
$data = [
|
||||
'user' => $user,
|
||||
'page_title' => 'Password Reset'
|
||||
];
|
||||
return view('organisation.reset', $data);
|
||||
}
|
||||
|
||||
public function sendResetMail(Request $request){
|
||||
|
||||
// dd($request->all());
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
|
||||
'email' => 'required',
|
||||
|
||||
]);
|
||||
|
||||
if($validator->fails()){
|
||||
|
||||
return redirect()->back()->with('login-error', 'Enter required data!');
|
||||
|
||||
}
|
||||
$email = $request->input('email');
|
||||
$user = User::where('email', $email)->first();
|
||||
if ($user == null ) {
|
||||
return redirect()->back()->with('login-error', 'Email Doesnt Exist!');
|
||||
}
|
||||
|
||||
$newUser = [
|
||||
|
||||
'name' => $user->name,
|
||||
'email' => $email,
|
||||
|
||||
];
|
||||
|
||||
Mail::to($email)->send(new ResetPassword($newUser));
|
||||
|
||||
return redirect()->to('/confirm-mail');
|
||||
|
||||
}
|
||||
|
||||
public function confirmMail()
|
||||
{
|
||||
return view('login.confirm');
|
||||
}
|
||||
public function handleLogin(Request $request){
|
||||
// $this->log_query();
|
||||
$validator = Validator::make($request->all(), [
|
||||
'email' => 'required|email',
|
||||
'password' =>'required'
|
||||
]);
|
||||
|
||||
|
||||
if($validator->fails()){
|
||||
return redirect()->back()->with('login-error', 'Email/Password required!');
|
||||
}
|
||||
$org_user = Models\OrgUser::with('org_info')->where('email', $request->email)->first();
|
||||
// dd($org_user);
|
||||
if($org_user == null){
|
||||
return redirect()->back()->with('login-error', 'Email/Password Incorrect!');
|
||||
}
|
||||
|
||||
if (Hash::check($request->password, $org_user->password)) {
|
||||
$request->session()->regenerate(true);
|
||||
$request->session()->put('current_org_user.id', $org_user->id);
|
||||
$request->session()->put('current_org_user.name', $org_user->name);
|
||||
$request->session()->put('current_org_user.email', $org_user->email);
|
||||
$request->session()->put('current_org_user.org_id', $org_user->id); //remove this in the next update
|
||||
$request->session()->put('current_org_user.org_name', $org_user->org_info->name);
|
||||
$request->session()->put('current_org_user.currency', $org_user->org_info->currency);
|
||||
|
||||
$desc = [
|
||||
'title' => 'Login',
|
||||
'data' => $org_user->name . ' Successful login'
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $request->session()->get('current_org_user.id');
|
||||
$activity->user_type = 'organisation';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
return redirect()->to('organisation');
|
||||
}
|
||||
else{
|
||||
return redirect()->back()->with('login-error', 'Email or Password incorrect!');
|
||||
}
|
||||
}
|
||||
public function logout(){
|
||||
session(['current_org_user' => null]);
|
||||
// return redirect()->to('/organisation/login');
|
||||
return redirect()->to('/');
|
||||
}
|
||||
}
|
||||
334
app/Http/Controllers/OrganisationsController.php
Normal file
334
app/Http/Controllers/OrganisationsController.php
Normal file
@@ -0,0 +1,334 @@
|
||||
<?php
|
||||
//dealers are not using the OrgUsers like SRWB
|
||||
namespace App\Http\Controllers;
|
||||
use App\Models;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Libs\Smsgateway;
|
||||
use Session;
|
||||
use App\ActivityLog;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
|
||||
class OrganisationsController extends Controller
|
||||
{
|
||||
public function index(){
|
||||
$org_user = session('current_org_user');
|
||||
// dd($org_user);
|
||||
$merchants = Models\Merchant::where('org_id', $org_user['org_id'])->latest()->paginate(20);
|
||||
$data = [
|
||||
'merchants_list' => $merchants,
|
||||
'merchants' => $merchants,
|
||||
'page_title' => 'Merchants',
|
||||
'org_user' => $org_user,
|
||||
];
|
||||
return view('organisation.merchants',$data);
|
||||
}
|
||||
public function landing(){
|
||||
$org_user = session('current_org_user');
|
||||
$merchants = Models\Merchant::get(); // to be used for tops in the dropdown
|
||||
$dealer = Models\OrgUser::find($org_user['org_id']);
|
||||
$merchant_ids = $merchants->pluck('id');
|
||||
$merchant_topups = Models\MerchantTopUp::with('merchantInfo')->where('org_user_id', $org_user['id'])->orderBy('id', 'DESC')->get();
|
||||
$data = [
|
||||
'transaction_count' => $merchant_topups->count(),
|
||||
'merchants' => $merchants,
|
||||
'merchant_topups' => $merchant_topups->take(5),
|
||||
'organisation' => $dealer,
|
||||
'page_title' => 'Dashboard'
|
||||
];
|
||||
return view('organisation.landing',$data);
|
||||
}
|
||||
public function transactions(){
|
||||
$org_user = session('current_org_user');
|
||||
$data = [
|
||||
// 'merchant_topups' => $merchant_topups,
|
||||
'org_user' => $org_user,
|
||||
'page_title' => 'Dealer Transactions'
|
||||
];
|
||||
return view('organisation.transactions', $data);
|
||||
}
|
||||
public function getTransactionsJson(Request $request){
|
||||
$dealer_id = session('current_org_user.id');
|
||||
$transactions_arr = \DB::table('merchant_top_ups')
|
||||
->join('org_users', 'merchant_top_ups.org_user_id', '=', 'org_users.id')
|
||||
->join('merchants', 'merchant_top_ups.merchant_id', '=', 'merchants.id')
|
||||
->select('merchant_top_ups.id', 'merchant_top_ups.status', 'merchants.phone', 'merchants.fullname', 'merchant_top_ups.payment_method', 'merchant_top_ups.org_user_id', 'merchant_top_ups.amount', 'merchant_top_ups.created_at')
|
||||
->whereRaw('merchant_top_ups.org_user_id = '. $dealer_id)
|
||||
->orderBy('merchant_top_ups.created_at', 'DESC')
|
||||
->paginate(10);
|
||||
|
||||
if($request->has('keyword')){
|
||||
$queries = [];
|
||||
$keyword = $request->keyword;
|
||||
$queries['keyword'] = $keyword;
|
||||
$transactions_arr = \DB::table('merchant_top_ups')
|
||||
->join('org_users', 'merchant_top_ups.org_user_id', '=', 'org_users.id')
|
||||
->join('merchants', 'merchant_top_ups.merchant_id', '=', 'merchants.id')
|
||||
->select('merchant_top_ups.id', 'merchant_top_ups.status', 'merchants.phone', 'merchants.fullname', 'merchant_top_ups.payment_method', 'merchant_top_ups.org_user_id', 'merchant_top_ups.amount', 'merchant_top_ups.created_at')
|
||||
->whereRaw("merchants.fullname LIKE '%$keyword%' OR merchants.phone LIKE '%$keyword%' OR merchant_top_ups.status LIKE '%$keyword%' OR merchant_top_ups.payment_method LIKE '%$keyword%' OR merchant_top_ups.amount LIKE '%$keyword%' OR merchant_top_ups.created_at LIKE '%$keyword%'")
|
||||
->whereRaw('merchant_top_ups.org_user_id = '. $dealer_id)
|
||||
->orderBy('merchant_top_ups.created_at', 'DESC')
|
||||
->paginate(10)->appends($queries);
|
||||
}
|
||||
return response()->json($transactions_arr);
|
||||
}
|
||||
public function mytopups(){
|
||||
$org_user = session('current_org_user');
|
||||
$data = [
|
||||
'org_user' => $org_user,
|
||||
'page_title' => 'My Top Ups'
|
||||
];
|
||||
return view('organisation.mytopups', $data);
|
||||
}
|
||||
public function getMyTopUpsJson(Request $request){
|
||||
$dealer_id = session('current_org_user.id');
|
||||
$transactions_arr = \DB::table('organisation_top_ups')
|
||||
->join('org_users', 'organisation_top_ups.org_id', '=', 'org_users.org_id')
|
||||
->join('users', 'organisation_top_ups.user_id', '=', 'users.id')
|
||||
->select('organisation_top_ups.id', 'organisation_top_ups.status', 'org_users.phone', 'users.name', 'organisation_top_ups.payment_method', 'organisation_top_ups.org_id', 'organisation_top_ups.amount', 'organisation_top_ups.created_at')
|
||||
->whereRaw('organisation_top_ups.org_user_id = '. $dealer_id)
|
||||
->orderBy('organisation_top_ups.created_at', 'DESC')
|
||||
->paginate(10);
|
||||
|
||||
if($request->has('keyword')){
|
||||
$queries = [];
|
||||
$keyword = $request->keyword;
|
||||
$queries['keyword'] = $keyword;
|
||||
$transactions_arr = \DB::table('organisation_top_ups')
|
||||
->join('org_users', 'organisation_top_ups.org_user_id', '=', 'org_users.id')
|
||||
->join('users', 'organisation_top_ups.user_id', '=', 'users.id')
|
||||
->select('organisation_top_ups.id', 'organisation_top_ups.status', 'org_users.phone', 'users.name', 'organisation_top_ups.payment_method', 'organisation_top_ups.org_id', 'organisation_top_ups.amount', 'organisation_top_ups.created_at')
|
||||
->whereRaw("org_users.name LIKE '%$keyword%' OR org_users.phone LIKE '%$keyword%' OR organisation_top_ups.status LIKE '%$keyword%' OR organisation_top_ups.payment_method LIKE '%$keyword%' OR organisation_top_ups.amount LIKE '%$keyword%' OR organisation_top_ups.created_at LIKE '%$keyword%'")
|
||||
->whereRaw('organisation_top_ups.org_user_id = '. $dealer_id)
|
||||
->orderBy('organisation_top_ups.created_at', 'DESC')
|
||||
->paginate(10)->appends($queries);
|
||||
}
|
||||
return response()->json($transactions_arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
|
||||
$merchant = Merchant::where('id',$id)->with('transactions')->get()[0];
|
||||
$data = [
|
||||
'merchant'=>$merchant,
|
||||
];
|
||||
return view('merchant.show',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//
|
||||
$merchant = Merchant::findorfail($id);
|
||||
$countries = Countries::all();
|
||||
|
||||
$data = [
|
||||
'countries'=>$countries,
|
||||
'merchant'=>$merchant,
|
||||
];
|
||||
return \view('merchant.update',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'fullname' => 'required',
|
||||
'phone_number'=> 'required',
|
||||
'language' => 'required'
|
||||
]);
|
||||
$check_phone = $this->validatePhoneNumber($request->phone_number);
|
||||
if ($check_phone == false) {
|
||||
return redirect()->back()->withInput()->with('admin-error', 'Invalid phone number!');
|
||||
}
|
||||
|
||||
|
||||
Merchant::where('id', $id)->update([
|
||||
'fullname'=> $request->fullname,
|
||||
'phone'=> $check_phone,
|
||||
'language' => $request->language
|
||||
]);
|
||||
|
||||
$desc = [
|
||||
'title' =>'updated a merchant',
|
||||
'data' => $request->fullname,
|
||||
'type' => 'merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $request->session()->get('current_org_user.id');
|
||||
$activity->user_type = 'dealer';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
return redirect()->to('/admin/merchant')->with('admin-sucsess', 'Successfully Updated Merchant');
|
||||
|
||||
}
|
||||
public function merchantTopupOtpStore(Request $request){
|
||||
|
||||
$org_id = $request->session()->get('current_org_user.org_id');
|
||||
$org_otp = random_int(1000, 9999);
|
||||
$dealer = Models\OrgUser::where('org_id', $org_id)->first();
|
||||
$smsgateway = new Smsgateway;
|
||||
$request->session()->put('current_org_user.otp', $org_otp);
|
||||
$msg = "Hello $dealer->name, your one time PIN is $org_otp. Enter this on the form to complete the top up.";
|
||||
|
||||
if(env('APP_ENV') !== 'local'){
|
||||
$message_result = $smsgateway->sendSmsNew($dealer->phone, $msg);
|
||||
}
|
||||
\Log::info($msg);
|
||||
//$this->sendNtfy($msg);
|
||||
$lastThree = substr($dealer->phone, -3);
|
||||
return response()->json([
|
||||
'code' => 1,
|
||||
'status' => 'success',
|
||||
'message' => "An OTP has been sent to your phone number ending ... $lastThree. Enter this on the form to complete the top up."
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function merchantTopupStore(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'merchant' => 'required|exists:merchants,id',
|
||||
'amount' => 'required|numeric|min:1',
|
||||
]);
|
||||
|
||||
$currentUser = $request->session()->get('current_org_user');
|
||||
|
||||
$orgId = $currentUser['org_id'];
|
||||
$userId = $currentUser['id'];
|
||||
$amount = (float) $request->amount;
|
||||
|
||||
$dealer = Models\OrgUser::findOrFail($orgId);
|
||||
$merchant = Models\Merchant::findOrFail($request->merchant);
|
||||
|
||||
if ($amount > $dealer->balance) {
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json([
|
||||
'code' => 3,
|
||||
'status' => 'failed',
|
||||
'message' => 'Insufficient Balance.'
|
||||
]);
|
||||
}
|
||||
Session::flash('success_message', 'Insufficient Balance!!');
|
||||
return back()->withInput()->withErrors(['amount' => 'Insufficient Balance.']);
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
$topup = Models\MerchantTopUp::create([
|
||||
'merchant_id' => $merchant->id,
|
||||
// 'org_id' => $orgId,
|
||||
'amount' => $amount,
|
||||
'transaction_id' => 'MCH-' . Str::uuid(),
|
||||
'org_user_id' => $userId,
|
||||
'created_by' => $userId,
|
||||
'payment_method' => 'cash'
|
||||
]);
|
||||
|
||||
$merchant->increment('balance', $amount);
|
||||
$dealer->decrement('balance', $amount);
|
||||
|
||||
DB::commit();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
\Log::error($e);
|
||||
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json([
|
||||
'code' => 3,
|
||||
'status' => 'failed',
|
||||
'message' => 'Merchant Top Up failed.'
|
||||
]);
|
||||
}
|
||||
Session::flash('error_message', 'Merchant Top Up failed!!');
|
||||
return back()->withInput()->with('error', 'Merchant Top Up failed.');
|
||||
}
|
||||
|
||||
ActivityLog::create([
|
||||
'user_id' => $userId,
|
||||
'user_type' => 'dealer',
|
||||
'description' => json_encode([
|
||||
'title' => 'dealer Added new Top Up',
|
||||
'data' => 'MWK ' . number_format($amount, 2) . ' for ' . $merchant->fullname,
|
||||
'type' => 'Dealer topup'
|
||||
])
|
||||
]);
|
||||
|
||||
$merchant->refresh();
|
||||
|
||||
try {
|
||||
if (!app()->environment('local')) {
|
||||
(new Smsgateway())->sendSmsNew(
|
||||
$merchant->phone,
|
||||
"Hello {$merchant->fullname}, your account has been credited with MWK {$amount}. Your new balance is MWK {$merchant->balance}."
|
||||
);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json([
|
||||
'code' => 1,
|
||||
'status' => 'success',
|
||||
'message' => 'Merchant Top Up Successfully completed.'
|
||||
]);
|
||||
}
|
||||
Session::flash('success_message', 'Merchant Top Up Successfully completed!!');
|
||||
return back()->with('success', 'Merchant Top Up Successfully completed.');
|
||||
}
|
||||
|
||||
public function getActivity()
|
||||
{
|
||||
//
|
||||
$org_user = session('current_org_user');
|
||||
$activities = ActivityLog::with('admin')->where('user_type', 'dealer')
|
||||
->where('user_id', $org_user['id'])
|
||||
->orderBy('created_at', 'desc')
|
||||
->paginate(20);
|
||||
|
||||
$data = [
|
||||
'activities' => $activities,
|
||||
'org_user' => $org_user,
|
||||
'page_title' => 'Dealer Activity Log'
|
||||
];
|
||||
return view('organisation.activity', $data);
|
||||
}
|
||||
}
|
||||
28
app/Http/Controllers/ResellersController.php
Normal file
28
app/Http/Controllers/ResellersController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use PragmaRX\Countries\Package\Countries;
|
||||
use Carbon\Carbon;
|
||||
|
||||
use App\ActivityLog;
|
||||
use Mode\Models;
|
||||
use App\Libs\Smsgateway;
|
||||
|
||||
|
||||
class ResellersController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
$merchants = Models\Reseller::latest()->paginate(10);
|
||||
$data = [
|
||||
'merchants'=>$merchants,
|
||||
|
||||
];
|
||||
|
||||
return view('resellers.index',$data);
|
||||
}
|
||||
}
|
||||
48
app/Http/Controllers/SettingsController.php
Normal file
48
app/Http/Controllers/SettingsController.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models;
|
||||
use Session;
|
||||
use DB;
|
||||
use App\ActivityLog;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$settings = Models\Settings::get();
|
||||
// dd($settings);
|
||||
$data = [
|
||||
'settings' => $settings,
|
||||
'page_title' => 'System Settings'
|
||||
];
|
||||
return view('super_admin.settings',$data);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => 'required',
|
||||
'value' => 'required',
|
||||
'id' => 'required'
|
||||
]);
|
||||
|
||||
$name = $request->input('name');
|
||||
$value = $request->input('value');
|
||||
|
||||
$settings = Models\Settings::find($id);
|
||||
if ($settings) {
|
||||
$settings->name = $value;
|
||||
$settings->save();
|
||||
} else {
|
||||
Models\Settings::create([
|
||||
'name' => $name,
|
||||
'value' => $value
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->back()->with('success', 'Settings updated successfully!');
|
||||
}
|
||||
}
|
||||
129
app/Http/Controllers/TopUpsController.php
Normal file
129
app/Http/Controllers/TopUpsController.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models;
|
||||
use Validator;
|
||||
use Carbon\Carbon;
|
||||
use App\ActivityLog;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Libs\Smsgateway;
|
||||
|
||||
class TopUpsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$topups = Models\OrganisationTopUp::with('orgInfo','userInfo')->latest()->paginate(10);
|
||||
$data = [
|
||||
'topups' => $topups,
|
||||
'page_title' => 'org_topup_list'
|
||||
];
|
||||
return view('super_admin.topups',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$organisations = Models\Organisation::get();
|
||||
$data = [
|
||||
'organisations' => $organisations,
|
||||
'page_title' => 'org_topups'
|
||||
];
|
||||
return view('topups.create',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'amount' => 'required',
|
||||
'payment' => 'required',
|
||||
'organisation' => 'required',
|
||||
'discount' => 'required|numeric'
|
||||
]);
|
||||
|
||||
// validate json request in laravel
|
||||
|
||||
|
||||
$organisation = Models\Organisation::findOrFail($request->organisation);
|
||||
$current_balance = $organisation->balance;
|
||||
|
||||
$discount = 1 + ($request->discount/100);
|
||||
$new_amount = (float)$request->amount * $discount;
|
||||
|
||||
$topup = new Models\OrganisationTopUp;
|
||||
$topup->amount = round($new_amount, 2);
|
||||
$topup->current_balance = $organisation->balance;
|
||||
$topup->org_id = $request->organisation;
|
||||
$topup->created_by = Auth::user()->id;
|
||||
$topup->user_id = Auth::user()->id;
|
||||
$topup->payment_method = $request->payment;
|
||||
$save = $topup->save();
|
||||
|
||||
//Update Organisation Amt
|
||||
$retval = Models\Organisation::where('id', $request->organisation)->increment('balance', $new_amount);
|
||||
if ($save == true && $retval == true) {
|
||||
$desc = [
|
||||
'title'=>'Account Top Up',
|
||||
'data'=>'MWK'. $request->amount.' for '.$organisation->name.' payment by '. $request->payment,
|
||||
'type'=>'topup',
|
||||
];
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = Auth::user()->id;
|
||||
$activity->user_type = 'admin'; // Auth::user()->id;
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
$smsgateway = new Smsgateway;
|
||||
$organisation = Models\Organisation::findOrFail($request->organisation);
|
||||
|
||||
$organisation_phone = $organisation->phone;
|
||||
$organisation_name = $organisation->name;
|
||||
$organisation_new_balance = $organisation->balance;
|
||||
$msg = "Hello $organisation_name, your account has been credited with $new_amount Kwacha and your new balance is : $organisation_new_balance";
|
||||
if (env('APP_ENV') != 'local') {
|
||||
$message_result = $smsgateway->sendSmsNew($organisation_phone, $msg);
|
||||
}
|
||||
\Log::info($msg);
|
||||
if($request->ajax()){{
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'code' => 1,
|
||||
'message' => 'Top Up Successful'
|
||||
]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
return redirect()->to('/admin/topups')->with('admin-sucsess', 'Successfully Added New Top Up');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($request->ajax()){{
|
||||
return response()->json([
|
||||
'status' => 'fail`',
|
||||
'code' => 3,
|
||||
'message' => 'Top Up Failed'
|
||||
]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
return redirect()->back()->with('admin-error', 'Error');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
26
app/Http/Controllers/TransactionController.php
Normal file
26
app/Http/Controllers/TransactionController.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Transaction;
|
||||
|
||||
class TransactionController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$transactions = Transaction::with('merchant')->latest()->paginate(30);
|
||||
|
||||
$data = [
|
||||
'transactions'=>$transactions,
|
||||
|
||||
];
|
||||
return \view('transactions.index',$data);
|
||||
|
||||
}
|
||||
}
|
||||
165
app/Http/Controllers/UserController.php
Normal file
165
app/Http/Controllers/UserController.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\User;
|
||||
use App\ActivityLog;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Validator;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use App\Mail\UserRegistration;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
//where('status','Active')->
|
||||
$users = User::where('status','Active')->latest()->paginate(10);
|
||||
|
||||
$data = [
|
||||
|
||||
'users' => $users,
|
||||
'page_title' => 'Admin Users',
|
||||
];
|
||||
return view('users.index',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$data = [
|
||||
'page_title' => 'New Admin User'
|
||||
];
|
||||
return view('users.create', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
\Log::info('here at the wall');
|
||||
// todo : form filler password : Pa$$w0rd!
|
||||
$this->validate($request, [
|
||||
'name' => 'required',
|
||||
'email'=> 'required|unique:users',
|
||||
'password' => 'required|confirmed'
|
||||
|
||||
]);
|
||||
// dd($request->all());
|
||||
// Hash::make($data['password'])
|
||||
|
||||
$user = new User;
|
||||
$user->name = $request->name;
|
||||
$user->email = $request->email;
|
||||
$user->password = Hash::make($request->password) ;
|
||||
$user->save();
|
||||
|
||||
//sending the mail
|
||||
$newUser = [
|
||||
'name' => $request->name,
|
||||
'email' => $request->email,
|
||||
];
|
||||
$email = $request->email;
|
||||
Mail::to($email)->send(new UserRegistration($newUser));
|
||||
|
||||
$desc = [
|
||||
'title' => 'Created a user',
|
||||
'data' => $request->name,
|
||||
'type' => 'user',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = Auth::user()->id;
|
||||
$activity->user_type = 'admin';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
return redirect()->to('/admin/users')->with('admin-sucsess', 'Successfully Added New User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$user = User::findOrFail($id);
|
||||
$data = [
|
||||
'user' => $user,
|
||||
'page_title' => 'list_create'
|
||||
];
|
||||
return view('users.update', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
$user = User::where('id', $id)->update([
|
||||
'status'=>'disabled',
|
||||
]);
|
||||
|
||||
$user = User::find($id);
|
||||
$desc = [
|
||||
'title'=> 'disabled a user with ID ' . $user->id,
|
||||
'data'=> $user->name,
|
||||
'type'=> 'user',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = Auth::user()->id;
|
||||
$activity->user_type = 'admin'; //Auth::user()->id;
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
return redirect()->to('/admin/users')->with('admin-sucsess', 'Successfully Disabled User');
|
||||
|
||||
}
|
||||
}
|
||||
116
app/Http/Controllers/UtilityController.php
Normal file
116
app/Http/Controllers/UtilityController.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models;
|
||||
use Session;
|
||||
use App\Libs\Smsgateway;
|
||||
use Carbon\Carbon;
|
||||
use App\ActivityLog;
|
||||
use Validator;
|
||||
|
||||
class UtilityController extends Controller
|
||||
{
|
||||
public function index(){
|
||||
\Log::info('here at the wall : users view');
|
||||
//where('status','Active')->
|
||||
// $users = User::where('status','Active')->latest()->paginate(10);
|
||||
|
||||
// $data = [
|
||||
|
||||
// 'users' => $users,
|
||||
// ];
|
||||
|
||||
// //
|
||||
// return view('users.index',$data);
|
||||
}
|
||||
public function customLogExample()
|
||||
{
|
||||
Log::channel('custom')->info('This is a custom log message.');
|
||||
|
||||
return response()->json(['message' => 'Custom log written successfully!']);
|
||||
}
|
||||
|
||||
public function mattermosttest()
|
||||
{
|
||||
// log::info('This is a test message for Mattermost logging.');
|
||||
// logger()->error('Some message', [
|
||||
// 'context' => 'Some contex',
|
||||
// 'an_array_of_things' => ['foo', 'bar', 'baz'],
|
||||
// ]);
|
||||
Log::channel('mattermost')->info("mattermost log test message");
|
||||
|
||||
// Or
|
||||
|
||||
// throw new \Exception('An exception occured');
|
||||
Log::error('Something really important');
|
||||
|
||||
|
||||
// Log::channel('mattermost')->info('This is a test message for Mattermost logging.');
|
||||
return response()->json(['message' => 'Mattermost log written successfully!']);
|
||||
}
|
||||
public function refundStore(Request $request){
|
||||
$validatedData = $request->validate([
|
||||
'dealer_id' => 'required',
|
||||
'merchant_id' => 'required',
|
||||
'amount' => 'required|numeric',
|
||||
'reason' => 'required',
|
||||
]);
|
||||
$merchant = Models\Merchant::findorfail($request->merchant_id);
|
||||
$merchant_name = $merchant->fullname;
|
||||
$dealer = Models\OrgUser::findorfail($request->dealer_id);
|
||||
$dealer_name = $dealer->name;
|
||||
$organisation = Models\Organisation::findorfail($dealer->org_id);
|
||||
$result = Models\MerchantToDealerRefund::create([
|
||||
'dealer_id' => $request->dealer_id,
|
||||
'merchant_id' => $request->dealer_id,
|
||||
'amount' => $request->amount,
|
||||
'dealer_msisdn' => $dealer->phone,
|
||||
'reason' => $request->reason,
|
||||
]);
|
||||
$merchant_balance = $merchant->balance;
|
||||
$merchant->balance = $merchant_balance - $request->amount;
|
||||
$merchant->save();
|
||||
|
||||
//Review this -- should dealers belong to a larger organisation or they should be on their own
|
||||
$dealer_balance = $organisation->balance;
|
||||
$organisation->balance = $dealer_balance + $request->amount;
|
||||
$organisation->save();
|
||||
|
||||
$desc = [
|
||||
'title' => 'Dealer Refund',
|
||||
'data' => "Redunded a dealer with an amount of " . $request->amount,
|
||||
'type' => 'merchant',
|
||||
];
|
||||
|
||||
$activity = new ActivityLog;
|
||||
$activity->user_id = $request->session()->get('current_org_user.id'); // org_user_id ;
|
||||
$activity->user_type = 'merchant';
|
||||
$activity->description = json_encode($desc);
|
||||
$activity->save();
|
||||
|
||||
|
||||
$msg = "You have been Successfully refunded a dealer ($dealer_name) with an amount of $request->amount.";
|
||||
$dealer_msg = "You have received a refund amount of $request->amount from Airtime Merchant ($merchant_name)";
|
||||
$smsgateway = new Smsgateway;
|
||||
if(env('APP_ENV') !== 'local'){
|
||||
$result = $smsgateway->sendSmsNew($merchant->phone, $msg);
|
||||
$result = $smsgateway->sendSmsNew($dealer->phone, $dealer_msg);
|
||||
}
|
||||
\Log::info($msg);
|
||||
\Log::info($dealer_msg);
|
||||
// $this->sendNtfy($msg);
|
||||
if($request->ajax()){
|
||||
return response()->json([
|
||||
'code' => 1,
|
||||
'status' => 'success',
|
||||
'message' => 'Dealer Refund Successfully processed'
|
||||
]);
|
||||
}
|
||||
else{
|
||||
return redirect()->to('merchant/refunds')->with('success_message', 'Dealer Refund Successfully processed');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
77
app/Http/Kernel.php
Normal file
77
app/Http/Kernel.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array<int, class-string|string>
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array<string, array<int, class-string|string>>
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
// \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
'throttle:api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
'throttle:api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'login'=>\App\Http\Middleware\Login::class,
|
||||
'logout'=>\App\Http\Middleware\Logout::class,
|
||||
'admin'=>\App\Http\Middleware\AuthUser::class,
|
||||
'merchant'=>\App\Http\Middleware\Merchant::class,
|
||||
'organisation'=>\App\Http\Middleware\Organisation::class,
|
||||
'merchant-login'=>\App\Http\Middleware\MerchantLogin::class,
|
||||
'merchant-logout'=>\App\Http\Middleware\MerchantLogout::class,
|
||||
];
|
||||
}
|
||||
28
app/Http/Middleware/AuthUser.php
Executable file
28
app/Http/Middleware/AuthUser.php
Executable file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AuthUser
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if(! Auth::check()){
|
||||
|
||||
|
||||
return redirect()->to('/login')->with('login-error','You need to Login to gain access');
|
||||
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
30
app/Http/Middleware/Authenticate.php
Normal file
30
app/Http/Middleware/Authenticate.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
/*
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
dd($request->expectsJson());
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
}
|
||||
else{
|
||||
return route('api');
|
||||
}
|
||||
}
|
||||
*/
|
||||
protected function redirectTo($request) {
|
||||
return $request->expectsJson() || str_starts_with($request->path(), 'api/') ? null : '/login'; // Adjust to your admin path
|
||||
}
|
||||
}
|
||||
17
app/Http/Middleware/EncryptCookies.php
Normal file
17
app/Http/Middleware/EncryptCookies.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
28
app/Http/Middleware/Login.php
Executable file
28
app/Http/Middleware/Login.php
Executable file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class Login
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if(Auth::check()){
|
||||
|
||||
return redirect()->to('/');
|
||||
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
||||
}
|
||||
}
|
||||
26
app/Http/Middleware/Logout.php
Executable file
26
app/Http/Middleware/Logout.php
Executable file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class Logout
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if(! Auth::check()){
|
||||
|
||||
return redirect()->to('/login');
|
||||
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
26
app/Http/Middleware/Merchant.php
Executable file
26
app/Http/Middleware/Merchant.php
Executable file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class Merchant
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
|
||||
$merchant = session('merchant');
|
||||
|
||||
if ($merchant == null) {
|
||||
return redirect()->to('/merchant/login')->with('login-error', 'Login to Gain Access!');
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
26
app/Http/Middleware/MerchantLogin.php
Executable file
26
app/Http/Middleware/MerchantLogin.php
Executable file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class MerchantLogin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$merchant = session('merchant');
|
||||
|
||||
if ($merchant !== null) {
|
||||
return redirect()->to('/merchant');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
26
app/Http/Middleware/MerchantLogout.php
Executable file
26
app/Http/Middleware/MerchantLogout.php
Executable file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class MerchantLogout
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$merchant = session('merchant');
|
||||
|
||||
if ($merchant == null) {
|
||||
return redirect()->to('/merchant/login')->with('login-error', 'Login to Gain Access!');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
28
app/Http/Middleware/Organisation.php
Executable file
28
app/Http/Middleware/Organisation.php
Executable file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class Organisation
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
// public function handle($request, Closure $next)
|
||||
// {
|
||||
// return $next($request);
|
||||
// }
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
// $merchant = session('merchant');
|
||||
if(!$request->session()->has('current_org_user')){
|
||||
return redirect(url('/organisation/login'))->withErrors("You need to be logged in");
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
32
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
32
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @param string|null ...$guards
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, ...$guards)
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
40
app/Http/Middleware/SessionTimeout.php
Normal file
40
app/Http/Middleware/SessionTimeout.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Session\Store;
|
||||
|
||||
class SessionTimeout{
|
||||
protected $session;
|
||||
protected $timeout = 600;
|
||||
|
||||
public function __construct(Store $session){
|
||||
$this->session = $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if( !$this->session->has('lastActivityTime') ) {
|
||||
$this->session->put('lastActivityTime', time());
|
||||
}
|
||||
elseif ( time() - $this->session->get('lastActivityTime') > $this->timeout ) {
|
||||
$this->session->forget('lastActivityTime');
|
||||
#\App\Http\Controllers\LoginController::merchant_logout($request);
|
||||
|
||||
$cookie = \Cookie::forget('fortunae');
|
||||
return redirect("/")->withErrors(['You had no activity over the past '. $this->timeout/60 .' minutes.'])->withCookie($cookie);
|
||||
}
|
||||
|
||||
$this->session->put('lastActivityTime',time());
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
19
app/Http/Middleware/TrimStrings.php
Normal file
19
app/Http/Middleware/TrimStrings.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
20
app/Http/Middleware/TrustHosts.php
Normal file
20
app/Http/Middleware/TrustHosts.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array<int, string|null>
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
||||
28
app/Http/Middleware/TrustProxies.php
Normal file
28
app/Http/Middleware/TrustProxies.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
93
app/Http/Requests/Auth/LoginRequest.php
Normal file
93
app/Http/Requests/Auth/LoginRequest.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Auth;
|
||||
|
||||
use Illuminate\Auth\Events\Lockout;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class LoginRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => ['required', 'string', 'email'],
|
||||
'password' => ['required', 'string'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to authenticate the request's credentials.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$this->ensureIsNotRateLimited();
|
||||
|
||||
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
|
||||
RateLimiter::hit($this->throttleKey());
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'email' => trans('auth.failed'),
|
||||
]);
|
||||
}
|
||||
|
||||
RateLimiter::clear($this->throttleKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the login request is not rate limited.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function ensureIsNotRateLimited()
|
||||
{
|
||||
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event(new Lockout($this));
|
||||
|
||||
$seconds = RateLimiter::availableIn($this->throttleKey());
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'email' => trans('auth.throttle', [
|
||||
'seconds' => $seconds,
|
||||
'minutes' => ceil($seconds / 60),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rate limiting throttle key for the request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function throttleKey()
|
||||
{
|
||||
return Str::lower($this->input('email')).'|'.$this->ip();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user