feat(sync-logs): tambah fitur sinkronisasi log biaya kartu

- Menambahkan route, controller, model, dan migration untuk fitur baru `sync-logs`.
- Mengganti referensi `BiayaKartuController` menjadi `SyncLogsController`.
- Menyediakan halaman untuk menampilkan data log sinkronisasi dengan filter, pencarian, dan pagination.
- Menambahkan kemampuan melihat detail proses sinkronisasi langsung dari modal.
- Memperbarui `module.json` dengan item menu baru untuk fitur log sinkronisasi.
- Menghapus `BiayaKartuController` yang sudah tidak digunakan lagi.
```

Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
This commit is contained in:
Daeng Deni Mardaeni
2025-05-10 15:12:56 +07:00
parent 1a62bda959
commit e1e52f78fb
8 changed files with 678 additions and 32 deletions

View File

@@ -1,29 +0,0 @@
<?php
namespace Modules\Webstatement\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Modules\Webstatement\Jobs\GenerateBiayaKartuCsvJob;
use Modules\Webstatement\Models\Atmcard;
use RuntimeException;
class BiayaKartuController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
// Memicu job untuk dijalankan dan menunggu hasilnya
$job = new GenerateBiayaKartuCsvJob();
$filename = $job->handle();
// Alternatif jika Anda ingin menjalankannya secara asinkron
// GenerateBiayaAtmCsvJob::dispatch();
// return response()->json(['message' => 'Proses pembuatan file CSV sedang berjalan di background']);
return response()->download($filename)->deleteFileAfterSend(true);
}
}

View File

@@ -0,0 +1,126 @@
<?php
namespace Modules\Webstatement\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Carbon\Carbon;
use Modules\Webstatement\Jobs\GenerateBiayaKartuCsvJob;
use Modules\Webstatement\Models\KartuSyncLog;
class SyncLogsController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view('webstatement::sync-logs.index');
}
/**
* Provide data for datatables - sync logs
*/
public function dataForDatatables(Request $request)
{
// Retrieve data from the database
$query = KartuSyncLog::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('periode', 'LIKE', "%$search%")
->orWhere('sync_notes', 'LIKE', "%$search%")
->orWhere('csv_notes', 'LIKE', "%$search%")
->orWhere('ftp_notes', 'LIKE', "%$search%")
->orWhere('file_name', 'LIKE', "%$search%");
});
}
// Apply filter for sync status if provided
if ($request->has('is_sync') && $request->get('is_sync') !== '') {
$query->where('is_sync', $request->get('is_sync') == '1');
}
// Apply filter for CSV status if provided
if ($request->has('is_csv') && $request->get('is_csv') !== '') {
$query->where('is_csv', $request->get('is_csv') == '1');
}
// Apply filter for FTP status if provided
if ($request->has('is_ftp') && $request->get('is_ftp') !== '') {
$query->where('is_ftp', $request->get('is_ftp') == '1');
}
// Apply sorting if provided
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
$order = $request->get('sortOrder');
$column = $request->get('sortField');
$query->orderBy($column, $order);
} else {
// Default sort by created_at descending
$query->orderBy('created_at', 'desc');
}
// 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();
// Get the data for the current page
$data = $query->get();
// Calculate the page count
$pageCount = ceil($filteredRecords / ($request->get('size') ?: 1));
// Calculate the current page number
$currentPage = $request->get('page') ?: 1;
// Return the response data as a JSON object
return response()->json([
'draw' => $request->get('draw'),
'recordsTotal' => $totalRecords,
'recordsFiltered' => $filteredRecords,
'pageCount' => $pageCount,
'page' => $currentPage,
'totalCount' => $totalRecords,
'data' => $data,
]);
}
/**
* Format file size to human readable format
*/
private function formatSize($bytes)
{
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, 2) . ' ' . $units[$pow];
}
public function show($id){
$syncLog = KartuSyncLog::find($id);
$csvSize = $this->formatSize(File::size($syncLog->csv_path));
$ftpSize = $this->formatSize(File::size($syncLog->ftp_path));
return response()->json($syncLog, 200, ['Content-Type' => 'application/json'], JSON_PRETTY_PRINT);
}
}

119
app/Models/KartuSyncLog.php Normal file
View File

@@ -0,0 +1,119 @@
<?php
namespace Modules\Webstatement\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class KartuSyncLog extends Model
{
use HasFactory;
/**
* Nama tabel yang digunakan oleh model.
*
* @var string
*/
protected $table = 'kartu_sync_logs';
/**
* Atribut yang dapat diisi secara massal.
*
* @var array<int, string>
*/
protected $fillable = [
'periode',
'is_sync',
'is_csv',
'is_ftp',
'sync_at',
'csv_at',
'ftp_at',
'sync_notes',
'csv_notes',
'ftp_notes',
'total_records',
'success_records',
'failed_records',
'file_path',
'file_name',
'ftp_destination',
];
/**
* Atribut yang harus diubah menjadi tipe native.
*
* @var array
*/
protected $casts = [
'is_sync' => 'boolean',
'is_csv' => 'boolean',
'is_ftp' => 'boolean',
'sync_at' => 'datetime',
'csv_at' => 'datetime',
'ftp_at' => 'datetime',
'total_records' => 'integer',
'success_records' => 'integer',
'failed_records' => 'integer',
];
/**
* Scope untuk mendapatkan log berdasarkan periode
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $periode Format: YYYY-MM
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeByPeriode($query, $periode)
{
return $query->where('periode', $periode);
}
/**
* Scope untuk mendapatkan log yang sudah sync
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeSynced($query)
{
return $query->where('is_sync', true);
}
/**
* Scope untuk mendapatkan log yang sudah membuat CSV
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeCsvGenerated($query)
{
return $query->where('is_csv', true);
}
/**
* Scope untuk mendapatkan log yang sudah upload FTP
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeFtpUploaded($query)
{
return $query->where('is_ftp', true);
}
/**
* Scope untuk mendapatkan log yang belum selesai prosesnya
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeIncomplete($query)
{
return $query->where(function ($q) {
$q->where('is_sync', false)
->orWhere('is_csv', false)
->orWhere('is_ftp', false);
});
}
}