feat(export): tambahkan fungsionalitas ekspor laporan hasil penilaian jaminan internal dan eksternal
- Menambahkan kelas LaporanHasilPenilaianJaminanInternalExternalExport untuk mengelola ekspor data. - Mengimplementasikan metode collection untuk mengambil data permohonan dengan filter. - Menambahkan metode map untuk memetakan data permohonan ke format yang sesuai untuk ekspor. - Menyediakan judul dan heading untuk laporan yang diekspor. - Mengatur format dan gaya untuk laporan yang dihasilkan.
This commit is contained in:
@@ -0,0 +1,272 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Exports;
|
||||||
|
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||||
|
use Maatwebsite\Excel\Events\AfterSheet;
|
||||||
|
use Modules\Lpj\Models\Permohonan;
|
||||||
|
use Modules\Lpj\Models\Branch;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
class LaporanHasilPenilaianJaminanInternalExternalExport implements FromCollection, WithHeadings, WithMapping, WithTitle, WithCustomStartCell, WithEvents
|
||||||
|
{
|
||||||
|
protected $request;
|
||||||
|
|
||||||
|
public function __construct($request)
|
||||||
|
{
|
||||||
|
$this->request = $request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
$query = Permohonan::query();
|
||||||
|
$query = $query->where('status', 'done');
|
||||||
|
|
||||||
|
// Apply date range filter if provided
|
||||||
|
if ($this->request->has('start_date') || $this->request->has('end_date')) {
|
||||||
|
$query->whereBetween('tanggal_permohonan', [
|
||||||
|
$this->request->start_date ?? '1900-01-01',
|
||||||
|
$this->request->end_date ?? now()->toDateString()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply branch filter if provided
|
||||||
|
if ($this->request->has('branch_id') && !empty($this->request->branch_id)) {
|
||||||
|
$query->where('branch_id', $this->request->branch_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply search filter if provided
|
||||||
|
if ($this->request->has('search') && !empty($this->request->search)) {
|
||||||
|
$search = $this->request->search;
|
||||||
|
$query->where(function ($q) use ($search) {
|
||||||
|
$q->where('nomor_registrasi', 'LIKE', '%' . $search . '%');
|
||||||
|
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%');
|
||||||
|
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%');
|
||||||
|
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||||
|
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');
|
||||||
|
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search . '%');
|
||||||
|
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||||
|
$q->orWhere('status', 'LIKE', '%' . $search . '%');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default ordering
|
||||||
|
$query->orderBy('nomor_registrasi', 'asc');
|
||||||
|
|
||||||
|
return $query->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $rowNumber = 0;
|
||||||
|
|
||||||
|
public function map($permohonan): array
|
||||||
|
{
|
||||||
|
$this->rowNumber++;
|
||||||
|
$luas_tanah = 0;
|
||||||
|
$luas_bangunan = 0;
|
||||||
|
$nilai_tanah = 0;
|
||||||
|
$nilai_bangunan = 0;
|
||||||
|
$npw = 0;
|
||||||
|
$nilai_liquidasi = 0;
|
||||||
|
|
||||||
|
if (isset($permohonan->penilai->lpj)) {
|
||||||
|
$lpj = json_decode($permohonan->penilai->lpj, true);
|
||||||
|
$npw = str_replace('.', '', $lpj['total_nilai_pasar_wajar'] ?? 0);
|
||||||
|
|
||||||
|
$luas_tanah = $lpj['luas_tanah'] ?? 0;
|
||||||
|
$luas_bangunan = $lpj['luas_bangunan'] ?? 0;
|
||||||
|
$nilai_tanah = str_replace('.', '', $lpj['nilai_tanah_2'] ?? 0);
|
||||||
|
$nilai_bangunan = str_replace('.', '', $lpj['nilai_bangunan_2'] ?? 0);
|
||||||
|
$nilai_liquidasi = str_replace('.', '', $lpj['likuidasi_nilai_2'] ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
$this->rowNumber,
|
||||||
|
$permohonan->nomor_registrasi,
|
||||||
|
$permohonan->tanggal_permohonan,
|
||||||
|
$permohonan->debiture->branch->name,
|
||||||
|
$permohonan->creator->name,
|
||||||
|
$permohonan->debiture->cif,
|
||||||
|
$permohonan->debiture->name,
|
||||||
|
$permohonan->jenisPenilaian->name,
|
||||||
|
$permohonan->tujuanPenilaian->name,
|
||||||
|
$permohonan->jenisFasilitasKredit->name,
|
||||||
|
$permohonan->documents->pluck('jenisJaminan.name')->unique()->implode(', '),
|
||||||
|
$permohonan->documents->map(function ($document) {
|
||||||
|
return formatAlamat($document);
|
||||||
|
})->unique()->implode(', '),
|
||||||
|
$permohonan->documents->flatMap(function ($document) {
|
||||||
|
return $document->detail->map(function ($detail) {
|
||||||
|
return (!empty($detail->dokumen_nomor) && is_array($detail->dokumen_nomor))
|
||||||
|
? ($detail->jenisLegalitasJaminan->name ?? '') . "\n" . implode(', ', $detail->dokumen_nomor)
|
||||||
|
: null;
|
||||||
|
});
|
||||||
|
})->filter()->unique()->implode(', '),
|
||||||
|
$permohonan->documents->pluck('pemilik.name')->unique()->implode(', '),
|
||||||
|
$luas_tanah . ' m²',
|
||||||
|
formatRupiah($nilai_tanah, 2),
|
||||||
|
$luas_bangunan . ' m²',
|
||||||
|
formatRupiah($nilai_bangunan, 2),
|
||||||
|
formatRupiah($permohonan->nilai_njop ?? 0, 2),
|
||||||
|
formatRupiah($npw, 2),
|
||||||
|
formatRupiah($nilai_liquidasi, 2),
|
||||||
|
$permohonan->documents->map(function ($document) {
|
||||||
|
return formatTanggalIndonesia($document->created_at);
|
||||||
|
})->first(),
|
||||||
|
'', // tanggal_spk
|
||||||
|
'', // nomor_spk
|
||||||
|
'', // tanggal_rencana_kunjungan
|
||||||
|
$permohonan->penilaian->tanggal_kunjungan ? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan) : '',
|
||||||
|
'', // tanggal_delivered
|
||||||
|
'', // jangka_waktu_sla
|
||||||
|
($permohonan->approval_dd_at || $permohonan->approval_eo_at) ?
|
||||||
|
formatTanggalIndonesia($permohonan->approval_dd_at ?? $permohonan->approval_eo_at) : '',
|
||||||
|
$permohonan->penilaian->tanggal_kunjungan ? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan) : '',
|
||||||
|
$permohonan->penilaian->_user_penilai->userPenilaiTeam->name ?? '',
|
||||||
|
$permohonan->penilaian->teams ?? '',
|
||||||
|
'', // saran
|
||||||
|
'' // catatan
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'No',
|
||||||
|
'Nomor Registrasi',
|
||||||
|
'Tanggal Permohonan',
|
||||||
|
'Cabang',
|
||||||
|
'Pemohon',
|
||||||
|
'CIF',
|
||||||
|
'Nama Debitur',
|
||||||
|
'Jenis Penilaian',
|
||||||
|
'Tujuan Penilaian',
|
||||||
|
'Jenis Fasilitas Kredit',
|
||||||
|
'Jenis Agunan',
|
||||||
|
'Alamat Agunan',
|
||||||
|
'Bukti Kepemilikan',
|
||||||
|
'Nama Pemilik',
|
||||||
|
'Luas Tanah',
|
||||||
|
'Nilai Tanah',
|
||||||
|
'Luas Bangunan',
|
||||||
|
'Nilai Bangunan',
|
||||||
|
'Nilai NJOP',
|
||||||
|
'Nilai Pasar Wajar',
|
||||||
|
'Nilai Likuidasi',
|
||||||
|
'Tanggal Dokumen Diterima',
|
||||||
|
'Tanggal SPK',
|
||||||
|
'Nomor SPK',
|
||||||
|
'Tanggal Rencana Kunjungan',
|
||||||
|
'Tanggal Kunjungan',
|
||||||
|
'Tanggal Delivered',
|
||||||
|
'Jangka Waktu SLA',
|
||||||
|
'Tanggal Laporan',
|
||||||
|
'Tanggal Review',
|
||||||
|
'Nama Penilai',
|
||||||
|
'Nama Team Leader',
|
||||||
|
'Saran',
|
||||||
|
'Catatan'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function title(): string
|
||||||
|
{
|
||||||
|
return 'Laporan Hasil Penilaian Jaminan Internal & External';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function startCell(): string
|
||||||
|
{
|
||||||
|
return 'A7';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function registerEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AfterSheet::class => function(AfterSheet $event) {
|
||||||
|
// Get the sheet
|
||||||
|
$sheet = $event->sheet->getDelegate();
|
||||||
|
|
||||||
|
// Set the title
|
||||||
|
$sheet->setCellValue('A1', 'LAPORAN PENILAIAN JAMINAN');
|
||||||
|
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(16);
|
||||||
|
|
||||||
|
// Merge cells for title
|
||||||
|
$sheet->mergeCells('A1:AH1');
|
||||||
|
$sheet->getStyle('A1')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||||
|
|
||||||
|
// Set the branch information if filtered
|
||||||
|
$branchInfo = '';
|
||||||
|
if ($this->request->has('branch_id') && !empty($this->request->branch_id)) {
|
||||||
|
$branch = Branch::find($this->request->branch_id);
|
||||||
|
if ($branch) {
|
||||||
|
$branchInfo = 'Cabang: ' . $branch->name;
|
||||||
|
$sheet->setCellValue('A2', $branchInfo);
|
||||||
|
$sheet->mergeCells('A2:AH2');
|
||||||
|
$sheet->getStyle('A2')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||||
|
$sheet->getStyle('A2')->getFont()->setBold(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the period
|
||||||
|
$startDate = $this->request->start_date ?? '';
|
||||||
|
$endDate = $this->request->end_date ?? '';
|
||||||
|
|
||||||
|
$rowIndex = $branchInfo ? 3 : 2;
|
||||||
|
|
||||||
|
if ($startDate && $endDate) {
|
||||||
|
$startDateFormatted = Carbon::parse($startDate)->format('d F Y');
|
||||||
|
$endDateFormatted = Carbon::parse($endDate)->format('d F Y');
|
||||||
|
$sheet->setCellValue('A' . $rowIndex, 'Periode: ' . $startDateFormatted . ' - ' . $endDateFormatted);
|
||||||
|
} else {
|
||||||
|
$sheet->setCellValue('A' . $rowIndex, 'Periode: Semua Data');
|
||||||
|
}
|
||||||
|
$sheet->mergeCells('A' . $rowIndex . ':AH' . $rowIndex);
|
||||||
|
$sheet->getStyle('A' . $rowIndex)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||||
|
|
||||||
|
// Set the date of export
|
||||||
|
$rowIndex++;
|
||||||
|
$sheet->setCellValue('A' . $rowIndex, 'Tanggal Export: ' . Carbon::now()->format('d F Y H:i:s'));
|
||||||
|
|
||||||
|
// Set the user who exported
|
||||||
|
$rowIndex++;
|
||||||
|
$userName = Auth::user() ? Auth::user()->name : 'System';
|
||||||
|
$sheet->setCellValue('A' . $rowIndex, 'Diexport oleh: ' . $userName);
|
||||||
|
|
||||||
|
// Add a blank line
|
||||||
|
$rowIndex++;
|
||||||
|
$sheet->setCellValue('A' . $rowIndex, '');
|
||||||
|
|
||||||
|
// Style the header row
|
||||||
|
$headerRange = 'A7:' . $sheet->getHighestColumn() . '7';
|
||||||
|
$sheet->getStyle($headerRange)->getFont()->setBold(true);
|
||||||
|
$sheet->getStyle($headerRange)->getFill()
|
||||||
|
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
|
||||||
|
->getStartColor()->setARGB('FFCCCCCC');
|
||||||
|
|
||||||
|
// Add borders to all cells with data
|
||||||
|
$dataRange = 'A7:' . $sheet->getHighestColumn() . $sheet->getHighestRow();
|
||||||
|
$sheet->getStyle($dataRange)->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
|
||||||
|
|
||||||
|
// Center align the header row
|
||||||
|
$sheet->getStyle($headerRange)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||||
|
|
||||||
|
// Set text wrap for header cells
|
||||||
|
$sheet->getStyle($headerRange)->getAlignment()->setWrapText(true);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,17 @@ class Penilaian extends Model
|
|||||||
return $this->belongsTo(Teams::class, 'teams_id', 'id');
|
return $this->belongsTo(Teams::class, 'teams_id', 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function teamLeader(){
|
||||||
|
return $this->belongsTo(Teams::class, 'teams_id', 'id')
|
||||||
|
->with(['teamsUsers' => function($query) {
|
||||||
|
$query->whereHas('user', function($q) {
|
||||||
|
$q->whereHas('roles', function($r) {
|
||||||
|
$r->where('name', 'senior-officer');
|
||||||
|
});
|
||||||
|
})->with('user');
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
public function userPenilai()
|
public function userPenilai()
|
||||||
{
|
{
|
||||||
return $this->hasMany(PenilaianTeam::class, 'penilaian_id', 'id');
|
return $this->hasMany(PenilaianTeam::class, 'penilaian_id', 'id');
|
||||||
|
|||||||
Reference in New Issue
Block a user