Merge branch 'staging' of https://git.putrakuningan.com/daengdeni/lpj into tender

This commit is contained in:
2025-04-23 13:52:29 +07:00
9 changed files with 941 additions and 0 deletions

View File

@@ -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);
},
];
}
}

View File

@@ -0,0 +1,182 @@
<?php
namespace Modules\Lpj\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Modules\Lpj\Exports\LaporanHasilPenilaianJaminanInternalExternalExport;
use Modules\Lpj\Models\Permohonan;
use Maatwebsite\Excel\Facades\Excel;
class LaporanHasilPenilaianJaminanInternalExternalController extends Controller
{
public $user;
/**
* Display a listing of the resource.
*/
public function index()
{
return view('lpj::laporan_hasil_penilaian_jaminan_internal_external.index');
}
public function dataForDatatables(Request $request)
{
if (is_null($this->user) || !$this->user->can('laporan-admin-kredit.view')) {
//abort(403, 'Sorry! You are not allowed to view laporan admin kredit.');
}
// Retrieve data from the database
$query = Permohonan::query();
$query = $query->where('status', 'done');
// Apply search filter if provided
if ($request->has('search') && !empty($request->get('search'))) {
$search = json_decode($request->get('search'));
if (isset($search->start_date) || isset($search->end_date)) {
$query->whereBetween('tanggal_permohonan', [
$search->start_date ?? '1900-01-01',
$search->end_date ?? now()->toDateString()
]);
}
// Filter by branch if provided
if (isset($search->branch_id) && !empty($search->branch_id)) {
$query->where('branch_id', $search->branch_id);
}
if (isset($search->search)) {
$query->where(function ($q) use ($search) {
$q->where('nomor_registrasi', 'LIKE', '%' . $search->search . '%');
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhere('status', 'LIKE', '%' . $search->search . '%');
});
}
}
// Apply sorting if provided
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
$order = $request->get('sortOrder');
$column = $request->get('sortField');
$query->orderBy($column, $order);
}
// 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; // Calculate the offset
$query->skip($offset)->take($size);
}
// Get the filtered count of records
$filteredRecords = $query->count();
// Get the data for the current page
$data = $query->with(['debiture.branch'])->get();
$data = $data->map(function ($permohonan) {
$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;
// Calculate nilai_tanah dynamically by looking for all keys that start with 'nilai_tanah_'
$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 [
'id' => $permohonan->id,
'nomor_registrasi' => $permohonan->nomor_registrasi,
'jenis_penilaian' => $permohonan->jenisPenilaian->name,
'tujuan_penilaian' => $permohonan->tujuanPenilaian->name,
'jenis_fasilitas_kredit' => $permohonan->jenisFasilitasKredit->name,
'branch' => $permohonan->debiture->branch->name,
'pemohon' => $permohonan->creator->name,
'cif' => $permohonan->debiture->cif,
'name' => $permohonan->debiture->name,
'jenis_agunan' => $permohonan->documents->pluck('jenisJaminan.name')->unique()->implode(', '),
'alamat_agunan' => $permohonan->documents->map(function ($document) {
return formatAlamat($document);
})->unique()->implode(', '),
'bukti_kepemilikan' => $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(', '),
'nama_pemilik' => $permohonan->documents->pluck('pemilik.name')->unique()->implode(', '),
'luas_tanah' => $luas_tanah . ' m²',
'nilai_tanah' => formatRupiah($nilai_tanah,2),
'luas_bangunan' => $luas_bangunan . ' m²',
'nilai_bangunan' => formatRupiah($nilai_bangunan,2),
'nilai_njop' => formatRupiah($permohonan->nilai_njop,2),
'nilai_pasar_wajar' => formatRupiah($npw,2),
'nilai_likuidasi' => formatRupiah($nilai_liquidasi,2),
'tanggal_documen_diterima' => $permohonan->documents->map(function ($document) {
return $document->created_at->format('d-m-Y');
}),
'tanggal_spk' => '',
'nomor_spk' => '',
'tanggal_rencana_kunjunagn' => '',
'tanggal_kunjungan' => '',
'taggal_delivered' => '',
'jangka_waktu_sla' => '',
'nama_penilai' => $permohonan->penilaian->_user_penilai->userPenilaiTeam->name,
'nama_team_leader' => $permohonan->penilaian->teams,
'saran' => '',
'catatan' => '',
'tanggal_permohonan' => $permohonan->tanggal_permohonan,
'tanggal_laporan' => $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? '',
'tanggal_review' => $permohonan->penilaian->tanggal_kunjungan ?? '',
];
});
// Calculate the page count
$pageCount = ceil($totalRecords / $request->get('size'));
// 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,
]);
}
public function export(Request $request)
{
return Excel::download(new LaporanHasilPenilaianJaminanInternalExternalExport($request), 'laporan_hasil_penilaian_jaminan_internal_external.xlsx');
}
}

View File

@@ -207,6 +207,7 @@ class PermohonanController extends Controller
$search = $request->get('search');
$query->where(function ($q) use ($search) {
$q->where('nomor_registrasi', 'LIKE', '%' . $search . '%');
$q->orWhere('mig_mst_lpj_nomor_jaminan', 'LIKE', '%' . $search . '%');
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%');
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%');
$q->orWhereRelation('debiture', 'name', 'LIKE', '%' . $search . '%');

View File

@@ -32,6 +32,17 @@ class Penilaian extends Model
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()
{
return $this->hasMany(PenilaianTeam::class, 'penilaian_id', 'id');