I want to optimize cash transactions history page loading time and optimize bankDetails function
Every time i load Cash Ledger or "accounts/bank-details/cash" page either my whole laravel serve is crush neither this page loading time minimum about 10m, it is too difficult to handle this page or reset every time laravel serve.
Is there any optimization function or method to optimize the loading time of Cash Ledger page?
My Route is
Route::get('/bank-details/{id}', 'BankController@bankDetails')->name('bank.show');
BankController.php bankDetails function
public function bankDetails($id) {
if(!Auth::user()->isAdmin() && !Auth::user()->isAccountant()) {
return redirectBackWithNotification('error', 'You are not authorised!');
}
if($id == 'cash') {
$projects = Project::select(['bsoft_projects.project_id', 'bsoft_projects.project_name'])->get();
return view('admin.accounting.banks.show')
->with([
'projects' => $projects
]);
}
$bank = BankAccount::findOrFail($id);
if(!$bank->user) {
$payments = Payment::where('payment_from_bank_account', '=', $bank->bank_id)
->orWhere('payment_to_bank_account', '=', $bank->bank_id)
->get();
$balance = $bank->bank_balance;
}
else {
$payments = Payment::where('payment_from_bank_account', '=', $bank->bank_id)
->orWhere('payment_to_bank_account', '=', $bank->bank_id)
->orWhere('payment_to_user', '=', $bank->user->id)
->orWhere('payment_from_user', '=', $bank->user->id)
->get();
$balance = 0;
$exp = 0;
$inc = 0;
foreach ($payments as $payment) {
if($payment->payment_from_user == $bank->user->id) {
$exp += $payment->payment_amount;
}
elseif ($payment->payment_to_user == $bank->user->id) {
$inc += $payment->payment_amount;
}
}
$balance = $inc - $exp;
}
return view('admin.accounting.banks.show')
->with([
'bank' => $bank,
'payments' => $payments,
'balance' => $balance
]);
}
index.blade.php
<div class="card-footer text-center">
<a href="" class="btn btn-link text-white">Cash Transaction History</a>
</div>
TransactionsDataTable.vue
<template>
<div class="rbt-data-table">
<div class="card">
<div class="card-header">
<h4 class="text-center w-100">Cash Ledger</h4>
</div>
<div class="card-body">
<div class="selection-form">
<form>
<div class="form-group">
<strong class="font-weight-bold">Select Type: </strong>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline1" class="custom-control-input" v-model="type" value="all">
<label class="custom-control-label" for="customRadioInline1">All</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline2" class="custom-control-input" v-model="type" value="loan">
<label class="custom-control-label" for="customRadioInline2">Loans</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline3" class="custom-control-input" v-model="type" value="project">
<label class="custom-control-label" for="customRadioInline3">By Project</label>
</div>
</div>
</form>
</div>
<div class="data-table-header" v-if="!isLoading">
<div class="row justify-content-between">
<div class="col-sm-4 d-none d-sm-block">
<div class="data-per-page">
<label>
Show:
<select v-model="perPage" class="custom-select">
<option value="15">15</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</label>
</div>
</div>
<div class="col-sm-8">
<div class="data-search float-right">
<!--<label class="sr-only" for="Search">Search</label>
<div class="input-group">
<input v-model="search" @keyup="fetchData()" type="text" class="form-control" id="Search" placeholder="Search Here">
<div class="input-group-append">
<div class="input-group-text"><i class="feather icon-search text-dark"></i></div>
</div>
</div>-->
<div class="data-search" v-if="type === 'project'">
<label for="project_id">
For Project:
<select class="custom-select" id="project_id" style="width: auto !important;" v-model="projectId">
<option value="">Select A Project</option>
<option v-for="project in projects" :value="project.project_id"></option>
</select>
</label>
</div>
</div>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped" id="FranchiseTable" style="width: 100%;">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Method</th>
<th scope="col">Type</th>
<th scope="col">Amounts</th>
<th scope="col">Purpose</th>
<th scope="col" v-if="type === 'all'">Project</th>
<th scope="col">From</th>
<th scope="col">To</th>
<th scope="col">Received By</th>
</tr>
</thead>
<tbody>
<tr v-for="data in paginatedData.data">
<th scope="row"></th>
<td></td>
<td></td>
<!-- <td class="font-weight-bold"></td>-->
<td style="text-transform: capitalize;"></td>
<td v-if="type === 'all'">
<a :href="'/project/show/' + data.project_id"></a>
</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<div class="data-table-footer">
<div class="row">
<div class="col-lg-6">
<div class="data-showing">
Showing <strong> - </strong>
</div>
</div>
<div class="col-lg-6">
<div class="data-pagination">
<ul class="pagination float-right">
<li class="page-item pagination-page-nav" v-if="paginatedData.current_page > 1">
<a href="#" class="page-link" @click.prevent="previousPage">
<i class="fa fa-angle-double-left"></i>
</a>
</li>
<li class="page-item pagination-page-nav" v-if="paginatedData.current_page > 1">
<a href="#" class="page-link" @click.prevent="fetchData(1)">
1
</a>
</li>
<li class="page-item pagination-page-nav active" v-if="paginatedData.current_page">
<a href="#" class="page-link">
</a>
</li>
<li class="page-item pagination-page-nav" v-if="paginatedData.current_page !== paginatedData.last_page">
<a href="#" class="page-link" @click.prevent="nextPage">
<i class="fa fa-angle-double-right"></i>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['projects'],
data() {
return {
isLoading: true,
paginatedData: {},
apiUrl: '/bsoft-api/cash-transactions/',
perPage: 5,
search: '',
type: 'all',
projectId: '',
deleteFranchiseId: ''
}
},
mounted() {
this.fetchData();
},
watch: {
perPage(newVal, oldVal) {
if(newVal !== oldVal)
this.fetchData();
},
type(newVal, oldVal) {
if(newVal !== oldVal) {
if(newVal === 'project') {
this.paginatedData = {};
}
else {
this.fetchData();
}
}
},
projectId(newVal, oldVal) {
if(newVal !== oldVal)
this.fetchData();
}
},
methods: {
fetchData(page = 1) {
let self = this;
self.isLoading = true;
let url = self.apiUrl + self.type;
if(self.type === 'project') {
url = url + '/' + self.projectId;
}
axios.get(`${url}?page=${page}&per_page=${self.perPage}&search=${self.search}`)
.then(function (response) {
console.log(response.data);
self.paginatedData = response.data;
self.isLoading = false;
})
.catch(function (error) {
console.log(error.response);
});
},
previousPage() {
let page = this.paginatedData.current_page - 1;
this.fetchData(page);
},
nextPage() {
let page = this.paginatedData.current_page + 1;
this.fetchData(page);
},
openDeleteModal(id) {
this.deleteFranchiseId = id;
$('#franchiseDeleteModal').modal('show');
},
deleteFranchise() {
axios.delete('/bs-admin-api/franchise-control/delete/' + this.deleteFranchiseId)
.then((response) => {
this.showToastMsg('Franchise deleted successfully...!', 'success', 3000);
$('#franchiseDeleteModal').modal('hide');
this.fetchData();
})
.catch((error) => {
this.showToastMsg('Something went wrong...! Try again later.', 'error', 5000);
});
},
showToastMsg(msg, method = 'show', duration = 2500) {
this.$toasted[method](msg, {
action : {
text : '',
icon: 'times',
onClick : (e, toastObject) => {
toastObject.goAway(0);
}
},
duration: duration
});
},
}
}
</script>
Api Route
Route::get('cash-transactions/{type}/{id?}', 'BankController@cashTransactions');
Api Controller
public function cashTransactions(Request $request, $type, $id = null) {
$per_page = ($request->get('per_page'))? $request->get('per_page') : 5;
$search = htmlspecialchars($request->get('search'));
$roles = Role::whereIn('role_slug', ['administrator', 'accountant'])
->pluck('role_id')
->toArray();
if($type === 'project') {
if(!$id) {
return response()->json('Project Id Required!', 404);
}
$payments = Payment::wherePaymentBy('cash')
->where('payment_for_project', '=', $id)
->orderByDesc('payment_date')
->get()
->filter(function ($payment) use ($roles) {
return in_array($payment->activity->activityBy->role_id, $roles);
});
// } else if($type === 'loan') {
// $payments = Payment::wherePaymentBy('cash')
// ->whereIn('payment_purpose', ['loan_received', 'loan_payment'])
// ->orderByDesc('payment_date')
// ->get()
// ->filter(function ($payment) use ($roles) {
// return in_array($payment->activity->activityBy->role_id, $roles);
// });
} else {
$payments = Payment::wherePaymentBy('cash')
->orderByDesc('payment_date')
->get()
->filter(function ($payment) use ($roles) {
return in_array($payment->activity->activityBy->role_id, $roles);
});
}
$page = $request->get('page') ?: (Paginator::resolveCurrentPage() ?: 1);
$paginatedPayments = new LengthAwarePaginator($payments->forPage($page, $per_page), $payments->count(), $per_page, $page);
return response()->json($this->makePaymentCollection($paginatedPayments), 200);
}
I want to know where is the problem facing i am?
is there any solution to solve this optimization problem is there any api function to optimize the whole cash transaction history?
in cashTransactions from API controller query to optimize this page loading time?
if i want to show date to date or month to month cash transaction history What should i do and where i can add this? and is it better to show date to date or month to month showing history or is it better to show all history of loan, by project or All
via
Chebli Mohamed