feat(webstatement): tambahkan AtmTransactionReportController untuk pengelolaan laporan transaksi ATM
- Menambahkan controller `AtmTransactionReportController` untuk mengelola laporan transaksi ATM. - Fungsi utama yang disediakan: 1. **index**: Menampilkan daftar laporan transaksi ATM. 2. **create**: Menampilkan form untuk permintaan laporan baru. 3. **store**: Menghandle penyimpanan permintaan laporan baru, termasuk validasi input, pembuatan log laporan, dan dispatching job. 4. **show**: Menampilkan detail laporan transaksi ATM berdasarkan log laporan. 5. **download**: Melakukan unduhan file laporan jika telah selesai diproses. 6. **authorize**: Menghandle otorisasi permintaan laporan, termasuk validasi status `approved` atau `rejected`. 7. **dataForDatatables**: Memberikan data laporan untuk tabular dengan filter, sorting, dan pagination. 8. **destroy**: Menghapus laporan transaksi ATM, termasuk file terkait jika ada. 9. **sendEmail**: Mengirim laporan ke email jika laporan dan alamat email tersedia. - Fitur tambahan: - Memastikan validasi input untuk keamanan data pengguna. - Menambahkan updating log laporan seperti status, error, hingga metadata unduhan. - Mendukung pencarian dan filtering data untuk pengelolaan laporan berjumlah besar. - Dispatch job `GenerateAtmTransactionReportJob` untuk menghasilkan laporan transaksi secara background: - Menambahkan log detail jika terjadi kegagalan saat dispatch. - Tujuan pembaruan: - Mempermudah pengelolaan dan pelacakan laporan transaksi ATM. - Menyediakan antarmuka user-friendly untuk pengguna, termasuk validasi dan feedback status laporan. - Meningkatkan fleksibilitas dan efisiensi pengelolaan laporan dengan mendukung filter, sorting, dan job asynchronous. Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
This commit is contained in:
295
app/Http/Controllers/AtmTransactionReportController.php
Normal file
295
app/Http/Controllers/AtmTransactionReportController.php
Normal file
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Webstatement\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Log;
|
||||
use Modules\Webstatement\Jobs\GenerateAtmTransactionReportJob;
|
||||
use Modules\Webstatement\Models\AtmTransactionReportLog;
|
||||
|
||||
class AtmTransactionReportController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the ATM transaction reports.
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('webstatement::atm-reports.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created ATM transaction report request.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'report_date' => ['required', 'date_format:Y-m-d'],
|
||||
]);
|
||||
|
||||
// Convert date to Ymd format for period
|
||||
$period = Carbon::createFromFormat('Y-m-d', $validated['report_date'])->format('Ymd');
|
||||
|
||||
// Add user tracking data
|
||||
$reportData = [
|
||||
'period' => $period,
|
||||
'report_date' => $validated['report_date'],
|
||||
'user_id' => Auth::id(),
|
||||
'created_by' => Auth::id(),
|
||||
'ip_address' => $request->ip(),
|
||||
'user_agent' => $request->userAgent(),
|
||||
'status' => 'pending',
|
||||
];
|
||||
|
||||
// Create the report request log
|
||||
$reportRequest = AtmTransactionReportLog::create($reportData);
|
||||
|
||||
// Dispatch the job to generate the report
|
||||
try {
|
||||
GenerateAtmTransactionReportJob::dispatch($period, $reportRequest->id);
|
||||
|
||||
$reportRequest->update([
|
||||
'status' => 'processing',
|
||||
'updated_by' => Auth::id()
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$reportRequest->update([
|
||||
'status' => 'failed',
|
||||
'error_message' => $e->getMessage(),
|
||||
'updated_by' => Auth::id()
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->route('atm-reports.index')
|
||||
->with('success', 'ATM Transaction report request has been created successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new report request.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('webstatement::atm-reports.create', compact('branches'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified report request.
|
||||
*/
|
||||
public function show(AtmTransactionReportLog $atmReport)
|
||||
{
|
||||
$atmReport->load(['user', 'creator', 'authorizer']);
|
||||
return view('webstatement::atm-reports.show', compact('atmReport'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Download the report if available.
|
||||
*/
|
||||
public function download(AtmTransactionReportLog $atmReport)
|
||||
{
|
||||
// Check if report is available
|
||||
if ($atmReport->status !== 'completed' || !$atmReport->file_path) {
|
||||
return back()->with('error', 'Report is not available for download.');
|
||||
}
|
||||
|
||||
// Update download status
|
||||
$atmReport->update([
|
||||
'is_downloaded' => true,
|
||||
'downloaded_at' => now(),
|
||||
'updated_by' => Auth::id()
|
||||
]);
|
||||
|
||||
// Download the file
|
||||
$filePath = $atmReport->file_path;
|
||||
if (Storage::exists($filePath)) {
|
||||
$fileName = "atm_transaction_report_{$atmReport->period}.csv";
|
||||
return Storage::download($filePath, $fileName);
|
||||
}
|
||||
|
||||
return back()->with('error', 'Report file not found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorize a report request.
|
||||
*/
|
||||
public function authorize(Request $request, AtmTransactionReportLog $atmReport)
|
||||
{
|
||||
$request->validate([
|
||||
'authorization_status' => ['required', Rule::in(['approved', 'rejected'])],
|
||||
'remarks' => ['nullable', 'string', 'max:255'],
|
||||
]);
|
||||
|
||||
// Update authorization status
|
||||
$atmReport->update([
|
||||
'authorization_status' => $request->authorization_status,
|
||||
'authorized_by' => Auth::id(),
|
||||
'authorized_at' => now(),
|
||||
'remarks' => $request->remarks,
|
||||
'updated_by' => Auth::id()
|
||||
]);
|
||||
|
||||
$statusText = $request->authorization_status === 'approved' ? 'approved' : 'rejected';
|
||||
|
||||
return redirect()->route('atm-reports.show', $atmReport->id)
|
||||
->with('success', "ATM Transaction report request has been {$statusText} successfully.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide data for datatables.
|
||||
*/
|
||||
public function dataForDatatables(Request $request)
|
||||
{
|
||||
// Retrieve data from the database
|
||||
$query = AtmTransactionReportLog::query();
|
||||
|
||||
// Apply search filter if provided
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = $request->get('search');
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('period', 'LIKE', "%$search%")
|
||||
->orWhere('status', 'LIKE', "%$search%")
|
||||
->orWhere('authorization_status', 'LIKE', "%$search%");
|
||||
});
|
||||
}
|
||||
|
||||
// Apply column filters if provided
|
||||
if ($request->has('filters') && !empty($request->get('filters'))) {
|
||||
$filters = json_decode($request->get('filters'), true);
|
||||
|
||||
foreach ($filters as $filter) {
|
||||
if (!empty($filter['value'])) {
|
||||
if ($filter['column'] === 'status') {
|
||||
$query->where('status', $filter['value']);
|
||||
} else if ($filter['column'] === 'authorization_status') {
|
||||
$query->where('authorization_status', $filter['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply sorting if provided
|
||||
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||
$order = $request->get('sortOrder');
|
||||
$column = $request->get('sortField');
|
||||
|
||||
// Map frontend column names to database column names if needed
|
||||
$columnMap = [
|
||||
'period' => 'period',
|
||||
'status' => 'status',
|
||||
];
|
||||
|
||||
$dbColumn = $columnMap[$column] ?? $column;
|
||||
$query->orderBy($dbColumn, $order);
|
||||
} else {
|
||||
// Default sorting
|
||||
$query->latest('created_at');
|
||||
}
|
||||
|
||||
// Get the total count of records
|
||||
$totalRecords = $query->count();
|
||||
|
||||
// Apply pagination if provided
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = $request->get('page');
|
||||
$size = $request->get('size');
|
||||
$offset = ($page - 1) * $size;
|
||||
|
||||
$query->skip($offset)->take($size);
|
||||
}
|
||||
|
||||
// Get the filtered count of records
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Eager load relationships (remove branch since it's not used anymore)
|
||||
$query->with(['user', 'authorizer']);
|
||||
|
||||
// Get the data for the current page
|
||||
$data = $query->get()->map(function ($item) {
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'period' => $item->period,
|
||||
'report_date' => Carbon::createFromFormat('Ymd', $item->period)->format('Y-m-d'),
|
||||
'status' => $item->status,
|
||||
'authorization_status' => $item->authorization_status,
|
||||
'is_downloaded' => $item->is_downloaded,
|
||||
'created_at' => dateFormat($item->created_at, 1, 1),
|
||||
'created_by' => $item->user->name ?? 'N/A',
|
||||
'authorized_by' => $item->authorizer ? $item->authorizer->name : null,
|
||||
'authorized_at' => $item->authorized_at ? $item->authorized_at->format('Y-m-d H:i:s') : null,
|
||||
'file_path' => $item->file_path,
|
||||
];
|
||||
});
|
||||
|
||||
// Calculate the page count
|
||||
$pageCount = ceil($filteredRecords / ($request->get('size') ?: 1));
|
||||
$currentPage = $request->get('page') ?: 1;
|
||||
|
||||
return response()->json([
|
||||
'draw' => $request->get('draw'),
|
||||
'recordsTotal' => $totalRecords,
|
||||
'recordsFiltered' => $filteredRecords,
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a report request.
|
||||
*/
|
||||
public function destroy(AtmTransactionReportLog $atmReport)
|
||||
{
|
||||
// Delete the file if exists
|
||||
if ($atmReport->file_path && Storage::exists($atmReport->file_path)) {
|
||||
Storage::delete($atmReport->file_path);
|
||||
}
|
||||
|
||||
// Delete the report request
|
||||
$atmReport->delete();
|
||||
|
||||
return response()->json([
|
||||
'message' => 'ATM Transaction report deleted successfully.',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send report to email
|
||||
*/
|
||||
public function sendEmail($id)
|
||||
{
|
||||
$atmReport = AtmTransactionReportLog::findOrFail($id);
|
||||
|
||||
// Check if report has email
|
||||
if (empty($atmReport->email)) {
|
||||
return redirect()->back()->with('error', 'No email address provided for this report.');
|
||||
}
|
||||
|
||||
// Check if report is available
|
||||
if ($atmReport->status !== 'completed' || !$atmReport->file_path) {
|
||||
return redirect()->back()->with('error', 'Report is not available for sending.');
|
||||
}
|
||||
|
||||
try {
|
||||
// Send email with report attachment
|
||||
// Implementation depends on your email system
|
||||
// Mail::to($atmReport->email)->send(new AtmTransactionReportEmail($atmReport));
|
||||
|
||||
$atmReport->update([
|
||||
'email_sent' => true,
|
||||
'email_sent_at' => now(),
|
||||
'updated_by' => Auth::id()
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('success', 'ATM Transaction report sent to email successfully.');
|
||||
} catch (Exception $e) {
|
||||
Log::error('Failed to send ATM Transaction report email: ' . $e->getMessage());
|
||||
return redirect()->back()->with('error', 'Failed to send email: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user