Compare commits
50 Commits
lpj-db-mig
...
6d137ad51c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d137ad51c | ||
|
|
6c004812a9 | ||
|
|
d932559849 | ||
|
|
c3c40fdc27 | ||
|
|
41262e0317 | ||
|
|
2a1ecfd9e2 | ||
|
|
20833213b1 | ||
|
|
81159983cf | ||
|
|
bc35785c9c | ||
|
|
041ca943c9 | ||
|
|
312861a933 | ||
|
|
96657de512 | ||
|
|
4ad11593d5 | ||
|
|
d851ab58bc | ||
|
|
c08e050815 | ||
|
|
4aeecf6a97 | ||
|
|
1caa7ebfdd | ||
|
|
8666a0c58b | ||
|
|
99bc711954 | ||
|
|
627d7f9b40 | ||
|
|
8a5bf21982 | ||
|
|
2433aacfbc | ||
|
|
ba29f5ee8e | ||
|
|
eb784a982f | ||
|
|
2173a36564 | ||
|
|
ee079a8aa8 | ||
|
|
b4aba1a02a | ||
|
|
32baffe636 | ||
|
|
19fb39b02f | ||
|
|
bc7fef05f6 | ||
|
|
4d8b72e33a | ||
|
|
cf0059fe66 | ||
|
|
d7e5df569a | ||
|
|
cd46a3b0dc | ||
|
|
3486b97aee | ||
|
|
dc6e326122 | ||
|
|
4459b70271 | ||
|
|
57dece449c | ||
|
|
5e7368ebcf | ||
|
|
cbdd4bd99e | ||
|
|
d0cc62f8c0 | ||
|
|
0c2c0c9e20 | ||
|
|
274addb069 | ||
|
|
5c3a93c49b | ||
|
|
36ac1370d7 | ||
|
|
3eb402ae08 | ||
|
|
07589370df | ||
|
|
8220466f03 | ||
|
|
5c57b9cb58 | ||
|
|
a72515bc30 |
117
app/Exports/LaporanSlikExport.php
Normal file
117
app/Exports/LaporanSlikExport.php
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Exports;
|
||||||
|
|
||||||
|
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
|
||||||
|
class LaporanSlikExport implements FromQuery, WithHeadings, WithMapping, WithStyles
|
||||||
|
{
|
||||||
|
protected $query;
|
||||||
|
|
||||||
|
public function __construct($query)
|
||||||
|
{
|
||||||
|
$this->query = $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function query()
|
||||||
|
{
|
||||||
|
return $this->query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Sandi Bank',
|
||||||
|
'Kode Kantor',
|
||||||
|
'Kode Cabang',
|
||||||
|
'Tahun',
|
||||||
|
'Bulan',
|
||||||
|
'No Rekening',
|
||||||
|
'CIF',
|
||||||
|
'Nama Debitur',
|
||||||
|
'NPWP',
|
||||||
|
'No KTP',
|
||||||
|
'No Telp',
|
||||||
|
'Alamat',
|
||||||
|
'Kode Pos',
|
||||||
|
'Kode Kab/Kota',
|
||||||
|
'Kode Negara Domisili',
|
||||||
|
'Kode Jenis',
|
||||||
|
'Kode Sifat',
|
||||||
|
'Kode Valuta',
|
||||||
|
'Baki Debet',
|
||||||
|
'Kolektibilitas',
|
||||||
|
'Tanggal Mulai',
|
||||||
|
'Tanggal Jatuh Tempo',
|
||||||
|
'Tanggal Selesai',
|
||||||
|
'Tanggal Restrukturisasi',
|
||||||
|
'Kode Sebab Macet',
|
||||||
|
'Tanggal Macet',
|
||||||
|
'Kode Kondisi',
|
||||||
|
'Tanggal Kondisi',
|
||||||
|
'Nilai Agunan',
|
||||||
|
'Jenis Agunan',
|
||||||
|
'Kode Agunan',
|
||||||
|
'Peringkat Agunan',
|
||||||
|
'Fasilitas',
|
||||||
|
'Status Agunan',
|
||||||
|
'Tanggal Lapor',
|
||||||
|
'Status',
|
||||||
|
'Tanggal Dibuat',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function map($laporanSlik): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
$laporanSlik->sandi_bank,
|
||||||
|
$laporanSlik->kode_kantor,
|
||||||
|
$laporanSlik->kode_cabang,
|
||||||
|
$laporanSlik->tahun,
|
||||||
|
$laporanSlik->bulan,
|
||||||
|
$laporanSlik->no_rekening,
|
||||||
|
$laporanSlik->cif,
|
||||||
|
$laporanSlik->nama_debitur,
|
||||||
|
$laporanSlik->npwp,
|
||||||
|
$laporanSlik->no_ktp,
|
||||||
|
$laporanSlik->no_telp,
|
||||||
|
$laporanSlik->alamat,
|
||||||
|
$laporanSlik->kode_pos,
|
||||||
|
$laporanSlik->kode_kab_kota,
|
||||||
|
$laporanSlik->kode_negara_domisili,
|
||||||
|
$laporanSlik->kode_jenis,
|
||||||
|
$laporanSlik->kode_sifat,
|
||||||
|
$laporanSlik->kode_valuta,
|
||||||
|
$laporanSlik->baki_debet,
|
||||||
|
$laporanSlik->kolektibilitas,
|
||||||
|
$laporanSlik->tanggal_mulai,
|
||||||
|
$laporanSlik->tanggal_jatuh_tempo,
|
||||||
|
$laporanSlik->tanggal_selesai,
|
||||||
|
$laporanSlik->tanggal_restrukturisasi,
|
||||||
|
$laporanSlik->kode_sebab_macet,
|
||||||
|
$laporanSlik->tanggal_macet,
|
||||||
|
$laporanSlik->kode_kondisi,
|
||||||
|
$laporanSlik->tanggal_kondisi,
|
||||||
|
$laporanSlik->nilai_agunan,
|
||||||
|
$laporanSlik->jenis_agunan,
|
||||||
|
$laporanSlik->kode_agunan,
|
||||||
|
$laporanSlik->peringkat_agunan,
|
||||||
|
$laporanSlik->fasilitas,
|
||||||
|
$laporanSlik->status_agunan,
|
||||||
|
$laporanSlik->tanggal_lapor,
|
||||||
|
$laporanSlik->status,
|
||||||
|
$laporanSlik->created_at->format('d/m/Y H:i'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function styles(Worksheet $sheet)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
1 => ['font' => ['bold' => true]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
232
app/Exports/LaporanUserLimitExport.php
Normal file
232
app/Exports/LaporanUserLimitExport.php
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
<?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;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class LaporanUserLimitExport 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')) {
|
||||||
|
$startDate = $this->request->start_date ?? '1900-01-01';
|
||||||
|
$endDate = $this->request->end_date ?? now()->toDateString();
|
||||||
|
|
||||||
|
$query->where(function ($q) use ($startDate, $endDate) {
|
||||||
|
|
||||||
|
$q->whereHas('penilaian', function ($q2) use ($startDate, $endDate) {
|
||||||
|
$q2->whereBetween('tanggal_kunjungan', [$startDate, $endDate]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// OR check if has penawaran with date in range
|
||||||
|
$q->orWhereHas('penawaran', function ($q3) use ($startDate, $endDate) {
|
||||||
|
$q3->whereBetween('tanggal_penilaian_sebelumnya', [$startDate, $endDate]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply branch filter if provided
|
||||||
|
if ($this->request->has('branch_id') && !empty($this->request->branch_id)) {
|
||||||
|
$query->where('branch_id', $this->request->branch_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->request->has('penilai_id') && !empty($this->request->penilai_id)) {
|
||||||
|
$request = $this->request; // Store in a local variable
|
||||||
|
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function ($q) use ($request) {
|
||||||
|
$q->where('user_id', $request->penilai_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('debiture', DB::raw('LOWER(name)'), 'LIKE', '%' . strtolower($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++;
|
||||||
|
$npw = 0;
|
||||||
|
|
||||||
|
if (isset($permohonan->penilai->lpj)) {
|
||||||
|
$lpj = json_decode($permohonan->penilai->lpj, true);
|
||||||
|
$npw = str_replace('.', '', $lpj['total_nilai_pasar_wajar'] ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
$this->rowNumber,
|
||||||
|
$permohonan->nomor_registrasi,
|
||||||
|
$permohonan->debiture->branch->name ?? '',
|
||||||
|
$permohonan->debiture->name ?? '',
|
||||||
|
$permohonan->user->name ?? $permohonan->mig_nama_ao ?? '',
|
||||||
|
$permohonan->tanggal_permohonan ?? '',
|
||||||
|
$permohonan->penilaian->_user_penilai->userPenilaiTeam->name ?? '',
|
||||||
|
$permohonan->penilaian && $permohonan->penilaian->tanggal_kunjungan
|
||||||
|
? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan)
|
||||||
|
: '',
|
||||||
|
formatRupiah($npw, 2),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'No',
|
||||||
|
'Nomor Registrasi',
|
||||||
|
'Cabang',
|
||||||
|
'Nama Debitur',
|
||||||
|
'Pemohon',
|
||||||
|
'Tanggal Permohonan',
|
||||||
|
'Nama Penilai',
|
||||||
|
'Tanggal Laporan',
|
||||||
|
'Nilai Pasar Wajar',
|
||||||
|
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function title(): string
|
||||||
|
{
|
||||||
|
return 'Laporan User Limit';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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');
|
||||||
|
|
||||||
|
// Auto-size columns - fixed to handle columns beyond Z
|
||||||
|
$highestColumn = $sheet->getHighestColumn();
|
||||||
|
$highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn);
|
||||||
|
|
||||||
|
for ($i = 1; $i <= $highestColumnIndex; $i++) {
|
||||||
|
$currentColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i);
|
||||||
|
$sheet->getColumnDimension($currentColumn)->setAutoSize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
183
app/Http/Controllers/Api/DebiturController.php
Normal file
183
app/Http/Controllers/Api/DebiturController.php
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Exception;
|
||||||
|
use Modules\Lpj\Models\Debiture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller untuk API pencarian debitur
|
||||||
|
* Digunakan untuk autocomplete search pada form pembayaran
|
||||||
|
*/
|
||||||
|
class DebiturController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Pencarian debitur untuk autocomplete
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function search(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Log aktivitas pencarian
|
||||||
|
Log::info('API Debitur Search - Request', [
|
||||||
|
'query' => $request->get('q'),
|
||||||
|
'user_id' => Auth::id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
$query = $request->get('q', '');
|
||||||
|
|
||||||
|
// Validasi minimal 2 karakter untuk pencarian
|
||||||
|
if (strlen($query) < 2) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Minimal 2 karakter untuk pencarian',
|
||||||
|
'data' => []
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mulai database transaction
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Query pencarian debitur
|
||||||
|
// Asumsi tabel debitur dengan kolom: id, code, nama, alamat
|
||||||
|
$debiturs = Debiture::query()
|
||||||
|
->select('id', 'cif', 'name', 'address')
|
||||||
|
->whereAny(['cif','name'], 'LIKE', "%{$query}%")
|
||||||
|
->orderBy('name', 'asc')
|
||||||
|
->limit(20) // Batasi hasil maksimal 20
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// Format data untuk TomSelect
|
||||||
|
$formattedData = $debiturs->map(function($debitur) {
|
||||||
|
return [
|
||||||
|
'id' => $debitur->id,
|
||||||
|
'kode_debitur' => $debitur->cif,
|
||||||
|
'name' => $debitur->name,
|
||||||
|
'address' => $debitur->address
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
// Log hasil pencarian
|
||||||
|
Log::info('API Debitur Search - Success', [
|
||||||
|
'query' => $query,
|
||||||
|
'results_count' => $formattedData->count(),
|
||||||
|
'user_id' => Auth::id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Data debitur berhasil ditemukan',
|
||||||
|
'data' => $formattedData
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
DB::rollback();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Log error
|
||||||
|
Log::error('API Debitur Search - Error', [
|
||||||
|
'query' => $request->get('q'),
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'trace' => $e->getTraceAsString(),
|
||||||
|
'user_id' => Auth::id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Terjadi kesalahan saat mencari data debitur',
|
||||||
|
'error' => config('app.debug') ? $e->getMessage() : 'Internal Server Error'
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get detail debitur berdasarkan code
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function getByCode(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$code = $request->get('code');
|
||||||
|
|
||||||
|
if (empty($code)) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Code debitur harus diisi',
|
||||||
|
'data' => null
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log aktivitas get detail
|
||||||
|
Log::info('API Debitur GetByCode - Request', [
|
||||||
|
'code' => $code,
|
||||||
|
'user_id' => Auth::id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$debitur = DB::table('debitur')
|
||||||
|
->select('id', 'code', 'nama', 'alamat', 'telepon', 'email')
|
||||||
|
->where('code', $code)
|
||||||
|
->where('status', 'aktif')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$debitur) {
|
||||||
|
DB::rollback();
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Debitur tidak ditemukan',
|
||||||
|
'data' => null
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
Log::info('API Debitur GetByCode - Success', [
|
||||||
|
'code' => $code,
|
||||||
|
'debitur_id' => $debitur->id,
|
||||||
|
'user_id' => Auth::id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Data debitur berhasil ditemukan',
|
||||||
|
'data' => $debitur
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
DB::rollback();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error('API Debitur GetByCode - Error', [
|
||||||
|
'code' => $request->get('code'),
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'trace' => $e->getTraceAsString(),
|
||||||
|
'user_id' => Auth::id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Terjadi kesalahan saat mengambil data debitur',
|
||||||
|
'error' => config('app.debug') ? $e->getMessage() : 'Internal Server Error'
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
209
app/Http/Controllers/BucokController.php
Normal file
209
app/Http/Controllers/BucokController.php
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Modules\Lpj\Imports\BucokImport;
|
||||||
|
use Modules\Lpj\Models\Bucok;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller untuk mengelola data Bucok
|
||||||
|
*
|
||||||
|
* @package Modules\Lpj\Http\Controllers
|
||||||
|
*/
|
||||||
|
class BucokController extends Controller
|
||||||
|
{
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menampilkan halaman index bucok
|
||||||
|
*
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('lpj::bucok.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menampilkan detail bucok
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
$bucok = Bucok::findOrFail($id);
|
||||||
|
return view('lpj::bucok.show', compact('bucok'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data untuk datatables dengan server-side processing
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function dataForDatatables(Request $request)
|
||||||
|
{
|
||||||
|
if (is_null($this->user) || !$this->user->can('bucok.view')) {
|
||||||
|
// abort(403, 'Sorry! You are not allowed to view bucok.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve data from the database
|
||||||
|
$query = Bucok::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('nomor_tiket', 'LIKE', "%$search%")
|
||||||
|
->orWhere('deskripsi', 'LIKE', "%$search%")
|
||||||
|
->orWhere('nomor_coa', 'LIKE', "%$search%")
|
||||||
|
->orWhere('nama_coa', 'LIKE', "%$search%")
|
||||||
|
->orWhere('cost_center', 'LIKE', "%$search%")
|
||||||
|
->orWhere('nama_sub_direktorat', 'LIKE', "%$search%")
|
||||||
|
->orWhere('nama_direktorat_cabang', 'LIKE', "%$search%")
|
||||||
|
->orWhere('penyelesaian', 'LIKE', "%$search%")
|
||||||
|
->orWhere('keterangan_gantung', 'LIKE', "%$search%");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply date range filter
|
||||||
|
if ($request->has('start_date') && !empty($request->get('start_date'))) {
|
||||||
|
$query->whereDate('tanggal', '>=', $request->get('start_date'));
|
||||||
|
}
|
||||||
|
if ($request->has('end_date') && !empty($request->get('end_date'))) {
|
||||||
|
$query->whereDate('tanggal', '<=', $request->get('end_date'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply year filter
|
||||||
|
if ($request->has('year') && !empty($request->get('year'))) {
|
||||||
|
$query->byYear($request->get('year'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply month filter
|
||||||
|
if ($request->has('month') && !empty($request->get('month'))) {
|
||||||
|
$query->byMonth($request->get('month'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply cost center filter
|
||||||
|
if ($request->has('cost_center') && !empty($request->get('cost_center'))) {
|
||||||
|
$query->byCostCenter($request->get('cost_center'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply completion status filter
|
||||||
|
if ($request->has('completion_status') && $request->get('completion_status') !== '') {
|
||||||
|
$isCompleted = $request->get('completion_status') == '1';
|
||||||
|
$query->byCompletionStatus($isCompleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply sorting if provided
|
||||||
|
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||||
|
$order = $request->get('sortOrder');
|
||||||
|
$column = $request->get('sortField', 'created_at');
|
||||||
|
$query->orderBy($column, $order);
|
||||||
|
} else {
|
||||||
|
$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; // Calculate the offset
|
||||||
|
|
||||||
|
$query->skip($offset)->take($size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the filtered count of records
|
||||||
|
$filteredRecords = $query->count();
|
||||||
|
|
||||||
|
// Get the data for the current page with relationships
|
||||||
|
$data = $query->get();
|
||||||
|
|
||||||
|
// Transform data untuk datatables
|
||||||
|
$transformedData = $data->map(function ($item) {
|
||||||
|
return [
|
||||||
|
'id' => $item->id,
|
||||||
|
'no' => $item->no,
|
||||||
|
'tanggal' => $item->tanggal ? dateFormat($item->tanggal,true) : '-',
|
||||||
|
'bulan' => $item->bulan,
|
||||||
|
'tahun' => $item->tahun,
|
||||||
|
'nomor_tiket' => $item->nomor_tiket,
|
||||||
|
'nomor_coa' => $item->nomor_coa,
|
||||||
|
'nama_coa' => $item->nama_coa,
|
||||||
|
'deskripsi' => $item->deskripsi,
|
||||||
|
'nominal' => $item->nominal_formatted,
|
||||||
|
'penyelesaian' => $item->penyelesaian,
|
||||||
|
'umur_aging' => $item->umur_aging,
|
||||||
|
'cost_center' => $item->cost_center,
|
||||||
|
'nama_sub_direktorat' => $item->nama_sub_direktorat,
|
||||||
|
'nama_direktorat_cabang' => $item->nama_direktorat_cabang,
|
||||||
|
'tanggal_penyelesaian' => $item->tanggal_penyelesaian ? dateFormat($item->tanggal_penyelesaian,true) : '-',
|
||||||
|
'nominal_penyelesaian' => $item->nominal_penyelesaian_formatted,
|
||||||
|
'status_penyelesaian' => $item->status_penyelesaian,
|
||||||
|
'status_badge' => $item->status_badge,
|
||||||
|
'created_by' => $item->creator?->name ?? '-',
|
||||||
|
'created_at' => dateFormat($item->created_at,true)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Calculate the page count
|
||||||
|
$pageCount = ceil($totalRecords / ($request->get('size', 10)));
|
||||||
|
|
||||||
|
// 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' => $transformedData,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import data bucok dari Excel
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function import(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'file' => 'required|mimes:xlsx,xls,csv|max:10240' // Max 10MB
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
Log::info('Importing Bucok data', ['user_id' => Auth::id(), 'filename' => $request->file('file')->getClientOriginalName()]);
|
||||||
|
|
||||||
|
$import = new BucokImport();
|
||||||
|
Excel::import($import, $request->file('file'));
|
||||||
|
$statistics = $import->getImportStatistics();
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
Log::info('Bucok data imported successfully', ['user_id' => Auth::id()]);
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', 'Data Bucok berhasil diimport. Total: ' . $statistics['total_processed'] . ', Created: ' . $statistics['created'] . ', Updated: ' . $statistics['updated'] . ', Skipped: ' . $statistics['skipped'] . ', Errors: ' . $statistics['errors']);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
DB::rollback();
|
||||||
|
Log::error('Failed to import Bucok data', ['error' => $e->getMessage(), 'user_id' => Auth::id()]);
|
||||||
|
|
||||||
|
return redirect()->back()->with('error', 'Gagal import data: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
152
app/Http/Controllers/CategoryDaftarPustakaController.php
Normal file
152
app/Http/Controllers/CategoryDaftarPustakaController.php
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Modules\Lpj\Models\CategoryDaftarPustaka;
|
||||||
|
use Modules\Lpj\Http\Requests\CategoryDaftarPustakaRequest;
|
||||||
|
|
||||||
|
class CategoryDaftarPustakaController extends Controller
|
||||||
|
{
|
||||||
|
public $user;
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('lpj::category-daftar-pustaka.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('lpj::category-daftar-pustaka.create');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(CategoryDaftarPustakaRequest $request)
|
||||||
|
{
|
||||||
|
$validated = $request->validated();
|
||||||
|
if ($validated) {
|
||||||
|
try {
|
||||||
|
CategoryDaftarPustaka::create($validated);
|
||||||
|
return redirect()->route('category-daftar-pustaka.index')->with('success', 'Data Berhasil Disimpan');
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
return redirect()->route('category-daftar-pustaka.index')->with('error', $th->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the specified resource.
|
||||||
|
*/
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
$category = CategoryDaftarPustaka::where('id', $id)->first();
|
||||||
|
return view('lpj::category-daftar-pustaka.show', compact('category'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
return view('lpj::category-daftar-pustaka.create', ['category' => CategoryDaftarPustaka::where('id', $id)->first()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(CategoryDaftarPustakaRequest $request, $id)
|
||||||
|
{
|
||||||
|
$validated = $request->validated();
|
||||||
|
if ($validated) {
|
||||||
|
try {
|
||||||
|
CategoryDaftarPustaka::where('id', $id)->update($validated);
|
||||||
|
return redirect()->route('category-daftar-pustaka.index')->with('success', 'Data Berhasil Disimpan');
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
return redirect()->route('category-daftar-pustaka.index')->with('error', $th->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
CategoryDaftarPustaka::where('id', $id)->delete();
|
||||||
|
return response()->json(['success' => true, 'message' => 'Data Berhasil Dihapus']);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
return response()->json(['success' => false, 'message' => $th->getMessage()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataForDatatables(Request $request)
|
||||||
|
{
|
||||||
|
if (is_null($this->user) || !$this->user->can('jenis_aset.view')) {
|
||||||
|
//abort(403, 'Sorry! You are not allowed to view users.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve data from the database
|
||||||
|
$query = CategoryDaftarPustaka::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('code', 'LIKE', "%$search%");
|
||||||
|
$q->orWhere('name', 'LIKE', "%$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->get();
|
||||||
|
|
||||||
|
// Calculate the page count
|
||||||
|
$pageCount = ceil($totalRecords / $request->get('size'));
|
||||||
|
|
||||||
|
// Calculate the current page number
|
||||||
|
$currentPage = 0 + 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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
129
app/Http/Controllers/DaftarPustakaController.php
Normal file
129
app/Http/Controllers/DaftarPustakaController.php
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Modules\Lpj\Models\CategoryDaftarPustaka;
|
||||||
|
use Modules\Lpj\Services\DaftarPustakaService;
|
||||||
|
use Modules\Lpj\Http\Requests\DaftarPustakaRequest;
|
||||||
|
|
||||||
|
class DaftarPustakaController extends Controller
|
||||||
|
{
|
||||||
|
private $daftarPustaka;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->daftarPustaka = app(DaftarPustakaService::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$categories = CategoryDaftarPustaka::all();
|
||||||
|
$daftar_pustaka = $this->daftarPustaka->getAllDaftarPustaka($request);
|
||||||
|
|
||||||
|
return view('lpj::daftar-pustaka.index', [
|
||||||
|
'categories' => $categories,
|
||||||
|
'daftar_pustaka' => $daftar_pustaka,
|
||||||
|
'page' => $daftar_pustaka->currentPage(),
|
||||||
|
'pageCount' => $daftar_pustaka->lastPage(),
|
||||||
|
'limit' => $daftar_pustaka->perPage(),
|
||||||
|
'total' => $daftar_pustaka->total(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
$categories = CategoryDaftarPustaka::all();
|
||||||
|
// dd($categories);
|
||||||
|
return view('lpj::daftar-pustaka.create', compact('categories'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(DaftarPustakaRequest $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
$validate = $request->validated();
|
||||||
|
// dd($validate);
|
||||||
|
$file = $request->file('attachment');
|
||||||
|
if ($validate) {
|
||||||
|
try {
|
||||||
|
// Save to database
|
||||||
|
$this->daftarPustaka->storeDaftarPustaka($validate, $file);
|
||||||
|
return redirect()
|
||||||
|
->route('daftar-pustaka.index')
|
||||||
|
->with('success', 'Daftar Pustaka created successfully');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return redirect()
|
||||||
|
->route('daftar-pustaka.create')
|
||||||
|
->with('error', 'Failed to create daftar pustaka');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the specified resource.
|
||||||
|
*/
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
$daftarPustaka = $this->daftarPustaka->getDaftarPustakaById($id);
|
||||||
|
$categories = CategoryDaftarPustaka::all();
|
||||||
|
|
||||||
|
return view('lpj::daftar-pustaka.show', compact('daftarPustaka', 'categories'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
$daftarPustaka = $this->daftarPustaka->getDaftarPustakaById($id);
|
||||||
|
$categories = CategoryDaftarPustaka::all();
|
||||||
|
return view('lpj::daftar-pustaka.create', compact('daftarPustaka', 'categories'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(DaftarPustakaRequest $request, $id)
|
||||||
|
{
|
||||||
|
$validate = $request->validated();
|
||||||
|
if ($validate) {
|
||||||
|
try {
|
||||||
|
// Save to database
|
||||||
|
$file = $request->file('attachment');
|
||||||
|
$this->daftarPustaka->updateDaftarPustaka($validate, $file, $id);
|
||||||
|
return redirect()
|
||||||
|
->route('daftar-pustaka.index')
|
||||||
|
->with('success', 'Daftar Pustaka updated successfully');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return redirect()
|
||||||
|
->route('daftar-pustaka.create')
|
||||||
|
->with('error', 'Failed to update daftar pustaka');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->daftarPustaka->deleteDaftarPustaka($id);
|
||||||
|
return response()->json(['success' => true, 'message' => 'Daftar Pustaka deleted successfully']);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return response()->json(['success' => false, 'message' => 'Failed to delete daftar pustaka']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -169,11 +169,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('laporan-admin-kredit.index')
|
->route('admin-kredit.laporan.index')
|
||||||
->with('success', 'Laporan Admin Kredit updated successfully');
|
->with('success', 'Laporan Admin Kredit updated successfully');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('laporan-admin-kredit.edit', $id)
|
->route('admin-kredit.laporan.edit', $id)
|
||||||
->with('error', 'Failed to update Laporan Admin Kredit');
|
->with('error', 'Failed to update Laporan Admin Kredit');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
304
app/Http/Controllers/LaporanSlikController.php
Normal file
304
app/Http/Controllers/LaporanSlikController.php
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Modules\Lpj\Models\LaporanSlik;
|
||||||
|
use Modules\Lpj\Models\Slik;
|
||||||
|
use Modules\Lpj\Exports\LaporanSlikExport;
|
||||||
|
|
||||||
|
class LaporanSlikController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('lpj::laporan-slik.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$request->validate([
|
||||||
|
'slik_id' => 'required|exists:sliks,id'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$slik = Slik::findOrFail($request->slik_id);
|
||||||
|
|
||||||
|
// Cek apakah data sudah ada di laporan_slik
|
||||||
|
$existing = LaporanSlik::where('slik_id', $slik->id)->first();
|
||||||
|
if ($existing) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Data sudah ada di laporan SLIK'
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy data dari tabel slik ke laporan_slik
|
||||||
|
$laporanSlik = LaporanSlik::create([
|
||||||
|
'slik_id' => $slik->id,
|
||||||
|
'sandi_bank' => $slik->sandi_bank,
|
||||||
|
'kode_kantor' => $slik->kode_kantor,
|
||||||
|
'kode_cabang' => $slik->kode_cabang,
|
||||||
|
'tahun' => $slik->tahun,
|
||||||
|
'bulan' => $slik->bulan,
|
||||||
|
'no_rekening' => $slik->no_rekening,
|
||||||
|
'cif' => $slik->cif,
|
||||||
|
'kode_jenis' => $slik->kode_jenis,
|
||||||
|
'kode_jenis_ket' => $slik->kode_jenis_ket,
|
||||||
|
'kode_sifat' => $slik->kode_sifat,
|
||||||
|
'kode_sifat_ket' => $slik->kode_sifat_ket,
|
||||||
|
'kode_valuta' => $slik->kode_valuta,
|
||||||
|
'kode_valuta_ket' => $slik->kode_valuta_ket,
|
||||||
|
'baki_debet' => $slik->baki_debet,
|
||||||
|
'kolektibilitas' => $slik->kolektibilitas,
|
||||||
|
'kolektibilitas_ket' => $slik->kolektibilitas_ket,
|
||||||
|
'tanggal_mulai' => $slik->tanggal_mulai,
|
||||||
|
'tanggal_jatuh_tempo' => $slik->tanggal_jatuh_tempo,
|
||||||
|
'tanggal_selesai' => $slik->tanggal_selesai,
|
||||||
|
'tanggal_restrukturisasi' => $slik->tanggal_restrukturisasi,
|
||||||
|
'kode_sebab_macet' => $slik->kode_sebab_macet,
|
||||||
|
'kode_sebab_macet_ket' => $slik->kode_sebab_macet_ket,
|
||||||
|
'tanggal_macet' => $slik->tanggal_macet,
|
||||||
|
'kode_kondisi' => $slik->kode_kondisi,
|
||||||
|
'kode_kondisi_ket' => $slik->kode_kondisi_ket,
|
||||||
|
'tanggal_kondisi' => $slik->tanggal_kondisi,
|
||||||
|
'nilai_agunan' => $slik->nilai_agunan,
|
||||||
|
'nilai_agunan_ket' => $slik->nilai_agunan_ket,
|
||||||
|
'jenis_agunan' => $slik->jenis_agunan,
|
||||||
|
'kode_agunan' => $slik->kode_agunan,
|
||||||
|
'kode_agunan_ket' => $slik->kode_agunan_ket,
|
||||||
|
'peringkat_agunan' => $slik->peringkat_agunan,
|
||||||
|
'peringkat_agunan_ket' => $slik->peringkat_agunan_ket,
|
||||||
|
'nama_debitur' => $slik->nama_debitur,
|
||||||
|
'npwp' => $slik->npwp,
|
||||||
|
'no_ktp' => $slik->no_ktp,
|
||||||
|
'no_telp' => $slik->no_telp,
|
||||||
|
'kode_kab_kota' => $slik->kode_kab_kota,
|
||||||
|
'kode_kab_kota_ket' => $slik->kode_kab_kota_ket,
|
||||||
|
'kode_negara_domisili' => $slik->kode_negara_domisili,
|
||||||
|
'kode_negara_domisili_ket' => $slik->kode_negara_domisili_ket,
|
||||||
|
'kode_pos' => $slik->kode_pos,
|
||||||
|
'alamat' => $slik->alamat,
|
||||||
|
'fasilitas' => $slik->fasilitas,
|
||||||
|
'status_agunan' => $slik->status_agunan,
|
||||||
|
'tanggal_lapor' => $slik->tanggal_lapor,
|
||||||
|
'status' => 'active',
|
||||||
|
'created_by' => auth()->id(),
|
||||||
|
'updated_by' => auth()->id(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Hapus data dari tabel slik setelah berhasil dipindahkan
|
||||||
|
$slik->delete();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Data berhasil dipindahkan ke laporan SLIK',
|
||||||
|
'data' => $laporanSlik
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Error moving SLIK to laporan: ' . $e->getMessage());
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Terjadi kesalahan saat memindahkan data'
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data untuk datatables dengan server-side processing
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function dataForDatatables(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Retrieve data from the database
|
||||||
|
$query = LaporanSlik::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('sandi_bank', 'LIKE', "%$search%")
|
||||||
|
->orWhere('no_rekening', 'LIKE', "%$search%")
|
||||||
|
->orWhere('cif', 'LIKE', "%$search%")
|
||||||
|
->orWhere('nama_debitur', 'LIKE', "%$search%")
|
||||||
|
->orWhere('fasilitas', 'LIKE', "%$search%")
|
||||||
|
->orWhere('status_agunan', 'LIKE', "%$search%");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply year filter
|
||||||
|
if ($request->has('year') && !empty($request->get('year'))) {
|
||||||
|
$query->where('tahun', $request->get('year'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply month filter
|
||||||
|
if ($request->has('month') && !empty($request->get('month'))) {
|
||||||
|
$query->where('bulan', $request->get('month'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply sandi bank filter
|
||||||
|
if ($request->has('sandi_bank') && !empty($request->get('sandi_bank'))) {
|
||||||
|
$query->where('sandi_bank', $request->get('sandi_bank'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply kolektibilitas filter
|
||||||
|
if ($request->has('kolektibilitas') && !empty($request->get('kolektibilitas'))) {
|
||||||
|
$query->where('kolektibilitas', $request->get('kolektibilitas'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply status filter
|
||||||
|
if ($request->has('status') && !empty($request->get('status'))) {
|
||||||
|
$query->where('status', $request->get('status'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply sorting if provided
|
||||||
|
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||||
|
$order = $request->get('sortOrder');
|
||||||
|
$column = $request->get('sortField', 'created_at');
|
||||||
|
$query->orderBy($column, $order);
|
||||||
|
} else {
|
||||||
|
$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; // 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->get();
|
||||||
|
|
||||||
|
// Transform data untuk datatables
|
||||||
|
$transformedData = $data->map(function ($item) {
|
||||||
|
return [
|
||||||
|
'id' => $item->id,
|
||||||
|
'sandi_bank' => $item->sandi_bank,
|
||||||
|
'tahun' => $item->tahun,
|
||||||
|
'bulan' => $item->bulan,
|
||||||
|
'no_rekening' => $item->no_rekening,
|
||||||
|
'cif' => $item->cif,
|
||||||
|
'nama_debitur' => $item->nama_debitur,
|
||||||
|
'kolektibilitas' => $item->kolektibilitas,
|
||||||
|
'kolektibilitas_badge' => $item->kolektibilitas_badge ?? '',
|
||||||
|
'fasilitas' => $item->fasilitas,
|
||||||
|
'nilai_agunan' => $item->nilai_agunan_formatted ?? '',
|
||||||
|
'status_agunan' => $item->status_agunan,
|
||||||
|
'status_badge' => $item->status_badge ?? '',
|
||||||
|
'created_by' => $item->creator?->name ?? '-',
|
||||||
|
'created_at' => dateFormat($item->created_at, true) ?? $item->created_at->format('d/m/Y H:i')
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Calculate the page count
|
||||||
|
$pageCount = ceil($totalRecords / ($request->get('size', 10)));
|
||||||
|
|
||||||
|
// 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' => $transformedData,
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Error in laporan slik datatables: ' . $e->getMessage());
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'draw' => $request->get('draw'),
|
||||||
|
'recordsTotal' => 0,
|
||||||
|
'recordsFiltered' => 0,
|
||||||
|
'pageCount' => 0,
|
||||||
|
'page' => 1,
|
||||||
|
'totalCount' => 0,
|
||||||
|
'data' => [],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$laporanSlik = LaporanSlik::findOrFail($id);
|
||||||
|
return view('lpj::laporan-slik.show', compact('laporanSlik'));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Error showing laporan slik: ' . $e->getMessage());
|
||||||
|
return back()->with('error', 'Data tidak ditemukan');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export laporan SLIK to Excel
|
||||||
|
*/
|
||||||
|
public function export(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$query = LaporanSlik::query();
|
||||||
|
|
||||||
|
// Apply filters
|
||||||
|
if ($request->has('search') && $request->search) {
|
||||||
|
$search = $request->search;
|
||||||
|
$query->where(function($q) use ($search) {
|
||||||
|
$q->where('nama_debitur', 'like', "%{$search}%")
|
||||||
|
->orWhere('no_rekening', 'like', "%{$search}%")
|
||||||
|
->orWhere('cif', 'like', "%{$search}%");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('year') && $request->year) {
|
||||||
|
$query->where('tahun', $request->year);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('month') && $request->month) {
|
||||||
|
$query->where('bulan', $request->month);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('status') && $request->status) {
|
||||||
|
$query->where('status', $request->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = 'laporan-slik-' . now()->format('Y-m-d-His') . '.xlsx';
|
||||||
|
|
||||||
|
return Excel::download(new LaporanSlikExport($query), $filename);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Error exporting laporan slik: ' . $e->getMessage());
|
||||||
|
return back()->with('error', 'Gagal export data: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@ namespace Modules\Lpj\Http\Controllers;
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Modules\Lpj\Exports\LaporanUserLimitExport;
|
||||||
use Modules\Lpj\Services\LaporanUserService;
|
use Modules\Lpj\Services\LaporanUserService;
|
||||||
|
|
||||||
class LaporanUserController extends Controller
|
class LaporanUserController extends Controller
|
||||||
@@ -38,4 +40,12 @@ class LaporanUserController extends Controller
|
|||||||
return $this->laporanUserService->dataForDatatables($request);
|
return $this->laporanUserService->dataForDatatables($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function export(Request $request)
|
||||||
|
{
|
||||||
|
$startDate = $request->start_date;
|
||||||
|
$endDate = $request->end_date;
|
||||||
|
// name of the file
|
||||||
|
$fileName = 'laporan_user_limit' . $startDate . '_' . $endDate . '.xlsx';
|
||||||
|
return Excel::download(new LaporanUserLimitExport($request), $fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
558
app/Http/Controllers/MemoController.php
Normal file
558
app/Http/Controllers/MemoController.php
Normal file
@@ -0,0 +1,558 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Http\Controllers;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Modules\Lpj\Models\Noc;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Modules\Lpj\Models\Permohonan;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class MemoController extends Controller
|
||||||
|
{
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menampilkan halaman index memo penyelesaian
|
||||||
|
*
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
Log::info('MemoController: Mengakses halaman index memo penyelesaian');
|
||||||
|
return view('lpj::memo.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menampilkan form untuk membuat memo penyelesaian dengan data yang dipilih
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
Log::info('MemoController: Mengakses halaman create memo penyelesaian');
|
||||||
|
|
||||||
|
$selectedIds = $request->get('selected_ids', []);
|
||||||
|
|
||||||
|
// Pastikan $selectedIds selalu berupa array
|
||||||
|
if (is_string($selectedIds)) {
|
||||||
|
$selectedIds = explode(',', $selectedIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter array untuk menghilangkan nilai kosong
|
||||||
|
$selectedIds = array_filter($selectedIds, function($id) {
|
||||||
|
return !empty(trim($id));
|
||||||
|
});
|
||||||
|
|
||||||
|
$permohonanList = [];
|
||||||
|
$totalBiayaPJ = 0;
|
||||||
|
|
||||||
|
if (!empty($selectedIds) && count($selectedIds) > 0) {
|
||||||
|
try {
|
||||||
|
$permohonanList = Permohonan::with([
|
||||||
|
'user',
|
||||||
|
'debiture',
|
||||||
|
'branch',
|
||||||
|
'tujuanPenilaian',
|
||||||
|
'penilaian',
|
||||||
|
'jenisFasilitasKredit',
|
||||||
|
'documents.inspeksi',
|
||||||
|
'penilai',
|
||||||
|
'documents.detail',
|
||||||
|
'noc'
|
||||||
|
])->whereIn('id', $selectedIds)->get();
|
||||||
|
|
||||||
|
// Hitung total biaya PJ dari nominal_bayar di tabel NOC
|
||||||
|
$totalBiayaPJ = Noc::whereIn('permohonan_id', $selectedIds)
|
||||||
|
->sum('nominal_bayar');
|
||||||
|
|
||||||
|
Log::info('MemoController: Total Biaya PJ dihitung: ' . $totalBiayaPJ);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error('MemoController: Error saat mengambil data permohonan - ' . $e->getMessage());
|
||||||
|
return redirect()->back()->with('error', 'Terjadi kesalahan saat memuat data');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('lpj::memo.create', compact('permohonanList', 'totalBiayaPJ'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menyimpan memo penyelesaian yang telah dibuat
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
Log::info('MemoController: Memulai proses penyimpanan memo penyelesaian');
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Validasi input
|
||||||
|
$request->validate([
|
||||||
|
'permohonan_ids' => 'required|array',
|
||||||
|
'permohonan_ids.*' => 'exists:permohonan,id',
|
||||||
|
'memo_number' => 'required|string|max:255',
|
||||||
|
'payment_date' => 'required|date',
|
||||||
|
'memo_date' => 'required|date'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$permohonanIds = $request->permohonan_ids;
|
||||||
|
$memoNumber = $request->memo_number;
|
||||||
|
$paymentDate = $request->payment_date;
|
||||||
|
$memoDate = $request->memo_date;
|
||||||
|
|
||||||
|
// Update status permohonan yang dipilih
|
||||||
|
foreach ($permohonanIds as $permohonanId) {
|
||||||
|
$permohonan = Permohonan::find($permohonanId);
|
||||||
|
if ($permohonan) {
|
||||||
|
$permohonan->status = 'memo-penyelesaian';
|
||||||
|
$permohonan->memo_penyelesaian_number = $memoNumber;
|
||||||
|
$permohonan->memo_penyelesaian_date = $memoDate;
|
||||||
|
$permohonan->memo_penyelesaian_payment_date = $paymentDate;
|
||||||
|
$permohonan->memo_penyelesaian_created_at = now();
|
||||||
|
//$permohonan->save();
|
||||||
|
|
||||||
|
Log::info('MemoController: Berhasil update permohonan ID: ' . $permohonanId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
Log::info('MemoController: Berhasil menyimpan memo penyelesaian untuk ' . count($permohonanIds) . ' permohonan');
|
||||||
|
|
||||||
|
return redirect()->route('memo.index')
|
||||||
|
->with('success', 'Memo penyelesaian berhasil dibuat untuk ' . count($permohonanIds) . ' permohonan');
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
DB::rollback();
|
||||||
|
Log::error('MemoController: Error saat menyimpan memo penyelesaian - ' . $e->getMessage());
|
||||||
|
|
||||||
|
return redirect()->back()
|
||||||
|
->withInput()
|
||||||
|
->with('error', 'Terjadi kesalahan saat menyimpan memo penyelesaian: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menampilkan detail memo penyelesaian
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
Log::info('MemoController: Mengakses detail memo penyelesaian ID: ' . $id);
|
||||||
|
|
||||||
|
$permohonan = Permohonan::with([
|
||||||
|
'user',
|
||||||
|
'debiture',
|
||||||
|
'branch',
|
||||||
|
'tujuanPenilaian',
|
||||||
|
'penilaian',
|
||||||
|
'jenisFasilitasKredit',
|
||||||
|
'documents.inspeksi',
|
||||||
|
'penilai',
|
||||||
|
'documents.detail',
|
||||||
|
'noc'
|
||||||
|
])->findOrFail($id);
|
||||||
|
|
||||||
|
return view('lpj::memo.show', compact('permohonan'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mengambil data untuk datatables pada halaman memo penyelesaian
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function dataForDatatables(Request $request)
|
||||||
|
{
|
||||||
|
Log::info('MemoController: Mengambil data untuk datatables');
|
||||||
|
|
||||||
|
if (is_null($this->user) || !$this->user->can('debitur.view')) {
|
||||||
|
Log::warning('MemoController: User tidak memiliki permission untuk melihat data');
|
||||||
|
// abort(403, 'Sorry! You are not allowed to view users.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mengambil data dari database dengan kondisi yang sama seperti LaporanController
|
||||||
|
$query = Permohonan::query()
|
||||||
|
->whereIn('status', ['proses-laporan', 'done', 'paparan', 'proses-paparan', 'memo-penyelesaian'])
|
||||||
|
/*->whereNotNull('approval_so_at')
|
||||||
|
->whereNotNull('approval_eo_at')
|
||||||
|
->where(function ($q) {
|
||||||
|
$q->whereIn('nilai_plafond_id', [1, 4])
|
||||||
|
->whereNotNull('approval_dd_at')
|
||||||
|
->orWhereIn('nilai_plafond_id', [2, 3]);
|
||||||
|
})*/
|
||||||
|
->whereHas('noc'); // Hanya tampilkan permohonan yang memiliki NOC
|
||||||
|
|
||||||
|
|
||||||
|
$query = $query->orderBy('nomor_registrasi', 'desc');
|
||||||
|
|
||||||
|
// Apply search filter jika ada
|
||||||
|
if ($request->has('search') && !empty($request->get('search'))) {
|
||||||
|
$searchParams = explode('|', $request->get('search'));
|
||||||
|
|
||||||
|
$filterJenisPenilaian = $searchParams[0] ?? '';
|
||||||
|
$searchTerm = $searchParams[1] ?? '';
|
||||||
|
|
||||||
|
// Filter berdasarkan jenis penilaian
|
||||||
|
if (!empty($filterJenisPenilaian)) {
|
||||||
|
$query->where('jenis_penilaian_id', $filterJenisPenilaian);
|
||||||
|
Log::info('Applied jenis penilaian filter', ['filter' => $filterJenisPenilaian]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query->where(function ($q) use ($searchTerm) {
|
||||||
|
$q->where('nomor_registrasi', 'LIKE', '%' . $searchTerm . '%');
|
||||||
|
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $searchTerm . '%');
|
||||||
|
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $searchTerm . '%');
|
||||||
|
$q->orWhereRelation('debiture', 'name', 'LIKE', '%' . $searchTerm . '%');
|
||||||
|
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $searchTerm . '%');
|
||||||
|
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $searchTerm . '%');
|
||||||
|
$q->orWhere('status', 'LIKE', '%' . $searchTerm . '%');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply sorting jika ada
|
||||||
|
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||||
|
$order = $request->get('sortOrder');
|
||||||
|
$column = $request->get('sortField');
|
||||||
|
$query->orderBy($column, $order);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mendapatkan total count records
|
||||||
|
$totalRecords = $query->count();
|
||||||
|
$size = $request->get('size', 10);
|
||||||
|
if ($size == 0) {
|
||||||
|
$size = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply pagination jika ada
|
||||||
|
if ($request->has('page') && $request->has('size')) {
|
||||||
|
$page = $request->get('page');
|
||||||
|
$size = $request->get('size');
|
||||||
|
$offset = ($page - 1) * $size;
|
||||||
|
|
||||||
|
$query->skip($offset)->take($size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mendapatkan filtered count records
|
||||||
|
$filteredRecords = $query->count();
|
||||||
|
|
||||||
|
// Mendapatkan data untuk halaman saat ini
|
||||||
|
$data = $query->with([
|
||||||
|
'user',
|
||||||
|
'debiture',
|
||||||
|
'branch',
|
||||||
|
'tujuanPenilaian',
|
||||||
|
'jenisPenilaian',
|
||||||
|
'penilaian',
|
||||||
|
'jenisFasilitasKredit',
|
||||||
|
'documents.inspeksi',
|
||||||
|
'penilai',
|
||||||
|
'documents.detail',
|
||||||
|
'noc'
|
||||||
|
])->get();
|
||||||
|
|
||||||
|
// Menghitung page count
|
||||||
|
$pageCount = ceil($totalRecords / $size);
|
||||||
|
|
||||||
|
// Menghitung current page number
|
||||||
|
$currentPage = max(1, $request->get('page', 1));
|
||||||
|
|
||||||
|
Log::info('MemoController: Berhasil mengambil data datatables - Total: ' . $totalRecords . ', Filtered: ' . $filteredRecords);
|
||||||
|
|
||||||
|
// Return response data sebagai JSON object
|
||||||
|
return response()->json([
|
||||||
|
'draw' => $request->get('draw'),
|
||||||
|
'recordsTotal' => $totalRecords,
|
||||||
|
'recordsFiltered' => $filteredRecords,
|
||||||
|
'pageCount' => $pageCount,
|
||||||
|
'page' => $currentPage,
|
||||||
|
'totalCount' => $totalRecords,
|
||||||
|
'data' => $data,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mengambil total biaya PJ berdasarkan permohonan yang dipilih
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function getTotalBiayaPJ(Request $request)
|
||||||
|
{
|
||||||
|
Log::info('MemoController: Mengambil total biaya PJ');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$permohonanIds = $request->get('permohonan_ids', []);
|
||||||
|
|
||||||
|
// Pastikan $permohonanIds selalu berupa array
|
||||||
|
if (is_string($permohonanIds)) {
|
||||||
|
$permohonanIds = explode(',', $permohonanIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter array untuk menghilangkan nilai kosong
|
||||||
|
$permohonanIds = array_filter($permohonanIds, function($id) {
|
||||||
|
return !empty(trim($id));
|
||||||
|
});
|
||||||
|
|
||||||
|
$totalBiayaPJ = 0;
|
||||||
|
|
||||||
|
if (!empty($permohonanIds) && count($permohonanIds) > 0) {
|
||||||
|
// Hitung total biaya PJ dari nominal_bayar di tabel NOC
|
||||||
|
$totalBiayaPJ = \Modules\Lpj\Models\Noc::whereIn('permohonan_id', $permohonanIds)
|
||||||
|
->sum('nominal_bayar');
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info('MemoController: Total Biaya PJ berhasil dihitung: ' . $totalBiayaPJ);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'total_biaya_pj' => $totalBiayaPJ,
|
||||||
|
'total_biaya_pj_formatted' => 'Rp ' . number_format($totalBiayaPJ, 0, ',', '.')
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error('MemoController: Error saat menghitung total biaya PJ - ' . $e->getMessage());
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Terjadi kesalahan saat menghitung total biaya PJ'
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menampilkan preview memo penyelesaian sebelum menyimpan
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function preview(Request $request)
|
||||||
|
{
|
||||||
|
Log::info('MemoController: Mengakses halaman preview memo penyelesaian');
|
||||||
|
|
||||||
|
|
||||||
|
$permohonanIds = $request->permohonan_ids;
|
||||||
|
$memoNumber = $request->memo_number;
|
||||||
|
$paymentDate = $request->payment_date;
|
||||||
|
$memoDate = $request->memo_date;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Ambil data permohonan yang dipilih
|
||||||
|
$permohonanList = Permohonan::with([
|
||||||
|
'user',
|
||||||
|
'debiture',
|
||||||
|
'branch',
|
||||||
|
'penilaian',
|
||||||
|
'jenisPenilaian',
|
||||||
|
'jenisFasilitasKredit',
|
||||||
|
'documents.inspeksi',
|
||||||
|
'penilai',
|
||||||
|
'documents.detail',
|
||||||
|
'noc'
|
||||||
|
])->whereIn('id', $permohonanIds);
|
||||||
|
|
||||||
|
// Hitung total biaya PJ dari nominal_bayar di tabel NOC
|
||||||
|
$totalBiayaPJ = Noc::whereIn('permohonan_id', $permohonanIds)
|
||||||
|
->sum('nominal_bayar');
|
||||||
|
|
||||||
|
// Data untuk template memo
|
||||||
|
$memoData = [
|
||||||
|
'memo_number' => $memoNumber,
|
||||||
|
'memo_date' => $memoDate,
|
||||||
|
'payment_date' => $paymentDate,
|
||||||
|
'total_biaya_pj' => $totalBiayaPJ,
|
||||||
|
'permohonan_list' => $permohonanList->get(),
|
||||||
|
'debitur_count' => $permohonanList->get()->count(),
|
||||||
|
'jaminan_info' => $this->getJaminanInfo($permohonanList->get()),
|
||||||
|
'jenisPenilaian' => $permohonanList->pluck('jenis_penilaian_id')->first()
|
||||||
|
];
|
||||||
|
|
||||||
|
$permohonanList= $permohonanList->get();
|
||||||
|
|
||||||
|
Log::info('MemoController: Data preview memo berhasil disiapkan');
|
||||||
|
|
||||||
|
return view('lpj::memo.preview', compact('memoData', 'permohonanList', 'totalBiayaPJ'));
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error('MemoController: Error saat menyiapkan preview memo - ' . $e->getMessage());
|
||||||
|
return redirect()->back()
|
||||||
|
->withInput()
|
||||||
|
->with('error', 'Terjadi kesalahan saat menyiapkan preview memo: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate PDF memo penyelesaian dan simpan ke database
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function generatePdf(Request $request)
|
||||||
|
{
|
||||||
|
Log::info('MemoController: Memulai generate PDF memo penyelesaian');
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Validasi input
|
||||||
|
|
||||||
|
$permohonanIds = $request->permohonan_ids;
|
||||||
|
$memoNumber = $request->memo_number;
|
||||||
|
$paymentDate = $request->payment_date;
|
||||||
|
$memoDate = $request->memo_date;
|
||||||
|
|
||||||
|
// Ambil data permohonan yang dipilih
|
||||||
|
$permohonanList = Permohonan::with([
|
||||||
|
'user',
|
||||||
|
'debiture',
|
||||||
|
'branch',
|
||||||
|
'penilaian',
|
||||||
|
'jenisPenilaian',
|
||||||
|
'jenisFasilitasKredit',
|
||||||
|
'documents.inspeksi',
|
||||||
|
'penilai',
|
||||||
|
'documents.detail',
|
||||||
|
'noc'
|
||||||
|
])->whereIn('id', $permohonanIds);
|
||||||
|
|
||||||
|
// Hitung total biaya PJ dari nominal_bayar di tabel NOC
|
||||||
|
$totalBiayaPJ = Noc::whereIn('permohonan_id', $permohonanIds)
|
||||||
|
->sum('nominal_bayar');
|
||||||
|
|
||||||
|
// Data untuk template memo
|
||||||
|
$memoData = [
|
||||||
|
'memo_number' => $memoNumber,
|
||||||
|
'memo_date' => $memoDate,
|
||||||
|
'payment_date' => $paymentDate,
|
||||||
|
'total_biaya_pj' => $totalBiayaPJ,
|
||||||
|
'permohonan_list' => $permohonanList->get(),
|
||||||
|
'debitur_count' => $permohonanList->get()->count(),
|
||||||
|
'jaminan_info' => $this->getJaminanInfo($permohonanList->get()),
|
||||||
|
'jenisPenilaian' => $permohonanList->pluck('jenis_penilaian_id')->first()
|
||||||
|
];
|
||||||
|
|
||||||
|
$permohonanList= $permohonanList->get();
|
||||||
|
|
||||||
|
// Generate PDF dari template
|
||||||
|
$pdf = Pdf::loadView('lpj::memo.pdf-template', compact('memoData', 'permohonanList', 'totalBiayaPJ'))
|
||||||
|
->setPaper('a4', 'portrait')
|
||||||
|
->setOptions([
|
||||||
|
'defaultFont' => 'Times-Roman',
|
||||||
|
'isRemoteEnabled' => true,
|
||||||
|
'isHtml5ParserEnabled' => true,
|
||||||
|
'isPhpEnabled' => true,
|
||||||
|
'dpi' => 150,
|
||||||
|
'defaultPaperSize' => 'a4',
|
||||||
|
'chroot' => public_path(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Nama file PDF
|
||||||
|
$fileName = 'memo-penyelesaian-' . str_replace(['/', ' '], ['-', '-'], $memoNumber) . '-' . date('Y-m-d-H-i-s') . '.pdf';
|
||||||
|
$filePath = 'memo-penyelesaian/' . $fileName;
|
||||||
|
|
||||||
|
// Simpan PDF ke storage
|
||||||
|
Storage::disk('public')->put($filePath, $pdf->output());
|
||||||
|
|
||||||
|
// Update status permohonan yang dipilih
|
||||||
|
// Update data di tabel NOC untuk setiap permohonan
|
||||||
|
foreach ($permohonanIds as $permohonanId) {
|
||||||
|
// Cari NOC berdasarkan permohonan_id
|
||||||
|
$noc = Noc::where('permohonan_id', $permohonanId)->first();
|
||||||
|
|
||||||
|
if ($noc) {
|
||||||
|
// Update field memo penyelesaian di tabel NOC
|
||||||
|
$noc->memo_penyelesaian = $filePath;
|
||||||
|
$noc->memo_penyelesaian_number = $memoNumber;
|
||||||
|
$noc->memo_penyelesaian_date = $memoDate;
|
||||||
|
$noc->memo_penyelesaian_payment_date = $paymentDate;
|
||||||
|
$noc->memo_penyelesaian_created_at = now();
|
||||||
|
$noc->save();
|
||||||
|
|
||||||
|
Log::info('MemoController: Berhasil update NOC untuk permohonan ID: ' . $permohonanId);
|
||||||
|
} else {
|
||||||
|
Log::warning('MemoController: NOC tidak ditemukan untuk permohonan ID: ' . $permohonanId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
Log::info('MemoController: Berhasil generate PDF dan menyimpan memo penyelesaian untuk ' . count($permohonanIds) . ' permohonan');
|
||||||
|
|
||||||
|
// Return PDF untuk download
|
||||||
|
return $pdf->download('memo-penyelesaian-' . $memoNumber . '.pdf');
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
DB::rollback();
|
||||||
|
Log::error('MemoController: Error saat generate PDF memo penyelesaian - ' . $e->getMessage());
|
||||||
|
|
||||||
|
return redirect()->back()
|
||||||
|
->with('error', 'Terjadi kesalahan saat generate PDF memo penyelesaian: ' . $e->getMessage())
|
||||||
|
->withInput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function untuk mendapatkan informasi jaminan
|
||||||
|
*
|
||||||
|
* @param $permohonanList
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getJaminanInfo($permohonanList)
|
||||||
|
{
|
||||||
|
$jaminanTypes = [];
|
||||||
|
foreach ($permohonanList as $permohonan) {
|
||||||
|
if ($permohonan->tujuanPenilaian) {
|
||||||
|
$jaminanTypes[] = $permohonan->tujuanPenilaian->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$uniqueJaminan = array_unique($jaminanTypes);
|
||||||
|
return implode(' & ', $uniqueJaminan);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Download PDF memo penyelesaian
|
||||||
|
*
|
||||||
|
* @param int $id - ID permohonan
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function downloadPdf($id)
|
||||||
|
{
|
||||||
|
Log::info('MemoController: Download PDF memo penyelesaian untuk permohonan ID: ' . $id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Cari NOC berdasarkan permohonan_id
|
||||||
|
$noc = Noc::where('permohonan_id', $id)->first();
|
||||||
|
|
||||||
|
if (!$noc || !$noc->memo_penyelesaian) {
|
||||||
|
Log::warning('MemoController: PDF memo penyelesaian tidak ditemukan untuk permohonan ID: ' . $id);
|
||||||
|
return redirect()->back()->with('error', 'File PDF memo penyelesaian tidak ditemukan.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cek apakah file ada di storage
|
||||||
|
if (!Storage::disk('public')->exists($noc->memo_penyelesaian)) {
|
||||||
|
Log::warning('MemoController: File PDF tidak ada di storage: ' . $noc->memo_penyelesaian);
|
||||||
|
return redirect()->back()->with('error', 'File PDF tidak ditemukan di server.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download file
|
||||||
|
$fileName = 'memo-penyelesaian-' . $noc->memo_penyelesaian_number . '.pdf';
|
||||||
|
|
||||||
|
Log::info('MemoController: Berhasil download PDF memo penyelesaian: ' . $fileName);
|
||||||
|
|
||||||
|
return Storage::disk('public')->download($noc->memo_penyelesaian, $fileName);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error('MemoController: Error saat download PDF memo penyelesaian - ' . $e->getMessage());
|
||||||
|
return redirect()->back()->with('error', 'Terjadi kesalahan saat mengunduh file PDF.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,10 +6,10 @@
|
|||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Modules\Lpj\Http\Requests\NocRequest;
|
use Modules\Lpj\Http\Requests\NocRequest;
|
||||||
use Modules\Lpj\Models\Noc;
|
use Modules\Lpj\Models\Bucok;
|
||||||
use Modules\Lpj\Models\PenawaranTender;
|
use Modules\Lpj\Models\Noc;
|
||||||
use Modules\Lpj\Models\Permohonan;
|
|
||||||
use Modules\Lpj\Models\PersetujuanPenawaran;
|
use Modules\Lpj\Models\PersetujuanPenawaran;
|
||||||
|
use Modules\Lpj\Models\JenisPenilaian;
|
||||||
|
|
||||||
class NocController extends Controller
|
class NocController extends Controller
|
||||||
{
|
{
|
||||||
@@ -26,13 +26,15 @@
|
|||||||
public function pembayaran()
|
public function pembayaran()
|
||||||
{
|
{
|
||||||
$persetujuanPenawarans = PersetujuanPenawaran::all();
|
$persetujuanPenawarans = PersetujuanPenawaran::all();
|
||||||
return view('lpj::noc.pembayaran', compact('persetujuanPenawarans'));
|
$jenisPenilaians = JenisPenilaian::get();
|
||||||
|
return view('lpj::noc.pembayaran', compact('persetujuanPenawarans', 'jenisPenilaians'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function penyelesaian()
|
public function penyelesaian()
|
||||||
{
|
{
|
||||||
$persetujuanPenawarans = PersetujuanPenawaran::all();
|
$persetujuanPenawarans = PersetujuanPenawaran::all();
|
||||||
return view('lpj::noc.penyelesaian', compact('persetujuanPenawarans'));
|
$jenisPenilaians = JenisPenilaian::get();
|
||||||
|
return view('lpj::noc.penyelesaian', compact('persetujuanPenawarans', 'jenisPenilaians'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,21 +49,27 @@
|
|||||||
public function store(NocRequest $request)
|
public function store(NocRequest $request)
|
||||||
{
|
{
|
||||||
$validated = $request->validated();
|
$validated = $request->validated();
|
||||||
|
|
||||||
|
|
||||||
$validated['updated_by'] = Auth::id();
|
$validated['updated_by'] = Auth::id();
|
||||||
if (request()->get('status_bayar') == "sudah_bayar") {
|
if (request()->get('status_bayar') == "sudah_bayar") {
|
||||||
$validated['status'] = '1';
|
$validated['status'] = '1';
|
||||||
$status = "spk";
|
|
||||||
} else {
|
|
||||||
$status = "persetujuan-penawaran";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$dataNoc = [
|
$dataNoc = [
|
||||||
'nominal_bayar' => $validated['nominal_bayar'],
|
'nominal_bayar' => $validated['nominal_bayar'],
|
||||||
|
'total_pembukuan' => $validated['total_pembukuan'],
|
||||||
'tanggal_pembayaran' => $validated['tanggal_pembayaran'] ?? date('Y-m-d'),
|
'tanggal_pembayaran' => $validated['tanggal_pembayaran'] ?? date('Y-m-d'),
|
||||||
'status_bayar' => $validated['nominal_bayar'] < $validated['total_harus_bayar'] ? false : true,
|
'status_bayar' => $validated['nominal_bayar'] < $validated['total_harus_bayar'] ? false : true,
|
||||||
'catatan_noc' => $validated['catatan_noc'],
|
'catatan_noc' => $validated['catatan_noc'] ?? '',
|
||||||
|
'status_kurang_bayar' => $validated['status_kurang_bayar'] ?? '0',
|
||||||
|
'status_lebih_bayar' => $validated['status_lebih_bayar'] ?? '0',
|
||||||
|
'nominal_kurang_bayar' => $validated['nominal_kurang_bayar'] ?? '0',
|
||||||
|
'nominal_lebih_bayar' => $validated['nominal_lebih_bayar'] ?? '0',
|
||||||
|
'bukti_pengembalian' => $validated['bukti_pengembalian'] ?? '',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if($validated['permohonan_id']){
|
||||||
$noc = Noc::updateOrCreate(
|
$noc = Noc::updateOrCreate(
|
||||||
[
|
[
|
||||||
'permohonan_id' => $validated['permohonan_id'],
|
'permohonan_id' => $validated['permohonan_id'],
|
||||||
@@ -69,6 +77,14 @@
|
|||||||
],
|
],
|
||||||
$dataNoc,
|
$dataNoc,
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
$noc = Noc::updateOrCreate(
|
||||||
|
[
|
||||||
|
'persetujuan_penawaran_id' => $validated['persetujuan_penawaran_id'],
|
||||||
|
],
|
||||||
|
$dataNoc,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$folderPath = 'noc/' . request()->get('persetujuan_penawaran_id') . '/bukti_ksl/';
|
$folderPath = 'noc/' . request()->get('persetujuan_penawaran_id') . '/bukti_ksl/';
|
||||||
|
|
||||||
@@ -80,26 +96,11 @@
|
|||||||
}
|
}
|
||||||
$noc->save();
|
$noc->save();
|
||||||
|
|
||||||
/* Update the status of the related permohonan to 'spk'
|
$bucok = Bucok::where('nomor_tiket', $noc->nomor_tiket)->first();
|
||||||
$permohonan = Permohonan::find(request()->get('permohonan_id'));
|
$bucok->nominal_penyelesaian = $noc->total_pembukuan ?? '';
|
||||||
if ($permohonan) {
|
$bucok->tanggal_penyelesaian = $noc->tanggal_pembayaran ?? date('Y-m-d');
|
||||||
$permohonan->status_bayar = request()->get('status_pembayar');
|
$bucok->penyelesaian = 'Selesai';
|
||||||
if ($permohonan->jenis_penilaian_id == 2) {
|
$bucok->save();
|
||||||
$permohonan->status = $status;
|
|
||||||
}
|
|
||||||
$permohonan->save();
|
|
||||||
|
|
||||||
// andy add, update status penawaran.status='spk'
|
|
||||||
// $penawaran = PenawaranTender::where('nomor_registrasi',$permohonan->nomor_registrasi)->first();
|
|
||||||
if ($permohonan->jenis_penilaian_id == 2) {
|
|
||||||
PenawaranTender::where('nomor_registrasi', $permohonan->nomor_registrasi)->update([
|
|
||||||
'status' => $status,
|
|
||||||
'updated_by' => Auth::id(),
|
|
||||||
'updated_at' => now(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
// andy add, update status penawaran.status='spk'
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('noc.index')->with('success', 'NOC berhasil disimpan.');
|
->route('noc.index')->with('success', 'NOC berhasil disimpan.');
|
||||||
@@ -112,6 +113,7 @@
|
|||||||
{
|
{
|
||||||
$validated = $request->validated();
|
$validated = $request->validated();
|
||||||
|
|
||||||
|
|
||||||
if($request->get('is_memo')){
|
if($request->get('is_memo')){
|
||||||
|
|
||||||
$memo = Noc::find($request->get('is_memo'));
|
$memo = Noc::find($request->get('is_memo'));
|
||||||
@@ -133,6 +135,7 @@
|
|||||||
->route('laporan.index')->with('success', 'Memo Penyelesaian updated successfully');
|
->route('laporan.index')->with('success', 'Memo Penyelesaian updated successfully');
|
||||||
}
|
}
|
||||||
$dataNoc = [
|
$dataNoc = [
|
||||||
|
'total_pembukuan' => $validated['total_pembukuan'],
|
||||||
'nominal_penyelesaian' => $validated['nominal_penyelesaian'],
|
'nominal_penyelesaian' => $validated['nominal_penyelesaian'],
|
||||||
'tanggal_penyelesaian' => $validated['tanggal_penyelesaian'] ?? date('Y-m-d'),
|
'tanggal_penyelesaian' => $validated['tanggal_penyelesaian'] ?? date('Y-m-d'),
|
||||||
'status_pelunasan' => ((int)$validated['nominal_bayar'] + (int)$validated['nominal_penyelesaian']) === (int)$validated['total_harus_bayar'] ? true : false,
|
'status_pelunasan' => ((int)$validated['nominal_bayar'] + (int)$validated['nominal_penyelesaian']) === (int)$validated['total_harus_bayar'] ? true : false,
|
||||||
@@ -215,15 +218,16 @@
|
|||||||
$query = PersetujuanPenawaran::query();
|
$query = PersetujuanPenawaran::query();
|
||||||
|
|
||||||
// Filter for pembayaran (where memo_penyelesaian is null)
|
// Filter for pembayaran (where memo_penyelesaian is null)
|
||||||
$query->whereDoesntHave('noc', function($q) {
|
/*$query->whereDoesntHave('noc', function($q) {
|
||||||
$q->whereNotNull('memo_penyelesaian');
|
$q->whereNotNull('memo_penyelesaian');
|
||||||
});
|
});*/
|
||||||
|
|
||||||
// Apply search filter if provided
|
// Apply search filter if provided
|
||||||
if ($request->has('search') && !empty($request->get('search'))) {
|
if ($request->has('search') && !empty($request->get('search'))) {
|
||||||
$search = $request->get('search');
|
$search = $request->get('search');
|
||||||
$query->where(function ($q) use ($search) {
|
$query->where(function ($q) use ($search) {
|
||||||
$q->orWhereRelation('penawaran', 'nomor_registrasi', 'LIKE', '%' . $search . '%');
|
$q->orWhereRelation('penawaran', 'nomor_registrasi', 'LIKE', '%' . $search . '%')
|
||||||
|
->orWhereRelation('permohonan.jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,9 +259,11 @@
|
|||||||
$data = $data->map(function ($persetujuanPenawaran) {
|
$data = $data->map(function ($persetujuanPenawaran) {
|
||||||
return [
|
return [
|
||||||
'id' => $persetujuanPenawaran->id,
|
'id' => $persetujuanPenawaran->id,
|
||||||
'nomor_registrasi' => $persetujuanPenawaran->permohonan->nomor_registrasi ?? $persetujuanPenawaran->penawaran->nomor_registrasi,
|
'nomor_registrasi' => $persetujuanPenawaran->permohonan?->nomor_registrasi ?? $persetujuanPenawaran->penawaran?->nomor_registrasi,
|
||||||
'nama_debitur' => $persetujuanPenawaran->permohonan->debiture->name ?? $persetujuanPenawaran->penawaran->permohonan->debiture->name,
|
'nomor_tiket' => $persetujuanPenawaran->nomor_tiket ?? '',
|
||||||
'cabang' => $persetujuanPenawaran->permohonan->branch->name ?? $persetujuanPenawaran->penawaran->permohonan->branch->name,
|
'nama_debitur' => $persetujuanPenawaran?->permohonan?->debiture->name ?? $persetujuanPenawaran->penawaran?->permohonan?->debiture->name ?? $persetujuanPenawaran->noc?->debiture->name,
|
||||||
|
'kode_cabang' => $persetujuanPenawaran?->permohonan?->branch->code ?? $persetujuanPenawaran->penawaran?->permohonan?->branch->code ?? $persetujuanPenawaran->noc?->branch->code,
|
||||||
|
'cabang' => $persetujuanPenawaran?->permohonan?->branch->name ?? $persetujuanPenawaran->penawaran?->permohonan?->branch->name ?? $persetujuanPenawaran->noc?->branch->name,
|
||||||
'tanggal_pembayaran' => dateFormat(
|
'tanggal_pembayaran' => dateFormat(
|
||||||
$persetujuanPenawaran->noc->tanggal_pembayaran ?? $persetujuanPenawaran->noc?->created_at,
|
$persetujuanPenawaran->noc->tanggal_pembayaran ?? $persetujuanPenawaran->noc?->created_at,
|
||||||
true,
|
true,
|
||||||
@@ -267,11 +273,19 @@
|
|||||||
'nominal_diterima' => currencyFormat(
|
'nominal_diterima' => currencyFormat(
|
||||||
$persetujuanPenawaran->noc->nominal_bayar ?? 0,
|
$persetujuanPenawaran->noc->nominal_bayar ?? 0,
|
||||||
),
|
),
|
||||||
|
'jenis_penilaian' => $persetujuanPenawaran->permohonan?->jenisPenilaian?->name ?? "",
|
||||||
'bukti_ksl' => $persetujuanPenawaran->noc->bukti_ksl ?? $persetujuanPenawaran->bukti_ksl ?? null,
|
'bukti_ksl' => $persetujuanPenawaran->noc->bukti_ksl ?? $persetujuanPenawaran->bukti_ksl ?? null,
|
||||||
'bukti_bayar' => $persetujuanPenawaran->bukti_bayar ?? null,
|
'bukti_bayar' => $persetujuanPenawaran->bukti_bayar ?? null,
|
||||||
'updated_at' => dateFormat($persetujuanPenawaran->updated_at, true),
|
'updated_at' => dateFormat($persetujuanPenawaran->updated_at, true),
|
||||||
];
|
];
|
||||||
})->sortBy('updated_at', 1);
|
})->sortBy('updated_at', 1)->values();
|
||||||
|
|
||||||
|
// Calculate total nominal diterima from all filtered data (not just current page)
|
||||||
|
$totalNominalDiterima = $data->sum(function ($item) {
|
||||||
|
// Extract numeric value from formatted currency string
|
||||||
|
$nominal = str_replace(['Rp', '.', ',00'], '', $item['nominal_diterima']);
|
||||||
|
return (float) $nominal;
|
||||||
|
});
|
||||||
|
|
||||||
// Calculate the page count
|
// Calculate the page count
|
||||||
$pageCount = ceil($totalRecords / $request->get('size'));
|
$pageCount = ceil($totalRecords / $request->get('size'));
|
||||||
@@ -287,6 +301,7 @@
|
|||||||
'pageCount' => $pageCount,
|
'pageCount' => $pageCount,
|
||||||
'page' => $currentPage,
|
'page' => $currentPage,
|
||||||
'totalCount' => $totalRecords,
|
'totalCount' => $totalRecords,
|
||||||
|
'totalNominalDiterima' => $totalNominalDiterima,
|
||||||
'data' => $data,
|
'data' => $data,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -301,15 +316,14 @@
|
|||||||
$query = PersetujuanPenawaran::query();
|
$query = PersetujuanPenawaran::query();
|
||||||
|
|
||||||
// Filter for penyelesaian (where memo_penyelesaian is not null)
|
// Filter for penyelesaian (where memo_penyelesaian is not null)
|
||||||
$query->whereHas('noc', function($q) {
|
|
||||||
$q->whereNotNull('memo_penyelesaian');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Apply search filter if provided
|
// Apply search filter if provided
|
||||||
if ($request->has('search') && !empty($request->get('search'))) {
|
if ($request->has('search') && !empty($request->get('search'))) {
|
||||||
$search = $request->get('search');
|
$search = $request->get('search');
|
||||||
$query->where(function ($q) use ($search) {
|
$query->where(function ($q) use ($search) {
|
||||||
$q->orWhereRelation('penawaran', 'nomor_registrasi', 'LIKE', '%' . $search . '%');
|
$q->orWhereRelation('penawaran', 'nomor_registrasi', 'LIKE', '%' . $search . '%')
|
||||||
|
->orWhereRelation('permohonan.jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,9 +355,11 @@
|
|||||||
$data = $data->map(function ($persetujuanPenawaran) {
|
$data = $data->map(function ($persetujuanPenawaran) {
|
||||||
return [
|
return [
|
||||||
'id' => $persetujuanPenawaran->id,
|
'id' => $persetujuanPenawaran->id,
|
||||||
'nomor_registrasi' => $persetujuanPenawaran->permohonan->nomor_registrasi ?? $persetujuanPenawaran->penawaran->nomor_registrasi,
|
'nomor_registrasi' => $persetujuanPenawaran->permohonan?->nomor_registrasi ?? $persetujuanPenawaran->penawaran?->nomor_registrasi ?? '',
|
||||||
'nama_debitur' => $persetujuanPenawaran->permohonan->debiture->name ?? $persetujuanPenawaran->penawaran->permohonan->debiture->name,
|
'nomor_tiket' => $persetujuanPenawaran->nomor_tiket ?? '',
|
||||||
'cabang' => $persetujuanPenawaran->permohonan->branch->name ?? $persetujuanPenawaran->penawaran->permohonan->branch->name,
|
'nama_debitur' => $persetujuanPenawaran->permohonan->debiture->name ?? $persetujuanPenawaran->penawaran->permohonan->debiture->name ?? $persetujuanPenawaran->noc->debiture->name,
|
||||||
|
'kode_cabang' => $persetujuanPenawaran?->permohonan?->branch->code ?? $persetujuanPenawaran->penawaran?->permohonan?->branch->code ?? $persetujuanPenawaran->noc?->branch->code,
|
||||||
|
'cabang' => $persetujuanPenawaran->permohonan->branch->name ?? $persetujuanPenawaran->penawaran->permohonan->branch->name ?? $persetujuanPenawaran->noc?->branch->name,
|
||||||
'tanggal_pembayaran' => dateFormat(
|
'tanggal_pembayaran' => dateFormat(
|
||||||
$persetujuanPenawaran->noc->tanggal_pembayaran ?? $persetujuanPenawaran->noc?->created_at,
|
$persetujuanPenawaran->noc->tanggal_pembayaran ?? $persetujuanPenawaran->noc?->created_at,
|
||||||
true,
|
true,
|
||||||
@@ -353,6 +369,7 @@
|
|||||||
'nominal_diterima' => currencyFormat(
|
'nominal_diterima' => currencyFormat(
|
||||||
$persetujuanPenawaran->noc->nominal_bayar ?? 0,
|
$persetujuanPenawaran->noc->nominal_bayar ?? 0,
|
||||||
),
|
),
|
||||||
|
'jenis_penilaian' => $persetujuanPenawaran->permohonan?->jenisPenilaian?->name ?? "",
|
||||||
'bukti_ksl' => $persetujuanPenawaran->noc->bukti_ksl ?? $persetujuanPenawaran->bukti_ksl ?? null,
|
'bukti_ksl' => $persetujuanPenawaran->noc->bukti_ksl ?? $persetujuanPenawaran->bukti_ksl ?? null,
|
||||||
'bukti_bayar' => $persetujuanPenawaran->bukti_bayar ?? null,
|
'bukti_bayar' => $persetujuanPenawaran->bukti_bayar ?? null,
|
||||||
'memo_penyelesaian' => $persetujuanPenawaran->noc->memo_penyelesaian ?? $persetujuanPenawaran->memo_penyelesaian ?? null,
|
'memo_penyelesaian' => $persetujuanPenawaran->noc->memo_penyelesaian ?? $persetujuanPenawaran->memo_penyelesaian ?? null,
|
||||||
@@ -365,7 +382,15 @@
|
|||||||
true) : '-',
|
true) : '-',
|
||||||
'updated_at' => dateFormat($persetujuanPenawaran->updated_at, true),
|
'updated_at' => dateFormat($persetujuanPenawaran->updated_at, true),
|
||||||
];
|
];
|
||||||
})->sortBy('updated_at', 1);
|
})->sortBy('updated_at', 1)->values();
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate total nominal diterima from all filtered data (not just current page)
|
||||||
|
$totalNominalDiterima = $data->sum(function ($item) {
|
||||||
|
// Extract numeric value from formatted currency string
|
||||||
|
$nominal = str_replace(['Rp', '.', ',00'], '', $item['nominal_diterima']);
|
||||||
|
return (float) $nominal;
|
||||||
|
});
|
||||||
|
|
||||||
// Calculate the page count
|
// Calculate the page count
|
||||||
$pageCount = ceil($totalRecords / $request->get('size'));
|
$pageCount = ceil($totalRecords / $request->get('size'));
|
||||||
@@ -381,6 +406,7 @@
|
|||||||
'pageCount' => $pageCount,
|
'pageCount' => $pageCount,
|
||||||
'page' => $currentPage,
|
'page' => $currentPage,
|
||||||
'totalCount' => $totalRecords,
|
'totalCount' => $totalRecords,
|
||||||
|
'totalNominalDiterima' => $totalNominalDiterima,
|
||||||
'data' => $data,
|
'data' => $data,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,17 @@
|
|||||||
|
|
||||||
namespace Modules\Lpj\Http\Controllers;
|
namespace Modules\Lpj\Http\Controllers;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Modules\Lpj\Models\Noc;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Modules\Lpj\Models\Bucok;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Maatwebsite\Excel\Facades\Excel;
|
|
||||||
use Modules\Lpj\Http\Requests\PersetujuanPenawaranRequest;
|
|
||||||
use Modules\Lpj\Models\PenawaranTender;
|
|
||||||
use Modules\Lpj\Models\Permohonan;
|
use Modules\Lpj\Models\Permohonan;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Modules\Lpj\Models\PenawaranTender;
|
||||||
use Modules\Lpj\Models\PersetujuanPenawaran;
|
use Modules\Lpj\Models\PersetujuanPenawaran;
|
||||||
|
use Modules\Lpj\Http\Requests\PersetujuanPenawaranRequest;
|
||||||
// use Modules\Lpj\Models\JenisPenilaian;
|
|
||||||
|
|
||||||
// use Modules\Lpj\Models\Regions;
|
|
||||||
|
|
||||||
class PembayaranController extends Controller
|
class PembayaranController extends Controller
|
||||||
{
|
{
|
||||||
@@ -27,6 +23,14 @@ class PembayaranController extends Controller
|
|||||||
return view('lpj::pembayaran.index');
|
return view('lpj::pembayaran.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function kurang(){
|
||||||
|
return view('lpj::pembayaran.kurang');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function lebih(){
|
||||||
|
return view('lpj::pembayaran.lebih');
|
||||||
|
}
|
||||||
|
|
||||||
public function approval()
|
public function approval()
|
||||||
{
|
{
|
||||||
return view('lpj::pembayaran.approval');
|
return view('lpj::pembayaran.approval');
|
||||||
@@ -107,16 +111,115 @@ class PembayaranController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function create(){
|
||||||
|
return view('lpj::pembayaran.create');
|
||||||
|
}
|
||||||
|
|
||||||
public function edit($id)
|
public function edit($id)
|
||||||
{
|
{
|
||||||
$permohonan = Permohonan::find($id);
|
|
||||||
|
|
||||||
|
$req = request()->all();
|
||||||
|
|
||||||
|
if(isset($req['tiket'])){
|
||||||
|
$persetujuanPenawaran = PersetujuanPenawaran::find($id);
|
||||||
|
$permohonan = Permohonan::find($persetujuanPenawaran?->permohonan_id);
|
||||||
|
} else {
|
||||||
|
$permohonan = Permohonan::find($id);
|
||||||
$persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first();
|
$persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first();
|
||||||
|
}
|
||||||
|
|
||||||
return view('lpj::pembayaran.form', compact('permohonan', 'persetujuanPenawaran'));
|
return view('lpj::pembayaran.form', compact('permohonan', 'persetujuanPenawaran'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function editKurang($id){
|
||||||
|
$noc = Noc::find($id);
|
||||||
|
$permohonan = Permohonan::find($noc->permohonan_id);
|
||||||
|
$persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first();
|
||||||
|
return view('lpj::pembayaran.form-kurang', compact('noc','permohonan','persetujuanPenawaran'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function editLebih($id){
|
||||||
|
$noc = Noc::find($id);
|
||||||
|
$permohonan = Permohonan::find($noc->permohonan_id);
|
||||||
|
$persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first();
|
||||||
|
return view('lpj::pembayaran.form-lebih', compact('noc','permohonan','persetujuanPenawaran'));
|
||||||
|
}
|
||||||
|
|
||||||
public function store(PersetujuanPenawaranRequest $request)
|
public function store(PersetujuanPenawaranRequest $request)
|
||||||
{
|
{
|
||||||
|
$req = request()->all();
|
||||||
|
|
||||||
|
if($req['type'] == 'create'){
|
||||||
|
$data = [
|
||||||
|
'nomor_tiket' => $req['nomor_tiket'] ?? '',
|
||||||
|
'nominal_bayar' => $req['nominal_bayar'] ?? '',
|
||||||
|
'catatan' => $req['catatan'] ?? ''
|
||||||
|
];
|
||||||
|
|
||||||
|
if(request()->hasFile('bukti_bayar')){
|
||||||
|
$folderPath = 'persetujuan_penawaran/bukti_bayar/' . $req['nomor_tiket'];
|
||||||
|
$data['bukti_bayar'] = $request->file('bukti_bayar')->store($folderPath, 'public');
|
||||||
|
}
|
||||||
|
|
||||||
|
$persetujuanPenawaran = PersetujuanPenawaran::create($data);
|
||||||
|
$noc = [
|
||||||
|
'persetujuan_penawaran_id' => $persetujuanPenawaran->id,
|
||||||
|
'nomor_tiket' => $req['nomor_tiket'] ?? '',
|
||||||
|
'debiture_id' => $req['debitur_id'] ?? '',
|
||||||
|
'branch_id' => Auth::user()->branch_id,
|
||||||
|
];
|
||||||
|
$noc = Noc::create($noc);
|
||||||
|
|
||||||
|
$bucok = [
|
||||||
|
'tanggal_penuh' => $persetujuanPenawaran->created_at,
|
||||||
|
'tanggal' => $persetujuanPenawaran->created_at->format('d'),
|
||||||
|
'bulan' => $persetujuanPenawaran->created_at->format('m'),
|
||||||
|
'tahun' => $persetujuanPenawaran->created_at->format('Y'),
|
||||||
|
'nomor_tiket' => $req['nomor_tiket'] ?? '',
|
||||||
|
'nominal' => $req['nominal_bayar'] ?? '',
|
||||||
|
'nominal_berjalan' => $req['nominal_bayar'] ?? '',
|
||||||
|
'penyelesaian' => 'Belum Selesai',
|
||||||
|
'nama_sub_direktorat' => $noc->branch?->name ?? '',
|
||||||
|
'nama_direktorat_cabang' => $noc->branch?->name ?? '',
|
||||||
|
];
|
||||||
|
|
||||||
|
Bucok::updateOrCreate([
|
||||||
|
'nomor_tiket' => $req['nomor_tiket'] ?? '',
|
||||||
|
], $bucok);
|
||||||
|
|
||||||
|
return redirect()
|
||||||
|
->route('pembayaran.index')->with('success', 'Pembayaran berhasil disimpan.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($req['type'] == 'kurang_bayar'){
|
||||||
|
$noc = Noc::find($req['noc_id']);
|
||||||
|
$noc->nominal_pelunasan = $req['nominal_pelunasan'];
|
||||||
|
if (request()->hasFile('bukti_ksl_kurang_bayar')) {
|
||||||
|
$folderPath = 'persetujuan_penawaran/bukti_ksl_kurang_bayar/' . $req['noc_id'];
|
||||||
|
$noc->bukti_ksl_kurang_bayar = $request->file('bukti_ksl_kurang_bayar')->store($folderPath, 'public');
|
||||||
|
}
|
||||||
|
$noc->save();
|
||||||
|
|
||||||
|
$persetujuanPenawaran = PersetujuanPenawaran::find($noc->persetujuan_penawaran_id);
|
||||||
|
$persetujuanPenawaran->bukti_ksl_kurang_bayar = $noc->bukti_ksl_kurang_bayar;
|
||||||
|
$persetujuanPenawaran->nominal_kurang_bayar = $req['nominal_pelunasan'];
|
||||||
|
$persetujuanPenawaran->save();
|
||||||
|
return redirect()
|
||||||
|
->route('pembayaran.kurang.index')->with('success', 'Pelunasan Kurang Bayar berhasil disimpan.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($req['type'] == 'lebih_bayar'){
|
||||||
|
$noc = Noc::find($req['noc_id']);
|
||||||
|
if (request()->hasFile('bukti_ksl_lebih_bayar')) {
|
||||||
|
$folderPath = 'persetujuan_penawaran/bukti_ksl_lebih_bayar/' . $req['noc_id'];
|
||||||
|
$noc->bukti_ksl_lebih_bayar = $request->file('bukti_ksl_lebih_bayar')->store($folderPath, 'public');
|
||||||
|
}
|
||||||
|
$noc->save();
|
||||||
|
|
||||||
|
return redirect()
|
||||||
|
->route('pembayaran.lebih.index')->with('success', 'Pengembalian Lebih Bayar berhasil disimpan.');
|
||||||
|
}
|
||||||
|
|
||||||
$validated = $request->validated();
|
$validated = $request->validated();
|
||||||
$validated['created_by'] = Auth::id();
|
$validated['created_by'] = Auth::id();
|
||||||
$validated['status'] = '0';
|
$validated['status'] = '0';
|
||||||
@@ -149,6 +252,15 @@ class PembayaranController extends Controller
|
|||||||
$validated
|
$validated
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(isset($validated['nomor_tiket'])){
|
||||||
|
$noc = Noc::where('nomor_tiket',$validated['nomor_tiket'])->first();
|
||||||
|
if($noc){
|
||||||
|
$noc->persetujuan_penawaran_id = $persetujuanPenawaran->id;
|
||||||
|
$noc->permohonan_id = $validated['permohonan_id'];
|
||||||
|
$noc->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$folderPath = 'persetujuan_penawaran/' . $validated['penawaran_id'];
|
$folderPath = 'persetujuan_penawaran/' . $validated['penawaran_id'];
|
||||||
|
|
||||||
if ($request->hasFile('bukti_bayar')) {
|
if ($request->hasFile('bukti_bayar')) {
|
||||||
@@ -254,31 +366,23 @@ class PembayaranController extends Controller
|
|||||||
// abort(403, 'Sorry! You are not allowed to view users.');
|
// abort(403, 'Sorry! You are not allowed to view users.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = Permohonan::query()->where(function ($query) {
|
$query = PersetujuanPenawaran::query();
|
||||||
$query->where(['status_bayar' => 'belum_bayar', 'jenis_penilaian_id' => 1])
|
|
||||||
->orWhere('status', 'revisi-pembayaran');
|
|
||||||
})
|
|
||||||
->where(function ($query) {
|
|
||||||
$query->whereNotIn('id', function ($subquery) {
|
|
||||||
$subquery->select('permohonan_id')
|
|
||||||
->from('persetujuan_penawaran')
|
|
||||||
->whereNotNull('permohonan_id');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
$query->where(function($q) {
|
||||||
|
$q->whereRelation('permohonan', function($query) {
|
||||||
|
$query->where('status_bayar', 'belum_bayar')
|
||||||
|
->where('jenis_penilaian_id', 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$query->orWhereRelation('permohonan','status_bayar','revisi-pembayaran');
|
||||||
|
$query->orWhere(function($q) {
|
||||||
|
$q->where('permohonan_id',null);
|
||||||
|
$q->where('nomor_tiket','!=',null);
|
||||||
|
});
|
||||||
|
|
||||||
// Pencarian berdasarkan parameter search
|
// Pencarian berdasarkan parameter search
|
||||||
if ($request->has('search') && !empty($request->get('search'))) {
|
if ($request->has('search') && !empty($request->get('search'))) {
|
||||||
$search = $request->get('search');
|
$search = $request->get('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('debiture', 'name', 'LIKE', '%' . $search . '%');
|
|
||||||
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
|
||||||
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');
|
|
||||||
$q->orWhere('status', 'LIKE', '%' . $search . '%');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sorting berdasarkan sortField dan sortOrder
|
// Sorting berdasarkan sortField dan sortOrder
|
||||||
@@ -308,9 +412,161 @@ class PembayaranController extends Controller
|
|||||||
$filteredRecords = $query->count();
|
$filteredRecords = $query->count();
|
||||||
|
|
||||||
// Ambil data dengan relasi
|
// Ambil data dengan relasi
|
||||||
$data = $query->with(['user', 'debiture', 'branch', 'jenisPenilaian'])->get();
|
$data = $query->get();
|
||||||
|
|
||||||
|
$data = $data->map(function ($item) {
|
||||||
|
return [
|
||||||
|
'id' => $item->permohonan?->id ?? $item->id,
|
||||||
|
'nomor_registrasi' => $item->permohonan?->nomor_registrasi,
|
||||||
|
'nomor_tiket' => $item->nomor_tiket ?? '',
|
||||||
|
'debiture' => $item->permohonan?->debiture ?? $item->noc?->debiture,
|
||||||
|
'user' => $item->permohonan?->user ?? $item->creator,
|
||||||
|
'status_bayar' => $item->permohonan?->status_bayar ?? ($item->nomor_tiket ? 'Sudah Bayar' : ''),
|
||||||
|
'tanggal_permohonan' => $item->permohonan?->tanggal_permohonan ?? '',
|
||||||
|
'branch' => $item->permohonan?->branch ?? $item->noc?->branch,
|
||||||
|
'is_permohonan' => $item->permohonan ?? ''
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Hitung jumlah halaman
|
||||||
|
$pageCount = ceil($totalRecords / $size);
|
||||||
|
|
||||||
|
// Ambil current page
|
||||||
|
$currentPage = max(1, $request->get('page', 1));
|
||||||
|
|
||||||
|
// Return JSON response
|
||||||
|
return response()->json([
|
||||||
|
'draw' => $request->get('draw'),
|
||||||
|
'recordsTotal' => $totalRecords,
|
||||||
|
'recordsFiltered' => $filteredRecords,
|
||||||
|
'pageCount' => $pageCount,
|
||||||
|
'page' => $currentPage,
|
||||||
|
'totalCount' => $totalRecords,
|
||||||
|
'data' => $data,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataForDatatablesKurang(Request $request)
|
||||||
|
{
|
||||||
|
if (is_null($this->user) || !$this->user->can('debitur.view')) {
|
||||||
|
// abort(403, 'Sorry! You are not allowed to view users.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = Noc::query()->where(function ($query) {
|
||||||
|
$query->where(['status_kurang_bayar' => '1'])
|
||||||
|
->where('bukti_ksl_kurang_bayar',null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sorting berdasarkan sortField dan sortOrder
|
||||||
|
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||||
|
$order = $request->get('sortOrder');
|
||||||
|
$column = $request->get('sortField');
|
||||||
|
$query->orderBy($column, $order);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hitung total records
|
||||||
|
$totalRecords = $query->count();
|
||||||
|
|
||||||
|
// Pagination (default page size 10)
|
||||||
|
$size = $request->get('size', 10);
|
||||||
|
if ($size == 0) {
|
||||||
|
$size = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('page') && $request->has('size')) {
|
||||||
|
$page = $request->get('page', 1);
|
||||||
|
$offset = ($page - 1) * $size;
|
||||||
|
|
||||||
|
$query->skip($offset)->take($size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filtered records
|
||||||
|
$filteredRecords = $query->count();
|
||||||
|
|
||||||
|
// Ambil data dengan relasi
|
||||||
|
$data = $query->get();
|
||||||
|
|
||||||
|
$data = $data->map(function ($item) {
|
||||||
|
return [
|
||||||
|
'id' => $item->id,
|
||||||
|
'permohonan' => $item->permohonan,
|
||||||
|
'pemohon' => $item->permohonan->user,
|
||||||
|
'branch' => $item->permohonan->branch,
|
||||||
|
'debiture' => $item->permohonan->debiture,
|
||||||
|
'nominal_kurang_bayar' => formatRupiah($item->nominal_kurang_bayar,2)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Hitung jumlah halaman
|
||||||
|
$pageCount = ceil($totalRecords / $size);
|
||||||
|
|
||||||
|
// Ambil current page
|
||||||
|
$currentPage = max(1, $request->get('page', 1));
|
||||||
|
|
||||||
|
// Return JSON response
|
||||||
|
return response()->json([
|
||||||
|
'draw' => $request->get('draw'),
|
||||||
|
'recordsTotal' => $totalRecords,
|
||||||
|
'recordsFiltered' => $filteredRecords,
|
||||||
|
'pageCount' => $pageCount,
|
||||||
|
'page' => $currentPage,
|
||||||
|
'totalCount' => $totalRecords,
|
||||||
|
'data' => $data,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataForDatatablesLebih(Request $request)
|
||||||
|
{
|
||||||
|
if (is_null($this->user) || !$this->user->can('debitur.view')) {
|
||||||
|
// abort(403, 'Sorry! You are not allowed to view users.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = Noc::query()->where(function ($query) {
|
||||||
|
$query->where(['status_lebih_bayar' => '1'])
|
||||||
|
->where('bukti_ksl_lebih_bayar',null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sorting berdasarkan sortField dan sortOrder
|
||||||
|
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||||
|
$order = $request->get('sortOrder');
|
||||||
|
$column = $request->get('sortField');
|
||||||
|
$query->orderBy($column, $order);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hitung total records
|
||||||
|
$totalRecords = $query->count();
|
||||||
|
|
||||||
|
// Pagination (default page size 10)
|
||||||
|
$size = $request->get('size', 10);
|
||||||
|
if ($size == 0) {
|
||||||
|
$size = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('page') && $request->has('size')) {
|
||||||
|
$page = $request->get('page', 1);
|
||||||
|
$offset = ($page - 1) * $size;
|
||||||
|
|
||||||
|
$query->skip($offset)->take($size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filtered records
|
||||||
|
$filteredRecords = $query->count();
|
||||||
|
|
||||||
|
// Ambil data dengan relasi
|
||||||
|
$data = $query->get();
|
||||||
|
|
||||||
|
$data = $data->map(function ($item) {
|
||||||
|
return [
|
||||||
|
'id' => $item->id,
|
||||||
|
'permohonan' => $item->permohonan,
|
||||||
|
'pemohon' => $item->permohonan->user,
|
||||||
|
'branch' => $item->permohonan->branch,
|
||||||
|
'debiture' => $item->permohonan->debiture,
|
||||||
|
'nominal_lebih_bayar' => formatRupiah($item->nominal_lebih_bayar,2)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
// Hitung jumlah halaman
|
// Hitung jumlah halaman
|
||||||
$pageCount = ceil($totalRecords / $size);
|
$pageCount = ceil($totalRecords / $size);
|
||||||
|
|
||||||
|
|||||||
473
app/Http/Controllers/SlikController.php
Normal file
473
app/Http/Controllers/SlikController.php
Normal file
@@ -0,0 +1,473 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Modules\Lpj\Imports\SlikImport;
|
||||||
|
use Modules\Lpj\Models\Slik;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller untuk mengelola data Slik
|
||||||
|
*
|
||||||
|
* Menangani operasi CRUD dan import data Slik dari file Excel
|
||||||
|
* dengan fitur server-side processing untuk datatables
|
||||||
|
*
|
||||||
|
* @package Modules\Lpj\Http\Controllers
|
||||||
|
*/
|
||||||
|
class SlikController extends Controller
|
||||||
|
{
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->user = Auth::user();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menampilkan halaman index slik
|
||||||
|
*
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('lpj::slik.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menampilkan detail slik
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
$slik = Slik::findOrFail($id);
|
||||||
|
return view('lpj::slik.show', compact('slik'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data untuk datatables dengan server-side processing
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function dataForDatatables(Request $request)
|
||||||
|
{
|
||||||
|
// Authorization check dapat ditambahkan sesuai kebutuhan
|
||||||
|
// if (is_null($this->user)) {
|
||||||
|
// abort(403, 'Unauthorized access.');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Retrieve data from the database
|
||||||
|
$query = Slik::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('sandi_bank', 'LIKE', "%$search%")
|
||||||
|
->orWhere('no_rekening', 'LIKE', "%$search%")
|
||||||
|
->orWhere('cif', 'LIKE', "%$search%")
|
||||||
|
->orWhere('nama_debitur', 'LIKE', "%$search%")
|
||||||
|
->orWhere('nama_cabang', 'LIKE', "%$search%")
|
||||||
|
->orWhere('jenis_agunan', 'LIKE', "%$search%")
|
||||||
|
->orWhere('nama_pemilik_agunan', 'LIKE', "%$search%")
|
||||||
|
->orWhere('alamat_agunan', 'LIKE', "%$search%")
|
||||||
|
->orWhere('lokasi_agunan', 'LIKE', "%$search%");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply year filter
|
||||||
|
if ($request->has('year') && !empty($request->get('year'))) {
|
||||||
|
$query->byYear($request->get('year'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply month filter
|
||||||
|
if ($request->has('month') && !empty($request->get('month'))) {
|
||||||
|
$query->byMonth($request->get('month'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply sandi bank filter
|
||||||
|
if ($request->has('sandi_bank') && !empty($request->get('sandi_bank'))) {
|
||||||
|
$query->where('sandi_bank', $request->get('sandi_bank'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply kolektibilitas filter
|
||||||
|
if ($request->has('kolektibilitas') && !empty($request->get('kolektibilitas'))) {
|
||||||
|
$query->where('kolektibilitas', $request->get('kolektibilitas'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply jenis agunan filter
|
||||||
|
if ($request->has('jenis_agunan') && !empty($request->get('jenis_agunan'))) {
|
||||||
|
$query->where('jenis_agunan', $request->get('jenis_agunan'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply sorting if provided
|
||||||
|
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||||
|
$order = $request->get('sortOrder');
|
||||||
|
$column = $request->get('sortField', 'created_at');
|
||||||
|
$query->orderBy($column, $order);
|
||||||
|
} else {
|
||||||
|
$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; // Calculate the offset
|
||||||
|
|
||||||
|
$query->skip($offset)->take($size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the filtered count of records
|
||||||
|
$filteredRecords = $query->count();
|
||||||
|
|
||||||
|
// Get the data for the current page with relationships
|
||||||
|
$data = $query->get();
|
||||||
|
|
||||||
|
// Transform data untuk datatables
|
||||||
|
$transformedData = $data->map(function ($item) {
|
||||||
|
return [
|
||||||
|
'id' => $item->id,
|
||||||
|
'sandi_bank' => $item->sandi_bank,
|
||||||
|
'tahun' => $item->tahun,
|
||||||
|
'bulan' => $item->bulan,
|
||||||
|
'no_rekening' => $item->no_rekening,
|
||||||
|
'cif' => $item->cif,
|
||||||
|
'nama_debitur' => $item->nama_debitur,
|
||||||
|
'kolektibilitas' => $item->kolektibilitas,
|
||||||
|
'kolektibilitas_badge' => $item->kolektibilitas_badge,
|
||||||
|
'fasilitas' => $item->fasilitas,
|
||||||
|
'jenis_agunan' => $item->jenis_agunan,
|
||||||
|
'nama_pemilik_agunan' => $item->nama_pemilik_agunan,
|
||||||
|
'nilai_agunan' => $item->nilai_agunan_formatted,
|
||||||
|
'nilai_agunan_ljk' => $item->nilai_agunan_ljk_formatted,
|
||||||
|
'alamat_agunan' => $item->alamat_agunan,
|
||||||
|
'lokasi_agunan' => $item->lokasi_agunan,
|
||||||
|
'nama_cabang' => $item->nama_cabang,
|
||||||
|
'kode_cabang' => $item->kode_cabang,
|
||||||
|
'created_by' => $item->creator?->name ?? '-',
|
||||||
|
'created_at' => dateFormat($item->created_at, true)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Calculate the page count
|
||||||
|
$pageCount = ceil($totalRecords / ($request->get('size', 10)));
|
||||||
|
|
||||||
|
// 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' => $transformedData,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import data slik dari Excel dengan optimasi memory dan progress tracking
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function import(Request $request)
|
||||||
|
{
|
||||||
|
Log::info('SlikController: Starting import process with optimizations', [
|
||||||
|
'user_id' => Auth::id(),
|
||||||
|
'request_size' => $request->header('Content-Length'),
|
||||||
|
'has_file' => $request->hasFile('file'),
|
||||||
|
'memory_limit' => ini_get('memory_limit'),
|
||||||
|
'max_execution_time' => ini_get('max_execution_time')
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Validasi file upload dengan logging detail dan error handling komprehensif
|
||||||
|
try {
|
||||||
|
// Cek apakah ada file yang diupload
|
||||||
|
if (!$request->hasFile('file')) {
|
||||||
|
Log::error('SlikController: Tidak ada file yang diupload', [
|
||||||
|
'user_id' => Auth::id(),
|
||||||
|
'files_count' => count($request->allFiles()),
|
||||||
|
'request_data' => $request->all()
|
||||||
|
]);
|
||||||
|
throw ValidationException::withMessages(['file' => 'Tidak ada file yang diupload.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $request->file('file');
|
||||||
|
|
||||||
|
// Cek apakah file valid
|
||||||
|
if (!$file->isValid()) {
|
||||||
|
$error = $file->getError();
|
||||||
|
$errorMessage = match($error) {
|
||||||
|
UPLOAD_ERR_INI_SIZE => 'File terlalu besar (melebihi upload_max_filesize).',
|
||||||
|
UPLOAD_ERR_FORM_SIZE => 'File terlalu besar (melebihi MAX_FILE_SIZE).',
|
||||||
|
UPLOAD_ERR_PARTIAL => 'File hanya terupload sebagian.',
|
||||||
|
UPLOAD_ERR_NO_FILE => 'Tidak ada file yang diupload.',
|
||||||
|
UPLOAD_ERR_NO_TMP_DIR => 'Direktori temp tidak tersedia.',
|
||||||
|
UPLOAD_ERR_CANT_WRITE => 'Gagal menulis file ke disk.',
|
||||||
|
UPLOAD_ERR_EXTENSION => 'Upload dibatalkan oleh ekstensi PHP.',
|
||||||
|
default => 'Error upload tidak diketahui: ' . $error
|
||||||
|
};
|
||||||
|
|
||||||
|
Log::error('SlikController: File upload tidak valid', [
|
||||||
|
'error' => $error,
|
||||||
|
'error_message' => $errorMessage,
|
||||||
|
'user_id' => Auth::id(),
|
||||||
|
'file_info' => [
|
||||||
|
'name' => $file->getClientOriginalName(),
|
||||||
|
'size' => $file->getSize(),
|
||||||
|
'mime' => $file->getMimeType()
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
throw ValidationException::withMessages(['file' => $errorMessage]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$maxFileSize = config('import.slik.max_file_size', 50) * 1024; // dalam KB
|
||||||
|
$request->validate([
|
||||||
|
'file' => 'required|file|mimes:xlsx,xls|max:' . $maxFileSize
|
||||||
|
]);
|
||||||
|
Log::info('SlikController: Validasi file berhasil');
|
||||||
|
} catch (\Illuminate\Validation\ValidationException $e) {
|
||||||
|
Log::error('SlikController: Validasi file gagal', [
|
||||||
|
'errors' => $e->errors(),
|
||||||
|
'user_id' => Auth::id(),
|
||||||
|
'request_size' => $request->header('Content-Length')
|
||||||
|
]);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$uploadedFile = $request->file('file');
|
||||||
|
$originalName = $uploadedFile->getClientOriginalName();
|
||||||
|
$fileSize = $uploadedFile->getSize();
|
||||||
|
|
||||||
|
Log::info('SlikController: Memulai import data Slik', [
|
||||||
|
'user_id' => Auth::id(),
|
||||||
|
'filename' => $originalName,
|
||||||
|
'filesize' => $fileSize,
|
||||||
|
'filesize_mb' => round($fileSize / 1024 / 1024, 2),
|
||||||
|
'mime_type' => $uploadedFile->getMimeType(),
|
||||||
|
'extension' => $uploadedFile->getClientOriginalExtension()
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Generate unique import ID
|
||||||
|
$importId = uniqid('slik_import_');
|
||||||
|
$userId = Auth::id() ?? 1;
|
||||||
|
|
||||||
|
// Cek apakah menggunakan queue processing untuk file besar
|
||||||
|
$useQueue = config('import.slik.queue.enabled', false) && $fileSize > (5 * 1024 * 1024); // > 5MB
|
||||||
|
|
||||||
|
// Pastikan direktori temp ada
|
||||||
|
$tempDir = storage_path('app/temp');
|
||||||
|
if (!file_exists($tempDir)) {
|
||||||
|
mkdir($tempDir, 0755, true);
|
||||||
|
Log::info('SlikController: Direktori temp dibuat', ['path' => $tempDir]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simpan file sementara dengan nama unik
|
||||||
|
$tempFileName = 'slik_import_' . time() . '_' . uniqid() . '.' . $uploadedFile->getClientOriginalExtension();
|
||||||
|
$tempFilePath = $tempDir . '/' . $tempFileName;
|
||||||
|
|
||||||
|
Log::info('SlikController: Memindahkan file ke temp', [
|
||||||
|
'temp_path' => $tempFilePath,
|
||||||
|
'use_queue' => $useQueue
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Pindahkan file ke direktori temp
|
||||||
|
$uploadedFile->move($tempDir, $tempFilePath);
|
||||||
|
|
||||||
|
// Verifikasi file berhasil dipindahkan
|
||||||
|
if (!file_exists($tempFilePath)) {
|
||||||
|
throw new Exception('File gagal dipindahkan ke direktori temp');
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info('SlikController: File berhasil dipindahkan', [
|
||||||
|
'file_size' => filesize($tempFilePath)
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($useQueue) {
|
||||||
|
Log::info('SlikController: Menggunakan queue processing untuk file besar', [
|
||||||
|
'import_id' => $importId,
|
||||||
|
'file_size_mb' => round($fileSize / 1024 / 1024, 2)
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Dispatch job ke queue
|
||||||
|
\Modules\Lpj\Jobs\ProcessSlikImport::dispatch($tempFilePath, $userId, $importId);
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', 'Import sedang diproses di background. ID: ' . $importId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import langsung untuk file kecil
|
||||||
|
Log::info('SlikController: Processing file directly', [
|
||||||
|
'import_id' => $importId,
|
||||||
|
'file_size_mb' => round($fileSize / 1024 / 1024, 2)
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Set optimasi memory untuk import langsung
|
||||||
|
$memoryLimit = config('import.slik.memory_limit', 256);
|
||||||
|
ini_set('memory_limit', $memoryLimit . 'M');
|
||||||
|
ini_set('max_execution_time', config('import.slik.timeout', 30000));
|
||||||
|
|
||||||
|
// Enable garbage collection jika diizinkan
|
||||||
|
if (config('import.slik.enable_gc', true)) {
|
||||||
|
gc_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proses import menggunakan SlikImport class
|
||||||
|
Log::info('SlikController: Memulai proses Excel import');
|
||||||
|
$import = new SlikImport();
|
||||||
|
Excel::import($import, $tempFilePath);
|
||||||
|
Log::info('SlikController: Excel import selesai');
|
||||||
|
|
||||||
|
// Force garbage collection setelah selesai
|
||||||
|
if (config('import.slik.enable_gc', true)) {
|
||||||
|
gc_collect_cycles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hapus file temporary setelah import
|
||||||
|
if (file_exists($tempFilePath)) {
|
||||||
|
unlink($tempFilePath);
|
||||||
|
Log::info('SlikController: File temp berhasil dihapus');
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info('SlikController: Data Slik berhasil diimport', [
|
||||||
|
'user_id' => Auth::id(),
|
||||||
|
'import_id' => $importId
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', 'Data Slik berhasil diimport dari file Excel.');
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Hapus file temporary jika ada error
|
||||||
|
if (isset($tempFilePath) && file_exists($tempFilePath)) {
|
||||||
|
unlink($tempFilePath);
|
||||||
|
Log::info('SlikController: File temp dihapus karena error');
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::error('SlikController: Gagal import data Slik', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'trace' => $e->getTraceAsString(),
|
||||||
|
'user_id' => Auth::id(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'memory_usage' => memory_get_usage(true)
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->back()->with('error', 'Gagal import data Slik: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menampilkan halaman form import
|
||||||
|
*
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function importForm()
|
||||||
|
{
|
||||||
|
return view('lpj::slik.import');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download template Excel untuk import
|
||||||
|
*
|
||||||
|
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||||
|
*/
|
||||||
|
public function downloadTemplate()
|
||||||
|
{
|
||||||
|
$templatePath = resource_path('metronic/slik.xlsx');
|
||||||
|
|
||||||
|
if (!file_exists($templatePath)) {
|
||||||
|
return redirect()->back()->with('error', 'Template file tidak ditemukan.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->download($templatePath, 'template_slik.xlsx');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get import progress
|
||||||
|
*
|
||||||
|
* @param string $importId
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function progress(string $importId)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$progressService = new \Modules\Lpj\Services\ImportProgressService();
|
||||||
|
$progress = $progressService->getProgress($importId);
|
||||||
|
|
||||||
|
if (!$progress) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Progress import tidak ditemukan'
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'progress' => $progress
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('SlikController: Error getting progress', [
|
||||||
|
'import_id' => $importId,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Gagal mendapatkan progress: ' . $e->getMessage()
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hapus semua data slik
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function truncate()
|
||||||
|
{
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
Log::info('SlikController: Menghapus semua data Slik', [
|
||||||
|
'user_id' => Auth::id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
Slik::truncate();
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
Log::info('SlikController: Semua data Slik berhasil dihapus', [
|
||||||
|
'user_id' => Auth::id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', 'Semua data Slik berhasil dihapus.');
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
DB::rollback();
|
||||||
|
Log::error('SlikController: Gagal menghapus data Slik', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'user_id' => Auth::id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->back()->with('error', 'Gagal menghapus data Slik: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
app/Http/Requests/CategoryDaftarPustakaRequest.php
Normal file
33
app/Http/Requests/CategoryDaftarPustakaRequest.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class CategoryDaftarPustakaRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
$rules = [
|
||||||
|
'name' => 'required|max:255',
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($this->method() == 'PUT') {
|
||||||
|
$rules['code'] = 'required|max:50|unique:category_daftar_pustaka,code,' . $this->id;
|
||||||
|
} else {
|
||||||
|
$rules['code'] = 'required|max:50|unique:category_daftar_pustaka,code';
|
||||||
|
}
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
app/Http/Requests/DaftarPustakaRequest.php
Normal file
38
app/Http/Requests/DaftarPustakaRequest.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class DaftarPustakaRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
|
||||||
|
$rules = [
|
||||||
|
'judul' => 'required|max:255',
|
||||||
|
'category_id' => 'required',
|
||||||
|
'deskripsi' => 'nullable',
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($this->method() == 'PUT') {
|
||||||
|
$rules['attachment'] = 'nullable|mimes:pdf,jpg,jpeg,png,gif';
|
||||||
|
} else {
|
||||||
|
$rules['attachment'] = 'required|mimes:pdf,jpg,jpeg,png,gif';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
private function getBasicInfoRules()
|
private function getBasicInfoRules()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'permohonan_id' => 'required|exists:permohonan,id',
|
'permohonan_id' => 'nullable|exists:permohonan,id',
|
||||||
'persetujuan_penawaran_id' => 'required|exists:persetujuan_penawaran,id',
|
'persetujuan_penawaran_id' => 'required|exists:persetujuan_penawaran,id',
|
||||||
'status' => 'nullable|boolean',
|
'status' => 'nullable|boolean',
|
||||||
'created_by' => 'nullable|exists:users,id',
|
'created_by' => 'nullable|exists:users,id',
|
||||||
@@ -72,10 +72,16 @@
|
|||||||
return [
|
return [
|
||||||
'total_harus_bayar' => 'nullable|numeric|min:0',
|
'total_harus_bayar' => 'nullable|numeric|min:0',
|
||||||
'nominal_bayar' => 'nullable|numeric|min:0',
|
'nominal_bayar' => 'nullable|numeric|min:0',
|
||||||
|
'total_pembukuan' => 'nullable|numeric|min:0',
|
||||||
'bukti_ksl' => $fileRule,
|
'bukti_ksl' => $fileRule,
|
||||||
'bukti_bayar' => $fileRule,
|
'bukti_bayar' => $fileRule,
|
||||||
'status_bayar' => 'nullable|boolean',
|
'status_bayar' => 'nullable|boolean',
|
||||||
'tanggal_pembayaran' => 'nullable|date',
|
'tanggal_pembayaran' => 'nullable|date',
|
||||||
|
'status_kurang_bayar' => 'nullable|boolean',
|
||||||
|
'status_lebih_bayar' => 'nullable|boolean',
|
||||||
|
'nominal_kurang_bayar' => 'nullable|numeric|min:0',
|
||||||
|
'nominal_lebih_bayar' => 'nullable|numeric|min:0',
|
||||||
|
'bukti_pengembalian' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:2048',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +101,10 @@
|
|||||||
'bukti_penyelesaian' => $fileRule,
|
'bukti_penyelesaian' => $fileRule,
|
||||||
'memo_penyelesaian' => $fileRule,
|
'memo_penyelesaian' => $fileRule,
|
||||||
'catatan_noc' => 'nullable|string',
|
'catatan_noc' => 'nullable|string',
|
||||||
|
'nomor_tiket' => 'nullable|string',
|
||||||
|
'nomor_rekening_lebih_bayar' => 'nullable|string',
|
||||||
|
'bukti_ksl_lebih_bayar' => 'nullable|string',
|
||||||
|
'bukti_ksl_kurang_bayar' => 'nullable|string'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +130,6 @@
|
|||||||
public function messages()
|
public function messages()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'permohonan_id.required' => 'ID Permohonan harus diisi',
|
|
||||||
'permohonan_id.exists' => 'ID Permohonan tidak valid',
|
'permohonan_id.exists' => 'ID Permohonan tidak valid',
|
||||||
'persetujuan_penawaran_id.required' => 'ID Persetujuan Penawaran harus diisi',
|
'persetujuan_penawaran_id.required' => 'ID Persetujuan Penawaran harus diisi',
|
||||||
'persetujuan_penawaran_id.exists' => 'ID Persetujuan Penawaran tidak valid',
|
'persetujuan_penawaran_id.exists' => 'ID Persetujuan Penawaran tidak valid',
|
||||||
@@ -148,6 +157,11 @@
|
|||||||
'authorized_status.boolean' => 'Status Otorisasi harus berupa boolean',
|
'authorized_status.boolean' => 'Status Otorisasi harus berupa boolean',
|
||||||
'authorized_at.date' => 'Format Tanggal Otorisasi tidak valid',
|
'authorized_at.date' => 'Format Tanggal Otorisasi tidak valid',
|
||||||
'authorized_by.exists' => 'User Otorisasi tidak valid',
|
'authorized_by.exists' => 'User Otorisasi tidak valid',
|
||||||
|
'status_kurang_bayar.boolean' => 'Status Kurang Bayar harus berupa boolean',
|
||||||
|
'status_lebih_bayar.boolean' => 'Status Lebih Bayar harus berupa boolean',
|
||||||
|
'nominal_kurang_bayar.numeric' => 'Nominal Kurang Bayar harus berupa angka',
|
||||||
|
'nominal_kurang_bayar.min' => 'Nominal Kurang Bayar minimal 0',
|
||||||
|
'nominal_lebih_bayar.numeric' => 'Nominal Lebih Bayar harus berupa angka',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
'permohonan_id' => 'nullable|exists:permohonan,id',
|
'permohonan_id' => 'nullable|exists:permohonan,id',
|
||||||
'penawaran_id' => 'nullable|exists:penawaran,id',
|
'penawaran_id' => 'nullable|exists:penawaran,id',
|
||||||
'nomor_proposal_penawaran' => 'nullable|string|max:255',
|
'nomor_proposal_penawaran' => 'nullable|string|max:255',
|
||||||
|
'nomor_tiket' => 'nullable|string|max:100',
|
||||||
|
'nominal_kurang_bayar' => 'nullable|string|max:100',
|
||||||
|
'bukti_ksl_kurang_bayar' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
|
||||||
'tanggal_proposal_penawaran' => 'nullable|date',
|
'tanggal_proposal_penawaran' => 'nullable|date',
|
||||||
'biaya_final' => 'nullable|numeric|min:0',
|
'biaya_final' => 'nullable|numeric|min:0',
|
||||||
'sla_resume' => 'nullable|numeric|min:0',
|
'sla_resume' => 'nullable|numeric|min:0',
|
||||||
@@ -37,6 +40,8 @@
|
|||||||
'penawaran_id.required' => 'Penawaran ID wajib diisi.',
|
'penawaran_id.required' => 'Penawaran ID wajib diisi.',
|
||||||
'penawaran_id.exists' => 'Penawaran ID tidak valid.',
|
'penawaran_id.exists' => 'Penawaran ID tidak valid.',
|
||||||
'nomor_proposal_penawaran.required' => 'Nomor proposal penawaran wajib diisi.',
|
'nomor_proposal_penawaran.required' => 'Nomor proposal penawaran wajib diisi.',
|
||||||
|
'nomor_tiket.string' => 'Nomor tiket harus berupa teks.',
|
||||||
|
'nomor_tiket.max' => 'Nomor tiket tidak boleh lebih dari 100 karakter.',
|
||||||
'tanggal_proposal_penawaran.required' => 'Tanggal proposal penawaran wajib diisi.',
|
'tanggal_proposal_penawaran.required' => 'Tanggal proposal penawaran wajib diisi.',
|
||||||
'tanggal_proposal_penawaran.date' => 'Tanggal proposal penawaran harus berupa tanggal yang valid.',
|
'tanggal_proposal_penawaran.date' => 'Tanggal proposal penawaran harus berupa tanggal yang valid.',
|
||||||
'biaya_final.required' => 'Biaya final wajib diisi.',
|
'biaya_final.required' => 'Biaya final wajib diisi.',
|
||||||
|
|||||||
341
app/Imports/BucokImport.php
Normal file
341
app/Imports/BucokImport.php
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Imports;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStartRow;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithValidation;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithBatchInserts;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithChunkReading;
|
||||||
|
use Modules\Lpj\Models\Bucok;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kelas untuk mengimpor data Excel ke tabel bucoks
|
||||||
|
* Menggunakan Laravel Excel dengan validasi dan batch processing
|
||||||
|
* Data dimulai dari baris ke-5 tanpa header
|
||||||
|
*/
|
||||||
|
class BucokImport implements ToCollection, WithStartRow, WithValidation, WithBatchInserts, WithChunkReading
|
||||||
|
{
|
||||||
|
private $importedCount = 0;
|
||||||
|
private $skippedCount = 0;
|
||||||
|
private $createdCount = 0;
|
||||||
|
private $updatedCount = 0;
|
||||||
|
private $errors = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menentukan baris mulai membaca data (baris ke-5)
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function startRow(): int
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memproses koleksi data dari Excel
|
||||||
|
*
|
||||||
|
* @param Collection $collection
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function collection(Collection $collection)
|
||||||
|
{
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
foreach ($collection as $rowIndex => $row) {
|
||||||
|
// Log setiap baris yang diproses
|
||||||
|
Log::info('Processing Bucok import row', [
|
||||||
|
'row_number' => $rowIndex + 5, // +5 karena mulai dari baris 5
|
||||||
|
'row_data' => $row->toArray()
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Konversi row ke array dengan indeks numerik
|
||||||
|
$rowArray = $row->toArray();
|
||||||
|
|
||||||
|
// Skip baris kosong
|
||||||
|
if (empty(array_filter($rowArray))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi data baris
|
||||||
|
$mappedData = $this->mapRowToBucok($rowArray, $rowIndex + 5);
|
||||||
|
|
||||||
|
// Update atau create berdasarkan nomor_tiket
|
||||||
|
if (!empty($mappedData['nomor_tiket'])) {
|
||||||
|
// Update atau create berdasarkan nomor_tiket
|
||||||
|
$bucok = Bucok::updateOrCreate(
|
||||||
|
['nomor_tiket' => $mappedData['nomor_tiket']], // Kondisi pencarian
|
||||||
|
array_merge($mappedData, ['updated_by' => auth()->id()]) // Data yang akan diupdate/create
|
||||||
|
);
|
||||||
|
|
||||||
|
// Log dan tracking apakah data di-update atau di-create
|
||||||
|
if ($bucok->wasRecentlyCreated) {
|
||||||
|
$this->createdCount++;
|
||||||
|
Log::info('Bucok created successfully', [
|
||||||
|
'row_number' => $rowIndex + 5,
|
||||||
|
'nomor_tiket' => $mappedData['nomor_tiket'],
|
||||||
|
'action' => 'created'
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$this->updatedCount++;
|
||||||
|
Log::info('Bucok updated successfully', [
|
||||||
|
'row_number' => $rowIndex + 5,
|
||||||
|
'nomor_tiket' => $mappedData['nomor_tiket'],
|
||||||
|
'action' => 'updated'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->importedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
// Log summary
|
||||||
|
Log::info('Bucok import completed', [
|
||||||
|
'imported' => $this->importedCount,
|
||||||
|
'skipped' => $this->skippedCount,
|
||||||
|
'total_errors' => count($this->errors)
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
DB::rollback();
|
||||||
|
Log::error('Bucok import failed', ['error' => $e->getMessage()]);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping data Excel berdasarkan indeks kolom ke struktur model Bucok
|
||||||
|
* Kolom dimulai dari indeks 0 (A=0, B=1, C=2, dst.)
|
||||||
|
*
|
||||||
|
* @param array $row
|
||||||
|
* @param int $rowNumber
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function mapRowToBucok(array $row, int $rowNumber): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'no' => $row[0] ?? null, // Kolom A
|
||||||
|
'tanggal' => !empty($row[1]) ? $this->parseDate($row[1]) : null, // Kolom B
|
||||||
|
'bulan' => $row[2] ?? null, // Kolom C
|
||||||
|
'tahun' => $row[3] ?? null, // Kolom D
|
||||||
|
'tanggal_penuh' => !empty($row[4]) ? $this->parseDate($row[4]) : null, // Kolom E
|
||||||
|
'nomor_categ' => $row[5] ?? null, // Kolom F
|
||||||
|
'coa_summary' => $row[6] ?? null, // Kolom G
|
||||||
|
'nomor_coa' => $row[7] ?? null, // Kolom H
|
||||||
|
'nama_coa' => $row[8] ?? null, // Kolom I
|
||||||
|
'nomor_tiket' => $row[9] ?? null, // Kolom J - Auto-generate jika kosong
|
||||||
|
'deskripsi' => $row[10] ?? null, // Kolom K
|
||||||
|
'nominal' => $this->parseNumeric($row[11] ?? 0), // Kolom L
|
||||||
|
'penyelesaian' => $row[12] ?? 'Belum Selesai', // Kolom M
|
||||||
|
'umur_aging' => $this->parseNumeric($row[13] ?? 0), // Kolom N
|
||||||
|
'cost_center' => $row[14] ?? null, // Kolom O
|
||||||
|
'nama_sub_direktorat' => $row[15] ?? null, // Kolom P
|
||||||
|
'nama_direktorat_cabang' => $row[16] ?? null, // Kolom Q
|
||||||
|
'tanggal_penyelesaian' => !empty($row[17]) ? $this->parseDate($row[17]) : null, // Kolom R
|
||||||
|
'nominal_penyelesaian' => $this->parseNumeric($row[18] ?? 0), // Kolom S
|
||||||
|
'nominal_berjalan' => $this->parseNumeric($row[19] ?? 0), // Kolom T
|
||||||
|
'amortisasi_berjalan' => $this->parseNumeric($row[20] ?? 0), // Kolom U
|
||||||
|
'sistem_berjalan' => $this->parseNumeric($row[21] ?? 0), // Kolom V
|
||||||
|
'lainnya_berjalan' => $this->parseNumeric($row[22] ?? 0), // Kolom W
|
||||||
|
'nominal_gantung' => $this->parseNumeric($row[23] ?? 0), // Kolom X
|
||||||
|
'aset_gantung' => $this->parseNumeric($row[24] ?? 0), // Kolom Y
|
||||||
|
'keterangan_gantung' => $row[25] ?? null, // Kolom Z
|
||||||
|
'lainnya_satu' => $row[26] ?? null, // Kolom AA
|
||||||
|
'lainnya_dua' => $row[27] ?? null, // Kolom AB
|
||||||
|
'created_by' => auth()->id(),
|
||||||
|
'updated_by' => auth()->id()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse tanggal dari berbagai format
|
||||||
|
*
|
||||||
|
* @param mixed $dateValue
|
||||||
|
* @return Carbon|null
|
||||||
|
*/
|
||||||
|
private function parseDate($dateValue)
|
||||||
|
{
|
||||||
|
if (empty($dateValue)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Jika berupa angka Excel date serial
|
||||||
|
if (is_numeric($dateValue)) {
|
||||||
|
return Carbon::createFromFormat('Y-m-d', \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($dateValue)->format('Y-m-d'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika berupa string tanggal
|
||||||
|
return Carbon::parse($dateValue);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::warning('Failed to parse date', ['value' => $dateValue, 'error' => $e->getMessage()]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse nilai numerik dari berbagai format
|
||||||
|
*
|
||||||
|
* @param mixed $numericValue
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
private function parseNumeric($numericValue): float
|
||||||
|
{
|
||||||
|
if (empty($numericValue)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hapus karakter non-numerik kecuali titik dan koma
|
||||||
|
$cleaned = preg_replace('/[^0-9.,\-]/', '', $numericValue);
|
||||||
|
|
||||||
|
// Ganti koma dengan titik untuk decimal
|
||||||
|
$cleaned = str_replace(',', '.', $cleaned);
|
||||||
|
|
||||||
|
return (float) $cleaned;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validasi data yang sudah dimapping
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return \Illuminate\Validation\Validator
|
||||||
|
*/
|
||||||
|
private function validateMappedData(array $data)
|
||||||
|
{
|
||||||
|
return Validator::make($data, [
|
||||||
|
'no' => 'nullable|integer',
|
||||||
|
'tanggal' => 'nullable|date',
|
||||||
|
'bulan' => 'nullable|integer|between:1,12',
|
||||||
|
'tahun' => 'nullable|integer|min:2000|max:2099',
|
||||||
|
'tanggal_penuh' => 'nullable|date',
|
||||||
|
'nomor_categ' => 'nullable|string|max:50',
|
||||||
|
'coa_summary' => 'nullable|string|max:255',
|
||||||
|
'nomor_coa' => 'nullable|string|max:50',
|
||||||
|
'nama_coa' => 'nullable|string|max:255',
|
||||||
|
'nomor_tiket' => 'nullable|string|max:50',
|
||||||
|
'deskripsi' => 'nullable|string',
|
||||||
|
'nominal' => 'nullable|numeric|min:0',
|
||||||
|
'penyelesaian' => 'nullable|in:Selesai,Belum Selesai,Dalam Proses',
|
||||||
|
'umur_aging' => 'nullable|integer|min:0',
|
||||||
|
'cost_center' => 'nullable|string|max:100',
|
||||||
|
'nama_sub_direktorat' => 'nullable|string|max:255',
|
||||||
|
'nama_direktorat_cabang' => 'nullable|string|max:255',
|
||||||
|
'tanggal_penyelesaian' => 'nullable|date',
|
||||||
|
'nominal_penyelesaian' => 'nullable|numeric|min:0',
|
||||||
|
'nominal_berjalan' => 'nullable|numeric|min:0',
|
||||||
|
'amortisasi_berjalan' => 'nullable|numeric|min:0',
|
||||||
|
'sistem_berjalan' => 'nullable|numeric|min:0',
|
||||||
|
'lainnya_berjalan' => 'nullable|numeric|min:0',
|
||||||
|
'nominal_gantung' => 'nullable|numeric|min:0',
|
||||||
|
'aset_gantung' => 'nullable|numeric|min:0',
|
||||||
|
'keterangan_gantung' => 'nullable|string',
|
||||||
|
'lainnya_satu' => 'nullable|string',
|
||||||
|
'lainnya_dua' => 'nullable|string'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aturan validasi untuk seluruh file Excel (tidak digunakan karena tanpa header)
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ukuran batch untuk insert
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function batchSize(): int
|
||||||
|
{
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ukuran chunk untuk membaca file
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function chunkSize(): int
|
||||||
|
{
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mendapatkan jumlah data yang berhasil diimpor
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getImportedCount(): int
|
||||||
|
{
|
||||||
|
return $this->importedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mendapatkan jumlah data yang berhasil dibuat
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getCreatedCount(): int
|
||||||
|
{
|
||||||
|
return $this->createdCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mendapatkan jumlah data yang berhasil diupdate
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getUpdatedCount(): int
|
||||||
|
{
|
||||||
|
return $this->updatedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mendapatkan statistik lengkap import
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getImportStatistics(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'total_processed' => $this->importedCount,
|
||||||
|
'created' => $this->createdCount,
|
||||||
|
'updated' => $this->updatedCount,
|
||||||
|
'skipped' => $this->skippedCount,
|
||||||
|
'errors' => count($this->errors)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mendapatkan jumlah data yang dilewati
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getSkippedCount(): int
|
||||||
|
{
|
||||||
|
return $this->skippedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mendapatkan daftar error yang terjadi
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getErrors(): array
|
||||||
|
{
|
||||||
|
return $this->errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
415
app/Imports/SlikImport.php
Normal file
415
app/Imports/SlikImport.php
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Imports;
|
||||||
|
|
||||||
|
use Modules\Lpj\Models\Slik;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStartRow;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithChunkReading;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithBatchInserts;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SlikImport
|
||||||
|
*
|
||||||
|
* Handle import data Excel untuk modul Slik
|
||||||
|
* Menggunakan Laravel Excel package untuk membaca file Excel
|
||||||
|
* dengan optimasi memory dan chunk processing
|
||||||
|
*
|
||||||
|
* @package Modules\Lpj\app\Imports
|
||||||
|
*/
|
||||||
|
class SlikImport implements ToCollection, WithStartRow, WithBatchInserts, WithChunkReading, WithCustomCsvSettings
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Mulai membaca dari baris ke-5 (skip header)
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function startRow(): int
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Batch size untuk insert data dari konfigurasi
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function batchSize(): int
|
||||||
|
{
|
||||||
|
return config('import.slik.batch_size', 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chunk size untuk membaca file dari konfigurasi
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function chunkSize(): int
|
||||||
|
{
|
||||||
|
return config('import.slik.chunk_size', 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom CSV settings untuk optimasi pembacaan file
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getCsvSettings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'input_encoding' => 'UTF-8',
|
||||||
|
'delimiter' => ',',
|
||||||
|
'enclosure' => '"',
|
||||||
|
'escape_character' => '\\',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process collection data dari Excel dengan optimasi memory
|
||||||
|
*
|
||||||
|
* @param Collection $collection
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function collection(Collection $collection)
|
||||||
|
{
|
||||||
|
// Set memory limit dari konfigurasi
|
||||||
|
$memoryLimit = config('import.slik.memory_limit', 1024);
|
||||||
|
$currentMemoryLimit = ini_get('memory_limit');
|
||||||
|
|
||||||
|
if ($currentMemoryLimit !== '-1' && $this->convertToBytes($currentMemoryLimit) < $memoryLimit * 1024 * 1024) {
|
||||||
|
ini_set('memory_limit', $memoryLimit . 'M');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set timeout handler
|
||||||
|
$timeout = config('import.slik.timeout', 1800);
|
||||||
|
set_time_limit($timeout);
|
||||||
|
|
||||||
|
// Force garbage collection sebelum memulai
|
||||||
|
if (config('import.slik.enable_gc', true)) {
|
||||||
|
gc_collect_cycles();
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info('SlikImport: Memulai import data', [
|
||||||
|
'total_rows' => $collection->count(),
|
||||||
|
'memory_usage' => memory_get_usage(true),
|
||||||
|
'memory_peak' => memory_get_peak_usage(true),
|
||||||
|
'memory_limit' => ini_get('memory_limit'),
|
||||||
|
'php_version' => PHP_VERSION,
|
||||||
|
'memory_limit_before' => $currentMemoryLimit,
|
||||||
|
'config' => [
|
||||||
|
'memory_limit' => $memoryLimit,
|
||||||
|
'chunk_size' => $this->chunkSize(),
|
||||||
|
'batch_size' => $this->batchSize()
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$processedRows = 0;
|
||||||
|
$skippedRows = 0;
|
||||||
|
$errorRows = 0;
|
||||||
|
$totalRows = $collection->count();
|
||||||
|
|
||||||
|
foreach ($collection as $index => $row) {
|
||||||
|
// Log progress setiap 25 baris untuk chunk lebih kecil
|
||||||
|
if ($index % 25 === 0) {
|
||||||
|
Log::info('SlikImport: Processing chunk', [
|
||||||
|
'current_row' => $index + 5,
|
||||||
|
'progress' => round(($index / max($totalRows, 1)) * 100, 2) . '%',
|
||||||
|
'processed' => $processedRows,
|
||||||
|
'skipped' => $skippedRows,
|
||||||
|
'errors' => $errorRows,
|
||||||
|
'memory_usage' => memory_get_usage(true),
|
||||||
|
'memory_peak' => memory_get_peak_usage(true),
|
||||||
|
'memory_diff' => memory_get_peak_usage(true) - memory_get_usage(true)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip baris kosong
|
||||||
|
if ($this->isEmptyRow($row)) {
|
||||||
|
$skippedRows++;
|
||||||
|
Log::debug('SlikImport: Skipping empty row', ['row_number' => $index + 5]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi data
|
||||||
|
if (!$this->validateRow($row)) {
|
||||||
|
$errorRows++;
|
||||||
|
Log::warning('SlikImport: Invalid row data', [
|
||||||
|
'row_number' => $index + 5,
|
||||||
|
'data' => $row->toArray()
|
||||||
|
]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Map data dari Excel ke model
|
||||||
|
$slikData = $this->mapRowToSlik($row);
|
||||||
|
|
||||||
|
// Update atau create berdasarkan no_rekening dan cif
|
||||||
|
$slik = Slik::updateOrCreate(
|
||||||
|
[
|
||||||
|
'no_rekening' => $slikData['no_rekening'],
|
||||||
|
'cif' => $slikData['cif']
|
||||||
|
],
|
||||||
|
$slikData
|
||||||
|
);
|
||||||
|
|
||||||
|
$processedRows++;
|
||||||
|
|
||||||
|
// Log detail untuk baris pertama sebagai sample
|
||||||
|
if ($index === 0) {
|
||||||
|
Log::info('SlikImport: Sample data processed', [
|
||||||
|
'slik_id' => $slik->id,
|
||||||
|
'no_rekening' => $slik->no_rekening,
|
||||||
|
'cif' => $slik->cif,
|
||||||
|
'was_recently_created' => $slik->wasRecentlyCreated
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force garbage collection setiap 25 baris untuk mengurangi memory
|
||||||
|
if (config('import.slik.enable_gc', true) && $index > 0 && $index % 25 === 0) {
|
||||||
|
gc_collect_cycles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unset data yang sudah tidak digunakan untuk mengurangi memory
|
||||||
|
if ($index > 0 && $index % 25 === 0) {
|
||||||
|
unset($slikData, $slik);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset collection internal untuk mengurangi memory
|
||||||
|
if ($index > 0 && $index % 100 === 0) {
|
||||||
|
$collection = collect($collection->slice($index + 1)->values());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$errorRows++;
|
||||||
|
Log::error('SlikImport: Error processing row', [
|
||||||
|
'row_number' => $index + 5,
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'data' => $row->toArray(),
|
||||||
|
'memory_usage' => memory_get_usage(true)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
// Force garbage collection setelah selesai
|
||||||
|
if (config('import.slik.enable_gc', true)) {
|
||||||
|
gc_collect_cycles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup variables
|
||||||
|
unset($collection);
|
||||||
|
|
||||||
|
Log::info('SlikImport: Import berhasil diselesaikan', [
|
||||||
|
'total_rows' => $totalRows,
|
||||||
|
'processed_rows' => $processedRows,
|
||||||
|
'skipped_rows' => $skippedRows,
|
||||||
|
'error_rows' => $errorRows,
|
||||||
|
'final_memory_usage' => memory_get_usage(true),
|
||||||
|
'peak_memory_usage' => memory_get_peak_usage(true),
|
||||||
|
'memory_saved' => memory_get_peak_usage(true) - memory_get_usage(true),
|
||||||
|
'memory_efficiency' => ($processedRows > 0) ? round(memory_get_peak_usage(true) / $processedRows, 2) : 0
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
|
||||||
|
// Force garbage collection jika error
|
||||||
|
if (config('import.slik.enable_gc', true)) {
|
||||||
|
gc_collect_cycles();
|
||||||
|
}
|
||||||
|
|
||||||
|
$errorType = 'general';
|
||||||
|
if (str_contains(strtolower($e->getMessage()), 'memory')) {
|
||||||
|
$errorType = 'memory';
|
||||||
|
} elseif (str_contains(strtolower($e->getMessage()), 'timeout') || str_contains(strtolower($e->getMessage()), 'maximum execution time')) {
|
||||||
|
$errorType = 'timeout';
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::error('SlikImport: Error during import', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'error_type' => $errorType,
|
||||||
|
'exception_type' => get_class($e),
|
||||||
|
'trace' => $e->getTraceAsString(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'memory_usage' => memory_get_usage(true),
|
||||||
|
'memory_peak' => memory_get_peak_usage(true),
|
||||||
|
'memory_limit' => ini_get('memory_limit'),
|
||||||
|
'timeout_limit' => ini_get('max_execution_time'),
|
||||||
|
'is_memory_error' => str_contains(strtolower($e->getMessage()), 'memory'),
|
||||||
|
'is_timeout_error' => str_contains(strtolower($e->getMessage()), 'timeout') || str_contains(strtolower($e->getMessage()), 'maximum execution time')
|
||||||
|
]);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert memory limit string ke bytes
|
||||||
|
*
|
||||||
|
* @param string $memoryLimit
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function convertToBytes(string $memoryLimit): int
|
||||||
|
{
|
||||||
|
$memoryLimit = trim($memoryLimit);
|
||||||
|
$lastChar = strtolower(substr($memoryLimit, -1));
|
||||||
|
$number = (int) substr($memoryLimit, 0, -1);
|
||||||
|
|
||||||
|
switch ($lastChar) {
|
||||||
|
case 'g':
|
||||||
|
return $number * 1024 * 1024 * 1024;
|
||||||
|
case 'm':
|
||||||
|
return $number * 1024 * 1024;
|
||||||
|
case 'k':
|
||||||
|
return $number * 1024;
|
||||||
|
default:
|
||||||
|
return (int) $memoryLimit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cek apakah baris kosong
|
||||||
|
*
|
||||||
|
* @param Collection $row
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isEmptyRow(Collection $row): bool
|
||||||
|
{
|
||||||
|
return $row->filter(function ($value) {
|
||||||
|
return !empty(trim($value));
|
||||||
|
})->isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validasi data baris
|
||||||
|
*
|
||||||
|
* @param Collection $row
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function validateRow(Collection $row): bool
|
||||||
|
{
|
||||||
|
// Validasi minimal: sandi_bank, no_rekening, dan cif harus ada
|
||||||
|
return !empty(trim($row[0])) && // sandi_bank
|
||||||
|
!empty(trim($row[5])) && // no_rekening
|
||||||
|
!empty(trim($row[6])); // cif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map data dari baris Excel ke array untuk model Slik
|
||||||
|
*
|
||||||
|
* @param Collection $row
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function mapRowToSlik(Collection $row): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'sandi_bank' => trim($row[0]) ?: null,
|
||||||
|
'tahun' => $this->parseInteger($row[1]),
|
||||||
|
'bulan' => $this->parseInteger($row[2]),
|
||||||
|
'flag_detail' => trim($row[3]) ?: null,
|
||||||
|
'kode_register_agunan' => trim($row[4]) ?: null,
|
||||||
|
'no_rekening' => trim($row[5]) ?: null,
|
||||||
|
'cif' => trim($row[6]) ?: null,
|
||||||
|
'kolektibilitas' => trim($row[7]) ?: null,
|
||||||
|
'fasilitas' => trim($row[8]) ?: null,
|
||||||
|
'jenis_segmen_fasilitas' => trim($row[9]) ?: null,
|
||||||
|
'status_agunan' => trim($row[10]) ?: null,
|
||||||
|
'jenis_agunan' => trim($row[11]) ?: null,
|
||||||
|
'peringkat_agunan' => trim($row[12]) ?: null,
|
||||||
|
'lembaga_pemeringkat' => trim($row[13]) ?: null,
|
||||||
|
'jenis_pengikatan' => trim($row[14]) ?: null,
|
||||||
|
'tanggal_pengikatan' => $this->parseDate($row[15]),
|
||||||
|
'nama_pemilik_agunan' => trim($row[16]) ?: null,
|
||||||
|
'bukti_kepemilikan' => trim($row[17]) ?: null,
|
||||||
|
'alamat_agunan' => trim($row[18]) ?: null,
|
||||||
|
'lokasi_agunan' => trim($row[19]) ?: null,
|
||||||
|
'nilai_agunan' => $this->parseDecimal($row[20]),
|
||||||
|
'nilai_agunan_menurut_ljk' => $this->parseDecimal($row[21]),
|
||||||
|
'tanggal_penilaian_ljk' => $this->parseDate($row[22]),
|
||||||
|
'nilai_agunan_penilai_independen' => $this->parseDecimal($row[23]),
|
||||||
|
'nama_penilai_independen' => trim($row[24]) ?: null,
|
||||||
|
'tanggal_penilaian_penilai_independen' => $this->parseDate($row[25]),
|
||||||
|
'jumlah_hari_tunggakan' => $this->parseInteger($row[26]),
|
||||||
|
'status_paripasu' => trim($row[27]) ?: null,
|
||||||
|
'prosentase_paripasu' => $this->parseDecimal($row[28]),
|
||||||
|
'status_kredit_join' => trim($row[29]) ?: null,
|
||||||
|
'diasuransikan' => trim($row[30]) ?: null,
|
||||||
|
'keterangan' => trim($row[31]) ?: null,
|
||||||
|
'kantor_cabang' => trim($row[32]) ?: null,
|
||||||
|
'operasi_data' => trim($row[33]) ?: null,
|
||||||
|
'kode_cabang' => trim($row[34]) ?: null,
|
||||||
|
'nama_debitur' => trim($row[35]) ?: null,
|
||||||
|
'nama_cabang' => trim($row[36]) ?: null,
|
||||||
|
'flag' => trim($row[37]) ?: null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse integer value
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
private function parseInteger($value): ?int
|
||||||
|
{
|
||||||
|
if (empty(trim($value))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse decimal value
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @return float|null
|
||||||
|
*/
|
||||||
|
private function parseDecimal($value): ?float
|
||||||
|
{
|
||||||
|
if (empty(trim($value))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove currency formatting
|
||||||
|
$cleaned = str_replace([',', '.'], ['', '.'], $value);
|
||||||
|
$cleaned = preg_replace('/[^0-9.]/', '', $cleaned);
|
||||||
|
|
||||||
|
return (float) $cleaned;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse date value
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
private function parseDate($value): ?string
|
||||||
|
{
|
||||||
|
if (empty(trim($value))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Try to parse various date formats
|
||||||
|
$date = \Carbon\Carbon::parse($value);
|
||||||
|
return $date->format('Y-m-d');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::warning('SlikImport: Invalid date format', [
|
||||||
|
'value' => $value,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
179
app/Jobs/ProcessSlikImport.php
Normal file
179
app/Jobs/ProcessSlikImport.php
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Jobs;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Modules\Lpj\Imports\SlikImport;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
|
||||||
|
class ProcessSlikImport implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
public $timeout = 1800; // 30 menit untuk file besar
|
||||||
|
public $tries = 5; // Tambah retry untuk file sangat besar
|
||||||
|
public $maxExceptions = 5;
|
||||||
|
public $backoff = [60, 300, 900, 1800, 3600]; // Exponential backoff dalam detik
|
||||||
|
|
||||||
|
protected string $filePath;
|
||||||
|
protected int $userId;
|
||||||
|
protected string $importId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new job instance.
|
||||||
|
*
|
||||||
|
* @param string $filePath
|
||||||
|
* @param int $userId
|
||||||
|
* @param string $importId
|
||||||
|
*/
|
||||||
|
public function __construct(string $filePath, int $userId, string $importId)
|
||||||
|
{
|
||||||
|
$this->filePath = $filePath;
|
||||||
|
$this->userId = $userId;
|
||||||
|
$this->importId = $importId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
Log::info('ProcessSlikImport: Memulai proses import via queue', [
|
||||||
|
'file_path' => $this->filePath,
|
||||||
|
'user_id' => $this->userId,
|
||||||
|
'import_id' => $this->importId,
|
||||||
|
'memory_limit' => ini_get('memory_limit'),
|
||||||
|
'max_execution_time' => ini_get('max_execution_time')
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Cek file size terlebih dahulu
|
||||||
|
$fileSize = filesize($this->filePath);
|
||||||
|
$maxFileSize = config('import.slik.max_file_size', 50) * 1024 * 1024; // Convert MB to bytes
|
||||||
|
|
||||||
|
if ($fileSize > $maxFileSize) {
|
||||||
|
throw new \Exception('File terlalu besar: ' . number_format($fileSize / 1024 / 1024, 2) . ' MB. Maksimum: ' . config('import.slik.max_file_size', 50) . ' MB');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set optimasi memory untuk queue processing
|
||||||
|
$memoryLimit = config('import.slik.memory_limit', 1024);
|
||||||
|
ini_set('memory_limit', $memoryLimit . 'M');
|
||||||
|
ini_set('max_execution_time', config('import.slik.timeout', 1800));
|
||||||
|
|
||||||
|
// Set timeout untuk XML Scanner
|
||||||
|
$xmlScannerTimeout = config('import.slik.xml_scanner.timeout', 1800);
|
||||||
|
$xmlScannerMemory = config('import.slik.xml_scanner.memory_limit', 1024);
|
||||||
|
|
||||||
|
// Enable garbage collection jika diizinkan
|
||||||
|
if (config('import.slik.enable_gc', true)) {
|
||||||
|
gc_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update progress status
|
||||||
|
$this->updateProgress('processing', 0, 'Memproses file Excel...');
|
||||||
|
|
||||||
|
Log::info('SlikImport: Processing file', [
|
||||||
|
'file' => basename($this->filePath),
|
||||||
|
'file_size' => number_format(filesize($this->filePath) / 1024 / 1024, 2) . ' MB',
|
||||||
|
'memory_limit' => $memoryLimit . 'M',
|
||||||
|
'timeout' => config('import.slik.timeout', 1800),
|
||||||
|
'enable_gc' => config('import.slik.enable_gc', true),
|
||||||
|
'xml_scanner_timeout' => config('import.slik.xml_scanner.timeout', 1800),
|
||||||
|
'chunk_size' => config('import.slik.chunk_size', 50),
|
||||||
|
'batch_size' => config('import.slik.batch_size', 50),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Import file menggunakan SlikImport
|
||||||
|
$import = new SlikImport();
|
||||||
|
Excel::import($import, $this->filePath);
|
||||||
|
|
||||||
|
// Update progress selesai
|
||||||
|
$this->updateProgress('completed', 100, 'Import berhasil diselesaikan');
|
||||||
|
|
||||||
|
Log::info('ProcessSlikImport: Import berhasil diselesaikan', [
|
||||||
|
'import_id' => $this->importId,
|
||||||
|
'file_path' => $this->filePath,
|
||||||
|
'memory_usage' => memory_get_usage(true),
|
||||||
|
'memory_peak' => memory_get_peak_usage(true)
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Hapus file temporary setelah selesai
|
||||||
|
if (config('import.general.cleanup_temp_files', true)) {
|
||||||
|
Storage::delete($this->filePath);
|
||||||
|
Log::info('ProcessSlikImport: File temporary dihapus', ['file_path' => $this->filePath]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// Update progress error
|
||||||
|
$this->updateProgress('failed', 0, 'Error: ' . $e->getMessage());
|
||||||
|
|
||||||
|
Log::error('ProcessSlikImport: Error saat proses import', [
|
||||||
|
'import_id' => $this->importId,
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'trace' => $e->getTraceAsString(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'memory_usage' => memory_get_usage(true)
|
||||||
|
]);
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update progress import
|
||||||
|
*
|
||||||
|
* @param string $status
|
||||||
|
* @param int $percentage
|
||||||
|
* @param string $message
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function updateProgress(string $status, int $percentage, string $message): void
|
||||||
|
{
|
||||||
|
if (config('import.slik.progress.enabled', true)) {
|
||||||
|
$cacheKey = config('import.slik.progress.cache_key', 'slik_import_progress') . '_' . $this->importId;
|
||||||
|
$cacheTtl = config('import.slik.progress.cache_ttl', 3600);
|
||||||
|
|
||||||
|
$progressData = [
|
||||||
|
'status' => $status,
|
||||||
|
'percentage' => $percentage,
|
||||||
|
'message' => $message,
|
||||||
|
'timestamp' => now(),
|
||||||
|
'user_id' => $this->userId
|
||||||
|
];
|
||||||
|
|
||||||
|
cache()->put($cacheKey, $progressData, $cacheTtl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle job failure
|
||||||
|
*
|
||||||
|
* @param \Throwable $exception
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function failed(\Throwable $exception): void
|
||||||
|
{
|
||||||
|
Log::error('ProcessSlikImport: Job failed', [
|
||||||
|
'import_id' => $this->importId,
|
||||||
|
'error' => $exception->getMessage(),
|
||||||
|
'trace' => $exception->getTraceAsString()
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Update progress ke failed
|
||||||
|
$this->updateProgress('failed', 0, 'Import gagal: ' . $exception->getMessage());
|
||||||
|
|
||||||
|
// Cleanup file temporary
|
||||||
|
if (Storage::exists($this->filePath)) {
|
||||||
|
Storage::delete($this->filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Spatie\Activitylog\LogOptions;
|
use Spatie\Activitylog\LogOptions;
|
||||||
use Spatie\Activitylog\Traits\LogsActivity;
|
use Spatie\Activitylog\Traits\LogsActivity;
|
||||||
use Wildside\Userstamps\Userstamps;
|
use Mattiverse\Userstamps\Traits\Userstamps;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
113
app/Models/Bucok.php
Normal file
113
app/Models/Bucok.php
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Models;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Auth\User;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Bucok untuk mengelola data bucok
|
||||||
|
*
|
||||||
|
* @property int $id
|
||||||
|
* @property int|null $no
|
||||||
|
* @property string|null $tanggal
|
||||||
|
* @property string|null $bulan
|
||||||
|
* @property int|null $tahun
|
||||||
|
* @property string|null $tanggal_penuh
|
||||||
|
* @property string|null $nomor_categ
|
||||||
|
* @property string|null $coa_summary
|
||||||
|
* @property string|null $nomor_coa
|
||||||
|
* @property string|null $nama_coa
|
||||||
|
* @property string $nomor_tiket
|
||||||
|
* @property string|null $deskripsi
|
||||||
|
* @property float|null $nominal
|
||||||
|
* @property string|null $penyelesaian
|
||||||
|
* @property int|null $umur_aging
|
||||||
|
* @property string|null $cost_center
|
||||||
|
* @property string|null $nama_sub_direktorat
|
||||||
|
* @property string|null $nama_direktorat_cabang
|
||||||
|
* @property string|null $tanggal_penyelesaian
|
||||||
|
* @property float|null $nominal_penyelesaian
|
||||||
|
* @property float|null $nominal_berjalan
|
||||||
|
* @property float|null $amortisasi_berjalan
|
||||||
|
* @property float|null $sistem_berjalan
|
||||||
|
* @property float|null $lainnya_berjalan
|
||||||
|
* @property float|null $nominal_gantung
|
||||||
|
* @property float|null $aset_gantung
|
||||||
|
* @property string|null $keterangan_gantung
|
||||||
|
* @property string|null $lainnya_satu
|
||||||
|
* @property string|null $lainnya_dua
|
||||||
|
*/
|
||||||
|
class Bucok extends Base
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nama tabel yang digunakan oleh model
|
||||||
|
*/
|
||||||
|
protected $table = 'bucoks';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field yang dapat diisi secara mass assignment
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'no',
|
||||||
|
'tanggal',
|
||||||
|
'bulan',
|
||||||
|
'tahun',
|
||||||
|
'tanggal_penuh',
|
||||||
|
'nomor_categ',
|
||||||
|
'coa_summary',
|
||||||
|
'nomor_coa',
|
||||||
|
'nama_coa',
|
||||||
|
'nomor_tiket',
|
||||||
|
'deskripsi',
|
||||||
|
'nominal',
|
||||||
|
'penyelesaian',
|
||||||
|
'umur_aging',
|
||||||
|
'cost_center',
|
||||||
|
'nama_sub_direktorat',
|
||||||
|
'nama_direktorat_cabang',
|
||||||
|
'tanggal_penyelesaian',
|
||||||
|
'nominal_penyelesaian',
|
||||||
|
'nominal_berjalan',
|
||||||
|
'amortisasi_berjalan',
|
||||||
|
'sistem_berjalan',
|
||||||
|
'lainnya_berjalan',
|
||||||
|
'nominal_gantung',
|
||||||
|
'aset_gantung',
|
||||||
|
'keterangan_gantung',
|
||||||
|
'lainnya_satu',
|
||||||
|
'lainnya_dua',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casting tipe data untuk field tertentu
|
||||||
|
*/
|
||||||
|
protected $casts = [
|
||||||
|
'no' => 'integer',
|
||||||
|
'tanggal' => 'date',
|
||||||
|
'tahun' => 'integer',
|
||||||
|
'tanggal_penuh' => 'date',
|
||||||
|
'nominal' => 'decimal:2',
|
||||||
|
'umur_aging' => 'integer',
|
||||||
|
'tanggal_penyelesaian' => 'date',
|
||||||
|
'nominal_penyelesaian' => 'decimal:2',
|
||||||
|
'nominal_berjalan' => 'decimal:2',
|
||||||
|
'amortisasi_berjalan' => 'decimal:2',
|
||||||
|
'sistem_berjalan' => 'decimal:2',
|
||||||
|
'lainnya_berjalan' => 'decimal:2',
|
||||||
|
'nominal_gantung' => 'decimal:2',
|
||||||
|
'aset_gantung' => 'decimal:2',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field yang akan di-hidden saat serialization
|
||||||
|
*/
|
||||||
|
protected $hidden = [
|
||||||
|
'created_by',
|
||||||
|
'updated_by',
|
||||||
|
'deleted_by',
|
||||||
|
];
|
||||||
|
}
|
||||||
27
app/Models/CategoryDaftarPustaka.php
Normal file
27
app/Models/CategoryDaftarPustaka.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
// use Modules\Lpj\Database\Factories\CategoryDaftarPustakaFactory;
|
||||||
|
|
||||||
|
class CategoryDaftarPustaka extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'category_daftar_pustaka';
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'code',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function daftarPustaka(){
|
||||||
|
return $this->hasMany(DaftarPustaka::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
29
app/Models/DaftarPustaka.php
Normal file
29
app/Models/DaftarPustaka.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
// use Modules\Lpj\Database\Factories\DaftarPustakaFactory;
|
||||||
|
|
||||||
|
class DaftarPustaka extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'daftar_pustaka';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'id',
|
||||||
|
'category_id',
|
||||||
|
'judul',
|
||||||
|
'attachment',
|
||||||
|
'deskripsi',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function category(){
|
||||||
|
return $this->belongsTo(CategoryDaftarPustaka::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
114
app/Models/LaporanSlik.php
Normal file
114
app/Models/LaporanSlik.php
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Modules\Usermanagement\Models\User;
|
||||||
|
|
||||||
|
class LaporanSlik extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'laporan_slik';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'slik_id',
|
||||||
|
'sandi_bank',
|
||||||
|
'kode_kantor',
|
||||||
|
'kode_cabang',
|
||||||
|
'tahun',
|
||||||
|
'bulan',
|
||||||
|
'no_rekening',
|
||||||
|
'cif',
|
||||||
|
'kode_jenis',
|
||||||
|
'kode_jenis_ket',
|
||||||
|
'kode_sifat',
|
||||||
|
'kode_sifat_ket',
|
||||||
|
'kode_valuta',
|
||||||
|
'kode_valuta_ket',
|
||||||
|
'baki_debet',
|
||||||
|
'kolektibilitas',
|
||||||
|
'kolektibilitas_ket',
|
||||||
|
'tanggal_mulai',
|
||||||
|
'tanggal_jatuh_tempo',
|
||||||
|
'tanggal_selesai',
|
||||||
|
'tanggal_restrukturisasi',
|
||||||
|
'kode_sebab_macet',
|
||||||
|
'kode_sebab_macet_ket',
|
||||||
|
'tanggal_macet',
|
||||||
|
'kode_kondisi',
|
||||||
|
'kode_kondisi_ket',
|
||||||
|
'tanggal_kondisi',
|
||||||
|
'nilai_agunan',
|
||||||
|
'nilai_agunan_ket',
|
||||||
|
'jenis_agunan',
|
||||||
|
'kode_agunan',
|
||||||
|
'kode_agunan_ket',
|
||||||
|
'peringkat_agunan',
|
||||||
|
'peringkat_agunan_ket',
|
||||||
|
'nama_debitur',
|
||||||
|
'npwp',
|
||||||
|
'no_ktp',
|
||||||
|
'no_telp',
|
||||||
|
'kode_kab_kota',
|
||||||
|
'kode_kab_kota_ket',
|
||||||
|
'kode_negara_domisili',
|
||||||
|
'kode_negara_domisili_ket',
|
||||||
|
'kode_pos',
|
||||||
|
'alamat',
|
||||||
|
'fasilitas',
|
||||||
|
'status_agunan',
|
||||||
|
'tanggal_lapor',
|
||||||
|
'status',
|
||||||
|
'created_by',
|
||||||
|
'updated_by',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'created_at' => 'datetime',
|
||||||
|
'updated_at' => 'datetime',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function slik()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Slik::class, 'slik_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function creator()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'created_by');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updater()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'updated_by');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope untuk filter berdasarkan status
|
||||||
|
*/
|
||||||
|
public function scopeActive($query)
|
||||||
|
{
|
||||||
|
return $query->where('status', 'aktif');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor untuk nilai agunan yang diformat
|
||||||
|
*/
|
||||||
|
public function getNilaiAgunanFormattedAttribute()
|
||||||
|
{
|
||||||
|
return number_format($this->nilai_agunan ?? 0, 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor untuk status badge
|
||||||
|
*/
|
||||||
|
public function getStatusBadgeAttribute()
|
||||||
|
{
|
||||||
|
$status = $this->status ?? 'aktif';
|
||||||
|
$class = $status == 'aktif' ? 'success' : 'danger';
|
||||||
|
|
||||||
|
return '<span class="badge badge-light-' . $class . '">' . ucfirst($status) . '</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,41 +2,28 @@
|
|||||||
|
|
||||||
namespace Modules\Lpj\Models;
|
namespace Modules\Lpj\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Foundation\Auth\User;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
// use Modules\Lpj\Database\Factories\NocFactory;
|
|
||||||
|
|
||||||
class Noc extends Base
|
class Noc extends Base
|
||||||
{
|
{
|
||||||
protected $table = 'noc';
|
protected $table = 'noc';
|
||||||
|
|
||||||
protected $fillable = [
|
protected $guarded = ['id'];
|
||||||
'permohonan_id',
|
|
||||||
'persetujuan_penawaran_id',
|
|
||||||
'bukti_bayar',
|
|
||||||
'nominal_bayar',
|
|
||||||
'status_bayar',
|
|
||||||
'tanggal_pembayaran',
|
|
||||||
'nominal_penyelesaian',
|
|
||||||
'status_penyelesaiaan',
|
|
||||||
'tanggal_penyelesaian',
|
|
||||||
'bukti_penyelesaian',
|
|
||||||
'bukti_ksl',
|
|
||||||
'memo_penyelesaian',
|
|
||||||
'catatan_noc',
|
|
||||||
'status',
|
|
||||||
'authorized_status',
|
|
||||||
'authorized_at',
|
|
||||||
'authorized_by',
|
|
||||||
];
|
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'nominal_bayar' => 'decimal:2',
|
'nominal_bayar' => 'decimal:2',
|
||||||
'status_bayar' => 'boolean',
|
'status_bayar' => 'boolean',
|
||||||
|
'status_kurang_bayar' => 'boolean',
|
||||||
|
'nominal_kurang_bayar' => 'decimal:2',
|
||||||
|
'status_lebih_bayar' => 'boolean',
|
||||||
|
'nominal_lebih_bayar' => 'decimal:2',
|
||||||
'tanggal_pembayaran' => 'date',
|
'tanggal_pembayaran' => 'date',
|
||||||
'nominal_penyelesaian' => 'decimal:2',
|
'nominal_penyelesaian' => 'decimal:2',
|
||||||
'status_penyelesaiaan' => 'boolean',
|
'status_penyelesaiaan' => 'boolean',
|
||||||
'tanggal_penyelesaian' => 'date',
|
'tanggal_penyelesaian' => 'date',
|
||||||
|
'memo_penyelesaian_date' => 'date',
|
||||||
|
'memo_penyelesaian_payment_date' => 'date',
|
||||||
|
'memo_penyelesaian_created_at' => 'datetime',
|
||||||
'status' => 'boolean',
|
'status' => 'boolean',
|
||||||
'authorized_status' => 'boolean',
|
'authorized_status' => 'boolean',
|
||||||
'authorized_at' => 'datetime',
|
'authorized_at' => 'datetime',
|
||||||
@@ -59,4 +46,12 @@ class Noc extends Base
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(User::class, 'authorized_by');
|
return $this->belongsTo(User::class, 'authorized_by');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function debiture(){
|
||||||
|
return $this->belongsTo(Debiture::class,'debiture_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function branch(){
|
||||||
|
return $this->belongsTo(Branch::class,'branch_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Modules\Lpj\Models;
|
namespace Modules\Lpj\Models;
|
||||||
|
|
||||||
use Modules\Usermanagemenet\Models\User;
|
use Modules\Usermanagement\Models\User;
|
||||||
|
|
||||||
class PersetujuanPenawaran extends Base
|
class PersetujuanPenawaran extends Base
|
||||||
{
|
{
|
||||||
@@ -13,6 +13,9 @@
|
|||||||
'permohonan_id',
|
'permohonan_id',
|
||||||
'penawaran_id',
|
'penawaran_id',
|
||||||
'nomor_proposal_penawaran',
|
'nomor_proposal_penawaran',
|
||||||
|
'nomor_tiket',
|
||||||
|
'nominal_kurang_bayar',
|
||||||
|
'bukti_ksl_kurang_bayar',
|
||||||
'tanggal_proposal_penawaran',
|
'tanggal_proposal_penawaran',
|
||||||
'biaya_final',
|
'biaya_final',
|
||||||
'sla_resume',
|
'sla_resume',
|
||||||
@@ -46,12 +49,6 @@
|
|||||||
return $this->belongsTo(Permohonan::class, 'permohonan_id');
|
return $this->belongsTo(Permohonan::class, 'permohonan_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relationship with Region
|
|
||||||
public function region()
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Region::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Relationship with User (for authorized_by)
|
// Relationship with User (for authorized_by)
|
||||||
public function authorizedBy()
|
public function authorizedBy()
|
||||||
{
|
{
|
||||||
|
|||||||
190
app/Models/Slik.php
Normal file
190
app/Models/Slik.php
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Slik untuk mengelola data SLIK (Sistem Layanan Informasi Keuangan)
|
||||||
|
*
|
||||||
|
* @property int $id
|
||||||
|
* @property string|null $sandi_bank
|
||||||
|
* @property string|null $tahun
|
||||||
|
* @property string|null $bulan
|
||||||
|
* @property string|null $flag_detail
|
||||||
|
* @property string|null $kode_register_agunan
|
||||||
|
* @property string|null $no_rekening
|
||||||
|
* @property string|null $cif
|
||||||
|
* @property string|null $kolektibilitas
|
||||||
|
* @property string|null $fasilitas
|
||||||
|
* @property string|null $jenis_segmen_fasilitas
|
||||||
|
* @property string|null $status_agunan
|
||||||
|
* @property string|null $jenis_agunan
|
||||||
|
* @property string|null $peringkat_agunan
|
||||||
|
* @property string|null $lembaga_pemeringkat
|
||||||
|
* @property string|null $jenis_pengikatan
|
||||||
|
* @property string|null $tanggal_pengikatan
|
||||||
|
* @property string|null $nama_pemilik_agunan
|
||||||
|
* @property string|null $bukti_kepemilikan
|
||||||
|
* @property string|null $alamat_agunan
|
||||||
|
* @property string|null $lokasi_agunan
|
||||||
|
* @property string|null $nilai_agunan
|
||||||
|
* @property string|null $nilai_agunan_menurut_ljk
|
||||||
|
* @property string|null $tanggal_penilaian_ljk
|
||||||
|
* @property string|null $nilai_agunan_penilai_independen
|
||||||
|
* @property string|null $nama_penilai_independen
|
||||||
|
* @property string|null $tanggal_penilaian_penilai_independen
|
||||||
|
* @property string|null $jumlah_hari_tunggakan
|
||||||
|
* @property string|null $status_paripasu
|
||||||
|
* @property string|null $prosentase_paripasu
|
||||||
|
* @property string|null $status_kredit_join
|
||||||
|
* @property string|null $diasuransikan
|
||||||
|
* @property string|null $keterangan
|
||||||
|
* @property string|null $kantor_cabang
|
||||||
|
* @property string|null $operasi_data
|
||||||
|
* @property string|null $kode_cabang
|
||||||
|
* @property string|null $nama_debitur
|
||||||
|
* @property string|null $nama_cabang
|
||||||
|
* @property string|null $flag
|
||||||
|
*/
|
||||||
|
class Slik extends Base
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nama tabel yang digunakan oleh model
|
||||||
|
*/
|
||||||
|
protected $table = 'sliks';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field yang dapat diisi secara mass assignment
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'sandi_bank',
|
||||||
|
'tahun',
|
||||||
|
'bulan',
|
||||||
|
'flag_detail',
|
||||||
|
'kode_register_agunan',
|
||||||
|
'no_rekening',
|
||||||
|
'cif',
|
||||||
|
'kolektibilitas',
|
||||||
|
'fasilitas',
|
||||||
|
'jenis_segmen_fasilitas',
|
||||||
|
'status_agunan',
|
||||||
|
'jenis_agunan',
|
||||||
|
'peringkat_agunan',
|
||||||
|
'lembaga_pemeringkat',
|
||||||
|
'jenis_pengikatan',
|
||||||
|
'tanggal_pengikatan',
|
||||||
|
'nama_pemilik_agunan',
|
||||||
|
'bukti_kepemilikan',
|
||||||
|
'alamat_agunan',
|
||||||
|
'lokasi_agunan',
|
||||||
|
'nilai_agunan',
|
||||||
|
'nilai_agunan_menurut_ljk',
|
||||||
|
'tanggal_penilaian_ljk',
|
||||||
|
'nilai_agunan_penilai_independen',
|
||||||
|
'nama_penilai_independen',
|
||||||
|
'tanggal_penilaian_penilai_independen',
|
||||||
|
'jumlah_hari_tunggakan',
|
||||||
|
'status_paripasu',
|
||||||
|
'prosentase_paripasu',
|
||||||
|
'status_kredit_join',
|
||||||
|
'diasuransikan',
|
||||||
|
'keterangan',
|
||||||
|
'kantor_cabang',
|
||||||
|
'operasi_data',
|
||||||
|
'kode_cabang',
|
||||||
|
'nama_debitur',
|
||||||
|
'nama_cabang',
|
||||||
|
'flag',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casting tipe data untuk field tertentu
|
||||||
|
*/
|
||||||
|
protected $casts = [
|
||||||
|
'tanggal_pengikatan' => 'date',
|
||||||
|
'tanggal_penilaian_ljk' => 'date',
|
||||||
|
'tanggal_penilaian_penilai_independen' => 'date',
|
||||||
|
'nilai_agunan' => 'decimal:2',
|
||||||
|
'nilai_agunan_menurut_ljk' => 'decimal:2',
|
||||||
|
'nilai_agunan_penilai_independen' => 'decimal:2',
|
||||||
|
'prosentase_paripasu' => 'decimal:2',
|
||||||
|
'jumlah_hari_tunggakan' => 'integer',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor untuk format nilai agunan dengan currency Indonesia
|
||||||
|
*/
|
||||||
|
public function getNilaiAgunanFormattedAttribute(): string
|
||||||
|
{
|
||||||
|
return $this->nilai_agunan ? 'Rp ' . number_format($this->nilai_agunan, 0, ',', '.') : 'Rp 0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor untuk format nilai agunan menurut LJK dengan currency Indonesia
|
||||||
|
*/
|
||||||
|
public function getNilaiAgunanMenurutLjkFormattedAttribute(): string
|
||||||
|
{
|
||||||
|
return $this->nilai_agunan_menurut_ljk ? 'Rp ' . number_format($this->nilai_agunan_menurut_ljk, 0, ',', '.') : 'Rp 0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor untuk format nilai agunan penilai independen dengan currency Indonesia
|
||||||
|
*/
|
||||||
|
public function getNilaiAgunanPenilaiIndependenFormattedAttribute(): string
|
||||||
|
{
|
||||||
|
return $this->nilai_agunan_penilai_independen ? 'Rp ' . number_format($this->nilai_agunan_penilai_independen, 0, ',', '.') : 'Rp 0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor untuk status badge berdasarkan status agunan
|
||||||
|
*/
|
||||||
|
public function getStatusBadgeAttribute(): string
|
||||||
|
{
|
||||||
|
$statusClass = match($this->status_agunan) {
|
||||||
|
'Aktif' => 'badge-success',
|
||||||
|
'Tidak Aktif' => 'badge-danger',
|
||||||
|
'Pending' => 'badge-warning',
|
||||||
|
default => 'badge-secondary'
|
||||||
|
};
|
||||||
|
|
||||||
|
return '<span class="badge ' . $statusClass . '">' . ($this->status_agunan ?? 'Unknown') . '</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope untuk filter berdasarkan tahun
|
||||||
|
*/
|
||||||
|
public function scopeByYear($query, $year)
|
||||||
|
{
|
||||||
|
return $query->where('tahun', $year);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope untuk filter berdasarkan bulan
|
||||||
|
*/
|
||||||
|
public function scopeByMonth($query, $month)
|
||||||
|
{
|
||||||
|
return $query->where('bulan', $month);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope untuk filter berdasarkan sandi bank
|
||||||
|
*/
|
||||||
|
public function scopeBySandiBank($query, $sandiBank)
|
||||||
|
{
|
||||||
|
return $query->where('sandi_bank', $sandiBank);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope untuk filter berdasarkan kode cabang
|
||||||
|
*/
|
||||||
|
public function scopeByKodeCabang($query, $kodeCabang)
|
||||||
|
{
|
||||||
|
return $query->where('kode_cabang', $kodeCabang);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method creator() dan editor() sudah disediakan oleh trait Userstamps
|
||||||
|
}
|
||||||
94
app/Services/DaftarPustakaService.php
Normal file
94
app/Services/DaftarPustakaService.php
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Services;
|
||||||
|
|
||||||
|
use Modules\Lpj\Models\DaftarPustaka;
|
||||||
|
|
||||||
|
class DaftarPustakaService
|
||||||
|
{
|
||||||
|
public function storeDaftarPustaka(array $data, $file)
|
||||||
|
{
|
||||||
|
if ($file) {
|
||||||
|
$data['attachment'] = $this->handleUpload($file);
|
||||||
|
}
|
||||||
|
return DaftarPustaka::create($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateDaftarPustaka($data, $file, $id)
|
||||||
|
{
|
||||||
|
// Ambil data inputan yang diperlukan saja
|
||||||
|
|
||||||
|
$daftarPustaka = DaftarPustaka::findOrFail($id);
|
||||||
|
|
||||||
|
// Jika ada file baru yang diupload
|
||||||
|
if ($file) {
|
||||||
|
// (Opsional) Hapus file lama
|
||||||
|
if ($daftarPustaka->attachment && file_exists(public_path($daftarPustaka->attachment))) {
|
||||||
|
unlink(public_path($daftarPustaka->attachment));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload file baru
|
||||||
|
$data['attachment'] = $this->handleUpload($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update data
|
||||||
|
$daftarPustaka->update($data);
|
||||||
|
|
||||||
|
return $daftarPustaka;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function deleteDaftarPustaka($id)
|
||||||
|
{
|
||||||
|
return DaftarPustaka::where('id', $id)->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDaftarPustakaById($id)
|
||||||
|
{
|
||||||
|
return DaftarPustaka::where('id', $id)->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get all with pagination
|
||||||
|
public function getAllDaftarPustaka($request)
|
||||||
|
{
|
||||||
|
$query = DaftarPustaka::query();
|
||||||
|
|
||||||
|
// Filter pencarian
|
||||||
|
if (!empty($request->get('search'))) {
|
||||||
|
$search = $request->get('search');
|
||||||
|
$query->where(function ($q) use ($search) {
|
||||||
|
$q->orWhere('judul', 'LIKE', "%$search%");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter kategori
|
||||||
|
if (!empty($request->get('category'))) {
|
||||||
|
$category = explode(',', $request->input('category'));
|
||||||
|
$query->whereIn('category_id', $category);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default pagination
|
||||||
|
$page = (int) $request->get('page', 1);
|
||||||
|
$size = (int) $request->get('size', 10);
|
||||||
|
|
||||||
|
return $query->paginate($size, ['*'], 'page', $page);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function handleUpload($file)
|
||||||
|
{
|
||||||
|
$today = now();
|
||||||
|
$folderPath = 'daftar_pustaka/' . $today->format('Y/m/d');
|
||||||
|
|
||||||
|
if (!file_exists(public_path($folderPath))) {
|
||||||
|
mkdir(public_path($folderPath), 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileName = $file->getClientOriginalName();
|
||||||
|
$file->move(public_path($folderPath), $fileName);
|
||||||
|
|
||||||
|
return $folderPath . '/' . $fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
236
app/Services/ImportProgressService.php
Normal file
236
app/Services/ImportProgressService.php
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Services;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class ImportProgressService
|
||||||
|
{
|
||||||
|
protected string $cacheKeyPrefix;
|
||||||
|
protected int $cacheTtl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->cacheKeyPrefix = config('import.slik.progress.cache_key', 'slik_import_progress');
|
||||||
|
$this->cacheTtl = config('import.slik.progress.cache_ttl', 3600);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start new import progress
|
||||||
|
*
|
||||||
|
* @param string $importId
|
||||||
|
* @param int $userId
|
||||||
|
* @param string $filename
|
||||||
|
* @param int $totalRows
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function start(string $importId, int $userId, string $filename, int $totalRows): array
|
||||||
|
{
|
||||||
|
$progressData = [
|
||||||
|
'import_id' => $importId,
|
||||||
|
'user_id' => $userId,
|
||||||
|
'filename' => $filename,
|
||||||
|
'total_rows' => $totalRows,
|
||||||
|
'processed_rows' => 0,
|
||||||
|
'skipped_rows' => 0,
|
||||||
|
'error_rows' => 0,
|
||||||
|
'status' => 'started',
|
||||||
|
'percentage' => 0,
|
||||||
|
'message' => 'Memulai import...',
|
||||||
|
'started_at' => now(),
|
||||||
|
'updated_at' => now()
|
||||||
|
];
|
||||||
|
|
||||||
|
$cacheKey = $this->getCacheKey($importId);
|
||||||
|
Cache::put($cacheKey, $progressData, $this->cacheTtl);
|
||||||
|
|
||||||
|
Log::info('ImportProgressService: Import started', $progressData);
|
||||||
|
|
||||||
|
return $progressData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update progress import
|
||||||
|
*
|
||||||
|
* @param string $importId
|
||||||
|
* @param int $processedRows
|
||||||
|
* @param int $skippedRows
|
||||||
|
* @param int $errorRows
|
||||||
|
* @param string|null $message
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function update(string $importId, int $processedRows, int $skippedRows, int $errorRows, ?string $message = null): array
|
||||||
|
{
|
||||||
|
$cacheKey = $this->getCacheKey($importId);
|
||||||
|
$progressData = Cache::get($cacheKey);
|
||||||
|
|
||||||
|
if (!$progressData) {
|
||||||
|
Log::warning('ImportProgressService: Progress data not found', ['import_id' => $importId]);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalRows = $progressData['total_rows'];
|
||||||
|
$percentage = $totalRows > 0 ? round(($processedRows / $totalRows) * 100, 2) : 0;
|
||||||
|
|
||||||
|
$progressData = array_merge($progressData, [
|
||||||
|
'processed_rows' => $processedRows,
|
||||||
|
'skipped_rows' => $skippedRows,
|
||||||
|
'error_rows' => $errorRows,
|
||||||
|
'percentage' => $percentage,
|
||||||
|
'message' => $message ?? "Memproses baris {$processedRows} dari {$totalRows}...",
|
||||||
|
'updated_at' => now()
|
||||||
|
]);
|
||||||
|
|
||||||
|
Cache::put($cacheKey, $progressData, $this->cacheTtl);
|
||||||
|
|
||||||
|
// Log progress setiap 10%
|
||||||
|
if ($percentage % 10 === 0) {
|
||||||
|
Log::info('ImportProgressService: Progress update', [
|
||||||
|
'import_id' => $importId,
|
||||||
|
'percentage' => $percentage,
|
||||||
|
'processed' => $processedRows,
|
||||||
|
'total' => $totalRows
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $progressData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark import as completed
|
||||||
|
*
|
||||||
|
* @param string $importId
|
||||||
|
* @param string|null $message
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function complete(string $importId, ?string $message = null): array
|
||||||
|
{
|
||||||
|
$cacheKey = $this->getCacheKey($importId);
|
||||||
|
$progressData = Cache::get($cacheKey);
|
||||||
|
|
||||||
|
if (!$progressData) {
|
||||||
|
Log::warning('ImportProgressService: Progress data not found for completion', ['import_id' => $importId]);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$progressData = array_merge($progressData, [
|
||||||
|
'status' => 'completed',
|
||||||
|
'percentage' => 100,
|
||||||
|
'message' => $message ?? 'Import berhasil diselesaikan',
|
||||||
|
'completed_at' => now(),
|
||||||
|
'updated_at' => now()
|
||||||
|
]);
|
||||||
|
|
||||||
|
Cache::put($cacheKey, $progressData, $this->cacheTtl);
|
||||||
|
|
||||||
|
Log::info('ImportProgressService: Import completed', [
|
||||||
|
'import_id' => $importId,
|
||||||
|
'total_rows' => $progressData['total_rows'],
|
||||||
|
'processed_rows' => $progressData['processed_rows'],
|
||||||
|
'skipped_rows' => $progressData['skipped_rows'],
|
||||||
|
'error_rows' => $progressData['error_rows']
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $progressData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark import as failed
|
||||||
|
*
|
||||||
|
* @param string $importId
|
||||||
|
* @param string $errorMessage
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function fail(string $importId, string $errorMessage): array
|
||||||
|
{
|
||||||
|
$cacheKey = $this->getCacheKey($importId);
|
||||||
|
$progressData = Cache::get($cacheKey);
|
||||||
|
|
||||||
|
if (!$progressData) {
|
||||||
|
Log::warning('ImportProgressService: Progress data not found for failure', ['import_id' => $importId]);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$progressData = array_merge($progressData, [
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => 'Import gagal: ' . $errorMessage,
|
||||||
|
'failed_at' => now(),
|
||||||
|
'updated_at' => now()
|
||||||
|
]);
|
||||||
|
|
||||||
|
Cache::put($cacheKey, $progressData, $this->cacheTtl);
|
||||||
|
|
||||||
|
Log::error('ImportProgressService: Import failed', [
|
||||||
|
'import_id' => $importId,
|
||||||
|
'error' => $errorMessage,
|
||||||
|
'progress_data' => $progressData
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $progressData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get progress data
|
||||||
|
*
|
||||||
|
* @param string $importId
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
public function getProgress(string $importId): ?array
|
||||||
|
{
|
||||||
|
$cacheKey = $this->getCacheKey($importId);
|
||||||
|
return Cache::get($cacheKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all active imports for user
|
||||||
|
*
|
||||||
|
* @param int $userId
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getUserImports(int $userId): array
|
||||||
|
{
|
||||||
|
$pattern = $this->cacheKeyPrefix . '_*';
|
||||||
|
$keys = Cache::get($pattern);
|
||||||
|
|
||||||
|
$imports = [];
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$data = Cache::get($key);
|
||||||
|
if ($data && $data['user_id'] === $userId) {
|
||||||
|
$imports[] = $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $imports;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear progress data
|
||||||
|
*
|
||||||
|
* @param string $importId
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function clear(string $importId): bool
|
||||||
|
{
|
||||||
|
$cacheKey = $this->getCacheKey($importId);
|
||||||
|
$result = Cache::forget($cacheKey);
|
||||||
|
|
||||||
|
Log::info('ImportProgressService: Progress data cleared', ['import_id' => $importId]);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate cache key
|
||||||
|
*
|
||||||
|
* @param string $importId
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getCacheKey(string $importId): string
|
||||||
|
{
|
||||||
|
return $this->cacheKeyPrefix . '_' . $importId;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
app/Services/LaporanBiayaService.php
Normal file
21
app/Services/LaporanBiayaService.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Lpj\Services;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Modules\Lpj\Models\Permohonan;
|
||||||
|
|
||||||
|
class LaporanBiayaService
|
||||||
|
{
|
||||||
|
public function buildDataTableQuery(array $data){
|
||||||
|
$query = Permohonan::with([
|
||||||
|
'noc'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if($data['search']){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ namespace Modules\Lpj\Services;
|
|||||||
use Modules\Lpj\Models\Permohonan;
|
use Modules\Lpj\Models\Permohonan;
|
||||||
use Modules\Lpj\Models\Penilaian;
|
use Modules\Lpj\Models\Penilaian;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
class LaporanSLAPenilaiService
|
class LaporanSLAPenilaiService
|
||||||
{
|
{
|
||||||
@@ -27,7 +28,7 @@ class LaporanSLAPenilaiService
|
|||||||
|
|
||||||
|
|
||||||
if (isset($search->penilai_id) && !empty($search->penilai_id)) {
|
if (isset($search->penilai_id) && !empty($search->penilai_id)) {
|
||||||
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function($q) use ($search) {
|
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function ($q) use ($search) {
|
||||||
$q->where('user_id', $search->penilai_id);
|
$q->where('user_id', $search->penilai_id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -70,27 +71,15 @@ class LaporanSLAPenilaiService
|
|||||||
$filteredRecords = $query->count();
|
$filteredRecords = $query->count();
|
||||||
|
|
||||||
// Get the data for the current page
|
// Get the data for the current page
|
||||||
$data = $query->with(['debiture.branch'])->get();
|
$data = $query->with(['documents','debiture.branch'])->get();
|
||||||
|
|
||||||
$data = $data->map(function ($permohonan) {
|
$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;
|
$tgl_kunjungan = $permohonan->penilaian?->tanggal_kunjungan;
|
||||||
$luas_bangunan = $lpj['luas_bangunan'] ?? 0;
|
$tgl_otorisator = $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? $permohonan->approval_so_at;
|
||||||
// Calculate nilai_tanah dynamically by looking for all keys that start with 'nilai_tanah_'
|
$jangkaWaktu = $this->hitungTotalJangkaWaktuSla($tgl_kunjungan, $tgl_otorisator);
|
||||||
$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 [
|
return [
|
||||||
'id' => $permohonan->id,
|
'id' => $permohonan->id,
|
||||||
@@ -100,11 +89,12 @@ class LaporanSLAPenilaiService
|
|||||||
'name' => $permohonan->debiture?->name,
|
'name' => $permohonan->debiture?->name,
|
||||||
'pemohon' => $permohonan->creator?->name,
|
'pemohon' => $permohonan->creator?->name,
|
||||||
'tujuan_penilaian' => $permohonan->tujuanPenilaian?->name,
|
'tujuan_penilaian' => $permohonan->tujuanPenilaian?->name,
|
||||||
'jenis_agunan' => $permohonan->documents?->pluck('jenisJaminan.name')->unique()->implode(', '),
|
|
||||||
|
|
||||||
'tanggal_laporan' => $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? '',
|
'tanggal_laporan' => $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? '',
|
||||||
'tanggal_review' => $permohonan->penilaian?->tanggal_kunjungan ?? '',
|
'tanggal_approval' => $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? '',
|
||||||
|
'tanggal_kunjungan' => $permohonan->penilaian?->tanggal_kunjungan ?? '',
|
||||||
'nama_penilai' => $permohonan->penilaian?->_user_penilai?->userPenilaiTeam?->name,
|
'nama_penilai' => $permohonan->penilaian?->_user_penilai?->userPenilaiTeam?->name,
|
||||||
|
'jangka_waktu' => $jangkaWaktu,
|
||||||
|
'keterangan' => $permohonan->keterangan
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -125,4 +115,9 @@ class LaporanSLAPenilaiService
|
|||||||
'data' => $data,
|
'data' => $data,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function hitungTotalJangkaWaktuSla($tgl_kunjungan,$tgl_otorisator){
|
||||||
|
$countHariKerja = hitungHariKerja($tgl_kunjungan, $tgl_otorisator);
|
||||||
|
return $countHariKerja;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,96 +85,25 @@ class LaporanUserService
|
|||||||
$data = $query->with(['debiture.branch'])->get();
|
$data = $query->with(['debiture.branch'])->get();
|
||||||
|
|
||||||
$data = $data->map(function ($permohonan) {
|
$data = $data->map(function ($permohonan) {
|
||||||
$luas_tanah = 0;
|
|
||||||
$luas_bangunan = 0;
|
|
||||||
$nilai_tanah = 0;
|
|
||||||
$nilai_bangunan = 0;
|
|
||||||
$npw = 0;
|
$npw = 0;
|
||||||
$nilai_liquidasi = 0;
|
|
||||||
|
|
||||||
if (isset($permohonan->penilai->lpj)) {
|
if (isset($permohonan->penilai->lpj)) {
|
||||||
$lpj = json_decode($permohonan->penilai->lpj, true);
|
$lpj = json_decode($permohonan->penilai->lpj, true);
|
||||||
$npw = str_replace('.', '', $lpj['total_nilai_pasar_wajar'] ?? 0);
|
$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 [
|
return [
|
||||||
'id' => $permohonan->id,
|
'id' => $permohonan->id,
|
||||||
'nomor_registrasi' => $permohonan->nomor_registrasi,
|
'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,
|
'branch' => $permohonan->debiture->branch?->name,
|
||||||
'pemohon' => $permohonan->creator?->name,
|
|
||||||
'cif' => $permohonan->debiture->cif,
|
|
||||||
'name' => $permohonan->debiture?->name,
|
'name' => $permohonan->debiture?->name,
|
||||||
'jenis_agunan' => $permohonan->documents?->pluck('jenisJaminan.name')
|
'pemohon' => $permohonan->creator?->name,
|
||||||
->unique()
|
|
||||||
->implode(', '),
|
|
||||||
'alamat_agunan' => $permohonan->documents?->map(function ($document) {
|
|
||||||
return formatAlamat($document);
|
|
||||||
})->unique()->implode(', '),
|
|
||||||
'bukti_kepemilikan' => (function () use ($permohonan) {
|
|
||||||
$legalitasItems = $permohonan->documents?->flatMap(function ($document) {
|
|
||||||
return $document->detail->map(function ($detail) {
|
|
||||||
// Jika tidak ada jenis legalitas jaminan, lewati
|
|
||||||
if (empty($detail->jenisLegalitasJaminan)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hanya tampilkan detail yang memiliki dokumen_jaminan
|
|
||||||
if (empty($detail->dokumen_jaminan)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tampilkan nama legalitas jaminan saja
|
|
||||||
return $detail->jenisLegalitasJaminan->name ?? '';
|
|
||||||
});
|
|
||||||
})->filter()->unique()->values()->toArray();
|
|
||||||
|
|
||||||
// Buat daftar bernomor
|
|
||||||
$result = '';
|
|
||||||
foreach ($legalitasItems as $index => $item) {
|
|
||||||
$result .= ($index + 1) . '. ' . $item . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
})(),
|
|
||||||
'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_permohonan' => $permohonan->tanggal_permohonan,
|
||||||
|
'nama_penilai' => $permohonan->penilaian?->_user_penilai?->userPenilaiTeam?->name,
|
||||||
'tanggal_laporan' => $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? '',
|
'tanggal_laporan' => $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? '',
|
||||||
'tanggal_review' => $permohonan->penilaian?->tanggal_kunjungan ?? '',
|
'nilai_pasar_wajar' => formatRupiah($npw, 2)
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,62 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'name' => 'Lpj',
|
'name' => 'Lpj',
|
||||||
|
'import' => [
|
||||||
|
'slik' => [
|
||||||
|
// Memory limit untuk import (dalam MB)
|
||||||
|
'memory_limit' => env('SLIK_IMPORT_MEMORY_LIMIT', 1024),
|
||||||
|
|
||||||
|
// Ukuran chunk untuk processing (jumlah baris per chunk)
|
||||||
|
'chunk_size' => env('SLIK_IMPORT_CHUNK_SIZE', 50),
|
||||||
|
|
||||||
|
// Ukuran batch untuk database insert
|
||||||
|
'batch_size' => env('SLIK_IMPORT_BATCH_SIZE', 50),
|
||||||
|
|
||||||
|
// Timeout untuk import (dalam detik)
|
||||||
|
'timeout' => env('SLIK_IMPORT_TIMEOUT', 1800), // 30 menit untuk file besar
|
||||||
|
|
||||||
|
// Maksimum file size yang diizinkan (dalam MB)
|
||||||
|
'max_file_size' => env('SLIK_IMPORT_MAX_FILE_SIZE', 50),
|
||||||
|
|
||||||
|
// Enable garbage collection untuk optimasi memory
|
||||||
|
'enable_gc' => env('SLIK_IMPORT_ENABLE_GC', true),
|
||||||
|
|
||||||
|
// Enable progress logging
|
||||||
|
'enable_progress_logging' => env('SLIK_IMPORT_ENABLE_PROGRESS_LOGGING', true),
|
||||||
|
|
||||||
|
// Enable detailed error logging
|
||||||
|
'enable_error_logging' => env('SLIK_IMPORT_ENABLE_ERROR_LOGGING', true),
|
||||||
|
|
||||||
|
// XML Scanner settings untuk optimasi memory
|
||||||
|
'xml_scanner' => [
|
||||||
|
'timeout' => env('SLIK_XML_SCANNER_TIMEOUT', 1800), // 30 menit
|
||||||
|
'memory_limit' => env('SLIK_XML_SCANNER_MEMORY_LIMIT', 1024), // 1GB
|
||||||
|
'chunk_size' => env('SLIK_XML_SCANNER_CHUNK_SIZE', 50), // Lebih kecil untuk XML
|
||||||
|
],
|
||||||
|
|
||||||
|
// Queue processing untuk file besar
|
||||||
|
'queue' => [
|
||||||
|
'enabled' => env('SLIK_IMPORT_QUEUE_ENABLED', false),
|
||||||
|
'connection' => env('SLIK_IMPORT_QUEUE_CONNECTION', 'database'),
|
||||||
|
'queue_name' => env('SLIK_IMPORT_QUEUE_NAME', 'imports'),
|
||||||
|
'chunk_size' => env('SLIK_IMPORT_QUEUE_CHUNK_SIZE', 500),
|
||||||
|
],
|
||||||
|
|
||||||
|
// Progress tracking
|
||||||
|
'progress' => [
|
||||||
|
'enabled' => env('SLIK_IMPORT_PROGRESS_ENABLED', true),
|
||||||
|
'update_interval' => env('SLIK_IMPORT_PROGRESS_INTERVAL', 50), // update setiap 50 baris
|
||||||
|
'cache_key' => 'slik_import_progress',
|
||||||
|
'cache_ttl' => 3600, // 1 jam
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
// General import settings
|
||||||
|
'general' => [
|
||||||
|
'default_memory_limit' => env('IMPORT_DEFAULT_MEMORY_LIMIT', 128),
|
||||||
|
'max_execution_time' => env('IMPORT_MAX_EXECUTION_TIME', 300000),
|
||||||
|
'temp_directory' => env('IMPORT_TEMP_DIRECTORY', storage_path('app/temp')),
|
||||||
|
'cleanup_temp_files' => env('IMPORT_CLEANUP_TEMP_FILES', true),
|
||||||
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class () extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('category_daftar_pustaka', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('code')->unique()->index();
|
||||||
|
$table->string('name');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->timestamp('authorized_at')->nullable();
|
||||||
|
$table->char('authorized_status', 1)->nullable();
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->unsignedBigInteger('created_by')->nullable();
|
||||||
|
$table->unsignedBigInteger('updated_by')->nullable();
|
||||||
|
$table->unsignedBigInteger('deleted_by')->nullable();
|
||||||
|
$table->unsignedBigInteger('authorized_by')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('category_daftar_pustaka');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class () extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('daftar_pustaka', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('judul');
|
||||||
|
$table->string('attachment')->nullable();
|
||||||
|
$table->text('deskripsi');
|
||||||
|
$table->unsignedBigInteger('category_id');
|
||||||
|
$table->foreign('category_id')->references('id')->on('category_daftar_pustaka');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->timestamp('authorized_at')->nullable();
|
||||||
|
$table->char('authorized_status', 1)->nullable();
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->unsignedBigInteger('created_by')->nullable();
|
||||||
|
$table->unsignedBigInteger('updated_by')->nullable();
|
||||||
|
$table->unsignedBigInteger('deleted_by')->nullable();
|
||||||
|
$table->unsignedBigInteger('authorized_by')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('daftar_pustaka');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('noc', function (Blueprint $table) {
|
||||||
|
// Field untuk informasi memo penyelesaian
|
||||||
|
$table->string('memo_penyelesaian_number')->nullable()->after('memo_penyelesaian');
|
||||||
|
$table->date('memo_penyelesaian_date')->nullable()->after('memo_penyelesaian_number');
|
||||||
|
$table->date('memo_penyelesaian_payment_date')->nullable()->after('memo_penyelesaian_date');
|
||||||
|
$table->timestamp('memo_penyelesaian_created_at')->nullable()->after('memo_penyelesaian_date');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('noc', function (Blueprint $table) {
|
||||||
|
$table->dropColumn([
|
||||||
|
'memo_penyelesaian_number',
|
||||||
|
'memo_penyelesaian_date',
|
||||||
|
'memo_penyelesaian_payment_date',
|
||||||
|
'memo_penyelesaian_created_at'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('noc', function (Blueprint $table) {
|
||||||
|
$table->decimal('total_pembukuan', 10, 2)->after('nominal_bayar');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('noc', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('total_pembukuan');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Menjalankan migration untuk menambahkan field status pembayaran
|
||||||
|
* Field yang ditambahkan: status_kurang_bayar, nominal_kurang_bayar,
|
||||||
|
* status_lebih_bayar, nominal_lebih_bayar, bukti_pengembalian
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('noc', function (Blueprint $table) {
|
||||||
|
// Field untuk status kurang bayar
|
||||||
|
$table->boolean('status_kurang_bayar')->default(false)->after('status_bayar');
|
||||||
|
$table->decimal('nominal_kurang_bayar', 15, 2)->nullable()->after('status_kurang_bayar');
|
||||||
|
|
||||||
|
// Field untuk status lebih bayar
|
||||||
|
$table->boolean('status_lebih_bayar')->default(false)->after('nominal_kurang_bayar');
|
||||||
|
$table->decimal('nominal_lebih_bayar', 15, 2)->nullable()->after('status_lebih_bayar');
|
||||||
|
|
||||||
|
// Field untuk bukti pengembalian jika lebih bayar
|
||||||
|
$table->string('bukti_pengembalian')->nullable()->after('nominal_lebih_bayar');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rollback migration
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('noc', function (Blueprint $table) {
|
||||||
|
$table->dropColumn([
|
||||||
|
'status_kurang_bayar',
|
||||||
|
'nominal_kurang_bayar',
|
||||||
|
'status_lebih_bayar',
|
||||||
|
'nominal_lebih_bayar',
|
||||||
|
'bukti_pengembalian'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('bucoks', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('no')->nullable(); // Nomor urut
|
||||||
|
$table->string('tanggal')->nullable(); // Tanggal
|
||||||
|
$table->string('bulan')->nullable(); // Bulan
|
||||||
|
$table->string('tahun')->nullable(); // Tahun
|
||||||
|
$table->string('tanggal_penuh')->nullable(); // Tanggal lengkap
|
||||||
|
$table->string('nomor_categ')->nullable(); // Nomor kategori
|
||||||
|
$table->string('coa_summary')->nullable(); // COA Summary
|
||||||
|
$table->string('nomor_coa')->nullable(); // Nomor COA
|
||||||
|
$table->string('nama_coa')->nullable(); // Nama COA
|
||||||
|
$table->string('nomor_tiket')->unique(); // Nomor tiket (unique)
|
||||||
|
$table->string('deskripsi')->nullable(); // Deskripsi
|
||||||
|
$table->string('nominal')->nullable(); // Nominal
|
||||||
|
$table->string('penyelesaian')->nullable(); // Penyelesaian
|
||||||
|
$table->string('umur_aging')->nullable(); // Umur aging
|
||||||
|
$table->string('cost_center')->nullable(); // Cost center
|
||||||
|
$table->string('nama_sub_direktorat')->nullable(); // Nama sub direktorat
|
||||||
|
$table->string('nama_direktorat_cabang')->nullable(); // Nama direktorat cabang
|
||||||
|
$table->string('tanggal_penyelesaian')->nullable(); // Tanggal penyelesaian
|
||||||
|
$table->string('nominal_penyelesaian')->nullable(); // Nominal penyelesaian
|
||||||
|
$table->string('nominal_berjalan')->nullable(); // Nominal berjalan
|
||||||
|
$table->string('amortisasi_berjalan')->nullable(); // Amortisasi berjalan
|
||||||
|
$table->string('sistem_berjalan')->nullable(); // Sistem berjalan
|
||||||
|
$table->string('lainnya_berjalan')->nullable(); // Lainnya berjalan
|
||||||
|
$table->string('nominal_gantung')->nullable(); // Nominal gantung
|
||||||
|
$table->string('aset_gantung')->nullable(); // Aset gantung
|
||||||
|
$table->string('keterangan_gantung')->nullable(); // Keterangan gantung
|
||||||
|
$table->string('lainnya_satu')->nullable(); // Lainnya satu
|
||||||
|
$table->string('lainnya_dua')->nullable(); // Lainnya dua
|
||||||
|
|
||||||
|
// Standard Laravel fields
|
||||||
|
$table->timestamps();
|
||||||
|
$table->string('created_by')->nullable();
|
||||||
|
$table->string('updated_by')->nullable();
|
||||||
|
$table->string('deleted_by')->nullable();
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
// Indexes untuk performa
|
||||||
|
$table->index(['nomor_tiket']);
|
||||||
|
$table->index(['tanggal']);
|
||||||
|
$table->index(['tahun']);
|
||||||
|
$table->index(['nomor_coa']);
|
||||||
|
$table->index(['cost_center']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('bucoks');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
* Menambahkan kolom nomor_tiket ke tabel persetujuan_penawaran
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('persetujuan_penawaran', function (Blueprint $table) {
|
||||||
|
// Menambahkan kolom nomor_tiket setelah nomor_proposal_penawaran
|
||||||
|
$table->string('nomor_tiket', 100)->nullable()->after('nomor_proposal_penawaran')
|
||||||
|
->comment('Nomor tiket untuk tracking persetujuan penawaran');
|
||||||
|
$table->string('nominal_kurang_bayar')->nullable()->after('nomor_proposal_penawaran');
|
||||||
|
$table->string('bukti_ksl_kurang_bayar')->nullable()->after('nominal_kurang_bayar');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('noc', function (Blueprint $table) {
|
||||||
|
// Menambahkan kolom nomor_tiket setelah nomor_proposal_penawaran
|
||||||
|
$table->string('nomor_tiket', 100)->nullable()->after('persetujuan_penawaran_id')
|
||||||
|
->comment('Nomor tiket untuk tracking persetujuan penawaran');
|
||||||
|
$table->string('nomor_rekening_lebih_bayar',20)->nullable()->after('nominal_lebih_bayar');
|
||||||
|
$table->string('bukti_ksl_lebih_bayar')->nullable()->after('nomor_rekening_lebih_bayar');
|
||||||
|
$table->string('bukti_ksl_kurang_bayar')->nullable()->after('bukti_ksl_lebih_bayar');
|
||||||
|
$table->string('nominal_pelunasan')->nullable()->after('bukti_ksl_kurang_bayar');
|
||||||
|
$table->string('debiture_id')->nullable()->after('persetujuan_penawaran_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
* Menghapus kolom nomor_tiket dari tabel persetujuan_penawaran
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('persetujuan_penawaran', function (Blueprint $table) {
|
||||||
|
// Menghapus kolom nomor_tiket
|
||||||
|
$table->dropColumn('nomor_tiket');
|
||||||
|
$table->dropColumn('nominal_kurang_bayar');
|
||||||
|
$table->dropColumn('bukti_ksl_kurang_bayar');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('noc', function (Blueprint $table) {
|
||||||
|
// Menghapus kolom nomor_tiket
|
||||||
|
$table->dropColumn('nomor_tiket');
|
||||||
|
$table->dropColumn('nomor_rekening_lebih_bayar');
|
||||||
|
$table->dropColumn('bukti_ksl_lebih_bayar');
|
||||||
|
$table->dropColumn('bukti_ksl_kurang_bayar');
|
||||||
|
$table->dropColumn('nominal_pelunasan');
|
||||||
|
$table->dropColumn('debiture_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('noc', function (Blueprint $table) {
|
||||||
|
$table->bigInteger('branch_id')->nullable()->after('debiture_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('noc', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('branch_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
88
database/migrations/2025_09_15_092525_create_sliks_table.php
Normal file
88
database/migrations/2025_09_15_092525_create_sliks_table.php
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* Migration untuk membuat tabel sliks dengan semua field yang diperlukan
|
||||||
|
* berdasarkan header Excel yang diberikan untuk import data SLIK
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('sliks', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
// Field utama berdasarkan header Excel
|
||||||
|
$table->string('sandi_bank')->nullable(); // Sandi Bank
|
||||||
|
$table->string('tahun')->nullable(); // Tahun
|
||||||
|
$table->string('bulan')->nullable(); // Bulan
|
||||||
|
$table->string('flag_detail')->nullable(); // Flag Detail
|
||||||
|
$table->string('kode_register_agunan')->nullable(); // Kode Register Agunan
|
||||||
|
$table->string('no_rekening')->nullable(); // No Rekening
|
||||||
|
$table->string('cif')->nullable(); // CIF
|
||||||
|
$table->string('kolektibilitas')->nullable(); // Kolektibilitas
|
||||||
|
$table->string('fasilitas')->nullable(); // Fasilitas
|
||||||
|
$table->string('jenis_segmen_fasilitas')->nullable(); // Jenis Segmen Fasilitas
|
||||||
|
$table->string('status_agunan')->nullable(); // Status Agunan
|
||||||
|
$table->string('jenis_agunan')->nullable(); // Jenis Agunan
|
||||||
|
$table->string('peringkat_agunan')->nullable(); // Peringkat Agunan
|
||||||
|
$table->string('lembaga_pemeringkat')->nullable(); // Lembaga Pemeringkat
|
||||||
|
$table->string('jenis_pengikatan')->nullable(); // Jenis Pengikatan
|
||||||
|
$table->string('tanggal_pengikatan')->nullable(); // Tanggal Pengikatan
|
||||||
|
$table->string('nama_pemilik_agunan')->nullable(); // Nama Pemilik Agunan
|
||||||
|
$table->string('bukti_kepemilikan')->nullable(); // Bukti Kepemilikan
|
||||||
|
$table->text('alamat_agunan')->nullable(); // Alamat Agunan
|
||||||
|
$table->string('lokasi_agunan')->nullable(); // Lokasi Agunan
|
||||||
|
$table->string('nilai_agunan')->nullable(); // Nilai Agunan
|
||||||
|
$table->string('nilai_agunan_menurut_ljk')->nullable(); // Nilai Agunan Menurut LJK
|
||||||
|
$table->string('tanggal_penilaian_ljk')->nullable(); // Tanggal Penilaian LJK
|
||||||
|
$table->string('nilai_agunan_penilai_independen')->nullable(); // Nilai Agunan Penilai Independen
|
||||||
|
$table->string('nama_penilai_independen')->nullable(); // Nama Penilai Independen
|
||||||
|
$table->string('tanggal_penilaian_penilai_independen')->nullable(); // Tanggal Penilaian Penilai Independen
|
||||||
|
$table->string('jumlah_hari_tunggakan')->nullable(); // Jumlah Hari Tunggakan
|
||||||
|
$table->string('status_paripasu')->nullable(); // Status Paripasu
|
||||||
|
$table->string('prosentase_paripasu')->nullable(); // Prosentase Paripasu
|
||||||
|
$table->string('status_kredit_join')->nullable(); // Status Kredit Join
|
||||||
|
$table->string('diasuransikan')->nullable(); // Diasuransikan
|
||||||
|
$table->text('keterangan')->nullable(); // Keterangan
|
||||||
|
$table->string('kantor_cabang')->nullable(); // Kantor Cabang
|
||||||
|
$table->string('operasi_data')->nullable(); // Operasi Data
|
||||||
|
$table->string('kode_cabang')->nullable(); // Kode Cabang
|
||||||
|
$table->string('nama_debitur')->nullable(); // Nama Debitur
|
||||||
|
$table->string('nama_cabang')->nullable(); // Nama Cabang
|
||||||
|
$table->string('flag')->nullable(); // Flag
|
||||||
|
|
||||||
|
// Standard Laravel fields
|
||||||
|
$table->timestamps();
|
||||||
|
$table->string('created_by')->nullable();
|
||||||
|
$table->string('updated_by')->nullable();
|
||||||
|
$table->string('deleted_by')->nullable();
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
// Indexes untuk performa query
|
||||||
|
$table->index(['sandi_bank']);
|
||||||
|
$table->index(['tahun']);
|
||||||
|
$table->index(['bulan']);
|
||||||
|
$table->index(['no_rekening']);
|
||||||
|
$table->index(['cif']);
|
||||||
|
$table->index(['kode_register_agunan']);
|
||||||
|
$table->index(['nama_debitur']);
|
||||||
|
$table->index(['kode_cabang']);
|
||||||
|
$table->index(['created_at']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* Menghapus tabel sliks jika migration di-rollback
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('sliks');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('laporan_slik', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('slik_id')->nullable();
|
||||||
|
$table->string('sandi_bank', 10)->nullable();
|
||||||
|
$table->string('kode_kantor', 10)->nullable();
|
||||||
|
$table->string('kode_cabang', 10)->nullable();
|
||||||
|
$table->string('tahun', 4)->nullable();
|
||||||
|
$table->string('bulan', 2)->nullable();
|
||||||
|
$table->string('no_rekening', 50)->nullable();
|
||||||
|
$table->string('cif', 50)->nullable();
|
||||||
|
$table->string('kode_jenis', 10)->nullable();
|
||||||
|
$table->string('kode_jenis_ket', 100)->nullable();
|
||||||
|
$table->string('kode_sifat', 10)->nullable();
|
||||||
|
$table->string('kode_sifat_ket', 100)->nullable();
|
||||||
|
$table->string('kode_valuta', 5)->nullable();
|
||||||
|
$table->string('kode_valuta_ket', 50)->nullable();
|
||||||
|
$table->string('baki_debet', 20)->nullable();
|
||||||
|
$table->string('kolektibilitas', 5)->nullable();
|
||||||
|
$table->string('kolektibilitas_ket', 50)->nullable();
|
||||||
|
$table->string('tanggal_mulai', 10)->nullable();
|
||||||
|
$table->string('tanggal_jatuh_tempo', 10)->nullable();
|
||||||
|
$table->string('tanggal_selesai', 10)->nullable();
|
||||||
|
$table->string('tanggal_restrukturisasi', 10)->nullable();
|
||||||
|
$table->string('kode_sebab_macet', 10)->nullable();
|
||||||
|
$table->string('kode_sebab_macet_ket', 100)->nullable();
|
||||||
|
$table->string('tanggal_macet', 10)->nullable();
|
||||||
|
$table->string('kode_kondisi', 10)->nullable();
|
||||||
|
$table->string('kode_kondisi_ket', 100)->nullable();
|
||||||
|
$table->string('tanggal_kondisi', 10)->nullable();
|
||||||
|
$table->string('nilai_agunan', 20)->nullable();
|
||||||
|
$table->string('nilai_agunan_ket', 100)->nullable();
|
||||||
|
$table->string('jenis_agunan', 50)->nullable();
|
||||||
|
$table->string('kode_agunan', 10)->nullable();
|
||||||
|
$table->string('kode_agunan_ket', 100)->nullable();
|
||||||
|
$table->string('peringkat_agunan', 10)->nullable();
|
||||||
|
$table->string('peringkat_agunan_ket', 100)->nullable();
|
||||||
|
$table->string('nama_debitur', 100)->nullable();
|
||||||
|
$table->string('npwp', 50)->nullable();
|
||||||
|
$table->string('no_ktp', 50)->nullable();
|
||||||
|
$table->string('no_telp', 50)->nullable();
|
||||||
|
$table->string('kode_kab_kota', 10)->nullable();
|
||||||
|
$table->string('kode_kab_kota_ket', 100)->nullable();
|
||||||
|
$table->string('kode_negara_domisili', 10)->nullable();
|
||||||
|
$table->string('kode_negara_domisili_ket', 100)->nullable();
|
||||||
|
$table->string('kode_pos', 10)->nullable();
|
||||||
|
$table->string('alamat', 200)->nullable();
|
||||||
|
$table->string('fasilitas', 100)->nullable();
|
||||||
|
$table->string('status_agunan', 20)->nullable();
|
||||||
|
$table->string('tanggal_lapor', 10)->nullable();
|
||||||
|
$table->string('status', 20)->default('aktif');
|
||||||
|
$table->unsignedBigInteger('created_by')->nullable();
|
||||||
|
$table->unsignedBigInteger('updated_by')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->index('slik_id');
|
||||||
|
$table->index('no_rekening');
|
||||||
|
$table->index('cif');
|
||||||
|
$table->index('nama_debitur');
|
||||||
|
$table->index(['tahun', 'bulan']);
|
||||||
|
$table->index('created_at');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('laporan_slik');
|
||||||
|
}
|
||||||
|
};
|
||||||
194
module.json
194
module.json
@@ -47,24 +47,7 @@
|
|||||||
"senior-officer"
|
"senior-officer"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"title": "Laporan Admin Kredit",
|
|
||||||
"path": "laporan-admin-kredit",
|
|
||||||
"icon": "ki-filled ki-filter-tablet text-lg text-primary",
|
|
||||||
"classes": "",
|
|
||||||
"attributes": [],
|
|
||||||
"permission": "",
|
|
||||||
"roles": [
|
|
||||||
"adk",
|
|
||||||
"administrator",
|
|
||||||
"pemohon-ao",
|
|
||||||
"pemohon-eo",
|
|
||||||
"admin",
|
|
||||||
"DD Appraisal",
|
|
||||||
"EO Appraisal",
|
|
||||||
"senior-officer"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"title": "Laporan Penilai Jaminan",
|
"title": "Laporan Penilai Jaminan",
|
||||||
"path": "laporan-penilai-jaminan",
|
"path": "laporan-penilai-jaminan",
|
||||||
@@ -378,6 +361,105 @@
|
|||||||
"pemohon-ao"
|
"pemohon-ao"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "Pembayaran",
|
||||||
|
"path": "pembayaran",
|
||||||
|
"icon": "ki-filled ki-credit-cart text-lg text-primary",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"administrator",
|
||||||
|
"pemohon-ao"
|
||||||
|
],
|
||||||
|
"sub": [
|
||||||
|
{
|
||||||
|
"title": "Pembayaran",
|
||||||
|
"path": "pembayaran",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"administrator",
|
||||||
|
"pemohon-ao"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Kurang Bayar",
|
||||||
|
"path": "pembayaran.kurang",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"administrator",
|
||||||
|
"pemohon-ao"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Lebih Bayar",
|
||||||
|
"path": "pembayaran.lebih",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"administrator",
|
||||||
|
"pemohon-ao"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Admin Kredit",
|
||||||
|
"path": "admin-kredit",
|
||||||
|
"icon": "ki-filled ki-briefcase text-lg text-primary",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"administrator",
|
||||||
|
"admin",
|
||||||
|
"adk"
|
||||||
|
],
|
||||||
|
"sub": [{
|
||||||
|
"title": "SLIK",
|
||||||
|
"path": "admin-kredit.slik",
|
||||||
|
"icon": "ki-filled ki-filter-tablet text-lg text-primary",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"adk",
|
||||||
|
"administrator",
|
||||||
|
"admin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Laporan Admin Kredit",
|
||||||
|
"path": "admin-kredit.laporan",
|
||||||
|
"icon": "ki-filled ki-filter-tablet text-lg text-primary",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"adk",
|
||||||
|
"administrator",
|
||||||
|
"admin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Laporan SLIK",
|
||||||
|
"path": "admin-kredit.laporan-slik",
|
||||||
|
"icon": "ki-filled ki-filter-tablet text-lg text-primary",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"adk",
|
||||||
|
"administrator",
|
||||||
|
"admin"
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "NOC",
|
"title": "NOC",
|
||||||
"path": "noc",
|
"path": "noc",
|
||||||
@@ -387,11 +469,12 @@
|
|||||||
"permission": "",
|
"permission": "",
|
||||||
"roles": [
|
"roles": [
|
||||||
"administrator",
|
"administrator",
|
||||||
"admin"
|
"admin",
|
||||||
|
"noc"
|
||||||
],
|
],
|
||||||
"sub": [
|
"sub": [
|
||||||
{
|
{
|
||||||
"title": "Pembayaran",
|
"title": "Pembukuan",
|
||||||
"path": "noc.pembayaran",
|
"path": "noc.pembayaran",
|
||||||
"icon": "ki-filled ki-two-credit-cart text-lg text-primary",
|
"icon": "ki-filled ki-two-credit-cart text-lg text-primary",
|
||||||
"classes": "",
|
"classes": "",
|
||||||
@@ -411,6 +494,20 @@
|
|||||||
"permission": "",
|
"permission": "",
|
||||||
"roles": [
|
"roles": [
|
||||||
"administrator",
|
"administrator",
|
||||||
|
"admin",
|
||||||
|
"noc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Bucok",
|
||||||
|
"path": "bucok",
|
||||||
|
"icon": "ki-filled ki-two-credit-cart text-lg text-primary",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"administrator",
|
||||||
|
"admin",
|
||||||
"noc"
|
"noc"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -500,18 +597,6 @@
|
|||||||
"admin"
|
"admin"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"title": "Pembayaran",
|
|
||||||
"path": "pembayaran",
|
|
||||||
"icon": "ki-filled ki-credit-cart text-lg text-primary",
|
|
||||||
"classes": "",
|
|
||||||
"attributes": [],
|
|
||||||
"permission": "",
|
|
||||||
"roles": [
|
|
||||||
"administrator",
|
|
||||||
"pemohon-ao"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"title": "Data Debitur",
|
"title": "Data Debitur",
|
||||||
"path": "debitur",
|
"path": "debitur",
|
||||||
@@ -607,6 +692,40 @@
|
|||||||
"EO Appraisal",
|
"EO Appraisal",
|
||||||
"senior-officer"
|
"senior-officer"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Daftar Pustaka",
|
||||||
|
"path": "daftar-pustaka",
|
||||||
|
"icon": "ki-filled ki-filter-tablet text-lg text-primary",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"administrator",
|
||||||
|
"pemohon-ao",
|
||||||
|
"pemohon-eo",
|
||||||
|
"admin",
|
||||||
|
"DD Appraisal",
|
||||||
|
"EO Appraisal",
|
||||||
|
"senior-officer"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Memo Penyelesaian",
|
||||||
|
"path": "memo",
|
||||||
|
"icon": "ki-filled ki-document text-lg text-primary",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"administrator",
|
||||||
|
"pemohon-ao",
|
||||||
|
"pemohon-eo",
|
||||||
|
"admin",
|
||||||
|
"DD Appraisal",
|
||||||
|
"EO Appraisal",
|
||||||
|
"senior-officer"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"master": [
|
"master": [
|
||||||
@@ -1149,6 +1268,17 @@
|
|||||||
"administrator",
|
"administrator",
|
||||||
"admin"
|
"admin"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Kategori Daftar Pustaka",
|
||||||
|
"path": "category-daftar-pustaka",
|
||||||
|
"classes": "",
|
||||||
|
"attributes": [],
|
||||||
|
"permission": "",
|
||||||
|
"roles": [
|
||||||
|
"administrator",
|
||||||
|
"admin"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,7 +268,7 @@
|
|||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="flex flex-nowrap justify-center">
|
<div class="flex flex-nowrap justify-center">
|
||||||
<a class="btn btn-sm btn-icon btn-clear btn-warning" href="activity/${data.id}/show" title="Lihat Detail">
|
<a class="btn btn-sm btn-icon ${status === 'freeze' ? 'btn-light' : 'btn-warning btn-clear'}" href="activity/${data.id}/show" title="Lihat Detail">
|
||||||
<i class="ki-outline ki-eye"></i>
|
<i class="ki-outline ki-eye"></i>
|
||||||
</a>
|
</a>
|
||||||
${
|
${
|
||||||
@@ -284,14 +284,44 @@
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let dataTable = new KTDataTable(element, dataTableOptions);
|
let dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
|
|
||||||
|
function highlightFreezeRows() {
|
||||||
|
const table = document.querySelector('#permohonan-table table[data-datatable-table="true"]');
|
||||||
|
if (!table) return;
|
||||||
|
|
||||||
|
const rows = table.querySelectorAll('tbody tr');
|
||||||
|
|
||||||
|
rows.forEach(row => {
|
||||||
|
const statusCell = row.cells[7];
|
||||||
|
if (!statusCell) return;
|
||||||
|
|
||||||
|
const statusText = statusCell.textContent.trim().toLowerCase();
|
||||||
|
|
||||||
|
if (statusText === 'freeze') {
|
||||||
|
row.classList.add('bg-red-400', 'text-white');
|
||||||
|
} else {
|
||||||
|
row.classList.remove('bg-red-400', 'text-white');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Polling setiap 1 detik untuk sementara
|
||||||
|
setInterval(() => {
|
||||||
|
highlightFreezeRows();
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
searchInput.addEventListener('input', function() {
|
searchInput.addEventListener('input', function() {
|
||||||
const searchValue = this.value.trim();
|
const searchValue = this.value.trim();
|
||||||
dataTable.search(searchValue, true);
|
dataTable.search(searchValue, true);
|
||||||
|
|||||||
342
resources/views/bucok/index.blade.php
Normal file
342
resources/views/bucok/index.blade.php
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('bucok') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid">
|
||||||
|
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="bucok-table" data-api-url="{{ route('bucok.datatables') }}">
|
||||||
|
<div class="flex-wrap py-5 card-header bg-agi-50">
|
||||||
|
<h3 class="card-title">
|
||||||
|
Data Bucok
|
||||||
|
</h3>
|
||||||
|
<div class="flex flex-wrap gap-2 lg:gap-5">
|
||||||
|
<div class="flex">
|
||||||
|
<label class="input input-sm">
|
||||||
|
<i class="ki-filled ki-magnifier"></i>
|
||||||
|
<input placeholder="Search Bucok" id="search" type="text" value="">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap gap-2.5">
|
||||||
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
|
|
||||||
|
<!-- Filter Tahun -->
|
||||||
|
<select class="select select-sm" id="year-filter">
|
||||||
|
<option value="">Semua Tahun</option>
|
||||||
|
@for($year = date('Y'); $year >= 2020; $year--)
|
||||||
|
<option value="{{ $year }}">{{ $year }}</option>
|
||||||
|
@endfor
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- Filter Bulan -->
|
||||||
|
<select class="select select-sm" id="month-filter">
|
||||||
|
<option value="">Semua Bulan</option>
|
||||||
|
@for($month = 1; $month <= 12; $month++)
|
||||||
|
<option value="{{ $month }}">{{ DateTime::createFromFormat('!m', $month)->format('F') }}</option>
|
||||||
|
@endfor
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- Filter Status Penyelesaian -->
|
||||||
|
<select class="select select-sm" id="completion-status-filter">
|
||||||
|
<option value="">Semua Status</option>
|
||||||
|
<option value="1">Selesai</option>
|
||||||
|
<option value="0">Belum Selesai</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- Import Excel -->
|
||||||
|
<button class="btn btn-sm btn-success" data-modal-toggle="#import-modal">
|
||||||
|
<i class="ki-filled ki-file-up"></i> Import Excel
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a class="btn btn-sm btn-light" href="#" id="export-excel">
|
||||||
|
<i class="ki-filled ki-file-down"></i> Export Excel
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="scrollable-x-auto">
|
||||||
|
<table class="table text-sm font-medium text-gray-700 align-middle table-auto table-border" data-datatable-table="true">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-14">
|
||||||
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox"/>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[80px]" data-datatable-column="no">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">No</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="tanggal">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Tanggal</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[120px]" data-datatable-column="nomor_tiket">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Nomor Tiket</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="nomor_coa">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Nomor COA</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="nama_coa">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Nama COA</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[200px]" data-datatable-column="deskripsi">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Deskripsi</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[120px]" data-datatable-column="nominal">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Nominal</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="cost_center">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Cost Center</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="status_penyelesaian">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Status</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[50px] text-center" data-datatable-column="actions">Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
Show
|
||||||
|
<select class="w-16 select select-sm" data-datatable-size="true" name="perpage"> </select> per page
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-4 items-center">
|
||||||
|
<span data-datatable-info="true"> </span>
|
||||||
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal Import Excel -->
|
||||||
|
<div class="modal" data-modal="true" id="import-modal">
|
||||||
|
<div class="modal-content max-w-[500px] top-[15%]">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 class="modal-title">Import Data Bucok</h3>
|
||||||
|
<button class="btn btn-sm btn-icon btn-light btn-clear shrink-0" data-modal-dismiss="true">
|
||||||
|
<i class="ki-filled ki-cross"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form action="{{ route('bucok.import') }}" method="POST" enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="flex flex-col gap-5">
|
||||||
|
<div class="flex flex-col gap-2.5">
|
||||||
|
<label class="text-gray-900 form-label">File Excel</label>
|
||||||
|
<input type="file" name="file" class="file-input" accept=".xlsx,.xls,.csv" required>
|
||||||
|
<div class="text-gray-600 text-2sm">
|
||||||
|
Format yang didukung: .xlsx, .xls, .csv (Maksimal 10MB)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 bg-yellow-100 rounded border border-yellow-300">
|
||||||
|
<div class="text-sm text-yellow-800">
|
||||||
|
<strong>Catatan:</strong>
|
||||||
|
<ul class="mt-1 list-disc list-inside">
|
||||||
|
<li>Data akan dimulai dari baris ke-5</li>
|
||||||
|
<li>File Excel tidak perlu header</li>
|
||||||
|
<li>Data akan di-update jika nomor tiket sudah ada</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<button type="button" class="btn btn-light" data-modal-dismiss="true">Batal</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Import</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Fungsi untuk menghapus data Bucok
|
||||||
|
* @param {number} data - ID data yang akan dihapus
|
||||||
|
*/
|
||||||
|
function deleteData(data) {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Apakah Anda yakin?',
|
||||||
|
text: "Data yang dihapus tidak dapat dikembalikan!",
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: 'Ya, hapus!',
|
||||||
|
cancelButtonText: 'Batal'
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
$.ajaxSetup({
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ajax(`bucok/${data}`, {
|
||||||
|
type: 'DELETE'
|
||||||
|
}).then((response) => {
|
||||||
|
Swal.fire('Terhapus!', 'Data Bucok berhasil dihapus.', 'success').then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
Swal.fire('Error!', error.responseJSON.message, 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
/**
|
||||||
|
* Inisialisasi DataTable untuk Bucok menggunakan KTDataTable
|
||||||
|
*/
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const element = document.querySelector('#bucok-table');
|
||||||
|
const searchInput = document.getElementById('search');
|
||||||
|
const yearFilter = document.getElementById('year-filter');
|
||||||
|
const monthFilter = document.getElementById('month-filter');
|
||||||
|
const completionStatusFilter = document.getElementById('completion-status-filter');
|
||||||
|
|
||||||
|
const apiUrl = element.getAttribute('data-api-url');
|
||||||
|
|
||||||
|
// Konfigurasi DataTable menggunakan KTDataTable
|
||||||
|
const dataTableOptions = {
|
||||||
|
apiEndpoint: apiUrl,
|
||||||
|
pageSize: 10,
|
||||||
|
columns: {
|
||||||
|
select: {
|
||||||
|
render: (item, data, context) => {
|
||||||
|
const checkbox = document.createElement('input');
|
||||||
|
checkbox.className = 'checkbox checkbox-sm';
|
||||||
|
checkbox.type = 'checkbox';
|
||||||
|
checkbox.value = data.id.toString();
|
||||||
|
checkbox.setAttribute('data-datatable-row-check', 'true');
|
||||||
|
return checkbox.outerHTML.trim();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
no: {
|
||||||
|
title: 'No',
|
||||||
|
},
|
||||||
|
tanggal: {
|
||||||
|
title: 'Tanggal',
|
||||||
|
},
|
||||||
|
nomor_tiket: {
|
||||||
|
title: 'Nomor Tiket',
|
||||||
|
},
|
||||||
|
nomor_coa: {
|
||||||
|
title: 'Nomor COA',
|
||||||
|
},
|
||||||
|
nama_coa: {
|
||||||
|
title: 'Nama COA',
|
||||||
|
},
|
||||||
|
deskripsi: {
|
||||||
|
title: 'Deskripsi',
|
||||||
|
render: (item, data) => {
|
||||||
|
const desc = data.deskripsi || '-';
|
||||||
|
return desc.length > 50 ? desc.substring(0, 50) + '...' : desc;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nominal: {
|
||||||
|
title: 'Nominal',
|
||||||
|
},
|
||||||
|
cost_center: {
|
||||||
|
title: 'Cost Center',
|
||||||
|
},
|
||||||
|
status_badge: {
|
||||||
|
title: 'Status',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.status_badge || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
title: 'Aksi',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.actions || '';
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Inisialisasi DataTable
|
||||||
|
let dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
|
dataTable.showSpinner();
|
||||||
|
|
||||||
|
// Fungsi pencarian
|
||||||
|
searchInput.addEventListener('input', function () {
|
||||||
|
const searchValue = this.value.trim();
|
||||||
|
dataTable.search(searchValue, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filter berdasarkan tahun
|
||||||
|
yearFilter.addEventListener('change', function() {
|
||||||
|
const yearValue = this.value;
|
||||||
|
// Implementasi filter tahun - perlu disesuaikan dengan API endpoint
|
||||||
|
dataTable.setParam('year', yearValue);
|
||||||
|
dataTable.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filter berdasarkan bulan
|
||||||
|
monthFilter.addEventListener('change', function() {
|
||||||
|
const monthValue = this.value;
|
||||||
|
// Implementasi filter bulan - perlu disesuaikan dengan API endpoint
|
||||||
|
dataTable.setParam('month', monthValue);
|
||||||
|
dataTable.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filter berdasarkan status penyelesaian
|
||||||
|
completionStatusFilter.addEventListener('change', function() {
|
||||||
|
const statusValue = this.value;
|
||||||
|
// Implementasi filter status - perlu disesuaikan dengan API endpoint
|
||||||
|
dataTable.setParam('completion_status', statusValue);
|
||||||
|
dataTable.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Export Excel functionality
|
||||||
|
document.getElementById('export-excel').addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Build export URL with current filters
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (searchInput.value) params.append('search', searchInput.value);
|
||||||
|
if (yearFilter.value) params.append('year', yearFilter.value);
|
||||||
|
if (monthFilter.value) params.append('month', monthFilter.value);
|
||||||
|
if (completionStatusFilter.value) params.append('completion_status', completionStatusFilter.value);
|
||||||
|
|
||||||
|
const exportUrl = '{{ route("bucok.export") }}?' + params.toString();
|
||||||
|
window.open(exportUrl, '_blank');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
236
resources/views/bucok/show.blade.php
Normal file
236
resources/views/bucok/show.blade.php
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('bucok.show', $bucok) }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid gap-5 lg:gap-7.5">
|
||||||
|
<!-- Header Card -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Detail Bucok #{{ $bucok->nomor_tiket }}</h3>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<a href="{{ route('bucok.index') }}" class="btn btn-sm btn-light">
|
||||||
|
<i class="ki-filled ki-left"></i> Kembali
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Detail Information -->
|
||||||
|
<div class="grid gap-5 lg:grid-cols-2 lg:gap-7.5">
|
||||||
|
<!-- Informasi Dasar -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Informasi Dasar</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid gap-5">
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">No</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->no ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Tanggal</div>
|
||||||
|
<div class="text-gray-700 text-2sm">
|
||||||
|
{{ $bucok->tanggal ? dateFormat($bucok->tanggal, true) : '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Bulan</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->bulan ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Tahun</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->tahun ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Nomor Tiket</div>
|
||||||
|
<div class="font-medium text-gray-700 text-2sm">{{ $bucok->nomor_tiket }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Status Penyelesaian</div>
|
||||||
|
<div class="text-2sm">{!! $bucok->status_badge !!}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informasi COA -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Informasi COA</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid gap-5">
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Nomor COA</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->nomor_coa ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Nama COA</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->nama_coa ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Deskripsi</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->deskripsi ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Nominal</div>
|
||||||
|
<div class="font-medium text-gray-700 text-2sm">{{ $bucok->nominal_formatted }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informasi Organisasi -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Informasi Organisasi</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid gap-5 lg:grid-cols-3">
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Cost Center</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->cost_center ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Sub Direktorat</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->nama_sub_direktorat ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Direktorat/Cabang</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->nama_direktorat_cabang ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informasi Penyelesaian -->
|
||||||
|
@if ($bucok->tanggal_penyelesaian || $bucok->nominal_penyelesaian || $bucok->penyelesaian)
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Informasi Penyelesaian</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid gap-5 lg:grid-cols-2">
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Tanggal Penyelesaian</div>
|
||||||
|
<div class="text-gray-700 text-2sm">
|
||||||
|
{{ $bucok->tanggal_penyelesaian ? dateFormat($bucok->tanggal_penyelesaian, true) : '-' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Nominal Penyelesaian</div>
|
||||||
|
<div class="font-medium text-gray-700 text-2sm">
|
||||||
|
{{ $bucok->nominal_penyelesaian_formatted }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Penyelesaian</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->penyelesaian ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Umur Aging</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->umur_aging ?? '-' }} hari</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if ($bucok->keterangan_gantung)
|
||||||
|
<div class="flex justify-between items-center py-2.5">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Keterangan Gantung</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->keterangan_gantung }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<!-- Informasi Audit -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Informasi Audit</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid gap-5 lg:grid-cols-2">
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Dibuat Oleh</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->creator?->name ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Tanggal Dibuat</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ dateFormat($bucok->created_at, true) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5 border-b border-gray-200">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Diperbarui Oleh</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ $bucok->updater?->name ?? '-' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center py-2.5">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<div class="text-sm font-medium text-gray-900">Tanggal Diperbarui</div>
|
||||||
|
<div class="text-gray-700 text-2sm">{{ dateFormat($bucok->updated_at, true) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
64
resources/views/category-daftar-pustaka/create.blade.php
Normal file
64
resources/views/category-daftar-pustaka/create.blade.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{-- {{ Breadcrumbs::render(request()->route()->getName()) }} --}}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
|
||||||
|
|
||||||
|
<form
|
||||||
|
action="{{ isset($category->id) ? route('category-daftar-pustaka.update', $category->id) : route('category-daftar-pustaka.store') }}"
|
||||||
|
method="POST">
|
||||||
|
@csrf
|
||||||
|
@if (isset($category->id))
|
||||||
|
@method('PUT')
|
||||||
|
<input type="text" name="id" value="{{ $category->id }}" hidden class="hidden">
|
||||||
|
@endif
|
||||||
|
<div class="card border border-agi-100 pb-2.5">
|
||||||
|
<div class="card-header bg-agi-50" id="basic_settings">
|
||||||
|
<h3 class="card-title">
|
||||||
|
Tambah
|
||||||
|
</h3>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<a href="{{ route('category-daftar-pustaka.index') }}" class="btn btn-xs btn-info"><i
|
||||||
|
class="ki-filled ki-exit-left"></i> Back</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body grid gap-5">
|
||||||
|
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Code
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input class="input @error('code') border-danger bg-danger-light @enderror" type="text"
|
||||||
|
name="code" value="{{ $category->code ?? old('code') }}"
|
||||||
|
{{ isset($category->id) ? 'readonly' : '' }}>
|
||||||
|
@error('code')
|
||||||
|
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Name
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input class="input input-file @error('name') border-danger bg-danger-light @enderror"
|
||||||
|
type="text" name="name" value="{{ $category->name ?? old('name') }}">
|
||||||
|
@error('name')
|
||||||
|
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
147
resources/views/category-daftar-pustaka/index.blade.php
Normal file
147
resources/views/category-daftar-pustaka/index.blade.php
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{-- {{ Breadcrumbs::render('basicdata.jenis-aset') }} --}}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid">
|
||||||
|
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="category-daftar-pustaka-table" data-api-url="{{ route('category-daftar-pustaka.datatables') }}">
|
||||||
|
<div class="card-header bg-agi-50 py-5 flex-wrap">
|
||||||
|
<h3 class="card-title">
|
||||||
|
Daftar Kategori Daftar Pustaka
|
||||||
|
</h3>
|
||||||
|
<div class="flex flex-wrap gap-2 lg:gap-5">
|
||||||
|
<div class="flex">
|
||||||
|
<label class="input input-sm"> <i class="ki-filled ki-magnifier"> </i>
|
||||||
|
<input placeholder="Search Kategori Daftar Pustaka" id="search" type="text" value="">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap gap-2.5">
|
||||||
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
|
<a class="btn btn-sm btn-light" href=""> Export to Excel </a>
|
||||||
|
<a class="btn btn-sm btn-primary" href="{{ route('category-daftar-pustaka.create') }}"> Tambah Kategori </a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="scrollable-x-auto">
|
||||||
|
<table class="table table-auto table-border align-middle text-gray-700 font-medium text-sm" data-datatable-table="true">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-14">
|
||||||
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox"/>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[250px]" data-datatable-column="code">
|
||||||
|
<span class="sort"> <span class="sort-label"> Code </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[250px]" data-datatable-column="name">
|
||||||
|
<span class="sort"> <span class="sort-label"> Name </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[50px] text-center" data-datatable-column="actions">Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer justify-center md:justify-between flex-col md:flex-row gap-3 text-gray-600 text-2sm font-medium">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
Show
|
||||||
|
<select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select> per page
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span data-datatable-info="true"> </span>
|
||||||
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
function deleteData(data) {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Are you sure?',
|
||||||
|
text: "You won't be able to revert this!",
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: 'Yes, delete it!'
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
$.ajaxSetup({
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ajax(`category-daftar-pustaka/${data}`, {
|
||||||
|
type: 'DELETE'
|
||||||
|
}).then((response) => {
|
||||||
|
swal.fire('Deleted!', 'User has been deleted.', 'success').then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
Swal.fire('Error!', 'An error occurred while deleting the file.', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
const element = document.querySelector('#category-daftar-pustaka-table ');
|
||||||
|
const searchInput = document.getElementById('search');
|
||||||
|
|
||||||
|
const apiUrl = element.getAttribute('data-api-url');
|
||||||
|
const dataTableOptions = {
|
||||||
|
apiEndpoint: apiUrl,
|
||||||
|
pageSize: 5,
|
||||||
|
columns: {
|
||||||
|
select: {
|
||||||
|
render: (item, data, context) => {
|
||||||
|
const checkbox = document.createElement('input');
|
||||||
|
checkbox.className = 'checkbox checkbox-sm';
|
||||||
|
checkbox.type = 'checkbox';
|
||||||
|
checkbox.value = data.id.toString();
|
||||||
|
checkbox.setAttribute('data-datatable-row-check', 'true');
|
||||||
|
return checkbox.outerHTML.trim();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
code: {
|
||||||
|
title: 'Code',
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
title: 'Name',
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
title: 'Status',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `<div class="flex flex-nowrap justify-center">
|
||||||
|
<a class="btn btn-sm btn-icon btn-clear btn-info" href="category-daftar-pustaka/${data.id}/edit">
|
||||||
|
<i class="ki-outline ki-notepad-edit"></i>
|
||||||
|
</a>
|
||||||
|
<a onclick="deleteData(${data.id})" class="delete btn btn-sm btn-icon btn-clear btn-danger">
|
||||||
|
<i class="ki-outline ki-trash"></i>
|
||||||
|
</a>
|
||||||
|
</div>`;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
|
// Custom search functionality
|
||||||
|
searchInput.addEventListener('input', function () {
|
||||||
|
const searchValue = this.value.trim();
|
||||||
|
dataTable.search(searchValue, true);
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|
||||||
113
resources/views/daftar-pustaka/create.blade.php
Normal file
113
resources/views/daftar-pustaka/create.blade.php
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{-- {{ Breadcrumbs::render(request()->route()->getName()) }} --}}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
|
||||||
|
<form
|
||||||
|
action="{{ isset($daftarPustaka->id) ? route('daftar-pustaka.update', $daftarPustaka->id) : route('daftar-pustaka.store') }}"
|
||||||
|
method="POST" enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
@if (isset($daftarPustaka->id))
|
||||||
|
<input type="hidden" name="id" value="{{ $daftarPustaka->id }}">
|
||||||
|
@method('PUT')
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="card border border-agi-100 pb-2.5">
|
||||||
|
<div class="card-header bg-agi-50" id="basic_settings">
|
||||||
|
<h3 class="card-title">
|
||||||
|
{{ isset($daftarPustaka->id) ? 'Edit' : 'Tambah' }} Daftar Pustaka
|
||||||
|
</h3>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<a href="{{ route('daftar-pustaka.index') }}" class="btn btn-xs btn-info"><i
|
||||||
|
class="ki-filled ki-exit-left"></i> Back</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body grid gap-5">
|
||||||
|
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Judul
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input class="input @error('judul') border-danger bg-danger-light @enderror" type="text"
|
||||||
|
name="judul" value="{{ $daftarPustaka->judul ?? old('judul') }}">
|
||||||
|
@error('judul')
|
||||||
|
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Upload File
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input class="input @error('attachment') border-danger bg-danger-light @enderror" type="file"
|
||||||
|
name="attachment">
|
||||||
|
@error('attachment')
|
||||||
|
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (isset($daftarPustaka->attachment))
|
||||||
|
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
File
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
{{-- ambil nama file pathnya hilangkan --}}
|
||||||
|
<a href="{{ asset($daftarPustaka->attachment) }}" class="badge badge-outline badge-md badge-info">{{ basename($daftarPustaka->attachment) }}
|
||||||
|
<i class="ki-filled ki-cloud-download"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Kategori
|
||||||
|
</label>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<select class="select tomselect w-full" name="category_id">
|
||||||
|
<option value="">Pilih Kategori</option>
|
||||||
|
@if (isset($categories))
|
||||||
|
@foreach ($categories as $item)
|
||||||
|
<option value="{{ $item->id }}"
|
||||||
|
{{ old('category_id', $daftarPustaka->category_id ?? '') == $item->id ? 'selected' : '' }}>
|
||||||
|
{{ $item->name }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</select>
|
||||||
|
@error('category_id')
|
||||||
|
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Deskripsi
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<textarea name="deskripsi" class="textarea" id="" cols="30" rows="10">{{ $daftarPustaka->deskripsi ?? old('deskripsi') }}</textarea>
|
||||||
|
@error('deskripsi')
|
||||||
|
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
{{ isset($daftarPustaka->id) ? 'Update' : 'Simpan' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
296
resources/views/daftar-pustaka/index.blade.php
Normal file
296
resources/views/daftar-pustaka/index.blade.php
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{-- {{ Breadcrumbs::render('basicdata.ijin_usaha') }} --}}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<style>
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
#previewContent {
|
||||||
|
height: 400px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="flex flex-col items-stretch gap-7">
|
||||||
|
<div class="flex items-center gap-3 w-full">
|
||||||
|
<div class="input w-full">
|
||||||
|
<i class="ki-filled ki-magnifier">
|
||||||
|
</i>
|
||||||
|
<input id="search" placeholder="Search Daftar Pustaka, Judul" type="text">
|
||||||
|
<span class="badge badge-outline -me-1.5">
|
||||||
|
⌘ K
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!--Filter-->
|
||||||
|
<a class="btn btn-info" id="search_filter" onclick="filterSearch()">
|
||||||
|
<i class="ki-filled ki-filter">
|
||||||
|
</i>
|
||||||
|
Filter
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-light" id="reset_filter" onclick="resetFilter()">
|
||||||
|
<i class="ki-filled ki-arrow-circle-left"></i>
|
||||||
|
Reset Filter
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap items-center gap-5 justify-between mt-3">
|
||||||
|
<h3 class="text-sm text-mono font-medium">
|
||||||
|
page {{ $page }} of {{ $pageCount }} — {{ $limit }} items per page, total
|
||||||
|
{{ $total }} items.
|
||||||
|
</h3>
|
||||||
|
<div class="flex gap-2.5">
|
||||||
|
<select id="category_id" name="category_id" class="select tomselect w-[300px]" multiple>
|
||||||
|
<option value="" selected disabled>Filter by Category</option>
|
||||||
|
@foreach ($categories as $item)
|
||||||
|
<option value="{{ $item->id }}">{{ $item->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
<div class="flex toggle-group" data-kt-tabs="true" data-kt-tabs-initialized="true">
|
||||||
|
<a class="btn btn-icon active selected" data-kt-tab-toggle="#daftar_pustaka_grid" onclick="showGrid()"
|
||||||
|
href="javascript:void(0)">
|
||||||
|
<i class="ki-filled ki-category"></i>
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-icon" data-kt-tab-toggle="#daftar_pustaka_list" onclick="showList()"
|
||||||
|
href="javascript:void(0)">
|
||||||
|
<i class="ki-filled ki-row-horizontal"></i>
|
||||||
|
</a>
|
||||||
|
@if (auth()->user()->hasRole(['administrator', 'admin']))
|
||||||
|
<a href="{{ route('daftar-pustaka.create') }}" class="btn btn-primary">
|
||||||
|
<i class="ki-filled ki-plus"></i>
|
||||||
|
Tambah
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4 " id="daftar_pustaka_grid">
|
||||||
|
@if (isset($daftar_pustaka))
|
||||||
|
@foreach ($daftar_pustaka as $item)
|
||||||
|
<div class="card border shadow-none ">
|
||||||
|
<a class="show-pustaka h-[300px] bg-gray-200 w-full block" href="{{ route('daftar-pustaka.show', $item->id) }}"
|
||||||
|
data-url="{{ $item->attachment }}">
|
||||||
|
<div class="p-4 h-full w-full flex items-center justify-center overflow-hidden">
|
||||||
|
<div class=" text-red-500 flex items-center justify-center rounded">
|
||||||
|
<i class="ki-filled ki-document text-3xl"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<a href="{{ route('daftar-pustaka.show', $item->id) }}">
|
||||||
|
|
||||||
|
<h3 class="text-md font-medium text-gray-900 hover:text-primary cursor-pointer">
|
||||||
|
{{ $item->judul }}</h3>
|
||||||
|
<p class="text-2sm text-gray-700">
|
||||||
|
{{-- batasi panjang deskripsi 50 --}}
|
||||||
|
{{ substr($item->deskripsi, 0, 50) }}
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
<div class="flex justify-between items-center gap-2.5 mt-2">
|
||||||
|
<p class="badge rounded-full badge-xs badge-outline badge-success text-xs text-gray-700">
|
||||||
|
# {{ $item->category->name }}</p>
|
||||||
|
|
||||||
|
@auth
|
||||||
|
@if (auth()->user()->hasRole(['administrator', 'admin']))
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-xs btn-danger" onclick="deleteData({{ $item->id }})">
|
||||||
|
<i class="ki-filled ki-trash">
|
||||||
|
</i>
|
||||||
|
Hapus
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-xs btn-info"
|
||||||
|
href="{{ route('daftar-pustaka.edit', $item->id) }}">
|
||||||
|
<i class="ki-filled ki-pencil">
|
||||||
|
</i>
|
||||||
|
Edit
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@endauth
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 gap-4 hidden" id="daftar_pustaka_list">
|
||||||
|
@if (isset($daftar_pustaka))
|
||||||
|
@foreach ($daftar_pustaka as $item)
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body flex items-center flex-wrap justify-between p-2 pe-5 gap-4.5">
|
||||||
|
<div class="flex items-center gap-3.5">
|
||||||
|
<div
|
||||||
|
class="card bg-gray-200 flex items-center justify-center bg-accent/50 h-[70px] w-[90px] shadow-none">
|
||||||
|
<a class="show-pustaka h-[90px] w-full block"
|
||||||
|
href="{{ route('daftar-pustaka.show', $item->id) }}"
|
||||||
|
data-url="{{ $item->attachment }}">
|
||||||
|
<div class="p-4 h-full w-full flex items-center justify-center overflow-hidden">
|
||||||
|
<div class=" text-red-500 flex items-center justify-center rounded">
|
||||||
|
<i class="ki-filled ki-document text-3xl"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<a href="{{ route('daftar-pustaka.show', $item->id) }}">
|
||||||
|
<div class="flex flex-col gap-2 cursor-pointer">
|
||||||
|
<div class="flex items-center mt-1">
|
||||||
|
<a class="hover:text-primary text-sm font-medium text-mono leading-5.5">
|
||||||
|
{{ $item->judul }}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="flex items-center flex-wrap gap-3">
|
||||||
|
<span class="kt-badge kt-badge-warning kt-badge-sm rounded-full gap-1">
|
||||||
|
<span class="text-xs font-medium text-foreground">
|
||||||
|
{{ substr($item->deskripsi, 0, 50) }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-1.5">
|
||||||
|
<p class="badge rounded-full badge-sm badge-outline badge-success text-xs text-gray-700">
|
||||||
|
# {{ $item->category->name }}</p>
|
||||||
|
@auth
|
||||||
|
@if (auth()->user()->hasRole(['administrator', 'admin']))
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-sm btn-danger" onclick="deleteData({{ $item->id }})">
|
||||||
|
<i class="ki-filled ki-trash">
|
||||||
|
</i>
|
||||||
|
Hapus
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-sm btn-info"
|
||||||
|
href="{{ route('daftar-pustaka.edit', $item->id) }}">
|
||||||
|
<i class="ki-filled ki-pencil">
|
||||||
|
</i>
|
||||||
|
Edit
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@endauth
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="pagination flex gap-2 justify-center mt-5">
|
||||||
|
@if ($daftar_pustaka->onFirstPage())
|
||||||
|
<span class="btn disabled"><i class="ki-filled ki-black-left"></i></span>
|
||||||
|
@else
|
||||||
|
<a href="{{ $daftar_pustaka->previousPageUrl() }}" class="btn">
|
||||||
|
<i class="ki-filled ki-black-left"></i>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@foreach ($daftar_pustaka->getUrlRange(1, $daftar_pustaka->lastPage()) as $page => $url)
|
||||||
|
<a href="{{ $url }}" class="btn {{ $page == $daftar_pustaka->currentPage() ? 'active' : '' }}">
|
||||||
|
{{ $page }}
|
||||||
|
</a>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
@if ($daftar_pustaka->hasMorePages())
|
||||||
|
<a href="{{ $daftar_pustaka->nextPageUrl() }}" class="btn">
|
||||||
|
<i class="ki-filled ki-black-right"></i>
|
||||||
|
</a>
|
||||||
|
@else
|
||||||
|
<span class="btn disabled"><i class="ki-filled ki-black-right"></i></span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
function deleteData(data) {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Are you sure?',
|
||||||
|
text: "You won't be able to revert this!",
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: 'Yes, delete it!'
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
$.ajaxSetup({
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ajax(`daftar-pustaka/${data}`, {
|
||||||
|
type: 'DELETE'
|
||||||
|
}).then((response) => {
|
||||||
|
swal.fire('Deleted!', 'User has been deleted.', 'success').then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
Swal.fire('Error!', 'An error occurred while deleting the file.', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function showGrid() {
|
||||||
|
document.getElementById("daftar_pustaka_grid").classList.remove("hidden");
|
||||||
|
document.getElementById("daftar_pustaka_grid").classList.add("active");
|
||||||
|
|
||||||
|
document.getElementById("daftar_pustaka_list").classList.add("hidden");
|
||||||
|
document.getElementById("daftar_pustaka_list").classList.remove("active");
|
||||||
|
|
||||||
|
// Update button active class
|
||||||
|
document.querySelectorAll(".toggle-group a").forEach(btn => btn.classList.remove("selected", "active"));
|
||||||
|
event.currentTarget.classList.add("selected", "active");
|
||||||
|
}
|
||||||
|
|
||||||
|
function showList() {
|
||||||
|
document.getElementById("daftar_pustaka_list").classList.remove("hidden");
|
||||||
|
document.getElementById("daftar_pustaka_list").classList.add("active");
|
||||||
|
|
||||||
|
document.getElementById("daftar_pustaka_grid").classList.add("hidden");
|
||||||
|
document.getElementById("daftar_pustaka_grid").classList.remove("active");
|
||||||
|
|
||||||
|
// Update button active class
|
||||||
|
document.querySelectorAll(".toggle-group a").forEach(btn => btn.classList.remove("selected", "active"));
|
||||||
|
event.currentTarget.classList.add("selected", "active");
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterSearch() {
|
||||||
|
const search = document.getElementById('search')?.value || '';
|
||||||
|
|
||||||
|
const select = document.getElementById('category_id');
|
||||||
|
const selectedCategories = Array.from(select.selectedOptions).map(option => option.value);
|
||||||
|
|
||||||
|
const categoryParam = selectedCategories.join(',');
|
||||||
|
|
||||||
|
const url = "{{ route('daftar-pustaka.index') }}?search=" + encodeURIComponent(search) + "&category=" +
|
||||||
|
encodeURIComponent(categoryParam);
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function resetFilter() {
|
||||||
|
const url = "{{ route('daftar-pustaka.index') }}";
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
96
resources/views/daftar-pustaka/show.blade.php
Normal file
96
resources/views/daftar-pustaka/show.blade.php
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{-- {{ Breadcrumbs::render(request()->route()->getName()) }} --}}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
|
||||||
|
|
||||||
|
<form
|
||||||
|
action="{{ isset($daftarPustaka->id) ? route('daftar-pustaka.update', $daftarPustaka->id) : route('daftar-pustaka.store') }}"
|
||||||
|
method="POST">
|
||||||
|
@csrf
|
||||||
|
<div class="card border border-agi-100 pb-2.5">
|
||||||
|
<div class="card-header bg-agi-50" id="basic_settings">
|
||||||
|
<h3 class="card-title">
|
||||||
|
{{ $daftarPustaka->judul ?? '' }}
|
||||||
|
</h3>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<a href="{{ route('daftar-pustaka.index') }}" class="btn btn-xs btn-info"><i
|
||||||
|
class="ki-filled ki-exit-left"></i> Back</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body grid gap-5">
|
||||||
|
<div class=" min-w-3xl">
|
||||||
|
<div class="p-4 h-full flex flex-col">
|
||||||
|
<div class="flex justify-between items-center mb-4">
|
||||||
|
<a href="{{ asset('storage/' . $daftarPustaka->attachment)}}" class="btn btn-primary btn-sm">
|
||||||
|
<i class="ki-duotone ki-cloud-download me-1"><span class="path1"></span><span
|
||||||
|
class="path2"></span></i>
|
||||||
|
Download File
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
@php
|
||||||
|
|
||||||
|
$fileExtension = pathinfo($daftarPustaka->attachment, PATHINFO_EXTENSION);
|
||||||
|
// cek extension
|
||||||
|
$isPdf = $fileExtension == 'pdf';
|
||||||
|
$imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
|
||||||
|
$isImage = in_array(strtolower($fileExtension), $imageExtensions);
|
||||||
|
$fileUrl = asset('storage/' . $daftarPustaka->attachment);
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@if ($isPdf)
|
||||||
|
<iframe src="{{$fileUrl}}"
|
||||||
|
width="100%" height="600px" frameborder="0"></iframe>
|
||||||
|
@elseif ($isImage)
|
||||||
|
<img src="{{ $fileUrl }}" class="w-full object-contain rounded" />
|
||||||
|
@else
|
||||||
|
<p class="text-red-500">File tidak bisa ditampilkan, silakan <a href="{{ $fileUrl }}"
|
||||||
|
class="text-blue-500 underline" download>unduh di sini</a>.</p>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="border border-t">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ $daftarPustaka->deskripsi ?? '' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
{{-- @push('scripts')
|
||||||
|
<script src="{{ asset('vendor/pdfobject.min.js') }}"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
let url = @json($daftarPustaka->attachment);
|
||||||
|
console.log(url);
|
||||||
|
|
||||||
|
const fileExtension = url.split('.').pop().toLowerCase();
|
||||||
|
const previewContent = document.getElementById('previewContent');
|
||||||
|
|
||||||
|
if (['pdf'].includes(fileExtension)) {
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
document.getElementById('pdfFrame').style.display = 'block';
|
||||||
|
document.getElementById('pdfFrame').src = urlStorage;
|
||||||
|
} else {
|
||||||
|
PDFObject.embed(urlStorage, "#previewContent");
|
||||||
|
}
|
||||||
|
} else if (['jpg', 'jpeg', 'png', 'gif'].includes(fileExtension)) {
|
||||||
|
previewContent.innerHTML =
|
||||||
|
`<img src="${url}" alt="Preview" class="max-w-full max-h-full object-contain">`;
|
||||||
|
} else {
|
||||||
|
previewContent.innerHTML = '<p class="text-center">Unsupported file type</p>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush --}}
|
||||||
@@ -44,15 +44,6 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col">
|
|
||||||
<label class="text-base font-medium mb-1">Penilai</label>
|
|
||||||
<select class="select tomselect" id="penilai_filter">
|
|
||||||
<option value="">Semua Penilai</option>
|
|
||||||
@foreach(\MOdules\Usermanagement\Models\User::role(['penilai','surveyor'])->get() as $penilai)
|
|
||||||
<option value="{{ $penilai->id }}">{{ $penilai->name }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Buttons row at the bottom -->
|
<!-- Buttons row at the bottom -->
|
||||||
@@ -73,7 +64,7 @@
|
|||||||
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="laporan-hasil-penilaian-jaminan-internal-external-table" data-api-url="{{ route('laporan-hasil-penilaian-jaminan-internal-external.data') }}">
|
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="laporan-hasil-penilaian-jaminan-internal-external-table" data-api-url="{{ route('laporan-hasil-penilaian-jaminan-internal-external.data') }}">
|
||||||
<div class="card-header bg-agi-50 py-5 flex-wrap">
|
<div class="card-header bg-agi-50 py-5 flex-wrap">
|
||||||
<h3 class="card-title">
|
<h3 class="card-title">
|
||||||
Laporan Hasil Penilaian Jaminan Internal & External
|
Rekap Penyelesaian External
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -89,130 +80,53 @@
|
|||||||
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Permohonan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="branch">
|
<th class="min-w-[150px]" data-datatable-column="branch">
|
||||||
<span class="sort"> <span class="sort-label"> Cabang </span>
|
<span class="sort"> <span class="sort-label"> Cabang </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="pemohon">
|
|
||||||
<span class="sort"> <span class="sort-label"> Pemohon </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="cif">
|
|
||||||
<span class="sort"> <span class="sort-label"> CIF </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="name">
|
<th class="min-w-[150px]" data-datatable-column="name">
|
||||||
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
|
||||||
|
<span class="sort"> <span class="sort-label"> Tanggal KSL </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="pemohon">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor KSL </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="cif">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nominal KSL </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="jenis_penilaian">
|
<th class="min-w-[150px]" data-datatable-column="jenis_penilaian">
|
||||||
<span class="sort"> <span class="sort-label"> Jenis Penilaian </span>
|
<span class="sort"> <span class="sort-label">Tanggal Penyelesaian </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="tujuan_penilaian">
|
<th class="min-w-[150px]" data-datatable-column="tujuan_penilaian">
|
||||||
<span class="sort"> <span class="sort-label"> Tujuan Penilaian </span>
|
<span class="sort"> <span class="sort-label"> Nominal Penyelesaian </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="jenis_fasilitas_kredit">
|
<th class="min-w-[150px]" data-datatable-column="jenis_fasilitas_kredit">
|
||||||
<span class="sort"> <span class="sort-label"> Jenis Fasilitas Kredit </span>
|
<span class="sort"> <span class="sort-label"> No. Rekening (Tujuan Akhir) </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="jenis_fasilitas_kredit">
|
||||||
|
<span class="sort"> <span class="sort-label"> Sisa KSL </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="jenis_agunan">
|
<th class="min-w-[150px]" data-datatable-column="jenis_agunan">
|
||||||
<span class="sort"> <span class="sort-label"> Jenis Agunan </span>
|
<span class="sort"> <span class="sort-label"> Memo </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="alamat_agunan">
|
<th class="min-w-[150px]" data-datatable-column="alamat_agunan">
|
||||||
<span class="sort"> <span class="sort-label"> Alamat Agunan </span>
|
<span class="sort"> <span class="sort-label"> Status</span>
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="bukti_kepemilikan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Bukti Kepemilikan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_pemilik">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nama Pemilik </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="luas_tanah">
|
|
||||||
<span class="sort"> <span class="sort-label"> Luas Tanah </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_tanah">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Tanah </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="luas_bangunan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Luas Bangunan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_bangunan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Bangunan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_njop">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai NJOP </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_pasar_wajar">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Pasar Wajar </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_likuidasi">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Likuidasi </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_documen_diterima">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Dokumen Diterima </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_spk">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal SPK </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nomor_spk">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nomor SPK </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_rencana_kunjunagn">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Rencana Kunjungan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_kunjungan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Kunjungan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="taggal_delivered">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Delivered </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="jangka_waktu_sla">
|
|
||||||
<span class="sort"> <span class="sort-label"> Jangka Waktu SLA </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_laporan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Laporan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_review">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Review </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_penilai">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nama Penilai </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_team_leader">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nama Team Leader </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="saran">
|
|
||||||
<span class="sort"> <span class="sort-label"> Saran </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="catatan">
|
<th class="min-w-[150px]" data-datatable-column="catatan">
|
||||||
<span class="sort"> <span class="sort-label"> Catatan </span>
|
<span class="sort"> <span class="sort-label"> Catatan </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
@@ -266,144 +180,41 @@
|
|||||||
nomor_registrasi: {
|
nomor_registrasi: {
|
||||||
title: 'Nomor Registrasi',
|
title: 'Nomor Registrasi',
|
||||||
},
|
},
|
||||||
tanggal_permohonan: {
|
branch: {
|
||||||
|
title: 'Cabang',
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
title: 'Nama Debitur',
|
||||||
|
},
|
||||||
|
tanggal_ksl: {
|
||||||
title: 'Tanggal Permohonan',
|
title: 'Tanggal Permohonan',
|
||||||
render: (item, data) => {
|
render: (item, data) => {
|
||||||
return data.tanggal_permohonan ? window.formatTanggalIndonesia(data.tanggal_permohonan) : '-';
|
return data.tanggal_permohonan ? window.formatTanggalIndonesia(data.tanggal_permohonan) : '-';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
branch: {
|
nomor_ksl: {
|
||||||
title: 'Cabang',
|
|
||||||
},
|
|
||||||
pemohon: {
|
|
||||||
title: 'Pemohon',
|
|
||||||
},
|
|
||||||
cif: {
|
|
||||||
title: 'CIF',
|
title: 'CIF',
|
||||||
},
|
},
|
||||||
name: {
|
nominal_ksl: {
|
||||||
title: 'Nama Debitur',
|
|
||||||
},
|
|
||||||
jenis_penilaian: {
|
|
||||||
title: 'Jenis Penilaian',
|
title: 'Jenis Penilaian',
|
||||||
},
|
},
|
||||||
tujuan_penilaian: {
|
tanggal_penyelesaian: {
|
||||||
title: 'Tujuan Penilaian',
|
title: 'Tujuan Penilaian',
|
||||||
},
|
},
|
||||||
jenis_fasilitas_kredit: {
|
nominal_penyelesaian: {
|
||||||
title: 'Jenis Fasilitas Kredit',
|
title: 'Jenis Fasilitas Kredit',
|
||||||
},
|
},
|
||||||
jenis_agunan: {
|
nomor_rekening: {
|
||||||
|
title: 'Nomor Rekening',
|
||||||
|
},
|
||||||
|
sisa_ksl: {
|
||||||
title: 'Jenis Agunan',
|
title: 'Jenis Agunan',
|
||||||
},
|
},
|
||||||
alamat_agunan: {
|
memo: {
|
||||||
title: 'Alamat Agunan',
|
title: 'Memo',
|
||||||
},
|
},
|
||||||
bukti_kepemilikan: {
|
status: {
|
||||||
title: 'Bukti Kepemilikan',
|
title: 'Status',
|
||||||
render: (item, data) => {
|
|
||||||
if (data.bukti_kepemilikan) {
|
|
||||||
// Ganti karakter baris baru dengan tag <br> untuk HTML
|
|
||||||
return data.bukti_kepemilikan.split('\n').join('<br>');
|
|
||||||
}
|
|
||||||
return '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nama_pemilik: {
|
|
||||||
title: 'Nama Pemilik',
|
|
||||||
},
|
|
||||||
luas_tanah: {
|
|
||||||
title: 'Luas Tanah',
|
|
||||||
},
|
|
||||||
nilai_tanah: {
|
|
||||||
title: 'Nilai Tanah',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_tanah ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
luas_bangunan: {
|
|
||||||
title: 'Luas Bangunan',
|
|
||||||
},
|
|
||||||
nilai_bangunan: {
|
|
||||||
title: 'Nilai Bangunan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_bangunan ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nilai_njop: {
|
|
||||||
title: 'Nilai NJOP',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_njop ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nilai_pasar_wajar: {
|
|
||||||
title: 'Nilai Pasar Wajar',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_pasar_wajar ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nilai_likuidasi: {
|
|
||||||
title: 'Nilai Likuidasi',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_likuidasi ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_documen_diterima: {
|
|
||||||
title: 'Tanggal Dokumen Diterima',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_documen_diterima ? window.formatTanggalIndonesia(data.tanggal_documen_diterima) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_spk: {
|
|
||||||
title: 'Tanggal SPK',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_spk ? window.formatTanggalIndonesia(data.tanggal_spk) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nomor_spk: {
|
|
||||||
title: 'Nomor SPK',
|
|
||||||
},
|
|
||||||
tanggal_rencana_kunjunagn: {
|
|
||||||
title: 'Tanggal Rencana Kunjungan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_rencana_kunjunagn ? window.formatTanggalIndonesia(data.tanggal_rencana_kunjunagn) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_kunjungan: {
|
|
||||||
title: 'Tanggal Kunjungan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_kunjungan ? window.formatTanggalIndonesia(data.tanggal_kunjungan) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
taggal_delivered: {
|
|
||||||
title: 'Tanggal Delivered',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.taggal_delivered ? window.formatTanggalIndonesia(data.taggal_delivered) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
jangka_waktu_sla: {
|
|
||||||
title: 'Jangka Waktu SLA',
|
|
||||||
},
|
|
||||||
tanggal_laporan: {
|
|
||||||
title: 'Tanggal Laporan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_laporan ? window.formatTanggalIndonesia(data.tanggal_laporan) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_review: {
|
|
||||||
title: 'Tanggal Review',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_review ? window.formatTanggalIndonesia(data.tanggal_review) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nama_penilai: {
|
|
||||||
title: 'Nama Penilai',
|
|
||||||
},
|
|
||||||
nama_team_leader: {
|
|
||||||
title: 'Nama Team Leader',
|
|
||||||
},
|
|
||||||
saran: {
|
|
||||||
title: 'Saran',
|
|
||||||
},
|
},
|
||||||
catatan: {
|
catatan: {
|
||||||
title: 'Catatan',
|
title: 'Catatan',
|
||||||
|
|||||||
@@ -44,15 +44,7 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col">
|
|
||||||
<label class="text-base font-medium mb-1">Penilai</label>
|
|
||||||
<select class="select tomselect" id="penilai_filter">
|
|
||||||
<option value="">Semua Penilai</option>
|
|
||||||
@foreach(\MOdules\Usermanagement\Models\User::role(['penilai','surveyor'])->get() as $penilai)
|
|
||||||
<option value="{{ $penilai->id }}">{{ $penilai->name }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Buttons row at the bottom -->
|
<!-- Buttons row at the bottom -->
|
||||||
@@ -73,7 +65,7 @@
|
|||||||
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="laporan-hasil-penilaian-jaminan-internal-external-table" data-api-url="{{ route('laporan-hasil-penilaian-jaminan-internal-external.data') }}">
|
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="laporan-hasil-penilaian-jaminan-internal-external-table" data-api-url="{{ route('laporan-hasil-penilaian-jaminan-internal-external.data') }}">
|
||||||
<div class="card-header bg-agi-50 py-5 flex-wrap">
|
<div class="card-header bg-agi-50 py-5 flex-wrap">
|
||||||
<h3 class="card-title">
|
<h3 class="card-title">
|
||||||
Laporan Hasil Penilaian Jaminan Internal & External
|
Rekap Penyelesaian Internal
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -89,130 +81,49 @@
|
|||||||
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Permohonan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="branch">
|
<th class="min-w-[150px]" data-datatable-column="branch">
|
||||||
<span class="sort"> <span class="sort-label"> Cabang </span>
|
<span class="sort"> <span class="sort-label"> Cabang </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="pemohon">
|
|
||||||
<span class="sort"> <span class="sort-label"> Pemohon </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="cif">
|
|
||||||
<span class="sort"> <span class="sort-label"> CIF </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="name">
|
<th class="min-w-[150px]" data-datatable-column="name">
|
||||||
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
|
||||||
|
<span class="sort"> <span class="sort-label"> Tanggal KSL </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="pemohon">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor KSL </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="cif">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nominal KSL </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="jenis_penilaian">
|
<th class="min-w-[150px]" data-datatable-column="jenis_penilaian">
|
||||||
<span class="sort"> <span class="sort-label"> Jenis Penilaian </span>
|
<span class="sort"> <span class="sort-label">Tanggal Penyelesaian </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="tujuan_penilaian">
|
<th class="min-w-[150px]" data-datatable-column="tujuan_penilaian">
|
||||||
<span class="sort"> <span class="sort-label"> Tujuan Penilaian </span>
|
<span class="sort"> <span class="sort-label"> Nominal Penyelesaian </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="jenis_fasilitas_kredit">
|
<th class="min-w-[150px]" data-datatable-column="jenis_fasilitas_kredit">
|
||||||
<span class="sort"> <span class="sort-label"> Jenis Fasilitas Kredit </span>
|
<span class="sort"> <span class="sort-label"> Sisa KSL </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="jenis_agunan">
|
<th class="min-w-[150px]" data-datatable-column="jenis_agunan">
|
||||||
<span class="sort"> <span class="sort-label"> Jenis Agunan </span>
|
<span class="sort"> <span class="sort-label"> Memo </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="alamat_agunan">
|
<th class="min-w-[150px]" data-datatable-column="alamat_agunan">
|
||||||
<span class="sort"> <span class="sort-label"> Alamat Agunan </span>
|
<span class="sort"> <span class="sort-label"> Status</span>
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="bukti_kepemilikan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Bukti Kepemilikan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_pemilik">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nama Pemilik </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="luas_tanah">
|
|
||||||
<span class="sort"> <span class="sort-label"> Luas Tanah </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_tanah">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Tanah </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="luas_bangunan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Luas Bangunan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_bangunan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Bangunan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_njop">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai NJOP </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_pasar_wajar">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Pasar Wajar </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_likuidasi">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Likuidasi </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_documen_diterima">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Dokumen Diterima </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_spk">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal SPK </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nomor_spk">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nomor SPK </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_rencana_kunjunagn">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Rencana Kunjungan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_kunjungan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Kunjungan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="taggal_delivered">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Delivered </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="jangka_waktu_sla">
|
|
||||||
<span class="sort"> <span class="sort-label"> Jangka Waktu SLA </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_laporan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Laporan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_review">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Review </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_penilai">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nama Penilai </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_team_leader">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nama Team Leader </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="saran">
|
|
||||||
<span class="sort"> <span class="sort-label"> Saran </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="catatan">
|
<th class="min-w-[150px]" data-datatable-column="catatan">
|
||||||
<span class="sort"> <span class="sort-label"> Catatan </span>
|
<span class="sort"> <span class="sort-label"> Catatan </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
@@ -266,144 +177,38 @@
|
|||||||
nomor_registrasi: {
|
nomor_registrasi: {
|
||||||
title: 'Nomor Registrasi',
|
title: 'Nomor Registrasi',
|
||||||
},
|
},
|
||||||
tanggal_permohonan: {
|
branch: {
|
||||||
|
title: 'Cabang',
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
title: 'Nama Debitur',
|
||||||
|
},
|
||||||
|
tanggal_ksl: {
|
||||||
title: 'Tanggal Permohonan',
|
title: 'Tanggal Permohonan',
|
||||||
render: (item, data) => {
|
render: (item, data) => {
|
||||||
return data.tanggal_permohonan ? window.formatTanggalIndonesia(data.tanggal_permohonan) : '-';
|
return data.tanggal_permohonan ? window.formatTanggalIndonesia(data.tanggal_permohonan) : '-';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
branch: {
|
nomor_ksl: {
|
||||||
title: 'Cabang',
|
|
||||||
},
|
|
||||||
pemohon: {
|
|
||||||
title: 'Pemohon',
|
|
||||||
},
|
|
||||||
cif: {
|
|
||||||
title: 'CIF',
|
title: 'CIF',
|
||||||
},
|
},
|
||||||
name: {
|
nominal_ksl: {
|
||||||
title: 'Nama Debitur',
|
|
||||||
},
|
|
||||||
jenis_penilaian: {
|
|
||||||
title: 'Jenis Penilaian',
|
title: 'Jenis Penilaian',
|
||||||
},
|
},
|
||||||
tujuan_penilaian: {
|
tanggal_penyelesaian: {
|
||||||
title: 'Tujuan Penilaian',
|
title: 'Tujuan Penilaian',
|
||||||
},
|
},
|
||||||
jenis_fasilitas_kredit: {
|
nominal_penyelesaian: {
|
||||||
title: 'Jenis Fasilitas Kredit',
|
title: 'Jenis Fasilitas Kredit',
|
||||||
},
|
},
|
||||||
jenis_agunan: {
|
sisa_ksl: {
|
||||||
title: 'Jenis Agunan',
|
title: 'Jenis Agunan',
|
||||||
},
|
},
|
||||||
alamat_agunan: {
|
memo: {
|
||||||
title: 'Alamat Agunan',
|
title: 'Memo',
|
||||||
},
|
},
|
||||||
bukti_kepemilikan: {
|
status: {
|
||||||
title: 'Bukti Kepemilikan',
|
title: 'Status',
|
||||||
render: (item, data) => {
|
|
||||||
if (data.bukti_kepemilikan) {
|
|
||||||
// Ganti karakter baris baru dengan tag <br> untuk HTML
|
|
||||||
return data.bukti_kepemilikan.split('\n').join('<br>');
|
|
||||||
}
|
|
||||||
return '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nama_pemilik: {
|
|
||||||
title: 'Nama Pemilik',
|
|
||||||
},
|
|
||||||
luas_tanah: {
|
|
||||||
title: 'Luas Tanah',
|
|
||||||
},
|
|
||||||
nilai_tanah: {
|
|
||||||
title: 'Nilai Tanah',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_tanah ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
luas_bangunan: {
|
|
||||||
title: 'Luas Bangunan',
|
|
||||||
},
|
|
||||||
nilai_bangunan: {
|
|
||||||
title: 'Nilai Bangunan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_bangunan ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nilai_njop: {
|
|
||||||
title: 'Nilai NJOP',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_njop ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nilai_pasar_wajar: {
|
|
||||||
title: 'Nilai Pasar Wajar',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_pasar_wajar ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nilai_likuidasi: {
|
|
||||||
title: 'Nilai Likuidasi',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_likuidasi ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_documen_diterima: {
|
|
||||||
title: 'Tanggal Dokumen Diterima',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_documen_diterima ? window.formatTanggalIndonesia(data.tanggal_documen_diterima) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_spk: {
|
|
||||||
title: 'Tanggal SPK',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_spk ? window.formatTanggalIndonesia(data.tanggal_spk) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nomor_spk: {
|
|
||||||
title: 'Nomor SPK',
|
|
||||||
},
|
|
||||||
tanggal_rencana_kunjunagn: {
|
|
||||||
title: 'Tanggal Rencana Kunjungan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_rencana_kunjunagn ? window.formatTanggalIndonesia(data.tanggal_rencana_kunjunagn) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_kunjungan: {
|
|
||||||
title: 'Tanggal Kunjungan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_kunjungan ? window.formatTanggalIndonesia(data.tanggal_kunjungan) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
taggal_delivered: {
|
|
||||||
title: 'Tanggal Delivered',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.taggal_delivered ? window.formatTanggalIndonesia(data.taggal_delivered) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
jangka_waktu_sla: {
|
|
||||||
title: 'Jangka Waktu SLA',
|
|
||||||
},
|
|
||||||
tanggal_laporan: {
|
|
||||||
title: 'Tanggal Laporan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_laporan ? window.formatTanggalIndonesia(data.tanggal_laporan) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_review: {
|
|
||||||
title: 'Tanggal Review',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_review ? window.formatTanggalIndonesia(data.tanggal_review) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nama_penilai: {
|
|
||||||
title: 'Nama Penilai',
|
|
||||||
},
|
|
||||||
nama_team_leader: {
|
|
||||||
title: 'Nama Team Leader',
|
|
||||||
},
|
|
||||||
saran: {
|
|
||||||
title: 'Saran',
|
|
||||||
},
|
},
|
||||||
catatan: {
|
catatan: {
|
||||||
title: 'Catatan',
|
title: 'Catatan',
|
||||||
|
|||||||
@@ -35,20 +35,19 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="min-w-[100px]">Nama Debitur</th>
|
<th class="min-w-[100px]">Nama Debitur</th>
|
||||||
<th class="min-w-[100px]">Tujuan Penilaian</th>
|
<th class="min-w-[100px]">Cabang</th>
|
||||||
<th class="min-w-[100px]">Status Bayar</th>
|
<th class="min-w-[100px]">Lokasi Jaminan</th>
|
||||||
<th class="min-w-[100px]">Jenis Asset</th>
|
<th class="min-w-[100px]">TUjuan Penilaian</th>
|
||||||
<th class="min-w-[100px]">Penugasan</th>
|
|
||||||
<th class="min-w-[100px]">Jenis Report</th>
|
|
||||||
<th class="min-w-[100px]">Tgl Register</th>
|
|
||||||
<th class="min-w-[100px]">Tgl Assign</th>
|
|
||||||
<th class="min-w-[100px]">Tgl Kunjungan</th>
|
<th class="min-w-[100px]">Tgl Kunjungan</th>
|
||||||
<th class="min-w-[100px]">Progress</th>
|
<th class="min-w-[100px]">Tgl Lpj Done</th>
|
||||||
<th class="min-w-[100px]">SLA Laporan</th>
|
<th class="min-w-[100px]">SLA Buku Kjpp</th>
|
||||||
<th class="min-w-[100px]">SLA Paparan</th>
|
<th class="min-w-[100px]">Status</th>
|
||||||
<th class="min-w-[100px]">Approve</th>
|
<th class="min-w-[100px]">Poin</th>
|
||||||
|
<th class="min-w-[100px]">SLA INTERNAL</th>
|
||||||
|
<th class="min-w-[100px]">SLA PENDAMPINGAN KJPP</th>
|
||||||
|
<th class="min-w-[100px]">Absensi</th>
|
||||||
|
<th class="min-w-[100px]">Zabtu</th>
|
||||||
<th class="min-w-[50px] text-center">Keterangan</th>
|
<th class="min-w-[50px] text-center">Keterangan</th>
|
||||||
<th class="min-w-[50px] text-center">Action</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -142,11 +141,17 @@
|
|||||||
render: (item, data) =>
|
render: (item, data) =>
|
||||||
`${window.formatTanggalIndonesia(data.created_at)}`,
|
`${window.formatTanggalIndonesia(data.created_at)}`,
|
||||||
},
|
},
|
||||||
|
|
||||||
tanggal_kunjungan: {
|
tanggal_kunjungan: {
|
||||||
title: 'Tgl Kunjungan',
|
title: 'Tgl Kunjungan',
|
||||||
render: (item, data) =>
|
render: (item, data) =>
|
||||||
`${window.formatTanggalIndonesia(data.waktu_penilaian) || ''}`,
|
`${window.formatTanggalIndonesia(data.waktu_penilaian) || ''}`,
|
||||||
},
|
},
|
||||||
|
tanggal_reported: {
|
||||||
|
title: 'Tgl Kunjungan',
|
||||||
|
render: (item, data) =>
|
||||||
|
`${window.formatTanggalIndonesia(data.waktu_penilaian) || ''}`,
|
||||||
|
},
|
||||||
progress: {
|
progress: {
|
||||||
title: 'Progress',
|
title: 'Progress',
|
||||||
render: (item, data) => {
|
render: (item, data) => {
|
||||||
@@ -182,20 +187,7 @@
|
|||||||
return `${window.formatTanggalIndonesia(data.paparan)}`;
|
return `${window.formatTanggalIndonesia(data.paparan)}`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
approve: {
|
|
||||||
title: 'Approve',
|
|
||||||
render: (item, data) => {
|
|
||||||
// Gabungkan nama dengan <br> untuk pemisah baris baru
|
|
||||||
let dataHtml = `
|
|
||||||
${data.permohonan?.approve_so?.name || ''}
|
|
||||||
<br>
|
|
||||||
${data.permohonan?.approve_eo?.name || ''}
|
|
||||||
<br>
|
|
||||||
${data.permohonan?.approve_dd?.name || ''}
|
|
||||||
`;
|
|
||||||
return dataHtml;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
keterangan: {
|
keterangan: {
|
||||||
|
|||||||
@@ -104,10 +104,6 @@
|
|||||||
<span class="sort"> <span class="sort-label"> Tujuan Penilaian </span>
|
<span class="sort"> <span class="sort-label"> Tujuan Penilaian </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="jenis_agunan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Penilaian</span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_laporan">
|
<th class="min-w-[150px]" data-datatable-column="tanggal_laporan">
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Dokuemen </span>
|
<span class="sort"> <span class="sort-label"> Tanggal Dokuemen </span>
|
||||||
@@ -117,12 +113,20 @@
|
|||||||
<span class="sort"> <span class="sort-label"> Tanggal Approval </span>
|
<span class="sort"> <span class="sort-label"> Tanggal Approval </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="tanggal_review">
|
||||||
|
<span class="sort"> <span class="sort-label"> Tanggal Kunjungan </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_review">
|
<th class="min-w-[150px]" data-datatable-column="tanggal_review">
|
||||||
<span class="sort"> <span class="sort-label"> Jangka Waktu </span>
|
<span class="sort"> <span class="sort-label"> Jangka Waktu </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="tanggal_review">
|
||||||
|
<span class="sort"> <span class="sort-label"> Keterangan </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
@@ -191,29 +195,34 @@
|
|||||||
tujuan_penilaian: {
|
tujuan_penilaian: {
|
||||||
title: 'Tujuan Penilaian',
|
title: 'Tujuan Penilaian',
|
||||||
},
|
},
|
||||||
jenis_agunan: {
|
|
||||||
title: 'Jenis Agunan',
|
|
||||||
},
|
|
||||||
|
|
||||||
tanggal_laporan: {
|
tanggal_laporan: {
|
||||||
title: 'Tanggal Laporan',
|
title: 'Tanggal Laporan',
|
||||||
render: (item, data) => {
|
render: (item, data) => {
|
||||||
return data.tanggal_laporan ? window.formatTanggalIndonesia(data.tanggal_laporan) : '-';
|
return data.tanggal_laporan ? window.formatTanggalIndonesia(data.tanggal_laporan) : '-';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tanggal_review: {
|
tanggal_approval: {
|
||||||
title: 'Tanggal Review',
|
title: 'Tanggal Approval',
|
||||||
render: (item, data) => {
|
render: (item, data) => {
|
||||||
return data.tanggal_review ? window.formatTanggalIndonesia(data.tanggal_review) : '-';
|
return data.tanggal_approval ? window.formatTanggalIndonesia(data.tanggal_approval) : '-';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
jangka_waktu: {
|
tanggal_kunjungan: {
|
||||||
title: 'Jangka Waktu',
|
title: 'Tanggal Kunjungan',
|
||||||
render: (item, data) => {
|
render: (item, data) => {
|
||||||
return data.jangka_waktu ?? '3';
|
return data.tanggal_kunjungan ? window.formatTanggalIndonesia(data.tanggal_kunjungan) : '-';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
jangka_waktu: {
|
||||||
|
title: 'Jangka Waktu',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.jangka_waktu ?? '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keterangan: {
|
||||||
|
title: 'Keterangan',
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
220
resources/views/laporan-slik/index.blade.php
Normal file
220
resources/views/laporan-slik/index.blade.php
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('admin-kredit.laporan-slik') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid">
|
||||||
|
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10"
|
||||||
|
data-datatable-state-save="false" id="laporan-slik-table"
|
||||||
|
data-api-url="{{ route('admin-kredit.laporan-slik.datatables') }}">
|
||||||
|
<div class="flex-wrap py-5 card-header bg-agi-50">
|
||||||
|
<h3 class="card-title">
|
||||||
|
Laporan SLIK
|
||||||
|
</h3>
|
||||||
|
<div class="flex flex-wrap gap-2 lg:gap-5">
|
||||||
|
<div class="flex">
|
||||||
|
<label class="input input-sm">
|
||||||
|
<i class="ki-filled ki-magnifier"></i>
|
||||||
|
<input placeholder="Search Laporan SLIK" id="search" type="text" value="">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap gap-2.5">
|
||||||
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
|
<a class="btn btn-sm btn-light" href="#" id="export-excel">
|
||||||
|
<i class="ki-filled ki-file-down"></i> Export Excel
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="scrollable-x-auto">
|
||||||
|
<table
|
||||||
|
class="table text-sm font-medium text-gray-700 align-middle table-auto table-border min-w-[1200px]"
|
||||||
|
data-datatable-table="true">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-14">
|
||||||
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox" />
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="sandi_bank">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Sandi Bank</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[120px]" data-datatable-column="no_rekening">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">No Rekening</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[120px]" data-datatable-column="baki_debet">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Baki Debet</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="status">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Status</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[50px] text-center" data-datatable-column="actions">Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
Show
|
||||||
|
<select class="w-16 select select-sm" data-datatable-size="true" name="perpage"> </select> per page
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-4 items-center">
|
||||||
|
<span data-datatable-info="true"> </span>
|
||||||
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('styles')
|
||||||
|
<style>
|
||||||
|
/* Responsive adjustments for table */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.table-responsive {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
max-width: 95% !important;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-cols-1.md\:grid-cols-2 {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure table is scrollable on small screens */
|
||||||
|
.scrollable-x-auto {
|
||||||
|
overflow-x: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent text wrapping in table cells */
|
||||||
|
.table th,
|
||||||
|
.table td {
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow wrapping for long text in detail modal */
|
||||||
|
.modal-body .text-gray-900 {
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
let dataTable;
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
/**
|
||||||
|
* Inisialisasi DataTable untuk Laporan SLIK menggunakan KTDataTable
|
||||||
|
*/
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const element = document.querySelector('#laporan-slik-table');
|
||||||
|
const searchInput = document.getElementById('search');
|
||||||
|
|
||||||
|
const apiUrl = element.getAttribute('data-api-url');
|
||||||
|
|
||||||
|
// Konfigurasi DataTable menggunakan KTDataTable
|
||||||
|
const dataTableOptions = {
|
||||||
|
apiEndpoint: apiUrl,
|
||||||
|
pageSize: 10,
|
||||||
|
columns: {
|
||||||
|
select: {
|
||||||
|
render: (item, data, context) => {
|
||||||
|
const checkbox = document.createElement('input');
|
||||||
|
checkbox.className = 'checkbox checkbox-sm';
|
||||||
|
checkbox.type = 'checkbox';
|
||||||
|
checkbox.value = data.id.toString();
|
||||||
|
checkbox.setAttribute('data-datatable-row-check', 'true');
|
||||||
|
return checkbox.outerHTML.trim();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sandi_bank: {
|
||||||
|
title: 'Sandi Bank',
|
||||||
|
},
|
||||||
|
no_rekening: {
|
||||||
|
title: 'No Rekening',
|
||||||
|
},
|
||||||
|
baki_debet_formatted: {
|
||||||
|
title: 'Baki Debet',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.baki_debet_formatted || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status_badge: {
|
||||||
|
title: 'Status',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.status_badge || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
title: 'Aksi',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<button class="btn btn-sm btn-light btn-icon" onclick="showDetail(${data.id})" title="Detail">
|
||||||
|
<i class="ki-filled ki-eye"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Inisialisasi DataTable
|
||||||
|
dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
|
dataTable.showSpinner();
|
||||||
|
|
||||||
|
// Fungsi pencarian
|
||||||
|
searchInput.addEventListener('input', function() {
|
||||||
|
const searchValue = this.value.trim();
|
||||||
|
dataTable.search(searchValue, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Export Excel functionality
|
||||||
|
document.getElementById('export-excel').addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Build export URL with current filters
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (searchInput.value) params.append('search', searchInput.value);
|
||||||
|
const exportUrl = '{{ route('admin-kredit.laporan-slik.export') }}?' + params.toString();
|
||||||
|
window.open(exportUrl, '_blank');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Fungsi untuk menampilkan detail data Laporan SLIK
|
||||||
|
* @param {number} id - ID data Laporan SLIK yang akan ditampilkan
|
||||||
|
*/
|
||||||
|
function showDetail(id) {
|
||||||
|
// Redirect ke halaman detail
|
||||||
|
window.location.href = `{{ route('admin-kredit.laporan-slik.show', ':id') }}`.replace(':id', id);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
172
resources/views/laporan-slik/show.blade.php
Normal file
172
resources/views/laporan-slik/show.blade.php
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('admin-kredit.laporan-slik.show', $laporanSlik) }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid">
|
||||||
|
<div class="w-full">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="flex flex-wrap gap-4 justify-between items-center mb-6">
|
||||||
|
<div>
|
||||||
|
<h3 class="text-xl font-semibold text-gray-900">Detail Laporan SLIK</h3>
|
||||||
|
<p class="mt-1 text-sm text-gray-600">Informasi lengkap laporan SLIK {{ $laporanSlik->nama_debitur }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<a href="{{ route('admin-kredit.laporan-slik.index') }}" class="btn btn-sm btn-light">
|
||||||
|
<i class="ki-filled ki-arrow-left"></i>
|
||||||
|
Kembali
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Card Detail -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Informasi Laporan SLIK</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||||
|
<!-- Informasi Debitur -->
|
||||||
|
<div class="space-y-4">
|
||||||
|
<h4 class="mb-3 text-base font-semibold text-gray-800">Data Debitur</h4>
|
||||||
|
|
||||||
|
<div class="space-y-3">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Nama Debitur:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->nama_debitur ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">No. Rekening:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->no_rekening ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">CIF:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->cif ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">NPWP:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->npwp ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">No. KTP:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->no_ktp ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">No. Telp:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->no_telp ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Alamat:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->alamat ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Kode Pos:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->kode_pos ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informasi Fasilitas -->
|
||||||
|
<div class="space-y-4">
|
||||||
|
<h4 class="mb-3 text-base font-semibold text-gray-800">Data Fasilitas</h4>
|
||||||
|
|
||||||
|
<div class="space-y-3">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Fasilitas:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->fasilitas ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Kolektibilitas:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->kolektibilitas ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Jenis Agunan:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->jenis_agunan ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Nilai Agunan:</span>
|
||||||
|
<span class="text-sm text-gray-900">Rp
|
||||||
|
{{ number_format($laporanSlik->nilai_agunan ?? 0, 0, ',', '.') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Baki Debet:</span>
|
||||||
|
<span class="text-sm text-gray-900">Rp
|
||||||
|
{{ number_format($laporanSlik->baki_debet ?? 0, 0, ',', '.') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Sandi Bank:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $laporanSlik->sandi_bank ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Status:</span>
|
||||||
|
<span class="text-sm text-gray-900">
|
||||||
|
<span
|
||||||
|
class="badge badge-light-{{ $laporanSlik->status == 'aktif' ? 'success' : 'danger' }}">
|
||||||
|
{{ $laporanSlik->status ?? 'aktif' }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-4 row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h5 class="mb-3">Detail Lainnya</h5>
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<td width="20%"><strong>Kolektibilitas</strong></td>
|
||||||
|
<td width="5%">:</td>
|
||||||
|
<td>{{ $laporanSlik->kolektibilitas }}</td>
|
||||||
|
<td width="20%"><strong>Tanggal Mulai</strong></td>
|
||||||
|
<td width="5%">:</td>
|
||||||
|
<td>{{ $laporanSlik->tanggal_mulai ?? '-' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Tanggal Jatuh Tempo</strong></td>
|
||||||
|
<td>:</td>
|
||||||
|
<td>{{ $laporanSlik->tanggal_jatuh_tempo ?? '-' }}</td>
|
||||||
|
<td><strong>Tanggal Selesai</strong></td>
|
||||||
|
<td>:</td>
|
||||||
|
<td>{{ $laporanSlik->tanggal_selesai ?? '-' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Jenis Agunan</strong></td>
|
||||||
|
<td>:</td>
|
||||||
|
<td>{{ $laporanSlik->jenis_agunan ?? '-' }}</td>
|
||||||
|
<td><strong>Fasilitas</strong></td>
|
||||||
|
<td>:</td>
|
||||||
|
<td>{{ $laporanSlik->fasilitas ?? '-' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Tanggal Lapor</strong></td>
|
||||||
|
<td>:</td>
|
||||||
|
<td>{{ $laporanSlik->tanggal_lapor ?? '-' }}</td>
|
||||||
|
<td><strong>Tanggal Dibuat</strong></td>
|
||||||
|
<td>:</td>
|
||||||
|
<td>{{ $laporanSlik->created_at->format('d/m/Y H:i') }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<!-- Filter Card -->
|
<!-- Filter Card -->
|
||||||
<div class="card border border-agi-100">
|
<div class="card border border-agi-100">
|
||||||
<div class="card-header bg-agi-50 py-5">
|
<div class="card-header bg-agi-50 py-5">
|
||||||
<h3 class="card-title"> Laporan User Pemohon</h3>
|
<h3 class="card-title"> Laporan User Penilai</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body grid gap-4">
|
<div class="card-body grid gap-4">
|
||||||
<!-- Search field at the top, full width -->
|
<!-- Search field at the top, full width -->
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
<i class="ki-outline ki-filter fs-2 me-1"></i>
|
<i class="ki-outline ki-filter fs-2 me-1"></i>
|
||||||
Terapkan Filter
|
Terapkan Filter
|
||||||
</button>
|
</button>
|
||||||
<a class="btn btn-sm btn-light" href="{{ route('laporan-hasil-penilaian-jaminan-internal-external.export') }}" id="export-btn">
|
<a class="btn btn-sm btn-light" href="{{ route('laporan-user.export') }}" id="export-btn">
|
||||||
<i class="ki-outline ki-file-down fs-2 me-1"></i>
|
<i class="ki-outline ki-file-down fs-2 me-1"></i>
|
||||||
Export to Excel
|
Export to Excel
|
||||||
</a>
|
</a>
|
||||||
@@ -77,132 +77,37 @@
|
|||||||
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Permohonan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="branch">
|
<th class="min-w-[150px]" data-datatable-column="branch">
|
||||||
<span class="sort"> <span class="sort-label"> Cabang </span>
|
<span class="sort"> <span class="sort-label"> Cabang </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="pemohon">
|
|
||||||
<span class="sort"> <span class="sort-label"> Pemohon </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="cif">
|
|
||||||
<span class="sort"> <span class="sort-label"> CIF </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="name">
|
<th class="min-w-[150px]" data-datatable-column="name">
|
||||||
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="pemohon">
|
||||||
|
<span class="sort"> <span class="sort-label"> Pemohon </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="jenis_penilaian">
|
<th class="min-w-[150px]" data-datatable-column="jenis_penilaian">
|
||||||
<span class="sort"> <span class="sort-label"> Jenis Penilaian </span>
|
<span class="sort"> <span class="sort-label"> Tgl Terima </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="tujuan_penilaian">
|
<th class="min-w-[150px]" data-datatable-column="tujuan_penilaian">
|
||||||
<span class="sort"> <span class="sort-label"> Tujuan Penilaian </span>
|
<span class="sort"> <span class="sort-label"> Penilai </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="jenis_fasilitas_kredit">
|
|
||||||
<span class="sort"> <span class="sort-label"> Jenis Fasilitas Kredit </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="jenis_agunan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Jenis Agunan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="alamat_agunan">
|
<th class="min-w-[150px]" data-datatable-column="alamat_agunan">
|
||||||
<span class="sort"> <span class="sort-label"> Alamat Agunan </span>
|
<span class="sort"> <span class="sort-label"> Tgl Laporan </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="bukti_kepemilikan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Bukti Kepemilikan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_pemilik">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nama Pemilik </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="luas_tanah">
|
|
||||||
<span class="sort"> <span class="sort-label"> Luas Tanah </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_tanah">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Tanah </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="luas_bangunan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Luas Bangunan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_bangunan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Bangunan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_njop">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai NJOP </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_pasar_wajar">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Pasar Wajar </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nilai_likuidasi">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nilai Likuidasi </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_documen_diterima">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Dokumen Diterima </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_spk">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal SPK </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nomor_spk">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nomor SPK </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_rencana_kunjunagn">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Rencana Kunjungan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_kunjungan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Kunjungan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="taggal_delivered">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Delivered </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="jangka_waktu_sla">
|
|
||||||
<span class="sort"> <span class="sort-label"> Jangka Waktu SLA </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_laporan">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Laporan </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_review">
|
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Review </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_penilai">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nama Penilai </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_team_leader">
|
|
||||||
<span class="sort"> <span class="sort-label"> Nama Team Leader </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
|
||||||
</th>
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="saran">
|
|
||||||
<span class="sort"> <span class="sort-label"> Saran </span>
|
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
|
|
||||||
<th class="min-w-[150px]" data-datatable-column="catatan">
|
<th class="min-w-[150px]" data-datatable-column="catatan">
|
||||||
<span class="sort"> <span class="sort-label"> Catatan </span>
|
<span class="sort"> <span class="sort-label"> Nilai Pasar Wajar </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -252,6 +157,15 @@
|
|||||||
},
|
},
|
||||||
nomor_registrasi: {
|
nomor_registrasi: {
|
||||||
title: 'Nomor Registrasi',
|
title: 'Nomor Registrasi',
|
||||||
|
},
|
||||||
|
branch: {
|
||||||
|
title: 'Cabang',
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
title: 'Nama Debitur',
|
||||||
|
},
|
||||||
|
pemohon: {
|
||||||
|
title: 'Pemohon',
|
||||||
},
|
},
|
||||||
tanggal_permohonan: {
|
tanggal_permohonan: {
|
||||||
title: 'Tanggal Permohonan',
|
title: 'Tanggal Permohonan',
|
||||||
@@ -259,68 +173,14 @@
|
|||||||
return data.tanggal_permohonan ? window.formatTanggalIndonesia(data.tanggal_permohonan) : '-';
|
return data.tanggal_permohonan ? window.formatTanggalIndonesia(data.tanggal_permohonan) : '-';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
branch: {
|
nama_penilai: {
|
||||||
title: 'Cabang',
|
title: 'Nama Penilai',
|
||||||
},
|
},
|
||||||
pemohon: {
|
|
||||||
title: 'Pemohon',
|
tanggal_laporan: {
|
||||||
},
|
title: 'Tanggal Dokumen Diterima',
|
||||||
cif: {
|
|
||||||
title: 'CIF',
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
title: 'Nama Debitur',
|
|
||||||
},
|
|
||||||
jenis_penilaian: {
|
|
||||||
title: 'Jenis Penilaian',
|
|
||||||
},
|
|
||||||
tujuan_penilaian: {
|
|
||||||
title: 'Tujuan Penilaian',
|
|
||||||
},
|
|
||||||
jenis_fasilitas_kredit: {
|
|
||||||
title: 'Jenis Fasilitas Kredit',
|
|
||||||
},
|
|
||||||
jenis_agunan: {
|
|
||||||
title: 'Jenis Agunan',
|
|
||||||
},
|
|
||||||
alamat_agunan: {
|
|
||||||
title: 'Alamat Agunan',
|
|
||||||
},
|
|
||||||
bukti_kepemilikan: {
|
|
||||||
title: 'Bukti Kepemilikan',
|
|
||||||
render: (item, data) => {
|
render: (item, data) => {
|
||||||
if (data.bukti_kepemilikan) {
|
return data.tanggal_laporan ? window.formatTanggalIndonesia(data.tanggal_laporan) : '-';
|
||||||
// Ganti karakter baris baru dengan tag <br> untuk HTML
|
|
||||||
return data.bukti_kepemilikan.split('\n').join('<br>');
|
|
||||||
}
|
|
||||||
return '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nama_pemilik: {
|
|
||||||
title: 'Nama Pemilik',
|
|
||||||
},
|
|
||||||
luas_tanah: {
|
|
||||||
title: 'Luas Tanah',
|
|
||||||
},
|
|
||||||
nilai_tanah: {
|
|
||||||
title: 'Nilai Tanah',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_tanah ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
luas_bangunan: {
|
|
||||||
title: 'Luas Bangunan',
|
|
||||||
},
|
|
||||||
nilai_bangunan: {
|
|
||||||
title: 'Nilai Bangunan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_bangunan ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nilai_njop: {
|
|
||||||
title: 'Nilai NJOP',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_njop ?? '-';
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nilai_pasar_wajar: {
|
nilai_pasar_wajar: {
|
||||||
@@ -328,72 +188,6 @@
|
|||||||
render: (item, data) => {
|
render: (item, data) => {
|
||||||
return data.nilai_pasar_wajar ?? '-';
|
return data.nilai_pasar_wajar ?? '-';
|
||||||
},
|
},
|
||||||
},
|
|
||||||
nilai_likuidasi: {
|
|
||||||
title: 'Nilai Likuidasi',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.nilai_likuidasi ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_documen_diterima: {
|
|
||||||
title: 'Tanggal Dokumen Diterima',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_documen_diterima ? window.formatTanggalIndonesia(data.tanggal_documen_diterima) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_spk: {
|
|
||||||
title: 'Tanggal SPK',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_spk ? window.formatTanggalIndonesia(data.tanggal_spk) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nomor_spk: {
|
|
||||||
title: 'Nomor SPK',
|
|
||||||
},
|
|
||||||
tanggal_rencana_kunjunagn: {
|
|
||||||
title: 'Tanggal Rencana Kunjungan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_rencana_kunjunagn ? window.formatTanggalIndonesia(data.tanggal_rencana_kunjunagn) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_kunjungan: {
|
|
||||||
title: 'Tanggal Kunjungan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_kunjungan ? window.formatTanggalIndonesia(data.tanggal_kunjungan) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
taggal_delivered: {
|
|
||||||
title: 'Tanggal Delivered',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.taggal_delivered ? window.formatTanggalIndonesia(data.taggal_delivered) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
jangka_waktu_sla: {
|
|
||||||
title: 'Jangka Waktu SLA',
|
|
||||||
},
|
|
||||||
tanggal_laporan: {
|
|
||||||
title: 'Tanggal Laporan',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_laporan ? window.formatTanggalIndonesia(data.tanggal_laporan) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tanggal_review: {
|
|
||||||
title: 'Tanggal Review',
|
|
||||||
render: (item, data) => {
|
|
||||||
return data.tanggal_review ? window.formatTanggalIndonesia(data.tanggal_review) : '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nama_penilai: {
|
|
||||||
title: 'Nama Penilai',
|
|
||||||
},
|
|
||||||
nama_team_leader: {
|
|
||||||
title: 'Nama Team Leader',
|
|
||||||
},
|
|
||||||
saran: {
|
|
||||||
title: 'Saran',
|
|
||||||
},
|
|
||||||
catatan: {
|
|
||||||
title: 'Catatan',
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -239,16 +239,6 @@
|
|||||||
let resumeButton = '';
|
let resumeButton = '';
|
||||||
let penyelesaian = '';
|
let penyelesaian = '';
|
||||||
|
|
||||||
|
|
||||||
if (data.noc) {
|
|
||||||
if (!data.noc?.memo_penyelesaian) {
|
|
||||||
penyelesaian = `
|
|
||||||
<a href="{{ route('noc.index') }}/${data.noc.id}" class="btn btn-sm btn-warning">
|
|
||||||
Penyelesaian
|
|
||||||
</a>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.penilai.resume) {
|
if (data.penilai.resume) {
|
||||||
resumeButton = `
|
resumeButton = `
|
||||||
<a href="{{ route('penilai.print-out') }}?permohonanId=${data.id}&documentId=${dokumenID}&inspeksiId=${inspeksiId}&jaminanId=${jenisJaminanID}&statusLpj=0" class="btn btn-sm btn-success">
|
<a href="{{ route('penilai.print-out') }}?permohonanId=${data.id}&documentId=${dokumenID}&inspeksiId=${inspeksiId}&jaminanId=${jenisJaminanID}&statusLpj=0" class="btn btn-sm btn-success">
|
||||||
|
|||||||
@@ -5,84 +5,94 @@
|
|||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
<div class="card border border-agi-100">
|
<div class="border card border-agi-100">
|
||||||
<div class="card-header bg-agi-50 py-5">
|
<div class="py-5 card-header bg-agi-50">
|
||||||
<h3 class="card-title">
|
<h3 class="card-title">
|
||||||
Edit Laporan Admin Kredit
|
Edit Laporan Admin Kredit
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form action="{{ route('laporan-admin-kredit.update', $laporanAdminKredit->id) }}" method="POST" class="grid gap-5">
|
<form action="{{ route('admin-kredit.laporan.update', $laporanAdminKredit->id) }}" method="POST"
|
||||||
|
class="grid gap-5">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PUT')
|
@method('PUT')
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
|
<div class="grid grid-cols-1 gap-5 md:grid-cols-2">
|
||||||
<!-- Editable Fields -->
|
<!-- Editable Fields -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="kode_register_t24" class="form-label">Kode Register T24</label>
|
<label for="kode_register_t24" class="form-label">Kode Register T24</label>
|
||||||
<input type="text" name="kode_register_t24" id="kode_register_t24" class="input" value="{{ $laporanAdminKredit->kode_register_t24 }}" required>
|
<input type="text" name="kode_register_t24" id="kode_register_t24" class="input"
|
||||||
|
value="{{ $laporanAdminKredit->kode_register_t24 }}" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="cif" class="form-label">CIF</label>
|
<label for="cif" class="form-label">CIF</label>
|
||||||
<input type="text" name="cif" id="cif" class="input" value="{{ $laporanAdminKredit->debiture ? $laporanAdminKredit->debiture->cif : '' }}" required>
|
<input type="text" name="cif" id="cif" class="input"
|
||||||
|
value="{{ $laporanAdminKredit->debiture ? $laporanAdminKredit->debiture->cif : '' }}"
|
||||||
|
required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Read-only Information Fields -->
|
<!-- Read-only Information Fields -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Nama Debitur</label>
|
<label class="form-label">Nama Debitur</label>
|
||||||
<div class="input bg-gray-100">{{ $laporanAdminKredit->debiture ? $laporanAdminKredit->debiture->name : '' }}</div>
|
<div class="bg-gray-100 input">
|
||||||
|
{{ $laporanAdminKredit->debiture ? $laporanAdminKredit->debiture->name : '' }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Cabang</label>
|
<label class="form-label">Cabang</label>
|
||||||
<div class="input bg-gray-100">{{ $laporanAdminKredit->debiture ? $laporanAdminKredit->debiture->branch->name : '' }}</div>
|
<div class="bg-gray-100 input">
|
||||||
|
{{ $laporanAdminKredit->debiture ? $laporanAdminKredit->debiture->branch->name : '' }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Jenis Agunan</label>
|
<label class="form-label">Jenis Agunan</label>
|
||||||
<div class="input bg-gray-100">{{ $laporanAdminKredit->jenis_agunan }}</div>
|
<div class="bg-gray-100 input">{{ $laporanAdminKredit->jenis_agunan }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Bukti Kepemilikan</label>
|
<label class="form-label">Bukti Kepemilikan</label>
|
||||||
<div class="input bg-gray-100">{{ $laporanAdminKredit->bukti_kepemilikan }}</div>
|
<div class="bg-gray-100 input">{{ $laporanAdminKredit->bukti_kepemilikan }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Alamat Agunan</label>
|
<label class="form-label">Alamat Agunan</label>
|
||||||
<div class="textarea bg-gray-100 h-auto min-h-[70px] p-3">{{ $laporanAdminKredit->alamat_agunan }}</div>
|
<div class="textarea bg-gray-100 h-auto min-h-[70px] p-3">
|
||||||
|
{{ $laporanAdminKredit->alamat_agunan }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Nama Pemilik</label>
|
<label class="form-label">Nama Pemilik</label>
|
||||||
<div class="input bg-gray-100">{{ $laporanAdminKredit->nama_pemilik }}</div>
|
<div class="bg-gray-100 input">{{ $laporanAdminKredit->nama_pemilik }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Tanggal Kunjungan</label>
|
<label class="form-label">Tanggal Kunjungan</label>
|
||||||
<div class="input bg-gray-100">{{ \Carbon\Carbon::parse($laporanAdminKredit->tanggal_kunjungan)->format('d-m-Y') }}</div>
|
<div class="bg-gray-100 input">
|
||||||
|
{{ \Carbon\Carbon::parse($laporanAdminKredit->tanggal_kunjungan)->format('d-m-Y') }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Nilai Pasar Wajar</label>
|
<label class="form-label">Nilai Pasar Wajar</label>
|
||||||
<div class="input bg-gray-100">{{ number_format($laporanAdminKredit->nilai_pasar_wajar, 0, ',', '.') }}</div>
|
<div class="bg-gray-100 input">
|
||||||
|
{{ number_format($laporanAdminKredit->nilai_pasar_wajar, 0, ',', '.') }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Nilai Likuidasi</label>
|
<label class="form-label">Nilai Likuidasi</label>
|
||||||
<div class="input bg-gray-100">{{ number_format($laporanAdminKredit->nilai_likuidasi, 0, ',', '.') }}</div>
|
<div class="bg-gray-100 input">
|
||||||
|
{{ number_format($laporanAdminKredit->nilai_likuidasi, 0, ',', '.') }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Nama Penilai</label>
|
<label class="form-label">Nama Penilai</label>
|
||||||
<div class="input bg-gray-100">{{ $laporanAdminKredit->nama_penilai }}</div>
|
<div class="bg-gray-100 input">{{ $laporanAdminKredit->nama_penilai }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end gap-3">
|
<div class="flex gap-3 justify-end">
|
||||||
<a href="{{ route('laporan-admin-kredit.index') }}" class="btn btn-light">Cancel</a>
|
<a href="{{ route('admin-kredit.laporan.index') }}" class="btn btn-light">Cancel</a>
|
||||||
<button type="submit" class="btn btn-primary">Update</button>
|
<button type="submit" class="btn btn-primary">Update</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="laporan-admin-kredit-table" data-api-url="{{ route('laporan-admin-kredit.datatables') }}">
|
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10"
|
||||||
<div class="card-header bg-agi-50 py-5 flex-wrap">
|
data-datatable-state-save="false" id="laporan-admin-kredit-table"
|
||||||
|
data-api-url="{{ route('admin-kredit.laporan.datatables') }}">
|
||||||
|
<div class="flex-wrap py-5 card-header bg-agi-50">
|
||||||
<h3 class="card-title">
|
<h3 class="card-title">
|
||||||
Daftar Laporan Admin Kredit
|
Daftar Laporan Admin Kredit
|
||||||
</h3>
|
</h3>
|
||||||
@@ -32,18 +34,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex flex-wrap gap-2.5">
|
<div class="flex flex-wrap gap-2.5">
|
||||||
<div class="h-[24px] border border-r-gray-200"></div>
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
<a class="btn btn-sm btn-light" href="{{ route('laporan-admin-kredit.export') }}"> Export to Excel </a>
|
<a class="btn btn-sm btn-light" href="{{ route('admin-kredit.laporan.export') }}"> Export to Excel
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="scrollable-x-auto">
|
<div class="scrollable-x-auto">
|
||||||
<table class="table table-auto table-border align-middle text-gray-700 font-medium text-sm" data-datatable-table="true">
|
<table class="table text-sm font-medium text-gray-700 align-middle table-auto table-border"
|
||||||
|
data-datatable-table="true">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="w-14">
|
<th class="w-14">
|
||||||
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox"/>
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox" />
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="cif">
|
<th class="min-w-[150px]" data-datatable-column="cif">
|
||||||
<span class="sort"> <span class="sort-label"> CIF </span>
|
<span class="sort"> <span class="sort-label"> CIF </span>
|
||||||
@@ -101,13 +105,14 @@
|
|||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer justify-center md:justify-between flex-col md:flex-row gap-3 text-gray-600 text-2sm font-medium">
|
<div
|
||||||
<div class="flex items-center gap-2">
|
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
Show
|
Show
|
||||||
<select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select> per
|
<select class="w-16 select select-sm" data-datatable-size="true" name="perpage"> </select> per
|
||||||
page
|
page
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex gap-4 items-center">
|
||||||
<span data-datatable-info="true"> </span>
|
<span data-datatable-info="true"> </span>
|
||||||
<div class="pagination" data-datatable-pagination="true">
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
306
resources/views/memo/create.blade.php
Normal file
306
resources/views/memo/create.blade.php
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('memo.create') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
|
<!-- Form Memo Penyelesaian -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">
|
||||||
|
Buat Memo Penyelesaian
|
||||||
|
</h3>
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
<a href="{{ route('memo.index') }}" class="btn btn-sm btn-light">
|
||||||
|
<i class="ki-filled ki-black-left"></i>
|
||||||
|
Kembali
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
@if (session('error'))
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
{{ session('error') }}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<form action="{{ route('memo.preview') }}" method="POST" id="memo-form">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<!-- Form Input Memo -->
|
||||||
|
<div class="grid grid-cols-1 gap-5 mb-7 lg:grid-cols-2">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<label class="text-gray-900 form-label">Nomor Memo <span class="text-red-500">*</span></label>
|
||||||
|
<input type="text" name="memo_number" class="input"
|
||||||
|
placeholder="Masukkan nomor memo penyelesaian" value="{{ old('memo_number') }}" required>
|
||||||
|
@error('memo_number')
|
||||||
|
<span class="text-sm text-red-500">{{ $message }}</span>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<label class="text-gray-900 form-label">Tanggal Pembayaran <span
|
||||||
|
class="text-red-500">*</span></label>
|
||||||
|
<input type="date" name="payment_date" class="input" value="{{ old('payment_date') }}"
|
||||||
|
required>
|
||||||
|
@error('payment_date')
|
||||||
|
<span class="text-sm text-red-500">{{ $message }}</span>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-1 lg:col-span-2">
|
||||||
|
<label class="text-gray-900 form-label">Total Biaya PJ</label>
|
||||||
|
<div class="relative">
|
||||||
|
<input type="text" id="total-biaya-pj" class="bg-gray-50 input"
|
||||||
|
value="Rp {{ number_format($totalBiayaPJ ?? 0, 0, ',', '.') }}" readonly>
|
||||||
|
<div class="flex absolute inset-y-0 right-0 items-center pr-3">
|
||||||
|
<i class="text-gray-400 ki-filled ki-calculator"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="text-sm text-gray-500">Total biaya dari nominal bayar NOC untuk permohonan yang
|
||||||
|
dipilih</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hidden field untuk tanggal memo otomatis -->
|
||||||
|
<input type="hidden" name="memo_date" value="{{ date('Y-m-d') }}">
|
||||||
|
|
||||||
|
<!-- Daftar Permohonan yang Dipilih -->
|
||||||
|
@if (count($permohonanList) > 0)
|
||||||
|
<div class="mb-7">
|
||||||
|
<h4 class="mb-4 text-lg font-semibold">Daftar Permohonan yang Akan Diproses</h4>
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="table table-border">
|
||||||
|
<thead>
|
||||||
|
<tr class="bg-gray-50">
|
||||||
|
<th class="w-12 text-center">
|
||||||
|
<input type="checkbox" id="select-all" class="checkbox checkbox-sm" checked
|
||||||
|
disabled>
|
||||||
|
</th>
|
||||||
|
<th>Nomor Registrasi</th>
|
||||||
|
<th>Debitur</th>
|
||||||
|
<th>Cabang</th>
|
||||||
|
<th>AO</th>
|
||||||
|
<th>Tujuan Penilaian</th>
|
||||||
|
<th>Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($permohonanList as $permohonan)
|
||||||
|
<tr>
|
||||||
|
<td class="text-center">
|
||||||
|
<input type="checkbox" class="checkbox checkbox-sm permohonan-checkbox"
|
||||||
|
checked disabled>
|
||||||
|
<input type="hidden" name="permohonan_ids[]"
|
||||||
|
value="{{ $permohonan->id }}">
|
||||||
|
</td>
|
||||||
|
<td class="font-medium">{{ $permohonan->nomor_registrasi }}</td>
|
||||||
|
<td>{{ $permohonan->debiture->name ?? '-' }}</td>
|
||||||
|
<td>{{ $permohonan->branch->name ?? '-' }}</td>
|
||||||
|
<td>{{ $permohonan->user->name ?? '-' }}</td>
|
||||||
|
<td>
|
||||||
|
@if ($permohonan->tujuanPenilaian)
|
||||||
|
<span class="badge badge-sm badge-primary">
|
||||||
|
{{ $permohonan->tujuanPenilaian->name }}
|
||||||
|
</span>
|
||||||
|
@else
|
||||||
|
-
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="uppercase badge badge-sm badge-warning">
|
||||||
|
{{ $permohonan->status }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4 mt-4 bg-blue-50 rounded-lg">
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
<i class="text-blue-600 ki-filled ki-information"></i>
|
||||||
|
<span class="font-medium text-blue-800">Informasi:</span>
|
||||||
|
</div>
|
||||||
|
<p class="mt-1 text-blue-700">
|
||||||
|
Total <span id="selected-count">{{ count($permohonanList) }}</span> permohonan akan
|
||||||
|
diproses untuk memo penyelesaian.
|
||||||
|
Anda dapat menghapus centang pada permohonan yang tidak ingin diproses.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tombol Submit -->
|
||||||
|
<div class="flex gap-2 justify-end">
|
||||||
|
<a href="{{ route('memo.index') }}" class="btn btn-light">
|
||||||
|
Batal
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="btn btn-primary" id="submit-btn">
|
||||||
|
<i class="ki-filled ki-eye"></i>
|
||||||
|
Preview Memo Penyelesaian
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<div class="py-10 text-center">
|
||||||
|
<div class="mb-4">
|
||||||
|
<i class="text-6xl text-gray-400 ki-filled ki-information-2"></i>
|
||||||
|
</div>
|
||||||
|
<h4 class="mb-2 text-lg font-semibold text-gray-600">Tidak Ada Data</h4>
|
||||||
|
<p class="mb-4 text-gray-500">Tidak ada permohonan yang dipilih untuk diproses.</p>
|
||||||
|
<a href="{{ route('memo.index') }}" class="btn btn-primary">
|
||||||
|
Kembali ke Daftar
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const selectAllCheckbox = document.getElementById('select-all');
|
||||||
|
const permohonanCheckboxes = document.querySelectorAll('.permohonan-checkbox');
|
||||||
|
const selectedCountSpan = document.getElementById('selected-count');
|
||||||
|
const submitBtn = document.getElementById('submit-btn');
|
||||||
|
const memoForm = document.getElementById('memo-form');
|
||||||
|
const totalBiayaPJInput = document.getElementById('total-biaya-pj');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fungsi untuk mengupdate total biaya PJ
|
||||||
|
*/
|
||||||
|
function updateTotalBiayaPJ() {
|
||||||
|
const checkedBoxes = document.querySelectorAll('.permohonan-checkbox:checked');
|
||||||
|
const permohonanIds = Array.from(checkedBoxes).map(cb => cb.value);
|
||||||
|
|
||||||
|
if (permohonanIds.length === 0) {
|
||||||
|
if (totalBiayaPJInput) {
|
||||||
|
totalBiayaPJInput.value = 'Rp 0';
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kirim AJAX request untuk mendapatkan total biaya PJ
|
||||||
|
fetch('{{ route('memo.total-biaya-pj') }}', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute(
|
||||||
|
'content')
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
permohonan_ids: permohonanIds
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success && totalBiayaPJInput) {
|
||||||
|
totalBiayaPJInput.value = data.total_biaya_pj_formatted;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
if (totalBiayaPJInput) {
|
||||||
|
totalBiayaPJInput.value = 'Error menghitung total';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fungsi untuk mengupdate jumlah item yang dipilih
|
||||||
|
*/
|
||||||
|
function updateSelectedCount() {
|
||||||
|
const checkedBoxes = document.querySelectorAll('.permohonan-checkbox:checked');
|
||||||
|
const count = checkedBoxes.length;
|
||||||
|
|
||||||
|
if (selectedCountSpan) {
|
||||||
|
selectedCountSpan.textContent = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable submit button jika tidak ada yang dipilih
|
||||||
|
if (submitBtn) {
|
||||||
|
submitBtn.disabled = count === 0;
|
||||||
|
if (count === 0) {
|
||||||
|
submitBtn.innerHTML = '<i class="ki-filled ki-check"></i> Pilih minimal 1 permohonan';
|
||||||
|
submitBtn.classList.add('btn-disabled');
|
||||||
|
} else {
|
||||||
|
submitBtn.innerHTML =
|
||||||
|
`<i class="ki-filled ki-check"></i> Buat Memo Penyelesaian (${count} item)`;
|
||||||
|
submitBtn.classList.remove('btn-disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update select all checkbox state
|
||||||
|
if (selectAllCheckbox) {
|
||||||
|
selectAllCheckbox.checked = count === permohonanCheckboxes.length;
|
||||||
|
selectAllCheckbox.indeterminate = count > 0 && count < permohonanCheckboxes.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update total biaya PJ
|
||||||
|
updateTotalBiayaPJ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event listener untuk select all checkbox
|
||||||
|
*/
|
||||||
|
if (selectAllCheckbox) {
|
||||||
|
selectAllCheckbox.addEventListener('change', function() {
|
||||||
|
const isChecked = this.checked;
|
||||||
|
permohonanCheckboxes.forEach(checkbox => {
|
||||||
|
checkbox.checked = isChecked;
|
||||||
|
});
|
||||||
|
updateSelectedCount();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event listener untuk individual checkboxes
|
||||||
|
*/
|
||||||
|
permohonanCheckboxes.forEach(checkbox => {
|
||||||
|
checkbox.addEventListener('change', function() {
|
||||||
|
updateSelectedCount();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event listener untuk form submission
|
||||||
|
*/
|
||||||
|
if (memoForm) {
|
||||||
|
memoForm.addEventListener('submit', function(e) {
|
||||||
|
const checkedBoxes = document.querySelectorAll('.permohonan-checkbox:checked');
|
||||||
|
|
||||||
|
if (checkedBoxes.length === 0) {
|
||||||
|
e.preventDefault();
|
||||||
|
alert('Pilih minimal 1 permohonan untuk diproses!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Konfirmasi sebelum submit
|
||||||
|
const confirmed = confirm(
|
||||||
|
`Apakah Anda yakin ingin membuat memo penyelesaian untuk ${checkedBoxes.length} permohonan?`
|
||||||
|
);
|
||||||
|
if (!confirmed) {
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable submit button untuk mencegah double submit
|
||||||
|
if (submitBtn) {
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
submitBtn.innerHTML = '<i class="ki-filled ki-loading"></i> Memproses...';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize count dan total biaya PJ
|
||||||
|
updateSelectedCount();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
421
resources/views/memo/index.blade.php
Normal file
421
resources/views/memo/index.blade.php
Normal file
@@ -0,0 +1,421 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('memo.index') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
|
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10"
|
||||||
|
data-datatable-state-save="false" id="memo-table" data-api-url="{{ route('memo.datatables') }}">
|
||||||
|
<div class="flex-wrap py-5 card-header bg-agi-50">
|
||||||
|
<h3 class="card-title">
|
||||||
|
Memo Penyelesaian
|
||||||
|
</h3>
|
||||||
|
<div class="flex flex-wrap gap-2 lg:gap-5">
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<label class="input input-sm"> <i class="ki-filled ki-magnifier"> </i>
|
||||||
|
<input placeholder="Search Memo Penyelesaian" id="search" type="text" value="">
|
||||||
|
</label>
|
||||||
|
<select class="select select-sm" id="filter-jenis-penilaian">
|
||||||
|
<option value="">Semua Jenis Penilaian</option>
|
||||||
|
<option value="1">Internal</option>
|
||||||
|
<option value="2">External</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap gap-2.5">
|
||||||
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
|
<button class="btn btn-sm btn-primary" id="btn-create-memo" disabled>
|
||||||
|
<i class="ki-filled ki-plus"></i>
|
||||||
|
Buat Memo Penyelesaian
|
||||||
|
</button>
|
||||||
|
<a class="btn btn-sm btn-light" href="#"> Export to Excel </a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="scrollable-x-auto">
|
||||||
|
<table class="table text-sm font-medium text-gray-700 align-middle table-auto table-border"
|
||||||
|
data-datatable-table="true">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-14">
|
||||||
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox" />
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="debitur_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> Debitur </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="branch_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> Pemohon(Cabang/Direktorat) </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="user_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> AO </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="jenis_penilaian_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> Jenis Penilaian </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="tujuan_penilaian_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> Tujuan Penilaian </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="jenis_fasilitas_kredit_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> Fasilitas Kredit </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="tanggal_survei">
|
||||||
|
<span class="sort"> <span class="sort-label"> Tanggal Survei </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="due_date_sla">
|
||||||
|
<span class="sort"> <span class="sort-label"> Due Date SLA </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[50px] text-center" data-datatable-column="status">Status</th>
|
||||||
|
<th class="min-w-[50px] text-center" data-datatable-column="actions">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
Show
|
||||||
|
<select class="w-16 select select-sm" data-datatable-size="true" name="perpage"> </select> per
|
||||||
|
page
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-4 items-center">
|
||||||
|
<span data-datatable-info="true"> </span>
|
||||||
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
/**
|
||||||
|
* Format tanggal ke format Indonesia
|
||||||
|
* @param {Date} date - Tanggal yang akan diformat
|
||||||
|
* @returns {string} - Tanggal dalam format Indonesia
|
||||||
|
*/
|
||||||
|
function formatDate(date) {
|
||||||
|
const day = date.getDate().toString().padStart(2, '0');
|
||||||
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||||
|
const year = date.getFullYear();
|
||||||
|
|
||||||
|
return `${day} ${getIndonesianMonth(month)} ${year}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mendapatkan nama bulan dalam bahasa Indonesia
|
||||||
|
* @param {string} month - Nomor bulan
|
||||||
|
* @returns {string} - Nama bulan dalam bahasa Indonesia
|
||||||
|
*/
|
||||||
|
function getIndonesianMonth(month) {
|
||||||
|
const months = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni',
|
||||||
|
'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'
|
||||||
|
];
|
||||||
|
return months[month - 1];
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
const element = document.querySelector('#memo-table');
|
||||||
|
const searchInput = document.getElementById('search');
|
||||||
|
const filterJenisPenilaian = document.getElementById('filter-jenis-penilaian');
|
||||||
|
const btnCreateMemo = document.getElementById('btn-create-memo');
|
||||||
|
let selectedItems = [];
|
||||||
|
|
||||||
|
const apiUrl = element.getAttribute('data-api-url');
|
||||||
|
const dataTableOptions = {
|
||||||
|
apiEndpoint: apiUrl,
|
||||||
|
pageSize: 10,
|
||||||
|
columns: {
|
||||||
|
select: {
|
||||||
|
render: (item, data, context) => {
|
||||||
|
// Cek apakah sudah ada memo penyelesaian
|
||||||
|
const hasMemo = data.noc && data.noc.memo_penyelesaian;
|
||||||
|
|
||||||
|
const checkbox = document.createElement('input');
|
||||||
|
checkbox.className = 'checkbox checkbox-sm';
|
||||||
|
checkbox.type = 'checkbox';
|
||||||
|
checkbox.value = data.id.toString();
|
||||||
|
checkbox.setAttribute('data-datatable-row-check', 'true');
|
||||||
|
|
||||||
|
// Disable checkbox jika sudah ada memo
|
||||||
|
if (hasMemo) {
|
||||||
|
checkbox.disabled = true;
|
||||||
|
checkbox.title = 'Permohonan ini sudah memiliki memo penyelesaian';
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkbox.outerHTML.trim();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nomor_registrasi: {
|
||||||
|
title: 'Nomor Registrasi',
|
||||||
|
},
|
||||||
|
debitur_id: {
|
||||||
|
title: 'Debitur',
|
||||||
|
render: (item, data) => {
|
||||||
|
if (data.debiture) {
|
||||||
|
return `${data.debiture.name.toUpperCase()}`;
|
||||||
|
}
|
||||||
|
return "-";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
branch_id: {
|
||||||
|
title: 'Cabang Pemohon',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.branch.name}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
user_id: {
|
||||||
|
title: 'User Pemohon',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.user.name}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
jenis_penilaian_id: {
|
||||||
|
title: 'Jenis Penilaian',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.jenis_penilaian.name}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tujuan_penilaian_id: {
|
||||||
|
title: 'Tujuan Penilaian',
|
||||||
|
render: (item, data) => {
|
||||||
|
switch (data.tujuan_penilaian.code) {
|
||||||
|
case "TP0001":
|
||||||
|
return `<span class="badge badge-sm badge-primary">${data.tujuan_penilaian.name}</span>`;
|
||||||
|
case "TP0002":
|
||||||
|
return `<span class="badge badge-sm badge-info">${data.tujuan_penilaian.name}</span>`;
|
||||||
|
case "TP0003":
|
||||||
|
return `<span class="badge badge-sm badge-success">${data.tujuan_penilaian.name}</span>`;
|
||||||
|
case "TP0004":
|
||||||
|
return `<span class="badge badge-sm badge-danger">${data.tujuan_penilaian.name}</span>`;
|
||||||
|
case "TP0005":
|
||||||
|
return `<span class="badge badge-sm badge-warning">${data.tujuan_penilaian.name}</span>`;
|
||||||
|
case "TP0006":
|
||||||
|
return `<span class="badge badge-sm badge-dark">${data.tujuan_penilaian.name}</span>`;
|
||||||
|
case "TP0007":
|
||||||
|
return `<span class="badge badge-sm badge-outline badge-info">${data.tujuan_penilaian.name}</span>`;
|
||||||
|
default:
|
||||||
|
return `<span class="badge badge-sm badge-outline badge-default">${data.tujuan_penilaian.name}</span>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
jenis_fasilitas_kredit_id: {
|
||||||
|
title: 'Fasilitas Kredit',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.jenis_fasilitas_kredit.name}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tanggal_survei: {
|
||||||
|
title: 'Tanggal Survei',
|
||||||
|
render: (item, data) => {
|
||||||
|
if (data.penilaian.waktu_penilaian) {
|
||||||
|
return `${formatDate(new Date(data.penilaian.waktu_penilaian))}`;
|
||||||
|
}
|
||||||
|
return `${formatDate(new Date(data.penilaian.created_at))}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
due_date_sla: {
|
||||||
|
title: 'Due Date SLA',
|
||||||
|
render: (item, data) => {
|
||||||
|
const tujuan_penilaian = data.tujuan_penilaian.name;
|
||||||
|
const tipe_laporan = data.penilai?.type;
|
||||||
|
const nilai_plafond = data.penilaian.nilaiPlafond?.name;
|
||||||
|
let waktu_penilaian = new Date(data.penilaian.created_at);
|
||||||
|
if (data.penilaian.waktu_penilaian) {
|
||||||
|
waktu_penilaian = new Date(data.penilaian.waktu_penilaian);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tujuan_penilaian === "RAP") {
|
||||||
|
waktu_penilaian.setDate(waktu_penilaian.getDate() + 3);
|
||||||
|
} else {
|
||||||
|
if (tipe_laporan === "sederhana") {
|
||||||
|
waktu_penilaian.setDate(waktu_penilaian.getDate() + 2);
|
||||||
|
} else if (tipe_laporan === "standar") {
|
||||||
|
if (nilai_plafond === "2 M - 5 M") {
|
||||||
|
waktu_penilaian.setDate(waktu_penilaian.getDate() + 3);
|
||||||
|
} else if (nilai_plafond === "< 2M") {
|
||||||
|
waktu_penilaian.setDate(waktu_penilaian.getDate() + 3);
|
||||||
|
} else {
|
||||||
|
waktu_penilaian.setDate(waktu_penilaian.getDate() + 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formatDate(waktu_penilaian);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
title: 'Status',
|
||||||
|
render: (item, data) => {
|
||||||
|
let badgeClass = 'badge-default';
|
||||||
|
if (data.status === 'memo-penyelesaian') {
|
||||||
|
badgeClass = 'badge-success';
|
||||||
|
} else if (data.status === 'done') {
|
||||||
|
badgeClass = 'badge-primary';
|
||||||
|
} else if (data.status === 'proses-laporan') {
|
||||||
|
badgeClass = 'badge-warning';
|
||||||
|
}
|
||||||
|
return `<span class="flex justify-center uppercase badge badge-sm ${badgeClass}">${data.status}</span>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
title: 'Actions',
|
||||||
|
render: (item, data) => {
|
||||||
|
let actionButtons = '';
|
||||||
|
|
||||||
|
// Cek apakah sudah ada memo penyelesaian dengan PDF
|
||||||
|
if (data.noc && data.noc.memo_penyelesaian) {
|
||||||
|
actionButtons = `
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<a href="memo/memo/download-pdf/${data.id}"
|
||||||
|
class="flex gap-1 items-center btn btn-sm btn-primary"
|
||||||
|
title="Download PDF Memo Penyelesaian">
|
||||||
|
<i class="fas fa-download"></i>
|
||||||
|
Download Memo
|
||||||
|
</a>
|
||||||
|
</div>`;
|
||||||
|
} else {
|
||||||
|
actionButtons = `
|
||||||
|
<span class="text-sm text-gray-500">Belum ada memo</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<div class="flex flex-wrap gap-1.5 justify-center">${actionButtons}</div>`;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fungsi untuk menangani perubahan checkbox
|
||||||
|
* Mengelola state tombol berdasarkan checkbox yang dipilih
|
||||||
|
*/
|
||||||
|
function handleCheckboxChange() {
|
||||||
|
// Hanya ambil checkbox yang tidak disabled dan checked
|
||||||
|
const checkboxes = document.querySelectorAll('input[data-datatable-row-check="true"]:checked:not(:disabled)');
|
||||||
|
selectedItems = Array.from(checkboxes).map(cb => cb.value);
|
||||||
|
|
||||||
|
// Log untuk debugging
|
||||||
|
console.log('Selected items:', selectedItems);
|
||||||
|
|
||||||
|
// Enable/disable tombol berdasarkan jumlah item yang dipilih
|
||||||
|
const hasSelection = selectedItems.length > 0;
|
||||||
|
btnCreateMemo.disabled = !hasSelection;
|
||||||
|
|
||||||
|
// Update text tombol create memo
|
||||||
|
if (hasSelection) {
|
||||||
|
btnCreateMemo.textContent = `Buat Memo Penyelesaian (${selectedItems.length} item)`;
|
||||||
|
} else {
|
||||||
|
btnCreateMemo.textContent = 'Buat Memo Penyelesaian';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fungsi untuk clear semua checkbox yang terpilih
|
||||||
|
* Menghapus semua selection dan reset state tombol
|
||||||
|
*/
|
||||||
|
function clearSelectedCheckboxes() {
|
||||||
|
try {
|
||||||
|
// Uncheck master checkbox juga - gunakan selector yang lebih spesifik
|
||||||
|
const masterCheckbox = document.querySelector('#memo-table thead input[type="checkbox"]');
|
||||||
|
if (masterCheckbox) {
|
||||||
|
masterCheckbox.checked = false;
|
||||||
|
}
|
||||||
|
// Uncheck semua checkbox yang tidak disabled
|
||||||
|
const checkboxes = document.querySelectorAll('input[data-datatable-row-check="true"]:not(:disabled)');
|
||||||
|
checkboxes.forEach(checkbox => {
|
||||||
|
checkbox.checked = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reset selected items array
|
||||||
|
selectedItems = [];
|
||||||
|
|
||||||
|
// Update state tombol
|
||||||
|
btnCreateMemo.disabled = true;
|
||||||
|
btnCreateMemo.textContent = 'Buat Memo Penyelesaian';
|
||||||
|
|
||||||
|
// Log untuk debugging
|
||||||
|
console.log('All checkboxes cleared successfully');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error clearing checkboxes:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listener untuk checkbox changes
|
||||||
|
element.addEventListener('change', function(e) {
|
||||||
|
if (e.target.type === 'checkbox') {
|
||||||
|
handleCheckboxChange();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Event listener untuk tombol create memo
|
||||||
|
btnCreateMemo.addEventListener('click', function() {
|
||||||
|
if (selectedItems.length > 0) {
|
||||||
|
const selectedIds = selectedItems.join(',');
|
||||||
|
console.log('Creating memo for IDs:', selectedIds);
|
||||||
|
window.location.href = `{{ route('memo.create') }}?selected_ids=${selectedIds}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Custom search functionality
|
||||||
|
searchInput.addEventListener('input', function() {
|
||||||
|
const searchValue = this.value.trim();
|
||||||
|
dataTable.search(searchValue, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter berdasarkan jenis penilaian
|
||||||
|
* Menggunakan pola yang sama dengan districts filter
|
||||||
|
*/
|
||||||
|
filterJenisPenilaian.addEventListener('change', function() {
|
||||||
|
const filterValue = this.value;
|
||||||
|
const searchValue = searchInput.value.trim();
|
||||||
|
|
||||||
|
// Gabungkan filter dan search dalam satu parameter
|
||||||
|
const combinedSearch = `${filterValue}|${searchValue}`;
|
||||||
|
|
||||||
|
// Log untuk debugging
|
||||||
|
console.log('Filter jenis penilaian:', filterValue);
|
||||||
|
console.log('Search value:', searchValue);
|
||||||
|
console.log('Combined search:', combinedSearch);
|
||||||
|
|
||||||
|
// Gunakan search method seperti di districts
|
||||||
|
dataTable.search(combinedSearch, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update search input handler untuk mendukung filter
|
||||||
|
*/
|
||||||
|
searchInput.addEventListener('input', function() {
|
||||||
|
const searchValue = this.value.trim();
|
||||||
|
const filterValue = filterJenisPenilaian.value;
|
||||||
|
|
||||||
|
// Gabungkan search dan filter
|
||||||
|
const combinedSearch = `${filterValue}|${searchValue}`;
|
||||||
|
|
||||||
|
// Log untuk debugging
|
||||||
|
console.log('Search input:', searchValue);
|
||||||
|
console.log('Current filter:', filterValue);
|
||||||
|
console.log('Combined search:', combinedSearch);
|
||||||
|
|
||||||
|
dataTable.search(combinedSearch, true);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
375
resources/views/memo/pdf-template.blade.php
Normal file
375
resources/views/memo/pdf-template.blade.php
Normal file
@@ -0,0 +1,375 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Memo Penyelesaian - {{ $memoData['memo_number'] }}</title>
|
||||||
|
<style>
|
||||||
|
@page {
|
||||||
|
margin: 20mm;
|
||||||
|
size: A4;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Times New Roman', serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
color: #000;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 53.55px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-title {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-info {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-info table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-info td {
|
||||||
|
padding: 2px 0;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-info .label {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-info .colon {
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-content {
|
||||||
|
text-align: justify;
|
||||||
|
margin: 20px 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-content table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-content td {
|
||||||
|
padding: 2px 0;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-content .label {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-content .colon {
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-section {
|
||||||
|
margin-top: 60px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-box {
|
||||||
|
text-align: center;
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-line {
|
||||||
|
border-bottom: 1px solid #000;
|
||||||
|
width: 120px;
|
||||||
|
height: 80px;
|
||||||
|
margin: 0 auto 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lampiran-section {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lampiran-list {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lampiran-list li {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-break {
|
||||||
|
page-break-before: always;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lampiran-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lampiran-subtitle {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
margin: 8px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lampiran-memo {
|
||||||
|
font-size: 11px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 8px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lampiran-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lampiran-table th,
|
||||||
|
.lampiran-table td {
|
||||||
|
border: 1px solid #000;
|
||||||
|
padding: 6px;
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lampiran-table th {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lampiran-table tfoot td {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-weight-500 {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-size-11 {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid #000;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<!-- Halaman Memo Utama -->
|
||||||
|
<div class="header">
|
||||||
|
<img src="{{ public_path('assets/media/images/logo-arthagraha.png') }}" alt="Logo Bank" class="logo">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="memo-title">
|
||||||
|
<strong>Memo Instruksi Penyelesaian</strong> Rekening Escrow / <strong>KSL Penilai Jaminan</strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="memo-info">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td class="label">Kepada</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td>SUBDIT E-Channel Support & Operation (NOC)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label">Dari</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td>SUBDIT Appraisal</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label">Nomor</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td><strong>{{ $memoData['memo_number'] }}</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label">Tanggal</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td>{{ \Carbon\Carbon::parse($memoData['memo_date'])->format('d F Y') }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label">Perihal</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td>Penyelesaian Rekening Escrow / <strong>KSL Penilai Jaminan (PJ)</strong></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="memo-content">
|
||||||
|
<p style="margin-bottom: 16px;">Sehubungan dengan telah dilakukannya penilaian jaminan dengan keterangan sbb :
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td class="label">Nama Debitur</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td>Terlampir ({{ $memoData['debitur_count'] }} Debitur)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label">Jaminan</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td>Tanah & Bangunan</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label">Total Biaya PJ</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td><strong>Rp {{ number_format($memoData['total_biaya_pj'], 0, ',', '.') }},-</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td class="font-size-11">({{ terbilang($memoData['total_biaya_pj']) }} Rupiah)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label">Pembayaran Tanggal</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td>{{ \Carbon\Carbon::parse($memoData['payment_date'])->format('d F Y') }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label">LPJ selesai dikirim</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td>-</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label">Jenis Penilaian</td>
|
||||||
|
<td class="colon">:</td>
|
||||||
|
<td><strong>
|
||||||
|
@if ($memoData['jenisPenilaian'] == 2)
|
||||||
|
KJPP
|
||||||
|
@else
|
||||||
|
Internal
|
||||||
|
@endif
|
||||||
|
</strong></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-bottom: 16px;">Kami menginstruksikan kepada Sentra Operasi untuk menyelesaikan Rekening Escrow
|
||||||
|
/ <strong>KSL Penilai Jaminan</strong> atas nama debitur tersebut diatas ke
|
||||||
|
|
||||||
|
@if ($memoData['jenisPenilaian'] == 2)
|
||||||
|
<strong>KJPP (terlampir)</strong>.
|
||||||
|
@else
|
||||||
|
<strong>PDPT-Lainnya Penilaian Jaminan KPNO (IDR 57557)</strong>.
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="margin-bottom: 16px;">Demikian kami sampaikan, atas perhatian dan kerjasamanya kami ucapkan terima
|
||||||
|
kasih.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="signature-section">
|
||||||
|
<table style="width: 100%; border-collapse: collapse; margin-top: 0px;">
|
||||||
|
<tr>
|
||||||
|
<td style="width: 33.33%; text-align: center; vertical-align: top; padding: 0 10px;">
|
||||||
|
<p style="margin-bottom: 40px;">Salam</p>
|
||||||
|
<div style="border-bottom: 1px solid #000; width: 120px; height: 40px; margin: 0 auto 8px;"></div>
|
||||||
|
<p style="font-weight: 500; margin: 0;">Innawati Sulina</p>
|
||||||
|
<p style="font-size: 11px; margin: 0;">DD Operation 2</p>
|
||||||
|
</td>
|
||||||
|
<td style="width: 33.33%; text-align: center; vertical-align: top; padding: 0 10px;">
|
||||||
|
<p style="margin-bottom: 40px;"> </p>
|
||||||
|
<div style="border-bottom: 1px solid #000; width: 120px; height: 40px; margin: 0 auto 8px;"></div>
|
||||||
|
<p style="font-weight: 500; margin: 0;">Wahab N. Wibawa</p>
|
||||||
|
<p style="font-size: 11px; margin: 0;">Pgs EO Subdit Appraisal</p>
|
||||||
|
</td>
|
||||||
|
<td style="width: 33.33%; text-align: center; vertical-align: top; padding: 0 10px;">
|
||||||
|
<p style="margin-bottom: 40px;"> </p>
|
||||||
|
<div style="border-bottom: 1px solid #000; width: 120px; height: 40px; margin: 0 auto 8px;"></div>
|
||||||
|
<p style="font-weight: 500; margin: 0;">Sumurung P. Siahaan</p>
|
||||||
|
<p style="font-size: 11px; margin: 0;"> </p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="lampiran-section">
|
||||||
|
<p class="font-weight-500" style="margin-bottom: 8px;">Lampiran :</p>
|
||||||
|
<ul class="lampiran-list">
|
||||||
|
<li>Rekap permohonan penyelesaian biaya KJPP (Eksternal)</li>
|
||||||
|
<li>Asli Invoice & Faktur Pajak KJPP (Eksternal)</li>
|
||||||
|
<li>Copy Tiket Debet (KSL)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Halaman Lampiran -->
|
||||||
|
<div class="page-break">
|
||||||
|
<div class="lampiran-title">LAMPIRAN</div>
|
||||||
|
<div class="lampiran-subtitle">REKAP PERMOHONAN PENYELESAIAN BIAYA KJPP</div>
|
||||||
|
<p class="lampiran-memo">Memo No: {{ $memoData['memo_number'] }}</p>
|
||||||
|
|
||||||
|
<table class="lampiran-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>No</th>
|
||||||
|
<th>Nomor Registrasi</th>
|
||||||
|
<th>Debitur</th>
|
||||||
|
<th>Cabang</th>
|
||||||
|
<th>AO</th>
|
||||||
|
<th>Tujuan Penilaian</th>
|
||||||
|
<th>Biaya PJ</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($permohonanList as $index => $permohonan)
|
||||||
|
<tr>
|
||||||
|
<td class="text-center">{{ $index + 1 }}</td>
|
||||||
|
<td class="font-weight-500">{{ $permohonan->nomor_registrasi }}</td>
|
||||||
|
<td>{{ $permohonan->debiture->name ?? '-' }}</td>
|
||||||
|
<td>{{ $permohonan->branch->name ?? '-' }}</td>
|
||||||
|
<td>{{ $permohonan->user->name ?? '-' }}</td>
|
||||||
|
<td>{{ $permohonan->tujuanPenilaian->name ?? '-' }}</td>
|
||||||
|
<td class="text-right font-weight-500">Rp
|
||||||
|
{{ number_format($permohonan->noc->nominal_bayar ?? 0, 0, ',', '.') }}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="font-bold text-right">Total Biaya PJ:</td>
|
||||||
|
<td class="font-bold text-right">Rp {{ number_format($totalBiayaPJ, 0, ',', '.') }}</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
373
resources/views/memo/preview.blade.php
Normal file
373
resources/views/memo/preview.blade.php
Normal file
@@ -0,0 +1,373 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('memo.create') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="w-full">
|
||||||
|
<!-- Preview Memo Penyelesaian -->
|
||||||
|
<div class="bg-white">
|
||||||
|
<!-- Header Controls - Hidden saat print -->
|
||||||
|
<div class="p-4 border-b bg-agi-50 no-print">
|
||||||
|
<div class="flex justify-between items-center mx-auto">
|
||||||
|
<h3 class="text-lg font-semibold text-gray-800">
|
||||||
|
Preview Memo Penyelesaian
|
||||||
|
</h3>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<button onclick="history.back()" class="btn btn-sm btn-light">
|
||||||
|
<i class="ki-filled ki-black-left"></i>
|
||||||
|
Kembali Edit
|
||||||
|
</button>
|
||||||
|
<button type="button" onclick="window.print()" class="btn btn-sm btn-secondary">
|
||||||
|
<i class="ki-filled ki-printer"></i>
|
||||||
|
Print Preview
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (session('error'))
|
||||||
|
<div class="m-4 no-print alert alert-danger">
|
||||||
|
{{ session('error') }}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<!-- Halaman 1: Memo Utama -->
|
||||||
|
<div class="p-5 w-full bg-white page-memo">
|
||||||
|
<!-- Header Bank -->
|
||||||
|
<div class="flex items-center mb-3">
|
||||||
|
<img class="default-logo min-h-[22px] max-w-none" style="height: 53.55px;"
|
||||||
|
src="assets/media/images/logo-arthagraha.png" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Judul Memo -->
|
||||||
|
<div class="mb-8 text-left">
|
||||||
|
<h4 class="text-base font-semibold" style="margin: 0;"><strong>Memo Instruksi Penyelesaian</strong>
|
||||||
|
Rekening Escrow / <strong>KSL Penilai Jaminan</strong></h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informasi Memo -->
|
||||||
|
<div class="mb-8">
|
||||||
|
<table style="width: 100%; border-collapse: collapse;">
|
||||||
|
<tr>
|
||||||
|
<td style="width: 80px; padding: 2px 0; vertical-align: top;">Kepada</td>
|
||||||
|
<td style="width: 10px; padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">SUBDIT E-Channel Support & Operation (NOC)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Dari</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">SUBDIT Appraisal</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Nomor</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;"><strong>{{ $memoData['memo_number'] }}</strong>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Tanggal</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">
|
||||||
|
{{ dateFormat($memoData['memo_date']) }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Perihal</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Penyelesaian Rekening Escrow / <strong>KSL
|
||||||
|
Penilai Jaminan (PJ)</strong></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr style="border: none; border-top: 1px solid #000; margin: 20px 0;">
|
||||||
|
|
||||||
|
<!-- Isi Memo -->
|
||||||
|
<div class="mb-8">
|
||||||
|
<p style="margin-bottom: 16px; text-align: justify;">Sehubungan dengan telah dilakukannya penilaian
|
||||||
|
jaminan dengan keterangan sbb :</p>
|
||||||
|
|
||||||
|
<table style="width: 100%; border-collapse: collapse; margin-bottom: 16px;">
|
||||||
|
<tr>
|
||||||
|
<td style="width: 200px; padding: 2px 0; vertical-align: top;">Nama Debitur</td>
|
||||||
|
<td style="width: 10px; padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Terlampir ({{ $memoData['debitur_count'] }}
|
||||||
|
Debitur)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Jaminan</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Tanah & Bangunan</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Total Biaya PJ</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;"><strong>Rp
|
||||||
|
{{ number_format($memoData['total_biaya_pj'], 0, ',', '.') }},-</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top; font-size: 11pt;">
|
||||||
|
({{ terbilang($memoData['total_biaya_pj']) }} Rupiah)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Pembayaran Tanggal</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">
|
||||||
|
{{ \Carbon\Carbon::parse($memoData['payment_date'])->format('d F Y') }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">LPJ selesai dikirim</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">-</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">Jenis Penilaian</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">:</td>
|
||||||
|
<td style="padding: 2px 0; vertical-align: top;">
|
||||||
|
<strong>
|
||||||
|
@if ($memoData['jenisPenilaian'] == 2)
|
||||||
|
KJPP
|
||||||
|
@else
|
||||||
|
Internal
|
||||||
|
@endif
|
||||||
|
</strong>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-bottom: 16px; text-align: justify;">
|
||||||
|
Kami menginstruksikan kepada Sentra Operasi untuk menyelesaikan Rekening Escrow /
|
||||||
|
<strong>KSL Penilai Jaminan</strong> atas nama debitur tersebut diatas ke
|
||||||
|
|
||||||
|
@if ($memoData['jenisPenilaian'] == 2)
|
||||||
|
<strong>KJPP (terlampir)</strong>.
|
||||||
|
@else
|
||||||
|
<strong>PDPT-Lainnya Penilaian Jaminan KPNO (IDR 57557)</strong>.
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="margin-bottom: 16px; text-align: justify;">Demikian kami sampaikan, atas perhatian dan
|
||||||
|
kerjasamanya kami ucapkan terima kasih.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tanda Tangan -->
|
||||||
|
<div style="display: flex; justify-content: space-between; margin-top: 60px;">
|
||||||
|
<div style="text-align: center; width: 30%;">
|
||||||
|
<p style="margin-bottom: 80px;">Salam</p>
|
||||||
|
<div style="border-bottom: 1px solid #000; margin: 0 auto 8px; width: 120px;"></div>
|
||||||
|
<p style="font-weight: 500; margin: 0;">Innawati Sulina</p>
|
||||||
|
<p style="font-size: 11pt; margin: 0;">DD Operation 2</p>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: center; width: 30%;">
|
||||||
|
<p style="margin-bottom: 80px;"> </p>
|
||||||
|
<div style="border-bottom: 1px solid #000; margin: 0 auto 8px; width: 120px;"></div>
|
||||||
|
<p style="font-weight: 500; margin: 0;">Wahab N. Wibawa</p>
|
||||||
|
<p style="font-size: 11pt; margin: 0;">Pgs EO Subdit Appraisal</p>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: center; width: 30%;">
|
||||||
|
<p style="margin-bottom: 80px;"> </p>
|
||||||
|
<div style="border-bottom: 1px solid #000; margin: 0 auto 8px; width: 120px;"></div>
|
||||||
|
<p style="font-weight: 500; margin: 0;">Sumurung P. Siahaan</p>
|
||||||
|
<p style="font-size: 11pt; margin: 0;"> </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Lampiran -->
|
||||||
|
<div style="margin-top: 40px;">
|
||||||
|
<p style="font-weight: 500; margin-bottom: 8px;">Lampiran :</p>
|
||||||
|
<ul style="margin: 0; padding-left: 20px; font-size: 11pt;">
|
||||||
|
<li style="margin-bottom: 4px;">Rekap permohonan penyelesaian biaya KJPP (Eksternal)</li>
|
||||||
|
<li style="margin-bottom: 4px;">Asli Invoice & Faktur Pajak KJPP (Eksternal)</li>
|
||||||
|
<li style="margin-bottom: 4px;">Copy Tiket Debet (KSL)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Halaman 2: Lampiran Daftar Permohonan -->
|
||||||
|
<div class="p-5 w-full bg-white page-lampiran">
|
||||||
|
<div style="text-align: center; margin-bottom: 30px;">
|
||||||
|
<h3 style="font-weight: bold; margin: 0; font-size: 14pt;">LAMPIRAN</h3>
|
||||||
|
<h4 style="font-weight: bold; margin: 8px 0 0 0; font-size: 13pt;">REKAP PERMOHONAN PENYELESAIAN BIAYA
|
||||||
|
KJPP</h4>
|
||||||
|
<p style="margin: 8px 0 0 0; font-size: 11pt;">Memo No: {{ $memoData['memo_number'] }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="overflow-x: auto;">
|
||||||
|
<table style="width: 100%; border-collapse: collapse; font-size: 10pt;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background-color: #f8f9fa;">
|
||||||
|
<th style="border: 1px solid #000; padding: 8px; text-align: center; font-weight: bold;">No
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid #000; padding: 8px; text-align: left; font-weight: bold;">Nomor
|
||||||
|
Registrasi</th>
|
||||||
|
<th style="border: 1px solid #000; padding: 8px; text-align: left; font-weight: bold;">
|
||||||
|
Debitur</th>
|
||||||
|
<th style="border: 1px solid #000; padding: 8px; text-align: left; font-weight: bold;">
|
||||||
|
Cabang</th>
|
||||||
|
<th style="border: 1px solid #000; padding: 8px; text-align: left; font-weight: bold;">AO
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid #000; padding: 8px; text-align: left; font-weight: bold;">
|
||||||
|
Tujuan Penilaian</th>
|
||||||
|
<th style="border: 1px solid #000; padding: 8px; text-align: right; font-weight: bold;">
|
||||||
|
Biaya PJ</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($permohonanList as $index => $permohonan)
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid #000; padding: 6px; text-align: center;">
|
||||||
|
{{ $index + 1 }}</td>
|
||||||
|
<td style="border: 1px solid #000; padding: 6px; font-weight: 500;">
|
||||||
|
{{ $permohonan->nomor_registrasi }}</td>
|
||||||
|
<td style="border: 1px solid #000; padding: 6px;">
|
||||||
|
{{ $permohonan->debiture->name ?? '-' }}</td>
|
||||||
|
<td style="border: 1px solid #000; padding: 6px;">
|
||||||
|
{{ $permohonan->branch->name ?? '-' }}</td>
|
||||||
|
<td style="border: 1px solid #000; padding: 6px;">{{ $permohonan->user->name ?? '-' }}
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid #000; padding: 6px;">
|
||||||
|
@if ($permohonan->tujuanPenilaian)
|
||||||
|
{{ $permohonan->tujuanPenilaian->name }}
|
||||||
|
@else
|
||||||
|
-
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid #000; padding: 6px; text-align: right; font-weight: 500;">
|
||||||
|
Rp {{ number_format($permohonan->noc->nominal_bayar ?? 0, 0, ',', '.') }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr style="background-color: #f8f9fa; font-weight: bold;">
|
||||||
|
<td colspan="6"
|
||||||
|
style="border: 1px solid #000; padding: 8px; text-align: right; font-weight: bold;">
|
||||||
|
Total Biaya PJ:</td>
|
||||||
|
<td style="border: 1px solid #000; padding: 8px; text-align: right; font-weight: bold;">Rp
|
||||||
|
{{ number_format($totalBiayaPJ, 0, ',', '.') }}</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Form untuk Generate PDF - Hidden saat print -->
|
||||||
|
<div class="p-4 bg-gray-50 border-t no-print">
|
||||||
|
<form action="{{ route('memo.generate-pdf') }}" method="POST" id="generate-form" class="mx-auto">
|
||||||
|
@csrf
|
||||||
|
@foreach ($permohonanList as $permohonan)
|
||||||
|
<input type="hidden" name="permohonan_ids[]" value="{{ $permohonan->id }}">
|
||||||
|
@endforeach
|
||||||
|
<input type="hidden" name="memo_number" value="{{ $memoData['memo_number'] }}">
|
||||||
|
<input type="hidden" name="memo_date" value="{{ $memoData['memo_date'] }}">
|
||||||
|
<input type="hidden" name="payment_date" value="{{ $memoData['payment_date'] }}">
|
||||||
|
|
||||||
|
<div class="flex gap-2 justify-end">
|
||||||
|
<button type="submit" class="btn btn-primary" id="generate-btn">
|
||||||
|
<i class="ki-filled ki-file-down"></i>
|
||||||
|
Generate PDF & Simpan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const generateForm = document.getElementById('generate-form');
|
||||||
|
const generateBtn = document.getElementById('generate-btn');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event listener untuk form generate PDF
|
||||||
|
*/
|
||||||
|
if (generateForm) {
|
||||||
|
generateForm.addEventListener('submit', function(e) {
|
||||||
|
// Konfirmasi sebelum generate
|
||||||
|
const confirmed = confirm(
|
||||||
|
'Apakah Anda yakin ingin generate PDF dan menyimpan memo penyelesaian ini?'
|
||||||
|
);
|
||||||
|
if (!confirmed) {
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable submit button untuk mencegah double submit
|
||||||
|
if (generateBtn) {
|
||||||
|
generateBtn.disabled = true;
|
||||||
|
generateBtn.innerHTML = '<i class="ki-filled ki-loading"></i> Memproses...';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@push('styles')
|
||||||
|
<style>
|
||||||
|
/* Print Styles */
|
||||||
|
@media print {
|
||||||
|
* {
|
||||||
|
-webkit-print-color-adjust: exact !important;
|
||||||
|
color-adjust: exact !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
background: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-print {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-memo,
|
||||||
|
.page-lampiran {
|
||||||
|
width: 210mm !important;
|
||||||
|
min-height: 297mm !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 20mm !important;
|
||||||
|
page-break-after: always;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-lampiran {
|
||||||
|
page-break-before: always !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure table borders print correctly */
|
||||||
|
table,
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
border-collapse: collapse !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
border: 1px solid #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure background colors print */
|
||||||
|
.bg-gray-50,
|
||||||
|
tr[style*="background-color: #f8f9fa"] {
|
||||||
|
background-color: #f8f9fa !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Screen Styles */
|
||||||
|
@media screen {
|
||||||
|
|
||||||
|
.page-memo,
|
||||||
|
.page-lampiran {
|
||||||
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endpush
|
||||||
313
resources/views/memo/show.blade.php
Normal file
313
resources/views/memo/show.blade.php
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('memo.show') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">
|
||||||
|
Detail Memo Penyelesaian
|
||||||
|
</h3>
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
<a href="{{ route('memo.index') }}" class="btn btn-sm btn-light">
|
||||||
|
<i class="ki-filled ki-black-left"></i>
|
||||||
|
Kembali
|
||||||
|
</a>
|
||||||
|
<button onclick="window.print()" class="btn btn-sm btn-primary">
|
||||||
|
<i class="ki-filled ki-printer"></i>
|
||||||
|
Cetak
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Detail Memo -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="bg-gray-50 card-header">
|
||||||
|
<h4 class="text-lg card-title">
|
||||||
|
Informasi Memo Penyelesaian
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid grid-cols-1 gap-6 mb-8 lg:grid-cols-2">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Judul Memo:</label>
|
||||||
|
<p class="mt-1 font-semibold text-gray-900">
|
||||||
|
{{ $permohonan->memo_penyelesaian_title ?? 'Belum ada memo' }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Tanggal Memo:</label>
|
||||||
|
<p class="mt-1 text-gray-900">
|
||||||
|
@if ($permohonan->memo_penyelesaian_date)
|
||||||
|
{{ \Carbon\Carbon::parse($permohonan->memo_penyelesaian_date)->format('d F Y') }}
|
||||||
|
@else
|
||||||
|
-
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Status:</label>
|
||||||
|
<p class="mt-1">
|
||||||
|
@if ($permohonan->status === 'memo-penyelesaian')
|
||||||
|
<span class="uppercase badge badge-success">{{ $permohonan->status }}</span>
|
||||||
|
@else
|
||||||
|
<span class="uppercase badge badge-warning">{{ $permohonan->status }}</span>
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Dibuat Pada:</label>
|
||||||
|
<p class="mt-1 text-gray-900">
|
||||||
|
@if ($permohonan->memo_penyelesaian_created_at)
|
||||||
|
{{ \Carbon\Carbon::parse($permohonan->memo_penyelesaian_created_at)->format('d F Y H:i') }}
|
||||||
|
@else
|
||||||
|
-
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if ($permohonan->memo_penyelesaian_content)
|
||||||
|
<div class="mb-8">
|
||||||
|
<label class="block mb-3 text-sm font-medium text-gray-600">Isi Memo:</label>
|
||||||
|
<div class="p-4 bg-gray-50 rounded-lg border">
|
||||||
|
<div class="max-w-none prose">
|
||||||
|
{!! nl2br(e($permohonan->memo_penyelesaian_content)) !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Detail Permohonan -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="bg-blue-50 card-header">
|
||||||
|
<h4 class="text-lg card-title">
|
||||||
|
Detail Permohonan
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Nomor Registrasi:</label>
|
||||||
|
<p class="mt-1 font-semibold text-gray-900">{{ $permohonan->nomor_registrasi }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Debitur:</label>
|
||||||
|
<p class="mt-1 text-gray-900">{{ $permohonan->debiture->name ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Cabang/Direktorat:</label>
|
||||||
|
<p class="mt-1 text-gray-900">{{ $permohonan->branch->name ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Account Officer:</label>
|
||||||
|
<p class="mt-1 text-gray-900">{{ $permohonan->user->name ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Tujuan Penilaian:</label>
|
||||||
|
<p class="mt-1">
|
||||||
|
@if ($permohonan->tujuanPenilaian)
|
||||||
|
<span class="badge badge-primary">{{ $permohonan->tujuanPenilaian->name }}</span>
|
||||||
|
@else
|
||||||
|
-
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Fasilitas Kredit:</label>
|
||||||
|
<p class="mt-1 text-gray-900">{{ $permohonan->jenisFasilitasKredit->name ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Tanggal Permohonan:</label>
|
||||||
|
<p class="mt-1 text-gray-900">
|
||||||
|
@if ($permohonan->tanggal_permohonan)
|
||||||
|
{{ \Carbon\Carbon::parse($permohonan->tanggal_permohonan)->format('d F Y') }}
|
||||||
|
@else
|
||||||
|
-
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if ($permohonan->nilai_liquidasi)
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Nilai Liquidasi:</label>
|
||||||
|
<p class="mt-1 font-semibold text-gray-900">
|
||||||
|
Rp {{ number_format($permohonan->nilai_liquidasi, 0, ',', '.') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informasi Penilaian -->
|
||||||
|
@if ($permohonan->penilaian)
|
||||||
|
<div class="card">
|
||||||
|
<div class="bg-green-50 card-header">
|
||||||
|
<h4 class="text-lg card-title">
|
||||||
|
Informasi Penilaian
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
||||||
|
<div class="space-y-4">
|
||||||
|
@if ($permohonan->penilaian->waktu_penilaian)
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Waktu Penilaian:</label>
|
||||||
|
<p class="mt-1 text-gray-900">
|
||||||
|
{{ \Carbon\Carbon::parse($permohonan->penilaian->waktu_penilaian)->format('d F Y H:i') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($permohonan->penilai)
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Tipe Penilai:</label>
|
||||||
|
<p class="mt-1">
|
||||||
|
<span
|
||||||
|
class="uppercase badge badge-info">{{ $permohonan->penilai->type_penilai ?? '-' }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
@if ($permohonan->penilaian->created_at)
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Dibuat Pada:</label>
|
||||||
|
<p class="mt-1 text-gray-900">
|
||||||
|
{{ \Carbon\Carbon::parse($permohonan->penilaian->created_at)->format('d F Y H:i') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<!-- Informasi Approval -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="bg-yellow-50 card-header">
|
||||||
|
<h4 class="text-lg card-title">
|
||||||
|
Status Approval
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
||||||
|
<div class="p-4 text-center rounded-lg border">
|
||||||
|
<div class="mb-2">
|
||||||
|
@if ($permohonan->approval_so_at)
|
||||||
|
<i class="text-3xl text-green-500 ki-filled ki-check-circle"></i>
|
||||||
|
@else
|
||||||
|
<i class="text-3xl text-gray-400 ki-filled ki-time"></i>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<h5 class="font-semibold text-gray-900">Senior Officer</h5>
|
||||||
|
<p class="mt-1 text-sm text-gray-600">
|
||||||
|
@if ($permohonan->approval_so_at)
|
||||||
|
Disetujui pada<br>
|
||||||
|
{{ \Carbon\Carbon::parse($permohonan->approval_so_at)->format('d F Y H:i') }}
|
||||||
|
@else
|
||||||
|
Menunggu Persetujuan
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4 text-center rounded-lg border">
|
||||||
|
<div class="mb-2">
|
||||||
|
@if ($permohonan->approval_eo_at)
|
||||||
|
<i class="text-3xl text-green-500 ki-filled ki-check-circle"></i>
|
||||||
|
@else
|
||||||
|
<i class="text-3xl text-gray-400 ki-filled ki-time"></i>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<h5 class="font-semibold text-gray-900">Executive Officer</h5>
|
||||||
|
<p class="mt-1 text-sm text-gray-600">
|
||||||
|
@if ($permohonan->approval_eo_at)
|
||||||
|
Disetujui pada<br>
|
||||||
|
{{ \Carbon\Carbon::parse($permohonan->approval_eo_at)->format('d F Y H:i') }}
|
||||||
|
@else
|
||||||
|
Menunggu Persetujuan
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4 text-center rounded-lg border">
|
||||||
|
<div class="mb-2">
|
||||||
|
@if ($permohonan->approval_dd_at)
|
||||||
|
<i class="text-3xl text-green-500 ki-filled ki-check-circle"></i>
|
||||||
|
@else
|
||||||
|
<i class="text-3xl text-gray-400 ki-filled ki-time"></i>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<h5 class="font-semibold text-gray-900">Deputy Director</h5>
|
||||||
|
<p class="mt-1 text-sm text-gray-600">
|
||||||
|
@if ($permohonan->approval_dd_at)
|
||||||
|
Disetujui pada<br>
|
||||||
|
{{ \Carbon\Carbon::parse($permohonan->approval_dd_at)->format('d F Y H:i') }}
|
||||||
|
@else
|
||||||
|
Menunggu Persetujuan
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('styles')
|
||||||
|
<style>
|
||||||
|
@media print {
|
||||||
|
|
||||||
|
.btn,
|
||||||
|
.card-header .flex {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
box-shadow: none !important;
|
||||||
|
border: 1px solid #e5e7eb !important;
|
||||||
|
margin-bottom: 1rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 16px !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endpush
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
<input type="hidden" name="persetujuan_penawaran_id"
|
<input type="hidden" name="persetujuan_penawaran_id"
|
||||||
value="{{ $persetujuanPenawaran->id ?? old('persetujuan_penawaran_id') }}">
|
value="{{ $persetujuanPenawaran->id ?? old('persetujuan_penawaran_id') }}">
|
||||||
<input type="hidden" name="permohonan_id"
|
<input type="hidden" name="permohonan_id"
|
||||||
value="{{ $persetujuanPenawaran->penawaran->permohonan->id ?? $persetujuanPenawaran->permohonan->id }}">
|
value="{{ $persetujuanPenawaran?->penawaran?->permohonan?->id ?? $persetujuanPenawaran?->permohonan?->id }}">
|
||||||
|
|
||||||
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
@@ -50,10 +50,17 @@
|
|||||||
name="status_pembayar" id="status_pembayar" {{ $hasMemo ? 'disabled' : '' }}>
|
name="status_pembayar" id="status_pembayar" {{ $hasMemo ? 'disabled' : '' }}>
|
||||||
<option value="">Pilih Status Bayar</option>
|
<option value="">Pilih Status Bayar</option>
|
||||||
<option value="sudah_bayar"
|
<option value="sudah_bayar"
|
||||||
{{ old('status_pembayar') == 'sudah_bayar' || $persetujuanPenawaran?->penawaran?->permohonan?->status_bayar == 'sudah_bayar' ? 'selected' : '' }}>
|
{{ old('status_pembayar') == 'sudah_bayar' ||
|
||||||
|
$persetujuanPenawaran?->penawaran?->permohonan?->status_bayar == 'sudah_bayar' ||
|
||||||
|
$persetujuanPenawaran?->nomor_tiket
|
||||||
|
? 'selected'
|
||||||
|
: '' }}>
|
||||||
Sudah Bayar</option>
|
Sudah Bayar</option>
|
||||||
<option value="belum_bayar"
|
<option value="belum_bayar"
|
||||||
{{ old('status_pembayar') == 'belum_bayar' || $persetujuanPenawaran?->penawaran?->permohonan?->status_bayar == 'belum_bayar' ? 'selected' : '' }}>
|
{{ old('status_pembayar') == 'belum_bayar' ||
|
||||||
|
($persetujuanPenawaran?->penawaran?->permohonan?->status_bayar == 'belum_bayar' && !$persetujuanPenawaran?->nomor_tiket)
|
||||||
|
? 'selected'
|
||||||
|
: '' }}>
|
||||||
Belum Bayar</option>
|
Belum Bayar</option>
|
||||||
</select>
|
</select>
|
||||||
@error('status_bayar')
|
@error('status_bayar')
|
||||||
@@ -80,7 +87,7 @@
|
|||||||
|
|
||||||
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
Nominal Bayar
|
Jumlah Yang Harus Disetor
|
||||||
</label>
|
</label>
|
||||||
<div class="flex flex-wrap items-baseline w-full">
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
<input type="number" name="total_harus_bayar" id="total_harus_bayar"
|
<input type="number" name="total_harus_bayar" id="total_harus_bayar"
|
||||||
@@ -95,7 +102,7 @@
|
|||||||
|
|
||||||
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
Nominal Diterima
|
Jumlah Yang Disetor
|
||||||
</label>
|
</label>
|
||||||
<div class="flex flex-wrap items-baseline w-full">
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
<input type="number" name="nominal_bayar" id="nominal_bayar"
|
<input type="number" name="nominal_bayar" id="nominal_bayar"
|
||||||
@@ -108,6 +115,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Jumlah Pembukuan
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="number" name="total_pembukuan" id="total_pembukuan"
|
||||||
|
class="input w-full @error('total_pembukuan') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('total_pembukuan', $persetujuanPenawaran->noc->total_pembukuan ?? '') }}"
|
||||||
|
placeholder="Masukkan total pembukuan" {{ $hasMemo ? 'readonly' : '' }}>
|
||||||
|
@error('total_pembukuan')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
Tanggal Pembayaran
|
Tanggal Pembayaran
|
||||||
@@ -124,6 +146,112 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Field Status Kurang Bayar -->
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Status Kurang Bayar
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<div class="flex gap-4 items-center">
|
||||||
|
<label class="checkbox-group">
|
||||||
|
<input class="checkbox checkbox-sm" name="status_kurang_bayar" id="status_kurang_bayar"
|
||||||
|
value="1" type="checkbox"
|
||||||
|
{{ old('status_kurang_bayar', $persetujuanPenawaran->noc->status_kurang_bayar ?? false) ? 'checked' : '' }}
|
||||||
|
{{ $hasMemo ? 'disabled' : '' }}>
|
||||||
|
<span class="checkbox-label">
|
||||||
|
Ya, ada kurang bayar
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
@error('status_kurang_bayar')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Field Nominal Kurang Bayar -->
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap" id="nominal_kurang_bayar_section"
|
||||||
|
style="display: none;">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Nominal Kurang Bayar
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="number" name="nominal_kurang_bayar" id="nominal_kurang_bayar"
|
||||||
|
class="input w-full @error('nominal_kurang_bayar') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('nominal_kurang_bayar', $persetujuanPenawaran->noc->nominal_kurang_bayar ?? '') }}"
|
||||||
|
placeholder="Masukkan nominal kurang bayar" {{ $hasMemo ? 'readonly' : '' }}>
|
||||||
|
@error('nominal_kurang_bayar')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Field Status Lebih Bayar -->
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Status Lebih Bayar
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<div class="flex gap-4 items-center">
|
||||||
|
<label class="checkbox-group">
|
||||||
|
<input class="checkbox checkbox-sm" name="status_lebih_bayar" id="status_lebih_bayar"
|
||||||
|
value="1" type="checkbox"
|
||||||
|
{{ old('status_lebih_bayar', $persetujuanPenawaran->noc->status_lebih_bayar ?? false) ? 'checked' : '' }}
|
||||||
|
{{ $hasMemo ? 'disabled' : '' }}>
|
||||||
|
<span class="checkbox-label">Ya, ada lebih bayar </span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
@error('status_lebih_bayar')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Field Nominal Lebih Bayar -->
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap" id="nominal_lebih_bayar_section"
|
||||||
|
style="display: none;">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Nominal Lebih Bayar
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="number" name="nominal_lebih_bayar" id="nominal_lebih_bayar"
|
||||||
|
class="input w-full @error('nominal_lebih_bayar') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('nominal_lebih_bayar', $persetujuanPenawaran->noc->nominal_lebih_bayar ?? '') }}"
|
||||||
|
placeholder="Masukkan nominal lebih bayar" {{ $hasMemo ? 'readonly' : '' }}>
|
||||||
|
@error('nominal_lebih_bayar')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Field Bukti Pengembalian -->
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap" id="bukti_pengembalian_section"
|
||||||
|
style="display: none;">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Bukti Pengembalian
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
@if (!$hasMemo)
|
||||||
|
<input type="file" name="bukti_pengembalian" id="bukti_pengembalian"
|
||||||
|
class="file-input w-full @error('bukti_pengembalian') border-danger bg-danger-light @enderror"
|
||||||
|
accept=".pdf,.jpg,.jpeg,.png">
|
||||||
|
@error('bukti_pengembalian')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if (isset($persetujuanPenawaran->noc->bukti_pengembalian) && !empty($persetujuanPenawaran->noc->bukti_pengembalian))
|
||||||
|
<div class="flex items-center mt-2">
|
||||||
|
<a href="{{ Storage::url($persetujuanPenawaran->noc->bukti_pengembalian) }}"
|
||||||
|
target="_blank" class="badge badge-sm badge-outline badge-warning">
|
||||||
|
<i class="mr-2 ki-filled ki-eye"></i> Lihat File
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
Bukti KSL
|
Bukti KSL
|
||||||
@@ -259,3 +387,176 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
/**
|
||||||
|
* Fungsi untuk mengelola mutual exclusive selection antara kurang bayar dan lebih bayar
|
||||||
|
* Hanya satu status yang bisa dipilih pada satu waktu
|
||||||
|
*/
|
||||||
|
const statusKurangBayar = document.getElementById('status_kurang_bayar');
|
||||||
|
const statusLebihBayar = document.getElementById('status_lebih_bayar');
|
||||||
|
const nominalKurangBayarSection = document.getElementById('nominal_kurang_bayar_section');
|
||||||
|
const nominalLebihBayarSection = document.getElementById('nominal_lebih_bayar_section');
|
||||||
|
const buktiPengembalianSection = document.getElementById('bukti_pengembalian_section');
|
||||||
|
|
||||||
|
// Field untuk perbandingan nilai
|
||||||
|
const totalHarusBayar = document.getElementById('total_harus_bayar');
|
||||||
|
const nominalBayar = document.getElementById('nominal_bayar');
|
||||||
|
const totalPembukuan = document.getElementById('total_pembukuan');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fungsi untuk mengatur enable/disable status checkbox berdasarkan perbandingan nilai
|
||||||
|
* Logika:
|
||||||
|
* - Jika semua nilai sama: kedua checkbox disabled
|
||||||
|
* - Jika nominal_bayar/total_pembukuan < total_harus_bayar: hanya status_kurang_bayar enabled
|
||||||
|
* - Jika nominal_bayar/total_pembukuan > total_harus_bayar: hanya status_lebih_bayar enabled
|
||||||
|
*/
|
||||||
|
function updateCheckboxStatus() {
|
||||||
|
const totalHarus = parseFloat(totalHarusBayar.value) || 0;
|
||||||
|
const nominal = parseFloat(nominalBayar.value) || 0;
|
||||||
|
const pembukuan = parseFloat(totalPembukuan.value) || 0;
|
||||||
|
|
||||||
|
console.log('Updating checkbox status:', {
|
||||||
|
totalHarus,
|
||||||
|
nominal,
|
||||||
|
pembukuan
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reset checkbox states
|
||||||
|
statusKurangBayar.disabled = false;
|
||||||
|
statusLebihBayar.disabled = false;
|
||||||
|
|
||||||
|
// Jika semua nilai sama, disable kedua checkbox
|
||||||
|
if (totalHarus === nominal && nominal === pembukuan && totalHarus > 0) {
|
||||||
|
statusKurangBayar.disabled = true;
|
||||||
|
statusLebihBayar.disabled = true;
|
||||||
|
statusKurangBayar.checked = false;
|
||||||
|
statusLebihBayar.checked = false;
|
||||||
|
nominalKurangBayarSection.style.display = 'none';
|
||||||
|
nominalLebihBayarSection.style.display = 'none';
|
||||||
|
buktiPengembalianSection.style.display = 'none';
|
||||||
|
console.log('Semua nilai sama, kedua checkbox disabled');
|
||||||
|
}
|
||||||
|
// Jika nominal/pembukuan kurang dari total harus bayar
|
||||||
|
else if ((nominal > 0 && nominal < totalHarus) || (pembukuan > 0 && pembukuan < totalHarus)) {
|
||||||
|
statusLebihBayar.disabled = true;
|
||||||
|
statusLebihBayar.checked = false;
|
||||||
|
statusKurangBayar.checked = true;
|
||||||
|
nominalKurangBayarSection.style.display = '';
|
||||||
|
nominalLebihBayarSection.style.display = 'none';
|
||||||
|
buktiPengembalianSection.style.display = 'none';
|
||||||
|
console.log('Kurang bayar, hanya status_kurang_bayar enabled');
|
||||||
|
}
|
||||||
|
// Jika nominal/pembukuan lebih dari total harus bayar
|
||||||
|
else if ((nominal > 0 && nominal > totalHarus) || (pembukuan > 0 && pembukuan > totalHarus)) {
|
||||||
|
statusKurangBayar.disabled = true;
|
||||||
|
statusKurangBayar.checked = false;
|
||||||
|
statusLebihBayar.checked = true;
|
||||||
|
nominalLebihBayarSection.style.display = '';
|
||||||
|
nominalKurangBayarSection.style.display = 'none';
|
||||||
|
console.log('Lebih bayar, hanya status_lebih_bayar enabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listeners untuk update otomatis saat nilai berubah
|
||||||
|
if (nominalBayar) {
|
||||||
|
nominalBayar.addEventListener('input', updateCheckboxStatus);
|
||||||
|
nominalBayar.addEventListener('change', updateCheckboxStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalPembukuan) {
|
||||||
|
totalPembukuan.addEventListener('input', updateCheckboxStatus);
|
||||||
|
totalPembukuan.addEventListener('change', updateCheckboxStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial check saat halaman dimuat
|
||||||
|
updateCheckboxStatus();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fungsi untuk reset field dan section visibility
|
||||||
|
* @param {string} type - 'kurang' atau 'lebih'
|
||||||
|
*/
|
||||||
|
function resetFields(type) {
|
||||||
|
if (type === 'kurang') {
|
||||||
|
// Reset field lebih bayar
|
||||||
|
statusLebihBayar.checked = false;
|
||||||
|
nominalLebihBayarSection.style.display = 'none';
|
||||||
|
buktiPengembalianSection.style.display = 'none';
|
||||||
|
document.getElementById('nominal_lebih_bayar').value = '';
|
||||||
|
document.getElementById('bukti_pengembalian').value = '';
|
||||||
|
} else if (type === 'lebih') {
|
||||||
|
// Reset field kurang bayar
|
||||||
|
statusKurangBayar.checked = false;
|
||||||
|
nominalKurangBayarSection.style.display = 'none';
|
||||||
|
document.getElementById('nominal_kurang_bayar').value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler untuk status kurang bayar
|
||||||
|
* Menampilkan field nominal kurang bayar dan menyembunyikan field lebih bayar
|
||||||
|
*/
|
||||||
|
if (statusKurangBayar) {
|
||||||
|
// Set initial state
|
||||||
|
if (statusKurangBayar.checked) {
|
||||||
|
nominalKurangBayarSection.style.display = 'flex';
|
||||||
|
resetFields('kurang');
|
||||||
|
}
|
||||||
|
|
||||||
|
statusKurangBayar.addEventListener('change', function() {
|
||||||
|
// Cek apakah checkbox tidak disabled sebelum memproses
|
||||||
|
if (this.disabled) {
|
||||||
|
this.checked = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.checked) {
|
||||||
|
nominalKurangBayarSection.style.display = 'flex';
|
||||||
|
resetFields('kurang');
|
||||||
|
console.log('Status kurang bayar dipilih, field lebih bayar direset');
|
||||||
|
} else {
|
||||||
|
nominalKurangBayarSection.style.display = 'none';
|
||||||
|
document.getElementById('nominal_kurang_bayar').value = '';
|
||||||
|
console.log('Status kurang bayar dibatalkan');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler untuk status lebih bayar
|
||||||
|
* Menampilkan field nominal dan bukti pengembalian, menyembunyikan field kurang bayar
|
||||||
|
*/
|
||||||
|
if (statusLebihBayar) {
|
||||||
|
// Set initial state
|
||||||
|
if (statusLebihBayar.checked) {
|
||||||
|
nominalLebihBayarSection.style.display = 'flex';
|
||||||
|
buktiPengembalianSection.style.display = 'flex';
|
||||||
|
resetFields('lebih');
|
||||||
|
}
|
||||||
|
|
||||||
|
statusLebihBayar.addEventListener('change', function() {
|
||||||
|
// Cek apakah checkbox tidak disabled sebelum memproses
|
||||||
|
if (this.disabled) {
|
||||||
|
this.checked = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.checked) {
|
||||||
|
nominalLebihBayarSection.style.display = 'flex';
|
||||||
|
buktiPengembalianSection.style.display = 'flex';
|
||||||
|
resetFields('lebih');
|
||||||
|
console.log('Status lebih bayar dipilih, field kurang bayar direset');
|
||||||
|
} else {
|
||||||
|
nominalLebihBayarSection.style.display = 'none';
|
||||||
|
buktiPengembalianSection.style.display = 'none';
|
||||||
|
document.getElementById('nominal_lebih_bayar').value = '';
|
||||||
|
document.getElementById('bukti_pengembalian').value = '';
|
||||||
|
console.log('Status lebih bayar dibatalkan');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|||||||
@@ -5,9 +5,10 @@
|
|||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="noc-table" data-api-url="{{ route('noc.datatables') }}">
|
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10"
|
||||||
<div class="card-header bg-agi-50 py-5 flex-wrap">
|
data-datatable-state-save="false" id="noc-table" data-api-url="{{ route('noc.datatables') }}">
|
||||||
|
<div class="flex-wrap py-5 card-header bg-agi-50">
|
||||||
<h3 class="card-title">
|
<h3 class="card-title">
|
||||||
Daftar NOC
|
Daftar NOC
|
||||||
</h3>
|
</h3>
|
||||||
@@ -27,16 +28,21 @@
|
|||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="scrollable-x-auto">
|
<div class="scrollable-x-auto">
|
||||||
<table class="table table-auto table-border align-middle text-gray-700 font-medium text-sm" data-datatable-table="true">
|
<table class="table text-sm font-medium text-gray-700 align-middle table-auto table-border"
|
||||||
|
data-datatable-table="true">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="w-14">
|
<th class="w-14">
|
||||||
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox"/>
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox" />
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
|
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
|
||||||
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="nomor_tiket">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor Tiket </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_debitur">
|
<th class="min-w-[150px]" data-datatable-column="nama_debitur">
|
||||||
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
@@ -91,13 +97,13 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="card-footer justify-center md:justify-between flex-col md:flex-row gap-3 text-gray-600 text-2sm font-medium">
|
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex gap-2 items-center">
|
||||||
Show
|
Show
|
||||||
<select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select> per
|
<select class="w-16 select select-sm" data-datatable-size="true" name="perpage"> </select> per
|
||||||
page
|
page
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex gap-4 items-center">
|
||||||
<span data-datatable-info="true"> </span>
|
<span data-datatable-info="true"> </span>
|
||||||
<div class="pagination" data-datatable-pagination="true">
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
</div>
|
</div>
|
||||||
@@ -149,11 +155,17 @@
|
|||||||
nomor_registrasi: {
|
nomor_registrasi: {
|
||||||
title: 'Nomor Registrasi'
|
title: 'Nomor Registrasi'
|
||||||
},
|
},
|
||||||
|
nomor_tiket: {
|
||||||
|
title: 'Nomor Tiket'
|
||||||
|
},
|
||||||
nama_debitur: {
|
nama_debitur: {
|
||||||
title: 'Nama Debitur',
|
title: 'Nama Debitur',
|
||||||
},
|
},
|
||||||
cabang: {
|
cabang: {
|
||||||
title: 'Cabang',
|
title: 'Cabang',
|
||||||
|
return: (item, data) => {
|
||||||
|
return data.cabang.code + ' - ' + data.cabang.nama;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
tanggal_setor: {
|
tanggal_setor: {
|
||||||
title: 'Tanggal Setor',
|
title: 'Tanggal Setor',
|
||||||
@@ -236,7 +248,7 @@
|
|||||||
|
|
||||||
let dataTable = new KTDataTable(element, dataTableOptions);
|
let dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
// Custom search functionality
|
// Custom search functionality
|
||||||
searchInput.addEventListener('input', function () {
|
searchInput.addEventListener('input', function() {
|
||||||
const searchValue = this.value.trim();
|
const searchValue = this.value.trim();
|
||||||
dataTable.search(searchValue, true);
|
dataTable.search(searchValue, true);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,6 +19,14 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-wrap gap-2.5">
|
<div class="flex flex-wrap gap-2.5">
|
||||||
|
<div class="flex">
|
||||||
|
<select id="jenis_penilaian_filter" class="select select-sm">
|
||||||
|
<option value="">Semua Jenis Penilaian</option>
|
||||||
|
@foreach ($jenisPenilaians as $jenisPenilaian)
|
||||||
|
<option value="{{ $jenisPenilaian->name }}">{{ $jenisPenilaian->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="h-[24px] border border-r-gray-200"></div>
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
<a class="btn btn-sm btn-light" href="#"> Export to Excel </a>
|
<a class="btn btn-sm btn-light" href="#"> Export to Excel </a>
|
||||||
</div>
|
</div>
|
||||||
@@ -39,6 +47,10 @@
|
|||||||
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="nomor_tiket">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor Tiket </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_debitur">
|
<th class="min-w-[150px]" data-datatable-column="nama_debitur">
|
||||||
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
@@ -47,6 +59,10 @@
|
|||||||
<span class="sort"> <span class="sort-label"> Cabang </span>
|
<span class="sort"> <span class="sort-label"> Cabang </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="jenis_penilaian">
|
||||||
|
<span class="sort"> <span class="sort-label"> Jenis Penilaian </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_setor">
|
<th class="min-w-[150px]" data-datatable-column="tanggal_setor">
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal KSL </span>
|
<span class="sort"> <span class="sort-label"> Tanggal KSL </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
@@ -76,6 +92,15 @@
|
|||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Table Footer untuk Total -->
|
||||||
|
<div class="px-5 py-3 bg-gray-50 border-t border-gray-200">
|
||||||
|
<div class="flex justify-end items-center">
|
||||||
|
<div class="text-sm font-semibold text-gray-700">
|
||||||
|
Total Nominal Diterima: <span id="total-nominal-diterima"
|
||||||
|
class="text-lg font-bold text-green-600">Rp 0</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
<div class="flex gap-2 items-center">
|
<div class="flex gap-2 items-center">
|
||||||
@@ -116,6 +141,7 @@
|
|||||||
<script type="module">
|
<script type="module">
|
||||||
const element = document.querySelector('#noc-table');
|
const element = document.querySelector('#noc-table');
|
||||||
const searchInput = document.getElementById('search');
|
const searchInput = document.getElementById('search');
|
||||||
|
const jenisPenilaianFilter = document.getElementById('jenis_penilaian_filter');
|
||||||
|
|
||||||
const apiUrl = element.getAttribute('data-api-url');
|
const apiUrl = element.getAttribute('data-api-url');
|
||||||
const dataTableOptions = {
|
const dataTableOptions = {
|
||||||
@@ -135,11 +161,20 @@
|
|||||||
nomor_registrasi: {
|
nomor_registrasi: {
|
||||||
title: 'Nomor Registrasi'
|
title: 'Nomor Registrasi'
|
||||||
},
|
},
|
||||||
|
nomor_tiket: {
|
||||||
|
title: 'Nomor Tiket'
|
||||||
|
},
|
||||||
nama_debitur: {
|
nama_debitur: {
|
||||||
title: 'Nama Debitur',
|
title: 'Nama Debitur',
|
||||||
},
|
},
|
||||||
cabang: {
|
cabang: {
|
||||||
title: 'Cabang',
|
title: 'Cabang',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.kode_cabang + ' - ' + data.cabang;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jenis_penilaian: {
|
||||||
|
title: 'Jenis Penilaian'
|
||||||
},
|
},
|
||||||
tanggal_setor: {
|
tanggal_setor: {
|
||||||
title: 'Tanggal KSL',
|
title: 'Tanggal KSL',
|
||||||
@@ -191,10 +226,45 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
let dataTable = new KTDataTable(element, dataTableOptions);
|
let dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fungsi untuk menampilkan total nominal diterima dari backend
|
||||||
|
* @param {number} total - Total nominal diterima dari backend
|
||||||
|
*/
|
||||||
|
function updateTotalNominalDiterima(total) {
|
||||||
|
// Format dan tampilkan total
|
||||||
|
const formattedTotal = new Intl.NumberFormat('id-ID', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'IDR',
|
||||||
|
minimumFractionDigits: 0
|
||||||
|
}).format(total || 0);
|
||||||
|
|
||||||
|
document.getElementById('total-nominal-diterima').textContent = formattedTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listener untuk update total saat data berubah
|
||||||
|
dataTable.on('fetched', function(e, response) {
|
||||||
|
// Ambil total dari response backend
|
||||||
|
console.log(e.response);
|
||||||
|
if (e.response && e.response.totalNominalDiterima !== undefined) {
|
||||||
|
updateTotalNominalDiterima(e.response.totalNominalDiterima);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Custom search functionality
|
// Custom search functionality
|
||||||
searchInput.addEventListener('input', function() {
|
searchInput.addEventListener('input', function() {
|
||||||
const searchValue = this.value.trim();
|
const searchValue = this.value.trim();
|
||||||
dataTable.search(searchValue, true);
|
dataTable.search(searchValue, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Filter berdasarkan jenis penilaian
|
||||||
|
jenisPenilaianFilter.addEventListener('change', function() {
|
||||||
|
const filterValue = this.value.trim();
|
||||||
|
if (filterValue === '') {
|
||||||
|
dataTable.search('', true); // Reset filter
|
||||||
|
} else {
|
||||||
|
dataTable.search(filterValue, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
@endpush
|
@endpush
|
||||||
|
|||||||
@@ -5,9 +5,10 @@
|
|||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="noc-table" data-api-url="{{ route('noc.datatables.penyelesaian') }}">
|
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10"
|
||||||
<div class="card-header bg-agi-50 py-5 flex-wrap">
|
data-datatable-state-save="false" id="noc-table" data-api-url="{{ route('noc.datatables.penyelesaian') }}">
|
||||||
|
<div class="flex-wrap py-5 card-header bg-agi-50">
|
||||||
<h3 class="card-title">
|
<h3 class="card-title">
|
||||||
Daftar NOC Penyelesaian
|
Daftar NOC Penyelesaian
|
||||||
</h3>
|
</h3>
|
||||||
@@ -18,6 +19,14 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-wrap gap-2.5">
|
<div class="flex flex-wrap gap-2.5">
|
||||||
|
<div class="flex">
|
||||||
|
<select id="jenis_penilaian_filter" class="select select-sm">
|
||||||
|
<option value="">Semua Jenis Penilaian</option>
|
||||||
|
@foreach ($jenisPenilaians as $jenisPenilaian)
|
||||||
|
<option value="{{ $jenisPenilaian->name }}">{{ $jenisPenilaian->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="h-[24px] border border-r-gray-200"></div>
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
<a class="btn btn-sm btn-light" href="#"> Export to Excel </a>
|
<a class="btn btn-sm btn-light" href="#"> Export to Excel </a>
|
||||||
</div>
|
</div>
|
||||||
@@ -27,16 +36,21 @@
|
|||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="scrollable-x-auto">
|
<div class="scrollable-x-auto">
|
||||||
<table class="table table-auto table-border align-middle text-gray-700 font-medium text-sm" data-datatable-table="true">
|
<table class="table text-sm font-medium text-gray-700 align-middle table-auto table-border"
|
||||||
|
data-datatable-table="true">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="w-14">
|
<th class="w-14">
|
||||||
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox"/>
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox" />
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
|
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
|
||||||
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="nomor_tiket">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor Tiket </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="nama_debitur">
|
<th class="min-w-[150px]" data-datatable-column="nama_debitur">
|
||||||
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
@@ -45,6 +59,10 @@
|
|||||||
<span class="sort"> <span class="sort-label"> Cabang </span>
|
<span class="sort"> <span class="sort-label"> Cabang </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="jenis_penilaian">
|
||||||
|
<span class="sort"> <span class="sort-label"> Jenis Penilaian </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_setor">
|
<th class="min-w-[150px]" data-datatable-column="tanggal_setor">
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal KSL </span>
|
<span class="sort"> <span class="sort-label"> Tanggal KSL </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
@@ -90,14 +108,23 @@
|
|||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Table Footer untuk Total -->
|
||||||
|
<div class="px-5 py-3 bg-gray-50 border-t border-gray-200">
|
||||||
|
<div class="flex justify-end items-center">
|
||||||
|
<div class="text-sm font-semibold text-gray-700">
|
||||||
|
Total Nominal Diterima: <span id="total-nominal-diterima"
|
||||||
|
class="text-lg font-bold text-green-600">Rp 0</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="card-footer justify-center md:justify-between flex-col md:flex-row gap-3 text-gray-600 text-2sm font-medium">
|
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex gap-2 items-center">
|
||||||
Show
|
Show
|
||||||
<select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select> per
|
<select class="w-16 select select-sm" data-datatable-size="true" name="perpage"> </select> per
|
||||||
page
|
page
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex gap-4 items-center">
|
||||||
<span data-datatable-info="true"> </span>
|
<span data-datatable-info="true"> </span>
|
||||||
<div class="pagination" data-datatable-pagination="true">
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
</div>
|
</div>
|
||||||
@@ -130,6 +157,7 @@
|
|||||||
<script type="module">
|
<script type="module">
|
||||||
const element = document.querySelector('#noc-table');
|
const element = document.querySelector('#noc-table');
|
||||||
const searchInput = document.getElementById('search');
|
const searchInput = document.getElementById('search');
|
||||||
|
const jenisPenilaianFilter = document.getElementById('jenis_penilaian_filter');
|
||||||
|
|
||||||
const apiUrl = element.getAttribute('data-api-url');
|
const apiUrl = element.getAttribute('data-api-url');
|
||||||
const dataTableOptions = {
|
const dataTableOptions = {
|
||||||
@@ -149,11 +177,20 @@
|
|||||||
nomor_registrasi: {
|
nomor_registrasi: {
|
||||||
title: 'Nomor Registrasi'
|
title: 'Nomor Registrasi'
|
||||||
},
|
},
|
||||||
|
nomor_tiket: {
|
||||||
|
title: 'Nomor Tiket',
|
||||||
|
},
|
||||||
nama_debitur: {
|
nama_debitur: {
|
||||||
title: 'Nama Debitur',
|
title: 'Nama Debitur',
|
||||||
},
|
},
|
||||||
cabang: {
|
cabang: {
|
||||||
title: 'Cabang',
|
title: 'Cabang',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.kode_cabang + ' - ' + data.cabang;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jenis_penilaian: {
|
||||||
|
title: 'Jenis Penilaian'
|
||||||
},
|
},
|
||||||
tanggal_setor: {
|
tanggal_setor: {
|
||||||
title: 'Tanggal Setor',
|
title: 'Tanggal Setor',
|
||||||
@@ -236,9 +273,43 @@
|
|||||||
|
|
||||||
let dataTable = new KTDataTable(element, dataTableOptions);
|
let dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
// Custom search functionality
|
// Custom search functionality
|
||||||
searchInput.addEventListener('input', function () {
|
searchInput.addEventListener('input', function() {
|
||||||
const searchValue = this.value.trim();
|
const searchValue = this.value.trim();
|
||||||
dataTable.search(searchValue, true);
|
dataTable.search(searchValue, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Filter berdasarkan jenis penilaian
|
||||||
|
jenisPenilaianFilter.addEventListener('change', function() {
|
||||||
|
const filterValue = this.value.trim();
|
||||||
|
if (filterValue === '') {
|
||||||
|
dataTable.search('', true); // Reset filter
|
||||||
|
} else {
|
||||||
|
dataTable.search(filterValue, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update total nominal diterima dari response backend
|
||||||
|
* @param {number} total - Total nominal diterima dari backend
|
||||||
|
*/
|
||||||
|
function updateTotalNominalDiterima(total) {
|
||||||
|
// Format dan tampilkan total
|
||||||
|
const formattedTotal = new Intl.NumberFormat('id-ID', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'IDR',
|
||||||
|
minimumFractionDigits: 0
|
||||||
|
}).format(total || 0);
|
||||||
|
|
||||||
|
document.getElementById('total-nominal-diterima').textContent = formattedTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listener untuk update total saat data berubah
|
||||||
|
dataTable.on('fetched', function(e, response) {
|
||||||
|
// Ambil total dari response backend
|
||||||
|
console.log(e.response);
|
||||||
|
if (e.response && e.response.totalNominalDiterima !== undefined) {
|
||||||
|
updateTotalNominalDiterima(e.response.totalNominalDiterima);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
@endpush
|
@endpush
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ function otorisasiKJPP(penawaran_id, id, kjpp_id, kjppName, biaya_penawaran) {
|
|||||||
|
|
||||||
//define variable
|
//define variable
|
||||||
let token = "{{ csrf_token() }}";
|
let token = "{{ csrf_token() }}";
|
||||||
let useURL = "{{ route($route[0].'.'.$route[1].'.otorisasiPenawaranKJPP','') }}/"+id;
|
let useURL = "{{ route($route[0].'.'.$route[1].'.otorisasiPenawaranKJPP', ':id') }}".replace(':id', id);
|
||||||
let noReg = $("#textReg").text();
|
let noReg = $("#textReg").text();
|
||||||
var input_data = new Object();
|
var input_data = new Object();
|
||||||
input_data._token = token;
|
input_data._token = token;
|
||||||
|
|||||||
322
resources/views/pembayaran/create.blade.php
Normal file
322
resources/views/pembayaran/create.blade.php
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render(request()->route()->getName()) }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
|
<div class="pb-2.5 border card border-agi-100">
|
||||||
|
<div class="card-header bg-agi-50" id="basic_settings">
|
||||||
|
<div class="flex flex-row gap-1.5 card-title">
|
||||||
|
Tambah Pembayaran
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
<a href="{{ route('pembayaran.index') }}" class="btn btn-xs btn-info"><i
|
||||||
|
class="ki-filled ki-exit-left"></i> Back</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form action="{{ route('pembayaran.store') }}" method="POST" class="grid gap-5"
|
||||||
|
enctype="multipart/form-data" id="pembayaranForm">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<!-- Hidden fields untuk menyimpan ID yang dipilih -->
|
||||||
|
<input type="hidden" name="permohonan_id" id="permohonan_id" value="{{ old('permohonan_id') }}">
|
||||||
|
<input type="hidden" name="penawaran_id" id="penawaran_id" value="{{ old('penawaran_id') }}">
|
||||||
|
<input type="hidden" name="debitur_id" id="debitur_id" value="{{ old('debitur_id') }}">
|
||||||
|
<input type="hidden" name="type" id="create" value="create">
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Debitur <span class="text-danger">*</span>
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<select name="debitur_search" id="debitur_search"
|
||||||
|
class="input w-full @error('debitur_id') border-danger bg-danger-light @enderror"
|
||||||
|
placeholder="Cari debitur berdasarkan kode atau nama...">
|
||||||
|
<option value="">Pilih Debitur</option>
|
||||||
|
</select>
|
||||||
|
@error('debitur_id')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Nomor Registrasi
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="text" name="nomor_registrasi" id="nomor_registrasi"
|
||||||
|
class="input w-full @error('nomor_registrasi') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('nomor_registrasi') }}" placeholder="Nomor Registrasi">
|
||||||
|
@error('nomor_registrasi')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Nomor Tiket
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="text" name="nomor_tiket" id="nomor_tiket"
|
||||||
|
class="input w-full @error('nomor_tiket') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('nomor_tiket') }}" placeholder="Nomor Tiket">
|
||||||
|
@error('nomor_tiket')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Nominal Bayar <span class="text-danger">*</span>
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="number" name="nominal_bayar" id="nominal_bayar"
|
||||||
|
class="input w-full @error('nominal_bayar') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('nominal_bayar') }}" placeholder="Masukkan nominal bayar" min="0"
|
||||||
|
step="0.01">
|
||||||
|
@error('nominal_bayar')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Bukti Bayar <span class="text-danger">*</span>
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="file" name="bukti_bayar" id="bukti_bayar"
|
||||||
|
class="file-input w-full @error('bukti_bayar') border-danger bg-danger-light @enderror"
|
||||||
|
accept=".pdf,.jpg,.jpeg,.png">
|
||||||
|
<small class="mt-1 text-gray-600">Format yang diizinkan: PDF, JPG, JPEG, PNG (Max: 2MB)</small>
|
||||||
|
@error('bukti_bayar')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Catatan
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<textarea name="catatan" id="catatan" rows="4"
|
||||||
|
class="textarea w-full @error('catatan') border-danger bg-danger-light @enderror"
|
||||||
|
placeholder="Masukkan catatan (opsional)">{{ old('catatan') }}</textarea>
|
||||||
|
@error('catatan')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex gap-2 justify-end">
|
||||||
|
<a href="{{ route('pembayaran.index') }}" class="btn btn-secondary">
|
||||||
|
Batal
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="btn btn-primary" id="submitBtn">
|
||||||
|
<i class="ki-filled ki-check"></i> Simpan Pembayaran
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Inisialisasi TomSelect untuk pencarian debitur dengan AJAX
|
||||||
|
* Menggunakan autocomplete untuk mencari berdasarkan kode atau nama debitur
|
||||||
|
*/
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Inisialisasi TomSelect untuk field debitur
|
||||||
|
const debiturSelect = new window.TomSelect('#debitur_search', {
|
||||||
|
valueField: 'id',
|
||||||
|
labelField: 'display_name',
|
||||||
|
searchField: ['kode_debitur', 'name'],
|
||||||
|
placeholder: 'Ketik kode atau nama debitur untuk mencari...',
|
||||||
|
load: function(query, callback) {
|
||||||
|
// Minimal 2 karakter untuk mulai pencarian
|
||||||
|
if (query.length < 2) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tampilkan loading state
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
// AJAX request untuk mencari debitur
|
||||||
|
fetch(`{{ route('api.debitur.search') }}?q=${encodeURIComponent(query)}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
// Log untuk debugging
|
||||||
|
console.log('Debitur search results:', data);
|
||||||
|
|
||||||
|
// Format data untuk TomSelect
|
||||||
|
const formattedData = data.data.map(item => ({
|
||||||
|
id: item.id,
|
||||||
|
display_name: `${item.kode_debitur} - ${item.name}`,
|
||||||
|
kode_debitur: item.kode_debitur,
|
||||||
|
name: item.name
|
||||||
|
}));
|
||||||
|
|
||||||
|
callback(formattedData);
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error fetching debitur data:', error);
|
||||||
|
callback();
|
||||||
|
this.loading = false;
|
||||||
|
|
||||||
|
// Tampilkan pesan error ke user
|
||||||
|
alert(
|
||||||
|
'Terjadi kesalahan saat mencari data debitur. Silakan coba lagi.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
render: {
|
||||||
|
option: function(data, escape) {
|
||||||
|
return `<div class="px-3 py-2 hover:bg-gray-50">
|
||||||
|
<div class="font-medium text-gray-900">${escape(data.kode_debitur)}</div>
|
||||||
|
<div class="text-sm text-gray-600">${escape(data.name)}</div>
|
||||||
|
</div>`;
|
||||||
|
},
|
||||||
|
item: function(data, escape) {
|
||||||
|
return `<div>${escape(data.kode_debitur)} - ${escape(data.name)}</div>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChange: function(value) {
|
||||||
|
// Log untuk debugging
|
||||||
|
console.log('Debitur selected:', value);
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
const selectedOption = this.options[value];
|
||||||
|
if (selectedOption) {
|
||||||
|
// Set hidden field untuk debitur_id
|
||||||
|
document.getElementById('debitur_id').value = value;
|
||||||
|
|
||||||
|
// Jika ada data permohonan, isi field terkait
|
||||||
|
if (selectedOption.permohonan) {
|
||||||
|
const permohonan = selectedOption.permohonan;
|
||||||
|
|
||||||
|
// Set hidden fields
|
||||||
|
document.getElementById('permohonan_id').value = permohonan.id || '';
|
||||||
|
document.getElementById('penawaran_id').value = permohonan
|
||||||
|
.penawaran_id || '';
|
||||||
|
|
||||||
|
// Set visible fields
|
||||||
|
document.getElementById('nomor_registrasi').value = permohonan
|
||||||
|
.nomor_registrasi || '';
|
||||||
|
document.getElementById('nomor_tiket').value = permohonan.nomor_tiket ||
|
||||||
|
'';
|
||||||
|
|
||||||
|
// Set nominal bayar jika ada dari penawaran
|
||||||
|
if (permohonan.nominal_penawaran) {
|
||||||
|
document.getElementById('nominal_bayar').value = permohonan
|
||||||
|
.nominal_penawaran;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Clear fields jika tidak ada data permohonan
|
||||||
|
document.getElementById('permohonan_id').value = '';
|
||||||
|
document.getElementById('penawaran_id').value = '';
|
||||||
|
document.getElementById('nomor_registrasi').value = '';
|
||||||
|
document.getElementById('nomor_tiket').value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Clear semua field jika tidak ada yang dipilih
|
||||||
|
document.getElementById('debitur_id').value = '';
|
||||||
|
document.getElementById('permohonan_id').value = '';
|
||||||
|
document.getElementById('penawaran_id').value = '';
|
||||||
|
document.getElementById('nomor_registrasi').value = '';
|
||||||
|
document.getElementById('nomor_tiket').value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validasi form sebelum submit
|
||||||
|
* Memastikan field wajib sudah diisi
|
||||||
|
*/
|
||||||
|
document.getElementById('pembayaranForm').addEventListener('submit', function(e) {
|
||||||
|
const debiturId = document.getElementById('debitur_id').value;
|
||||||
|
const nominalBayar = document.getElementById('nominal_bayar').value;
|
||||||
|
const buktiBayar = document.getElementById('bukti_bayar').files[0];
|
||||||
|
|
||||||
|
let errors = [];
|
||||||
|
|
||||||
|
// Validasi debitur
|
||||||
|
if (!debiturId) {
|
||||||
|
errors.push('Debitur harus dipilih');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi nominal bayar
|
||||||
|
if (!nominalBayar || parseFloat(nominalBayar) <= 0) {
|
||||||
|
errors.push('Nominal bayar harus diisi dan lebih dari 0');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi bukti bayar
|
||||||
|
if (!buktiBayar) {
|
||||||
|
errors.push('Bukti bayar harus diupload');
|
||||||
|
} else {
|
||||||
|
// Validasi ukuran file (max 2MB)
|
||||||
|
if (buktiBayar.size > 2 * 1024 * 1024) {
|
||||||
|
errors.push('Ukuran file bukti bayar maksimal 2MB');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi tipe file
|
||||||
|
const allowedTypes = ['application/pdf', 'image/jpeg', 'image/jpg', 'image/png'];
|
||||||
|
if (!allowedTypes.includes(buktiBayar.type)) {
|
||||||
|
errors.push('Format file bukti bayar harus PDF, JPG, JPEG, atau PNG');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tampilkan error jika ada
|
||||||
|
if (errors.length > 0) {
|
||||||
|
e.preventDefault();
|
||||||
|
alert('Terdapat kesalahan:\n\n' + errors.join('\n'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable submit button untuk mencegah double submit
|
||||||
|
const submitBtn = document.getElementById('submitBtn');
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
submitBtn.innerHTML = '<i class="ki-filled ki-loading"></i> Menyimpan...';
|
||||||
|
|
||||||
|
// Log untuk debugging
|
||||||
|
console.log('Form submitted with data:', {
|
||||||
|
debitur_id: debiturId,
|
||||||
|
permohonan_id: document.getElementById('permohonan_id').value,
|
||||||
|
penawaran_id: document.getElementById('penawaran_id').value,
|
||||||
|
nominal_bayar: nominalBayar
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Re-enable submit button jika ada error dari server
|
||||||
|
@if ($errors->any())
|
||||||
|
const submitBtn = document.getElementById('submitBtn');
|
||||||
|
submitBtn.disabled = false;
|
||||||
|
submitBtn.innerHTML = '<i class="ki-filled ki-check"></i> Simpan Pembayaran';
|
||||||
|
@endif
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
151
resources/views/pembayaran/form-kurang.blade.php
Normal file
151
resources/views/pembayaran/form-kurang.blade.php
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('pembayaran') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
|
<div class="pb-2.5 border card border-agi-100">
|
||||||
|
<div class="card-header bg-agi-50" id="basic_settings">
|
||||||
|
<div class="flex flex-row gap-1.5 card-title">
|
||||||
|
Form Pembayaran Kurang Bayar
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
<a href="{{ route('pembayaran.kurang.index') }}" class="btn btn-xs btn-info"><i
|
||||||
|
class="ki-filled ki-exit-left"></i> Back</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<!-- Detail Informasi -->
|
||||||
|
<div class="p-4 mb-6 bg-gray-50 rounded-lg">
|
||||||
|
<h4 class="mb-4 text-lg font-semibold text-gray-800">Detail Pembayaran</h4>
|
||||||
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Nomor Registrasi:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">{{ $noc->permohonan->nomor_registrasi ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Nomor Tiket:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">{{ $noc->nomor_tiket ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Tanggal Permohonan:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">{{ $noc->permohonan->tanggal_permohonan ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">User Pemohon:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">{{ $noc->permohonan->user->name ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Cabang Pemohon:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">
|
||||||
|
@if ($noc->permohonan->branch ?? null)
|
||||||
|
{{ $noc->permohonan->branch->code }} - {{ $noc->permohonan->branch->name }}
|
||||||
|
@else
|
||||||
|
-
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Debitur:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">{{ $noc->permohonan->debiture->name ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Status Bayar:</label>
|
||||||
|
<p class="text-sm font-bold text-red-600 uppercase">Kurang Bayar</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Nominal Kurang Bayar:</label>
|
||||||
|
<p class="text-sm font-bold text-red-600">{{ formatRupiah($noc->nominal_kurang_bayar ?? 0, 2) }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="{{ route('pembayaran.store') }}" method="POST" class="grid gap-5"
|
||||||
|
enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="noc_id" value="{{ $noc->id ?? '' }}">
|
||||||
|
<input type="hidden" name="type" value="kurang_bayar">
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Nominal Pelunasan <span class="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="number" name="nominal_pelunasan" id="nominal_pelunasan"
|
||||||
|
class="input w-full @error('nominal_pelunasan') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('nominal_pelunasan') }}" placeholder="Masukkan nominal pelunasan" required>
|
||||||
|
@error('nominal_pelunasan')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
<small class="mt-1 text-xs text-gray-500">
|
||||||
|
Nominal kurang bayar: {{ formatRupiah($noc->nominal_kurang_bayar ?? 0, 2) }}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Bukti KSL Kurang Bayar <span class="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="file" name="bukti_ksl_kurang_bayar" id="bukti_ksl_kurang_bayar"
|
||||||
|
class="file-input w-full @error('bukti_ksl_kurang_bayar') border-danger bg-danger-light @enderror"
|
||||||
|
accept=".pdf,.jpg,.jpeg,.png" required>
|
||||||
|
@error('bukti_ksl_kurang_bayar')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
<small class="mt-1 text-xs text-gray-500">
|
||||||
|
Format yang diizinkan: PDF, JPG, JPEG, PNG (Max: 2MB)
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Catatan
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<textarea name="catatan" id="catatan" rows="4"
|
||||||
|
class="textarea w-full @error('catatan') border-danger bg-danger-light @enderror"
|
||||||
|
placeholder="Masukkan catatan (opsional)">{{ old('catatan') }}</textarea>
|
||||||
|
@error('catatan')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex gap-2 justify-end">
|
||||||
|
<a href="{{ route('pembayaran.kurang.index') }}" class="btn btn-secondary">
|
||||||
|
Batal
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<i class="ki-filled ki-check"></i>
|
||||||
|
Proses Pelunasan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
// Validasi nominal pelunasan tidak boleh melebihi nominal kurang bayar
|
||||||
|
document.getElementById('nominal_pelunasan').addEventListener('input', function() {
|
||||||
|
const nominalKurangBayar = {{ $noc->nominal_kurang_bayar ?? 0 }};
|
||||||
|
const nominalPelunasan = parseFloat(this.value) || 0;
|
||||||
|
|
||||||
|
if (nominalPelunasan > nominalKurangBayar) {
|
||||||
|
this.setCustomValidity('Nominal pelunasan tidak boleh melebihi nominal kurang bayar');
|
||||||
|
} else if (nominalPelunasan <= 0) {
|
||||||
|
this.setCustomValidity('Nominal pelunasan harus lebih dari 0');
|
||||||
|
} else {
|
||||||
|
this.setCustomValidity('');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
141
resources/views/pembayaran/form-lebih.blade.php
Normal file
141
resources/views/pembayaran/form-lebih.blade.php
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('pembayaran') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
|
<div class="pb-2.5 border card border-agi-100">
|
||||||
|
<div class="card-header bg-agi-50" id="basic_settings">
|
||||||
|
<div class="flex flex-row gap-1.5 card-title">
|
||||||
|
Form Pembayaran Lebih Bayar
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
<a href="{{ route('pembayaran.lebih.index') }}" class="btn btn-xs btn-info"><i
|
||||||
|
class="ki-filled ki-exit-left"></i> Back</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<!-- Detail Informasi -->
|
||||||
|
<div class="p-4 mb-6 bg-gray-50 rounded-lg">
|
||||||
|
<h4 class="mb-4 text-lg font-semibold text-gray-800">Detail Pembayaran</h4>
|
||||||
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Nomor Registrasi:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">{{ $noc->permohonan->nomor_registrasi ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Nomor Tiket:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">{{ $noc->nomor_tiket ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Tanggal Permohonan:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">{{ $noc->permohonan->tanggal_permohonan ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">User Pemohon:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">{{ $noc->permohonan->user->name ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Cabang Pemohon:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">
|
||||||
|
@if ($noc->permohonan->branch ?? null)
|
||||||
|
{{ $noc->permohonan->branch->code }} - {{ $noc->permohonan->branch->name }}
|
||||||
|
@else
|
||||||
|
-
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Debitur:</label>
|
||||||
|
<p class="text-sm font-bold text-gray-800">{{ $noc->permohonan->debiture->name ?? '-' }}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Status Bayar:</label>
|
||||||
|
<p class="text-sm font-bold text-green-600 uppercase">Lebih Bayar</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="text-sm font-medium text-gray-600">Nominal Lebih Bayar:</label>
|
||||||
|
<p class="text-sm font-bold text-green-600">
|
||||||
|
{{ formatRupiah($noc->nominal_lebih_bayar ?? 0, 2) }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="{{ route('pembayaran.store') }}" method="POST" class="grid gap-5"
|
||||||
|
enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="noc_id" value="{{ $noc->id ?? '' }}">
|
||||||
|
<input type="hidden" name="type" value="lebih_bayar">
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Bukti KSL Lebih Bayar <span class="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="file" name="bukti_ksl_lebih_bayar" id="bukti_ksl_lebih_bayar"
|
||||||
|
class="file-input w-full @error('bukti_ksl_lebih_bayar') border-danger bg-danger-light @enderror"
|
||||||
|
accept=".pdf,.jpg,.jpeg,.png" required>
|
||||||
|
@error('bukti_ksl_lebih_bayar')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
<small class="mt-1 text-xs text-gray-500">
|
||||||
|
Format yang diizinkan: PDF, JPG, JPEG, PNG (Max: 2MB)
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Catatan
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<textarea name="catatan" id="catatan" rows="4"
|
||||||
|
class="textarea w-full @error('catatan') border-danger bg-danger-light @enderror"
|
||||||
|
placeholder="Masukkan catatan (opsional)">{{ old('catatan') }}</textarea>
|
||||||
|
@error('catatan')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex gap-2 justify-end">
|
||||||
|
<a href="{{ route('pembayaran.lebih.index') }}" class="btn btn-secondary">
|
||||||
|
Batal
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<i class="ki-filled ki-check"></i>
|
||||||
|
Proses Pengembalian
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
// Validasi file upload
|
||||||
|
document.getElementById('bukti_ksl_lebih_bayar').addEventListener('change', function() {
|
||||||
|
const file = this.files[0];
|
||||||
|
if (file) {
|
||||||
|
// Validasi ukuran file (max 2MB)
|
||||||
|
if (file.size > 2 * 1024 * 1024) {
|
||||||
|
alert('Ukuran file tidak boleh lebih dari 2MB');
|
||||||
|
this.value = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi tipe file
|
||||||
|
const allowedTypes = ['application/pdf', 'image/jpeg', 'image/jpg', 'image/png'];
|
||||||
|
if (!allowedTypes.includes(file.type)) {
|
||||||
|
alert('Format file tidak didukung. Gunakan PDF, JPG, JPEG, atau PNG');
|
||||||
|
this.value = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
@@ -5,93 +5,126 @@
|
|||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
<div class="card border border-agi-100 pb-2.5">
|
<div class="pb-2.5 border card border-agi-100">
|
||||||
<div class="card-header bg-agi-50" id="basic_settings">
|
<div class="card-header bg-agi-50" id="basic_settings">
|
||||||
<div class="card-title flex flex-row gap-1.5">
|
<div class="flex flex-row gap-1.5 card-title">
|
||||||
Pembayaran
|
Pembayaran
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex gap-2 items-center">
|
||||||
<a href="{{ route('pembayaran.index') }}" class="btn btn-xs btn-info"><i class="ki-filled ki-exit-left"></i> Back</a>
|
<a href="{{ route('pembayaran.index') }}" class="btn btn-xs btn-info"><i
|
||||||
|
class="ki-filled ki-exit-left"></i> Back</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form action="{{ route('pembayaran.store') }}" method="POST" class="grid gap-5" enctype="multipart/form-data">
|
<form action="{{ route('pembayaran.store') }}" method="POST" class="grid gap-5"
|
||||||
|
enctype="multipart/form-data">
|
||||||
@csrf
|
@csrf
|
||||||
<input type="hidden" name="permohonan_id" value="{{ $permohonan->id }}">
|
<input type="hidden" name="permohonan_id" value="{{ $permohonan->id ?? '' }}">
|
||||||
<input type="hidden" name="penawaran_id" value="{{ $permohonan->penawaran->id ?? "" }}">
|
<input type="hidden" name="penawaran_id" value="{{ $permohonan->penawaran->id ?? '' }}">
|
||||||
|
|
||||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
Nomor Registrasi
|
Nomor Registrasi
|
||||||
</label>
|
</label>
|
||||||
<div class="flex flex-wrap items-baseline w-full">
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
<input readonly type="text" name="nomor_registrasi" id="nomor_registrasi" class="input w-full @error('nomor_registrasi') border-danger bg-danger-light @enderror" value="{{ old('nomor_registrasi', $permohonan->nomor_registrasi ?? '') }}" placeholder="Nomor Registrasi">
|
<input readonly type="text" name="nomor_registrasi" id="nomor_registrasi"
|
||||||
|
class="input w-full @error('nomor_registrasi') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('nomor_registrasi', $permohonan->nomor_registrasi ?? '') }}"
|
||||||
|
placeholder="Nomor Registrasi">
|
||||||
@error('nomor_registrasi')
|
@error('nomor_registrasi')
|
||||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
@enderror
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
|
<label class="form-label max-w-56">
|
||||||
|
Nomor Tiket
|
||||||
|
</label>
|
||||||
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
|
<input type="text" name="nomor_tiket" id="nomor_tiket"
|
||||||
|
class="input w-full @error('nomor_tiket') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('nomor_tiket', $permohonan->nomor_tiket ?? '') }}" placeholder="Nomor Tiket">
|
||||||
|
@error('nomor_tiket')
|
||||||
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
Debitur
|
Debitur
|
||||||
</label>
|
</label>
|
||||||
<div class="flex flex-wrap items-baseline w-full">
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
<input readonly type="text" name="debitur" id="debitur" class="input w-full @error('debitur') border-danger bg-danger-light @enderror" value="{{ old('debitur', $permohonan->debiture->name ?? '') }}" placeholder="Debitur">
|
<input readonly type="text" name="debitur" id="debitur"
|
||||||
|
class="input w-full @error('debitur') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('debitur', $permohonan->debiture->name ?? '') }}" placeholder="Debitur">
|
||||||
@error('debitur')
|
@error('debitur')
|
||||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
@enderror
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5 hidden">
|
<div class="flex hidden flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
Status Bayar
|
Status Bayar
|
||||||
</label>
|
</label>
|
||||||
<div class="flex flex-wrap items-baseline w-full">
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
<select class="input tomselect w-full @error('status_bayar') border-danger bg-danger-light @enderror" name="status_bayar" id="status_bayar">
|
<select
|
||||||
|
class="input tomselect w-full @error('status_bayar') border-danger bg-danger-light @enderror"
|
||||||
|
name="status_bayar" id="status_bayar">
|
||||||
<option value="">Pilih Status Bayar</option>
|
<option value="">Pilih Status Bayar</option>
|
||||||
<option value="sudah_bayar" {{ (old('status_bayar') == 'sudah_bayar') || (isset($permohonan) && $permohonan->status_bayar == 'sudah_bayar') ? 'selected' : '' }}>Sudah Bayar</option>
|
<option value="sudah_bayar"
|
||||||
<option value="belum_bayar" {{ (old('status_bayar') == 'belum_bayar') || (isset($permohonan) && $permohonan->status_bayar == 'belum_bayar') ? 'selected' : '' }}>Belum Bayar</option>
|
{{ old('status_bayar') == 'sudah_bayar' || (isset($permohonan) && $permohonan?->status_bayar == 'sudah_bayar') ? 'selected' : '' }}>
|
||||||
|
Sudah Bayar</option>
|
||||||
|
<option value="belum_bayar"
|
||||||
|
{{ old('status_bayar') == 'belum_bayar' || (isset($permohonan) && $permohonan?->status_bayar == 'belum_bayar') ? 'selected' : '' }}>
|
||||||
|
Belum Bayar</option>
|
||||||
</select>
|
</select>
|
||||||
@error('status_bayar')
|
@error('status_bayar')
|
||||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
@enderror
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
Nominal Bayar
|
Nominal Bayar
|
||||||
</label>
|
</label>
|
||||||
<div class="flex flex-wrap items-baseline w-full">
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
<input type="number" name="nominal_bayar" id="nominal_bayar" class="input w-full @error('nominal_bayar') border-danger bg-danger-light @enderror" value="{{ old('nominal_bayar', $persetujuanPenawaran->nominal_bayar ?? '') }}" placeholder="Masukkan nominal bayar">
|
<input type="number" name="nominal_bayar" id="nominal_bayar"
|
||||||
|
class="input w-full @error('nominal_bayar') border-danger bg-danger-light @enderror"
|
||||||
|
value="{{ old('nominal_bayar', $persetujuanPenawaran->nominal_bayar ?? '') }}"
|
||||||
|
placeholder="Masukkan nominal bayar">
|
||||||
@error('nominal_bayar')
|
@error('nominal_bayar')
|
||||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
@enderror
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
Bukti Bayar
|
Bukti Bayar
|
||||||
</label>
|
</label>
|
||||||
<div class="flex flex-wrap items-baseline w-full">
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
<input type="file" name="bukti_bayar" id="bukti_bayar" class="file-input w-full @error('bukti_bayar') border-danger bg-danger-light @enderror" accept=".pdf,.jpg,.jpeg,.png">
|
<input type="file" name="bukti_bayar" id="bukti_bayar"
|
||||||
|
class="file-input w-full @error('bukti_bayar') border-danger bg-danger-light @enderror"
|
||||||
|
accept=".pdf,.jpg,.jpeg,.png">
|
||||||
@error('bukti_bayar')
|
@error('bukti_bayar')
|
||||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
@enderror
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
<div class="flex flex-wrap gap-2.5 items-baseline lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
Catatan
|
Catatan
|
||||||
</label>
|
</label>
|
||||||
<div class="flex flex-wrap items-baseline w-full">
|
<div class="flex flex-wrap items-baseline w-full">
|
||||||
<textarea name="catatan" id="catatan" rows="4" class="textarea w-full @error('catatan') border-danger bg-danger-light @enderror" placeholder="Masukkan catatan">{{ old('catatan', $persetujuanPenawaran->catatan ?? '') }}</textarea>
|
<textarea name="catatan" id="catatan" rows="4"
|
||||||
|
class="textarea w-full @error('catatan') border-danger bg-danger-light @enderror" placeholder="Masukkan catatan">{{ old('catatan', $persetujuanPenawaran->catatan ?? '') }}</textarea>
|
||||||
@error('catatan')
|
@error('catatan')
|
||||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
<em class="text-sm alert text-danger">{{ $message }}</em>
|
||||||
@enderror
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false"
|
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10"
|
||||||
id="pembayaran-table" data-api-url="{{ route('pembayaran.datatables') }}">
|
data-datatable-state-save="false" id="pembayaran-table" data-api-url="{{ route('pembayaran.datatables') }}">
|
||||||
<div class="card-header bg-agi-50 py-5 flex-wrap">
|
<div class="flex-wrap py-5 card-header bg-agi-50">
|
||||||
<h3 class="card-title">
|
<h3 class="card-title">
|
||||||
Daftar Pembayaran
|
Daftar Pembayaran
|
||||||
</h3>
|
</h3>
|
||||||
@@ -21,22 +21,27 @@
|
|||||||
<div class="flex flex-wrap gap-2.5">
|
<div class="flex flex-wrap gap-2.5">
|
||||||
<div class="h-[24px] border border-r-gray-200"></div>
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
<a class="btn btn-sm btn-light" href="#"> Export to Excel </a>
|
<a class="btn btn-sm btn-light" href="#"> Export to Excel </a>
|
||||||
|
<a class="btn btn-sm btn-primary" href="{{ route('pembayaran.create') }}"> Tambah Pembayaran </a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="scrollable-x-auto">
|
<div class="scrollable-x-auto">
|
||||||
<table class="table table-auto table-border align-middle text-gray-700 font-medium text-sm"
|
<table class="table text-sm font-medium text-gray-700 align-middle table-auto table-border"
|
||||||
data-datatable-table="true">
|
data-datatable-table="true">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="w-14">
|
<th class="w-14">
|
||||||
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox"/>
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox" />
|
||||||
</th>
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
|
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
|
||||||
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
</th>
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="nomor_tiket">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor Tiket </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
|
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
|
||||||
<span class="sort"> <span class="sort-label"> Tanggal Permohonan </span>
|
<span class="sort"> <span class="sort-label"> Tanggal Permohonan </span>
|
||||||
<span class="sort-icon"> </span> </span>
|
<span class="sort-icon"> </span> </span>
|
||||||
@@ -64,13 +69,13 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="card-footer justify-center md:justify-between flex-col md:flex-row gap-3 text-gray-600 text-2sm font-medium">
|
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex gap-2 items-center">
|
||||||
Show
|
Show
|
||||||
<select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select> per
|
<select class="w-16 select select-sm" data-datatable-size="true" name="perpage"> </select> per
|
||||||
page
|
page
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex gap-4 items-center">
|
||||||
<span data-datatable-info="true"> </span>
|
<span data-datatable-info="true"> </span>
|
||||||
<div class="pagination" data-datatable-pagination="true">
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
</div>
|
</div>
|
||||||
@@ -166,6 +171,9 @@
|
|||||||
nomor_registrasi: {
|
nomor_registrasi: {
|
||||||
title: 'Nomor Registrasi',
|
title: 'Nomor Registrasi',
|
||||||
},
|
},
|
||||||
|
nomor_tiket: {
|
||||||
|
title: 'Nomor Tiket',
|
||||||
|
},
|
||||||
tanggal_permohonan: {
|
tanggal_permohonan: {
|
||||||
title: 'Tanggal Permohonan'
|
title: 'Tanggal Permohonan'
|
||||||
},
|
},
|
||||||
@@ -179,7 +187,7 @@
|
|||||||
title: 'Cabang Pemohon',
|
title: 'Cabang Pemohon',
|
||||||
render: (item, data) => {
|
render: (item, data) => {
|
||||||
if (data.branch) {
|
if (data.branch) {
|
||||||
return `${data.branch.name}`;
|
return `${data.branch.code} - ${data.branch.name}`;
|
||||||
}
|
}
|
||||||
return '-';
|
return '-';
|
||||||
},
|
},
|
||||||
@@ -205,11 +213,19 @@
|
|||||||
actions: {
|
actions: {
|
||||||
title: 'Status',
|
title: 'Status',
|
||||||
render: (item, data) => {
|
render: (item, data) => {
|
||||||
return `<div class="flex justify-center gap-2">
|
if (data.is_permohonan) {
|
||||||
<a class="btn btn-icon btn-clear btn-warning " href="pembayaran/${data.id}/edit" title="Lakukan Pembayaran">
|
return `<div class="flex gap-2 justify-center">
|
||||||
|
<a class="btn btn-icon btn-clear btn-warning" href="pembayaran/${data.id}/edit" title="Lakukan Pembayaran">
|
||||||
<i class="ki-outline ki-credit-cart"></i>
|
<i class="ki-outline ki-credit-cart"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
} else {
|
||||||
|
return `<div class="flex gap-2 justify-center">
|
||||||
|
<a class="btn btn-icon btn-clear btn-warning" href="pembayaran/${data.id}/edit?tiket=true" title="Lakukan Pembayaran">
|
||||||
|
<i class="ki-outline ki-credit-cart"></i>
|
||||||
|
</a>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -217,11 +233,10 @@
|
|||||||
|
|
||||||
let dataTable = new KTDataTable(element, dataTableOptions);
|
let dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
// Custom search functionality
|
// Custom search functionality
|
||||||
searchInput.addEventListener('input', function () {
|
searchInput.addEventListener('input', function() {
|
||||||
const searchValue = this.value.trim();
|
const searchValue = this.value.trim();
|
||||||
dataTable.search(searchValue, true);
|
dataTable.search(searchValue, true);
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@endpush
|
@endpush
|
||||||
|
|
||||||
|
|||||||
242
resources/views/pembayaran/kurang.blade.php
Normal file
242
resources/views/pembayaran/kurang.blade.php
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('pembayaran') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid">
|
||||||
|
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10"
|
||||||
|
data-datatable-state-save="false" id="pembayaran-table" data-api-url="{{ route('pembayaran.kurang.datatables') }}">
|
||||||
|
<div class="flex-wrap py-5 card-header bg-agi-50">
|
||||||
|
<h3 class="card-title">
|
||||||
|
Daftar Pembayaran Kurang Bayar
|
||||||
|
</h3>
|
||||||
|
<div class="flex flex-wrap gap-2 lg:gap-5">
|
||||||
|
<div class="flex">
|
||||||
|
<label class="input input-sm"> <i class="ki-filled ki-magnifier"> </i>
|
||||||
|
<input placeholder="Search Kurang Bayar" id="search" type="text" value="">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap gap-2.5">
|
||||||
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
|
<a class="btn btn-sm btn-light" href="#"> Export to Excel </a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="scrollable-x-auto">
|
||||||
|
<table class="table text-sm font-medium text-gray-700 align-middle table-auto table-border"
|
||||||
|
data-datatable-table="true">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-14">
|
||||||
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox" />
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="nomor_tiket">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor Tiket </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
|
||||||
|
<span class="sort"> <span class="sort-label"> Tanggal Permohonan </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="user_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> User Pemohon </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="branch_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> Cabang Pemohon </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="debitur_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> Debitur </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px] text-center" data-datatable-column="status_bayar">
|
||||||
|
<span class="sort"> <span class="sort-label"> Status Bayar </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px] text-center" data-datatable-column="nominal_kurang_bayar">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nominal </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th class="min-w-[50px] text-center" data-datatable-column="actions">Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
Show
|
||||||
|
<select class="w-16 select select-sm" data-datatable-size="true" name="perpage"> </select> per
|
||||||
|
page
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-4 items-center">
|
||||||
|
<span data-datatable-info="true"> </span>
|
||||||
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
function pembayaranOtorisator(id) {
|
||||||
|
// alert('hai id = ' + id);
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Apakah Anda yakin?',
|
||||||
|
text: `Untuk melakukan approve Pembayaran!`,
|
||||||
|
icon: 'warning',
|
||||||
|
input: 'textarea', // Menambahkan input textarea
|
||||||
|
inputLabel: 'Keterangan',
|
||||||
|
inputPlaceholder: 'Masukkan keterangan...',
|
||||||
|
inputAttributes: {
|
||||||
|
'aria-label': 'Masukkan keterangan'
|
||||||
|
},
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: 'Ya, Lanjutkan!',
|
||||||
|
cancelButtonText: 'Lain kali',
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
|
||||||
|
let useURL = "{{ URL::to('pembayaran') }}" + "/" + id;
|
||||||
|
const keterangan = result.value || ''; // Ambil pesan dari textarea
|
||||||
|
|
||||||
|
var input_data = new Object();
|
||||||
|
input_data._method = 'PUT';
|
||||||
|
input_data.id = id;
|
||||||
|
input_data.keterangan = keterangan;
|
||||||
|
|
||||||
|
$.ajaxSetup({
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
$.ajax({
|
||||||
|
url: useURL,
|
||||||
|
type: 'PUT',
|
||||||
|
data: input_data,
|
||||||
|
dataType: "json",
|
||||||
|
success: (response) => {
|
||||||
|
if ('success' == response.status) {
|
||||||
|
Swal.fire('Berhasil!', response.message, 'success').then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
} else if ('error' == response.status) {
|
||||||
|
Swal.fire('Error!', response.message, 'error').then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(response);
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
Swal.fire('Gagal!', 'Terjadi kesalahan saat melakukan otorisator.',
|
||||||
|
'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
const element = document.querySelector('#pembayaran-table');
|
||||||
|
const searchInput = document.getElementById('search');
|
||||||
|
|
||||||
|
const apiUrl = element.getAttribute('data-api-url');
|
||||||
|
const dataTableOptions = {
|
||||||
|
apiEndpoint: apiUrl,
|
||||||
|
pageSize: 5,
|
||||||
|
columns: {
|
||||||
|
select: {
|
||||||
|
render: (item, data, context) => {
|
||||||
|
const checkbox = document.createElement('input');
|
||||||
|
checkbox.className = 'checkbox checkbox-sm';
|
||||||
|
checkbox.type = 'checkbox';
|
||||||
|
checkbox.value = data.id.toString();
|
||||||
|
checkbox.setAttribute('data-datatable-row-check', 'true');
|
||||||
|
return checkbox.outerHTML.trim();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nomor_registrasi: {
|
||||||
|
title: 'Nomor Registrasi',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.permohonan?.nomor_registrasi}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nomor_tiket: {
|
||||||
|
title: 'Nomor Tiket',
|
||||||
|
},
|
||||||
|
tanggal_permohonan: {
|
||||||
|
title: 'Tanggal Permohonan',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.permohonan?.tanggal_permohonan}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
user_id: {
|
||||||
|
title: 'User Pemohon',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.pemohon?.name}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
branch_id: {
|
||||||
|
title: 'Cabang Pemohon',
|
||||||
|
render: (item, data) => {
|
||||||
|
if (data.branch) {
|
||||||
|
return `${data.branch.code} - ${data.branch.name}`;
|
||||||
|
}
|
||||||
|
return '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
debitur_id: {
|
||||||
|
title: 'Debitur',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.debiture?.name}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status_bayar: {
|
||||||
|
title: 'Status Bayar',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `<span class="font-bold text-red-600 uppercase text-md">
|
||||||
|
Kurang Bayar
|
||||||
|
</span>`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nominal_kurang_bayar: {
|
||||||
|
title: 'Kurang Bayar'
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
title: 'Status',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `<div class="flex gap-2 justify-center">
|
||||||
|
<a class="btn btn-icon btn-clear btn-warning" href="pembayaran/${data.id}/kurang" title="Lakukan Pembayaran">
|
||||||
|
<i class="ki-outline ki-credit-cart"></i>
|
||||||
|
</a>
|
||||||
|
</div>`;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
|
// Custom search functionality
|
||||||
|
searchInput.addEventListener('input', function() {
|
||||||
|
const searchValue = this.value.trim();
|
||||||
|
dataTable.search(searchValue, true);
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
242
resources/views/pembayaran/lebih.blade.php
Normal file
242
resources/views/pembayaran/lebih.blade.php
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('pembayaran') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid">
|
||||||
|
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10"
|
||||||
|
data-datatable-state-save="false" id="pembayaran-table" data-api-url="{{ route('pembayaran.lebih.datatables') }}">
|
||||||
|
<div class="flex-wrap py-5 card-header bg-agi-50">
|
||||||
|
<h3 class="card-title">
|
||||||
|
Daftar Pembayaran Lebih Bayar
|
||||||
|
</h3>
|
||||||
|
<div class="flex flex-wrap gap-2 lg:gap-5">
|
||||||
|
<div class="flex">
|
||||||
|
<label class="input input-sm"> <i class="ki-filled ki-magnifier"> </i>
|
||||||
|
<input placeholder="Search Lebih Bayar" id="search" type="text" value="">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap gap-2.5">
|
||||||
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
|
<a class="btn btn-sm btn-light" href="#"> Export to Excel </a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="scrollable-x-auto">
|
||||||
|
<table class="table text-sm font-medium text-gray-700 align-middle table-auto table-border"
|
||||||
|
data-datatable-table="true">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-14">
|
||||||
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox" />
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="nomor_tiket">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nomor Tiket </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
|
||||||
|
<span class="sort"> <span class="sort-label"> Tanggal Permohonan </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="user_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> User Pemohon </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="branch_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> Cabang Pemohon </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px]" data-datatable-column="debitur_id">
|
||||||
|
<span class="sort"> <span class="sort-label"> Debitur </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px] text-center" data-datatable-column="status_bayar">
|
||||||
|
<span class="sort"> <span class="sort-label"> Status Bayar </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[150px] text-center" data-datatable-column="nominal_lebih_bayar">
|
||||||
|
<span class="sort"> <span class="sort-label"> Nominal </span>
|
||||||
|
<span class="sort-icon"> </span> </span>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th class="min-w-[50px] text-center" data-datatable-column="actions">Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
Show
|
||||||
|
<select class="w-16 select select-sm" data-datatable-size="true" name="perpage"> </select> per
|
||||||
|
page
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-4 items-center">
|
||||||
|
<span data-datatable-info="true"> </span>
|
||||||
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
function pembayaranOtorisator(id) {
|
||||||
|
// alert('hai id = ' + id);
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Apakah Anda yakin?',
|
||||||
|
text: `Untuk melakukan approve Pembayaran!`,
|
||||||
|
icon: 'warning',
|
||||||
|
input: 'textarea', // Menambahkan input textarea
|
||||||
|
inputLabel: 'Keterangan',
|
||||||
|
inputPlaceholder: 'Masukkan keterangan...',
|
||||||
|
inputAttributes: {
|
||||||
|
'aria-label': 'Masukkan keterangan'
|
||||||
|
},
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: 'Ya, Lanjutkan!',
|
||||||
|
cancelButtonText: 'Lain kali',
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
|
||||||
|
let useURL = "{{ URL::to('pembayaran') }}" + "/" + id;
|
||||||
|
const keterangan = result.value || ''; // Ambil pesan dari textarea
|
||||||
|
|
||||||
|
var input_data = new Object();
|
||||||
|
input_data._method = 'PUT';
|
||||||
|
input_data.id = id;
|
||||||
|
input_data.keterangan = keterangan;
|
||||||
|
|
||||||
|
$.ajaxSetup({
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
$.ajax({
|
||||||
|
url: useURL,
|
||||||
|
type: 'PUT',
|
||||||
|
data: input_data,
|
||||||
|
dataType: "json",
|
||||||
|
success: (response) => {
|
||||||
|
if ('success' == response.status) {
|
||||||
|
Swal.fire('Berhasil!', response.message, 'success').then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
} else if ('error' == response.status) {
|
||||||
|
Swal.fire('Error!', response.message, 'error').then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(response);
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
Swal.fire('Gagal!', 'Terjadi kesalahan saat melakukan otorisator.',
|
||||||
|
'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
const element = document.querySelector('#pembayaran-table');
|
||||||
|
const searchInput = document.getElementById('search');
|
||||||
|
|
||||||
|
const apiUrl = element.getAttribute('data-api-url');
|
||||||
|
const dataTableOptions = {
|
||||||
|
apiEndpoint: apiUrl,
|
||||||
|
pageSize: 5,
|
||||||
|
columns: {
|
||||||
|
select: {
|
||||||
|
render: (item, data, context) => {
|
||||||
|
const checkbox = document.createElement('input');
|
||||||
|
checkbox.className = 'checkbox checkbox-sm';
|
||||||
|
checkbox.type = 'checkbox';
|
||||||
|
checkbox.value = data.id.toString();
|
||||||
|
checkbox.setAttribute('data-datatable-row-check', 'true');
|
||||||
|
return checkbox.outerHTML.trim();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nomor_registrasi: {
|
||||||
|
title: 'Nomor Registrasi',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.permohonan?.nomor_registrasi}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nomor_tiket: {
|
||||||
|
title: 'Nomor Tiket',
|
||||||
|
},
|
||||||
|
tanggal_permohonan: {
|
||||||
|
title: 'Tanggal Permohonan',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.permohonan?.tanggal_permohonan}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
user_id: {
|
||||||
|
title: 'User Pemohon',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.pemohon?.name}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
branch_id: {
|
||||||
|
title: 'Cabang Pemohon',
|
||||||
|
render: (item, data) => {
|
||||||
|
if (data.branch) {
|
||||||
|
return `${data.branch.code} - ${data.branch.name}`;
|
||||||
|
}
|
||||||
|
return '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
debitur_id: {
|
||||||
|
title: 'Debitur',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `${data.debiture?.name}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status_bayar: {
|
||||||
|
title: 'Status Bayar',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `<span class="font-bold text-green-600 uppercase text-md">
|
||||||
|
Lebih Bayar
|
||||||
|
</span>`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nominal_lebih_bayar: {
|
||||||
|
title: 'Lebih Bayar'
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
title: 'Status',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `<div class="flex gap-2 justify-center">
|
||||||
|
<a class="btn btn-icon btn-clear btn-warning" href="pembayaran/${data.id}/lebih" title="Lakukan Pembayaran">
|
||||||
|
<i class="ki-outline ki-credit-cart"></i>
|
||||||
|
</a>
|
||||||
|
</div>`;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
|
// Custom search functionality
|
||||||
|
searchInput.addEventListener('input', function() {
|
||||||
|
const searchValue = this.value.trim();
|
||||||
|
dataTable.search(searchValue, true);
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
@@ -193,94 +193,7 @@
|
|||||||
<td>Demikian Kami Sampaikan, atas perhatiannya kami ucapkan terimakasih</td>
|
<td>Demikian Kami Sampaikan, atas perhatiannya kami ucapkan terimakasih</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<table style="width: 100%; border-collapse: collapse; text-align: center;">
|
@include('lpj::penilai.components.signature-approval')
|
||||||
@php
|
|
||||||
use Modules\Usermanagement\Models\User;
|
|
||||||
|
|
||||||
$penilaiUser = User::where('id', $penilai->userPenilaiTeam->id)->first();
|
|
||||||
$imagePathPenilai = storage_path(
|
|
||||||
'app/public/signatures/' . $penilaiUser->id . '/' . $penilaiUser->sign,
|
|
||||||
);
|
|
||||||
|
|
||||||
$soUser = User::where('id', $senior_officer->id)->first();
|
|
||||||
$imagePathSo = storage_path('app/public/signatures/' . $soUser->id . '/' . $soUser->sign);
|
|
||||||
|
|
||||||
$imagePathEO = storage_path(
|
|
||||||
'app/public/signatures/' .
|
|
||||||
User::role('EO Appraisal')->first()->id .
|
|
||||||
'/' .
|
|
||||||
User::role('EO Appraisal')->first()->sign,
|
|
||||||
);
|
|
||||||
|
|
||||||
$imagePathDD = storage_path(
|
|
||||||
'app/public/signatures/' .
|
|
||||||
User::role('DD Appraisal')->first()->id .
|
|
||||||
'/' .
|
|
||||||
User::role('DD Appraisal')->first()->sign,
|
|
||||||
);
|
|
||||||
@endphp
|
|
||||||
<tr>
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathPenilai))
|
|
||||||
<img src="{{ $imagePathPenilai }}" alt="{{ $imagePathPenilai }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@if ($permohonan->approval_so != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathSo))
|
|
||||||
<img src="{{ $imagePathSo }}" alt="{{ $imagePathSo }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_eo != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathEO))
|
|
||||||
<img src="{{ $imagePathEO }}" alt="{{ $imagePathEO }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_dd != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathDD))
|
|
||||||
<img src="{{ $imagePathDD }}" alt="{{ $imagePathDD }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=" padding: 4px;">{{ $penilai->userPenilaiTeam->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('PENILAI')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@if ($permohonan->approval_so != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ $senior_officer->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('SENIOR OFFICER')) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($permohonan->approval_eo != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ User::role('EO Appraisal')->first()->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('EXECUTIVE OFFICER')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_dd != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ User::role('DD Appraisal')->first()->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('DEPUTY DIRECTOR')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -229,93 +229,7 @@
|
|||||||
<td>Demikian Kami Sampaikan, atas perhatiannya kami ucapkan terimakasih</td>
|
<td>Demikian Kami Sampaikan, atas perhatiannya kami ucapkan terimakasih</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<table style="width: 100%; border-collapse: collapse; text-align: center;">
|
@include('lpj::penilai.components.signature-approval')
|
||||||
@php
|
|
||||||
use Modules\Usermanagement\Models\User;
|
|
||||||
$penilaiUser = User::where('id', $penilai->userPenilaiTeam->id)->first();
|
|
||||||
$imagePathPenilai = storage_path(
|
|
||||||
'app/public/signatures/' . $penilaiUser->id . '/' . $penilaiUser->sign,
|
|
||||||
);
|
|
||||||
|
|
||||||
$soUser = User::where('id', $senior_officer->id)->first();
|
|
||||||
$imagePathSo = storage_path('app/public/signatures/' . $soUser->id . '/' . $soUser->sign);
|
|
||||||
|
|
||||||
$imagePathEO = storage_path(
|
|
||||||
'app/public/signatures/' .
|
|
||||||
User::role('EO Appraisal')->first()->id .
|
|
||||||
'/' .
|
|
||||||
User::role('EO Appraisal')->first()->sign,
|
|
||||||
);
|
|
||||||
|
|
||||||
$imagePathDD = storage_path(
|
|
||||||
'app/public/signatures/' .
|
|
||||||
User::role('DD Appraisal')->first()->id .
|
|
||||||
'/' .
|
|
||||||
User::role('DD Appraisal')->first()->sign,
|
|
||||||
);
|
|
||||||
@endphp
|
|
||||||
<tr>
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathPenilai))
|
|
||||||
<img src="{{ $imagePathPenilai }}" alt="{{ $imagePathPenilai }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@if ($permohonan->approval_so != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathSo))
|
|
||||||
<img src="{{ $imagePathSo }}" alt="{{ $imagePathSo }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_eo != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathEO))
|
|
||||||
<img src="{{ $imagePathEO }}" alt="{{ $imagePathEO }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_dd != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathDD))
|
|
||||||
<img src="{{ $imagePathDD }}" alt="{{ $imagePathDD }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=" padding: 4px;">{{ $penilai->userPenilaiTeam->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('PENILAI')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@if ($permohonan->approval_so != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ $senior_officer->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('SENIOR OFFICER')) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($permohonan->approval_eo != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ User::role('EO Appraisal')->first()->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('EXECUTIVE OFFICER')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_dd != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ User::role('DD Appraisal')->first()->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('DEPUTY DIRECTOR')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@@ -412,91 +412,6 @@
|
|||||||
@endisset
|
@endisset
|
||||||
<p>Demikian kami sampaikan, atas perhatiannya kami ucapkan terima kasih.</p>
|
<p>Demikian kami sampaikan, atas perhatiannya kami ucapkan terima kasih.</p>
|
||||||
|
|
||||||
<table style="width: 100%; border-collapse: collapse; text-align: center;">
|
@include('lpj::penilai.components.signature-approval')
|
||||||
@php
|
|
||||||
use Modules\Usermanagement\Models\User;
|
|
||||||
|
|
||||||
$penilaiUser = User::where('id', $penilai->userPenilaiTeam->id)->first();
|
|
||||||
$imagePathPenilai = storage_path('app/public/signatures/' . $penilaiUser->id . '/' . $penilaiUser->sign);
|
|
||||||
|
|
||||||
$soUser = User::where('id', $senior_officer->id)->first();
|
|
||||||
$imagePathSo = storage_path('app/public/signatures/' . $soUser->id . '/' . $soUser->sign);
|
|
||||||
|
|
||||||
$imagePathEO = storage_path(
|
|
||||||
'app/public/signatures/' .
|
|
||||||
User::role('EO Appraisal')->first()->id .
|
|
||||||
'/' .
|
|
||||||
User::role('EO Appraisal')->first()->sign,
|
|
||||||
);
|
|
||||||
|
|
||||||
$imagePathDD = storage_path(
|
|
||||||
'app/public/signatures/' .
|
|
||||||
User::role('DD Appraisal')->first()->id .
|
|
||||||
'/' .
|
|
||||||
User::role('DD Appraisal')->first()->sign,
|
|
||||||
);
|
|
||||||
@endphp
|
|
||||||
<tr>
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathPenilai))
|
|
||||||
<img src="{{ $imagePathPenilai }}" alt="{{ $imagePathPenilai }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@if ($permohonan->approval_so != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathSo))
|
|
||||||
<img src="{{ $imagePathSo }}" alt="{{ $imagePathSo }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_eo != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathEO))
|
|
||||||
<img src="{{ $imagePathEO }}" alt="{{ $imagePathEO }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_dd != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathDD))
|
|
||||||
<img src="{{ $imagePathDD }}" alt="{{ $imagePathDD }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=" padding: 4px;">{{ $penilai->userPenilaiTeam->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('PENILAI')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@if ($permohonan->approval_so != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ $senior_officer->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('SENIOR OFFICER')) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($permohonan->approval_eo != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ User::role('EO Appraisal')->first()->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('EXECUTIVE OFFICER')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_dd != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ User::role('DD Appraisal')->first()->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('DEPUTY DIRECTOR')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</main>
|
</main>
|
||||||
@include('lpj::penilai.components.footer')
|
@include('lpj::penilai.components.footer')
|
||||||
|
|||||||
@@ -503,5 +503,43 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="no-break">
|
||||||
|
<table style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<table>
|
||||||
|
<div style="margin-top: 20px;">
|
||||||
|
<label style="font-weight: bold;">DISCLAIMER</label>
|
||||||
|
<div>
|
||||||
|
<ol style="padding-left: 20px; list-style-type: decimal; margin-top: 0;">
|
||||||
|
|
||||||
|
<li style="margin-bottom: 5px;">PENILAIAN INI DIBUAT BERDASARKAN ATURAN YANG
|
||||||
|
BERLAKU DI SUBDIT APPRAISAL</li>
|
||||||
|
<li style="margin-bottom: 5px;">LAPORAN INI DIBUAT BERDASARKAN DATA FOTOCOPY
|
||||||
|
DOKUMEN YANG DITERIMA PENILAI DENGAN ASUMSI BAHWA DATA TERSEBUT SESUAI DENGAN
|
||||||
|
DOKUMEN ASLINYA</li>
|
||||||
|
<li style="margin-bottom: 5px;">PENILAI TIDAK MELAKUKAN PEMBUKTIAN LEBIH RINCI ATAU
|
||||||
|
PENGAKUAN TERTULIS DARI PIHAK YANG DITEMUI SAAT PENILAIAN, ATAS INFORMASI YANG
|
||||||
|
DIBERIKAN SECARA LISAN SEHUBUNGAN DENGAN IDENTITAS DIRI DAN HUBUNGAN DI ANTARA
|
||||||
|
PIHAK TERKAIT SAAT MELAKUKAN INSPEKSI OBJEK YANG DINILAI</li>
|
||||||
|
<li style="margin-bottom: 5px;">LAPORAN INI DIGUNAKAN HANYA UNTUK KEPENTINGAN
|
||||||
|
INTERNAL DAN DILARANG MENYEBARKAN KEPADA PIHAK KETIGA</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Demikian laporan penilai jaminan ini di buat secara objektif, tanpa adanya pengaruh baik intern
|
||||||
|
maupun ekstern</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
@include('lpj::penilai.components.signature-approval')
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
@include('lpj::penilai.components.footer')
|
@include('lpj::penilai.components.footer')
|
||||||
|
|||||||
@@ -374,94 +374,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<table style="width: 100%; border-collapse: collapse; text-align: center;">
|
@include('lpj::penilai.components.signature-approval')
|
||||||
@php
|
|
||||||
use Modules\Usermanagement\Models\User;
|
|
||||||
|
|
||||||
$penilaiUser = User::where('id', $penilai->userPenilaiTeam->id)->first();
|
|
||||||
$imagePathPenilai = storage_path(
|
|
||||||
'app/public/signatures/' . $penilaiUser->id . '/' . $penilaiUser->sign,
|
|
||||||
);
|
|
||||||
|
|
||||||
$soUser = User::where('id', $senior_officer->id)->first();
|
|
||||||
$imagePathSo = storage_path('app/public/signatures/' . $soUser->id . '/' . $soUser->sign);
|
|
||||||
|
|
||||||
$imagePathEO = storage_path(
|
|
||||||
'app/public/signatures/' .
|
|
||||||
User::role('EO Appraisal')->first()->id .
|
|
||||||
'/' .
|
|
||||||
User::role('EO Appraisal')->first()->sign,
|
|
||||||
);
|
|
||||||
|
|
||||||
$imagePathDD = storage_path(
|
|
||||||
'app/public/signatures/' .
|
|
||||||
User::role('DD Appraisal')->first()->id .
|
|
||||||
'/' .
|
|
||||||
User::role('DD Appraisal')->first()->sign,
|
|
||||||
);
|
|
||||||
@endphp
|
|
||||||
<tr>
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathPenilai))
|
|
||||||
<img src="{{ $imagePathPenilai }}" alt="{{ $imagePathPenilai }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@if ($permohonan->approval_so != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathSo))
|
|
||||||
<img src="{{ $imagePathSo }}" alt="{{ $imagePathSo }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_eo != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathEO))
|
|
||||||
<img src="{{ $imagePathEO }}" alt="{{ $imagePathEO }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_dd != null)
|
|
||||||
<td style=" padding: 4px;height: 50px">
|
|
||||||
@if (file_exists($imagePathDD))
|
|
||||||
<img src="{{ $imagePathDD }}" alt="{{ $imagePathDD }}" width="80px">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=" padding: 4px;">{{ $penilai->userPenilaiTeam->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('PENILAI')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@if ($permohonan->approval_so != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ $senior_officer->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('SENIOR OFFICER')) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($permohonan->approval_eo != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ User::role('EO Appraisal')->first()->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('EXECUTIVE OFFICER')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
@if ($permohonan->approval_dd != null)
|
|
||||||
<td style=" padding: 4px;">
|
|
||||||
{{ User::role('DD Appraisal')->first()->name ?? '' }}</br>
|
|
||||||
<span>
|
|
||||||
{{ ucwords(strtolower('DEPUTY DIRECTOR')) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
@endif
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<table style="width: 100%; ">
|
<table style="width: 100%; ">
|
||||||
|
|||||||
105
resources/views/penilai/components/signature-approval.blade.php
Normal file
105
resources/views/penilai/components/signature-approval.blade.php
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<table style="width: 100%; border-collapse: collapse; text-align: center;">
|
||||||
|
@php
|
||||||
|
use Modules\Usermanagement\Models\User;
|
||||||
|
|
||||||
|
$penilaiUser = User::where('id', $penilai->userPenilaiTeam->id)->first();
|
||||||
|
$imagePathPenilai = storage_path(
|
||||||
|
'app/public/signatures/' . $penilaiUser->id . '/' . $penilaiUser->sign,
|
||||||
|
);
|
||||||
|
|
||||||
|
$soUser = User::where('id', $senior_officer->id)->first();
|
||||||
|
$imagePathSo = storage_path('app/public/signatures/' . $soUser->id . '/' . $soUser->sign);
|
||||||
|
|
||||||
|
$imagePathEO = storage_path(
|
||||||
|
'app/public/signatures/' .
|
||||||
|
User::role('EO Appraisal')->first()->id .
|
||||||
|
'/' .
|
||||||
|
User::role('EO Appraisal')->first()->sign,
|
||||||
|
);
|
||||||
|
|
||||||
|
$imagePathDD = storage_path(
|
||||||
|
'app/public/signatures/' .
|
||||||
|
User::role('DD Appraisal')->first()->id .
|
||||||
|
'/' .
|
||||||
|
User::role('DD Appraisal')->first()->sign,
|
||||||
|
);
|
||||||
|
@endphp
|
||||||
|
<tr>
|
||||||
|
<td style=" padding: 4px;height: 50px">
|
||||||
|
@if (file_exists($imagePathPenilai))
|
||||||
|
<img src="{{ $imagePathPenilai }}" alt="{{ $imagePathPenilai }}" width="80px">
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
@if ($permohonan->approval_so != null)
|
||||||
|
<td style=" padding: 4px;height: 50px">
|
||||||
|
@if (file_exists($imagePathSo))
|
||||||
|
<img src="{{ $imagePathSo }}" alt="{{ $imagePathSo }}" width="80px">
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
@endif
|
||||||
|
@if ($permohonan->approval_eo != null)
|
||||||
|
<td style=" padding: 4px;height: 50px">
|
||||||
|
@if (file_exists($imagePathEO))
|
||||||
|
<img src="{{ $imagePathEO }}" alt="{{ $imagePathEO }}" width="80px">
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
@endif
|
||||||
|
@if ($permohonan->approval_dd != null)
|
||||||
|
<td style=" padding: 4px;height: 50px">
|
||||||
|
@if (file_exists($imagePathDD))
|
||||||
|
<img src="{{ $imagePathDD }}" alt="{{ $imagePathDD }}" width="80px">
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
@endif
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style=" padding: 4px;">{{ $penilai->userPenilaiTeam->name ?? '' }}</br>
|
||||||
|
<span>
|
||||||
|
{{ ucwords(strtolower('PENILAI')) }}
|
||||||
|
</span>
|
||||||
|
</br>
|
||||||
|
<span>
|
||||||
|
{{ isset($penilai->updated_at) ? formatTanggalIndonesia($penilai->updated_at) : '' }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
@if ($permohonan->approval_so != null)
|
||||||
|
<td style=" padding: 4px;">
|
||||||
|
{{ $senior_officer->name ?? '' }}</br>
|
||||||
|
<span>
|
||||||
|
{{ ucwords(strtolower('SENIOR OFFICER')) }}
|
||||||
|
</span>
|
||||||
|
</br>
|
||||||
|
<span>
|
||||||
|
{{ isset($permohonan->approval_so_at) ? formatTanggalIndonesia($permohonan->approval_so_at) : '' }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($permohonan->approval_eo != null)
|
||||||
|
<td style=" padding: 4px;">
|
||||||
|
{{ User::role('EO Appraisal')->first()->name ?? '' }}</br>
|
||||||
|
<span>
|
||||||
|
{{ ucwords(strtolower('EXECUTIVE OFFICER')) }}
|
||||||
|
</span>
|
||||||
|
</br>
|
||||||
|
<span>
|
||||||
|
{{ isset($permohonan->approval_eo_at) ? formatTanggalIndonesia($permohonan->approval_eo_at) : '' }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
@endif
|
||||||
|
@if ($permohonan->approval_dd != null)
|
||||||
|
<td style=" padding: 4px;">
|
||||||
|
{{ User::role('DD Appraisal')->first()->name ?? '' }}</br>
|
||||||
|
<span>
|
||||||
|
{{ ucwords(strtolower('DEPUTY DIRECTOR')) }}
|
||||||
|
</span>
|
||||||
|
</br>
|
||||||
|
<span>
|
||||||
|
{{
|
||||||
|
isset($permohonan->approval_dd_at) ?
|
||||||
|
formatTanggalIndonesia($permohonan->approval_dd_at) : '' }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
@endif
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
@@ -72,7 +72,7 @@ function updateDataUlang(id, kjpp_id, kjppName){
|
|||||||
if(passednih)
|
if(passednih)
|
||||||
{
|
{
|
||||||
var file_data = $("#{{$route[1]}}_dokumenPersetujuan_"+id).prop("files")[0];
|
var file_data = $("#{{$route[1]}}_dokumenPersetujuan_"+id).prop("files")[0];
|
||||||
let useURL = "{{ route($route[0].'.'.$route[1].'.updateulang', '') }}/"+id;
|
let useURL = "{{ route($route[0].'.'.$route[1].'.updateulang', ':id') }}".replace(':id', id);
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
let token = "{{ csrf_token() }}";
|
let token = "{{ csrf_token() }}";
|
||||||
formData.append("dokumen_persetujuan", file_data ?? "");
|
formData.append("dokumen_persetujuan", file_data ?? "");
|
||||||
@@ -132,7 +132,7 @@ function deleteData(data, kjppName) {
|
|||||||
|
|
||||||
//define variable
|
//define variable
|
||||||
let token = "{{ csrf_token() }}";
|
let token = "{{ csrf_token() }}";
|
||||||
let useURL = "{{ route($route[0].'.'.$route[1].'.updateKJPPStatus','') }}/"+data;
|
let useURL = "{{ route($route[0].'.'.$route[1].'.updateKJPPStatus', ':id') }}".replace(':id', data);
|
||||||
|
|
||||||
var input_data = new Object();
|
var input_data = new Object();
|
||||||
input_data._token = token;
|
input_data._token = token;
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
if(passednih)
|
if(passednih)
|
||||||
{
|
{
|
||||||
var file_data = $("#{{$route[1]}}_dokumenPersetujuan_"+id).prop("files")[0];
|
var file_data = $("#{{$route[1]}}_dokumenPersetujuan_"+id).prop("files")[0];
|
||||||
let useURL = "{{ route($route[0].'.'.$route[1].'.update', '') }}/"+id;
|
let useURL = "{{ route($route[0].'.'.$route[1].'.update', $id) }}";
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
let token = "{{ csrf_token() }}";
|
let token = "{{ csrf_token() }}";
|
||||||
formData.append("dokumen_persetujuan", file_data ?? "");
|
formData.append("dokumen_persetujuan", file_data ?? "");
|
||||||
@@ -107,7 +107,8 @@
|
|||||||
|
|
||||||
//define variable
|
//define variable
|
||||||
let token = "{{ csrf_token() }}";
|
let token = "{{ csrf_token() }}";
|
||||||
let useURL = "{{ route($route[0].'.'.$route[1].'.updateKJPPStatus','') }}/"+data;
|
let useURL = "{{ route($route[0].'.'.$route[1].'.updateKJPPStatus', ':id') }}";
|
||||||
|
useURL = useURL.replace(':id', data);
|
||||||
var input_data = new Object();
|
var input_data = new Object();
|
||||||
input_data._token = token;
|
input_data._token = token;
|
||||||
input_data.id =data;
|
input_data.id =data;
|
||||||
|
|||||||
414
resources/views/slik/index.blade.php
Normal file
414
resources/views/slik/index.blade.php
Normal file
@@ -0,0 +1,414 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('admin-kredit.slik') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid">
|
||||||
|
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10"
|
||||||
|
data-datatable-state-save="false" id="slik-table" data-api-url="{{ route('admin-kredit.slik.datatables') }}">
|
||||||
|
<div class="flex-wrap py-5 card-header bg-agi-50">
|
||||||
|
<h3 class="card-title">
|
||||||
|
Data SLIK
|
||||||
|
</h3>
|
||||||
|
<div class="flex flex-wrap gap-2 lg:gap-5">
|
||||||
|
<div class="flex">
|
||||||
|
<label class="input input-sm">
|
||||||
|
<i class="ki-filled ki-magnifier"></i>
|
||||||
|
<input placeholder="Search SLIK" id="search" type="text" value="">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap gap-2.5">
|
||||||
|
<div class="h-[24px] border border-r-gray-200"></div>
|
||||||
|
|
||||||
|
<!-- Import Excel -->
|
||||||
|
<button class="btn btn-sm btn-success" data-modal-toggle="#import-modal">
|
||||||
|
<i class="ki-filled ki-file-up"></i> Import Excel
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a class="btn btn-sm btn-light" href="#" id="export-excel">
|
||||||
|
<i class="ki-filled ki-file-down"></i> Export Excel
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="scrollable-x-auto">
|
||||||
|
<table
|
||||||
|
class="table text-sm font-medium text-gray-700 align-middle table-auto table-border min-w-[1200px]"
|
||||||
|
data-datatable-table="true">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-14">
|
||||||
|
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox" />
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="sandi_bank">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Sandi Bank</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[80px]" data-datatable-column="tahun">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Tahun</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[120px]" data-datatable-column="no_rekening">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">No Rekening</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="cif">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">CIF</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[120px]" data-datatable-column="nama_debitur">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Nama Debitur</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="kolektibilitas">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Kolektibilitas</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="fasilitas">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Fasilitas</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[120px]" data-datatable-column="nilai_agunan">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Nilai Agunan</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[100px]" data-datatable-column="status_agunan">
|
||||||
|
<span class="sort">
|
||||||
|
<span class="sort-label">Status</span>
|
||||||
|
<span class="sort-icon"></span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="min-w-[50px] text-center" data-datatable-column="actions">Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex-col gap-3 justify-center font-medium text-gray-600 card-footer md:justify-between md:flex-row text-2sm">
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
Show
|
||||||
|
<select class="w-16 select select-sm" data-datatable-size="true" name="perpage"> </select> per page
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-4 items-center">
|
||||||
|
<span data-datatable-info="true"> </span>
|
||||||
|
<div class="pagination" data-datatable-pagination="true">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Modal Import Excel -->
|
||||||
|
<div class="modal" data-modal="true" id="import-modal">
|
||||||
|
<div class="modal-content max-w-[500px] top-[15%]">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 class="modal-title">Import Data SLIK</h3>
|
||||||
|
<button class="btn btn-sm btn-icon btn-light btn-clear shrink-0" data-modal-dismiss="true">
|
||||||
|
<i class="ki-filled ki-cross"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form action="{{ route('admin-kredit.slik.import') }}" method="POST" enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="flex flex-col gap-5">
|
||||||
|
<div class="flex flex-col gap-2.5">
|
||||||
|
<label class="text-gray-900 form-label">File Excel</label>
|
||||||
|
<input type="file" name="file" class="file-input" accept=".xlsx,.xls,.csv" required>
|
||||||
|
<div class="text-gray-600 text-2sm">
|
||||||
|
Format yang didukung: .xlsx, .xls, .csv (Maksimal 10MB)
|
||||||
|
</div>
|
||||||
|
<div class="text-blue-600 text-2sm">
|
||||||
|
<a href="{{ route('admin-kredit.slik.download-template') }}"
|
||||||
|
class="underline hover:text-blue-800">
|
||||||
|
<i class="ki-filled ki-download"></i> Download Template Excel
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 bg-yellow-100 rounded border border-yellow-300">
|
||||||
|
<div class="text-sm text-yellow-800">
|
||||||
|
<strong>Catatan:</strong>
|
||||||
|
<ul class="mt-1 list-disc list-inside">
|
||||||
|
<li>Data akan dimulai dari baris ke-2 (setelah header)</li>
|
||||||
|
<li>Pastikan urutan kolom sesuai dengan template</li>
|
||||||
|
<li>Data akan di-update jika sudah ada berdasarkan kombinasi sandi bank, tahun, bulan,
|
||||||
|
dan no rekening</li>
|
||||||
|
<li>Kolom yang wajib diisi: Sandi Bank, Tahun, Bulan, No Rekening, CIF</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<button type="button" class="btn btn-light" data-modal-dismiss="true">Batal</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Import</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('styles')
|
||||||
|
<style>
|
||||||
|
/* Responsive adjustments for table */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.table-responsive {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
max-width: 95% !important;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-cols-1.md\:grid-cols-2 {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure table is scrollable on small screens */
|
||||||
|
.scrollable-x-auto {
|
||||||
|
overflow-x: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent text wrapping in table cells */
|
||||||
|
.table th,
|
||||||
|
.table td {
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow wrapping for long text in detail modal */
|
||||||
|
.modal-body .text-gray-900 {
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
let dataTable;
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
/**
|
||||||
|
* Inisialisasi DataTable untuk SLIK menggunakan KTDataTable
|
||||||
|
*/
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const element = document.querySelector('#slik-table');
|
||||||
|
const searchInput = document.getElementById('search');
|
||||||
|
|
||||||
|
const apiUrl = element.getAttribute('data-api-url');
|
||||||
|
|
||||||
|
// Konfigurasi DataTable menggunakan KTDataTable
|
||||||
|
const dataTableOptions = {
|
||||||
|
apiEndpoint: apiUrl,
|
||||||
|
pageSize: 10,
|
||||||
|
columns: {
|
||||||
|
select: {
|
||||||
|
render: (item, data, context) => {
|
||||||
|
const checkbox = document.createElement('input');
|
||||||
|
checkbox.className = 'checkbox checkbox-sm';
|
||||||
|
checkbox.type = 'checkbox';
|
||||||
|
checkbox.value = data.id.toString();
|
||||||
|
checkbox.setAttribute('data-datatable-row-check', 'true');
|
||||||
|
return checkbox.outerHTML.trim();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sandi_bank: {
|
||||||
|
title: 'Sandi Bank',
|
||||||
|
},
|
||||||
|
tahun: {
|
||||||
|
title: 'Tahun',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.bulan + '-' + data.tahun;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
no_rekening: {
|
||||||
|
title: 'No Rekening',
|
||||||
|
},
|
||||||
|
cif: {
|
||||||
|
title: 'CIF',
|
||||||
|
},
|
||||||
|
nama_debitur: {
|
||||||
|
title: 'Nama Debitur',
|
||||||
|
render: (item, data) => {
|
||||||
|
const nama = data.nama_debitur || '-';
|
||||||
|
return nama.length > 30 ? nama.substring(0, 30) + '...' : nama;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kolektibilitas: {
|
||||||
|
title: 'Kolektibilitas',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.kolektibilitas || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fasilitas: {
|
||||||
|
title: 'Fasilitas',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.fasilitas || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nilai_agunan_formatted: {
|
||||||
|
title: 'Nilai Agunan',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.nilai_agunan_formatted || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status_badge: {
|
||||||
|
title: 'Status',
|
||||||
|
render: (item, data) => {
|
||||||
|
return data.status_badge || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
title: 'Aksi',
|
||||||
|
render: (item, data) => {
|
||||||
|
return `
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<button class="btn btn-sm btn-primary" onclick="moveToLaporan(${data.id})" title="SLIK">
|
||||||
|
<i class="ki-filled ki-file-up"></i> SLIK
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-sm btn-light btn-icon" onclick="showDetail(${data.id})" title="Detail">
|
||||||
|
<i class="ki-filled ki-eye"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Inisialisasi DataTable
|
||||||
|
dataTable = new KTDataTable(element, dataTableOptions);
|
||||||
|
dataTable.showSpinner();
|
||||||
|
|
||||||
|
// Fungsi pencarian
|
||||||
|
searchInput.addEventListener('input', function() {
|
||||||
|
const searchValue = this.value.trim();
|
||||||
|
dataTable.search(searchValue, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Export Excel functionality
|
||||||
|
document.getElementById('export-excel').addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Build export URL with current filters
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (searchInput.value) params.append('search', searchInput.value);
|
||||||
|
const exportUrl = '{{ route('admin-kredit.slik.export') }}?' + params.toString();
|
||||||
|
window.open(exportUrl, '_blank');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Fungsi untuk menampilkan detail data SLIK
|
||||||
|
* @param {number} id - ID data SLIK yang akan ditampilkan
|
||||||
|
*/
|
||||||
|
function showDetail(id) {
|
||||||
|
// Redirect ke halaman detail
|
||||||
|
window.location.href = `{{ route('admin-kredit.slik.show', ':id') }}`.replace(':id', id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fungsi untuk memindahkan data SLIK ke laporan
|
||||||
|
* @param {number} id - ID data SLIK yang akan dipindahkan
|
||||||
|
*/
|
||||||
|
function moveToLaporan(id) {
|
||||||
|
window.Swal.fire({
|
||||||
|
title: 'Konfirmasi',
|
||||||
|
text: 'Apakah Anda yakin ingin memindahkan data ini ke laporan SLIK?',
|
||||||
|
icon: 'question',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: 'Ya, Pindahkan!',
|
||||||
|
cancelButtonText: 'Batal',
|
||||||
|
reverseButtons: true
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
// Tampilkan loading
|
||||||
|
window.Swal.fire({
|
||||||
|
title: 'Memproses...',
|
||||||
|
text: 'Sedang memindahkan data ke laporan SLIK',
|
||||||
|
allowOutsideClick: false,
|
||||||
|
showConfirmButton: false,
|
||||||
|
willOpen: () => {
|
||||||
|
window.Swal.showLoading();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch(`{{ route('admin-kredit.laporan-slik.store') }}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
slik_id: id
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
window.Swal.close();
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
window.Swal.fire({
|
||||||
|
title: 'Berhasil!',
|
||||||
|
text: data.message || 'Data berhasil dipindahkan ke laporan SLIK',
|
||||||
|
icon: 'success',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
}).then(() => {
|
||||||
|
// Reload tabel DataTable
|
||||||
|
dataTable.reload();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
window.Swal.fire({
|
||||||
|
title: 'Gagal!',
|
||||||
|
text: data.message || 'Gagal memindahkan data',
|
||||||
|
icon: 'error',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
window.Swal.close();
|
||||||
|
window.Swal.fire({
|
||||||
|
title: 'Error!',
|
||||||
|
text: 'Terjadi kesalahan saat memindahkan data',
|
||||||
|
icon: 'error',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
260
resources/views/slik/show.blade.php
Normal file
260
resources/views/slik/show.blade.php
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('breadcrumbs')
|
||||||
|
{{ Breadcrumbs::render('admin-kredit.slik.show', $slik) }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="grid">
|
||||||
|
<div class="w-full">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="flex flex-wrap gap-4 justify-between items-center mb-6">
|
||||||
|
<div>
|
||||||
|
<h3 class="text-xl font-semibold text-gray-900">Detail SLIK</h3>
|
||||||
|
<p class="mt-1 text-sm text-gray-600">Informasi lengkap debitur {{ $slik->nama_debitur }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<button class="btn btn-sm btn-primary" onclick="moveToLaporan({{ $slik->id }})"
|
||||||
|
title="Pindahkan ke Laporan SLIK">
|
||||||
|
<i class="ki-filled ki-file-up"></i>
|
||||||
|
SLIK
|
||||||
|
</button>
|
||||||
|
<a href="{{ route('admin-kredit.slik.index') }}" class="btn btn-sm btn-light">
|
||||||
|
<i class="ki-filled ki-arrow-left"></i>
|
||||||
|
Kembali
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Card Detail -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Informasi Debitur</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||||
|
<!-- Informasi Debitur -->
|
||||||
|
<div class="space-y-4">
|
||||||
|
<h4 class="mb-3 text-base font-semibold text-gray-800">Data Debitur</h4>
|
||||||
|
|
||||||
|
<div class="space-y-3">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Nama Debitur:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $slik->nama_debitur ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">No. Rekening:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $slik->no_rekening ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">CIF:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $slik->cif ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">NPWP:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $slik->npwp ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">No. KTP:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $slik->no_ktp ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informasi Fasilitas -->
|
||||||
|
<div class="space-y-4">
|
||||||
|
<h4 class="mb-3 text-base font-semibold text-gray-800">Data Fasilitas</h4>
|
||||||
|
|
||||||
|
<div class="space-y-3">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Fasilitas:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $slik->fasilitas ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Kolektibilitas:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $slik->kolektibilitas ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Jenis Agunan:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $slik->jenis_agunan ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Nilai Agunan:</span>
|
||||||
|
<span class="text-sm text-gray-900">Rp
|
||||||
|
{{ number_format($slik->nilai_agunan ?? 0, 0, ',', '.') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informasi Tambahan -->
|
||||||
|
<div class="pt-6 mt-8 border-t border-gray-200">
|
||||||
|
<h4 class="mb-4 text-base font-semibold text-gray-800">Informasi Tambahan</h4>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||||
|
<div class="space-y-3">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Tanggal Mulai:</span>
|
||||||
|
<span
|
||||||
|
class="text-sm text-gray-900">{{ $slik->tanggal_mulai ? \Carbon\Carbon::parse($slik->tanggal_mulai)->format('d/m/Y') : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Tanggal Jatuh Tempo:</span>
|
||||||
|
<span
|
||||||
|
class="text-sm text-gray-900">{{ $slik->tanggal_jatuh_tempo ? \Carbon\Carbon::parse($slik->tanggal_jatuh_tempo)->format('d/m/Y') : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Tanggal Restrukturisasi:</span>
|
||||||
|
<span
|
||||||
|
class="text-sm text-gray-900">{{ $slik->tanggal_restrukturisasi ? \Carbon\Carbon::parse($slik->tanggal_restrukturisasi)->format('d/m/Y') : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-3">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Tanggal Kondisi:</span>
|
||||||
|
<span
|
||||||
|
class="text-sm text-gray-900">{{ $slik->tanggal_kondisi ? \Carbon\Carbon::parse($slik->tanggal_kondisi)->format('d/m/Y') : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Tanggal Lapor:</span>
|
||||||
|
<span
|
||||||
|
class="text-sm text-gray-900">{{ $slik->tanggal_lapor ? \Carbon\Carbon::parse($slik->tanggal_lapor)->format('d/m/Y') : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Tanggal Selesai:</span>
|
||||||
|
<span
|
||||||
|
class="text-sm text-gray-900">{{ $slik->tanggal_selesai ? \Carbon\Carbon::parse($slik->tanggal_selesai)->format('d/m/Y') : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-3">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Kode Kantor:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $slik->kode_kantor ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Kode Cabang:</span>
|
||||||
|
<span class="text-sm text-gray-900">{{ $slik->kode_cabang ?? '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-sm font-medium text-gray-600">Status:</span>
|
||||||
|
<span class="text-sm text-gray-900">
|
||||||
|
<span
|
||||||
|
class="badge badge-light-{{ $slik->status == 'aktif' ? 'success' : 'danger' }}">
|
||||||
|
{{ $slik->status ?? 'aktif' }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Fungsi untuk memindahkan data SLIK ke laporan
|
||||||
|
* @param {number} id - ID data SLIK yang akan dipindahkan
|
||||||
|
*/
|
||||||
|
function moveToLaporan(id) {
|
||||||
|
window.Swal.fire({
|
||||||
|
title: 'Konfirmasi',
|
||||||
|
text: 'Apakah Anda yakin ingin memindahkan data ini ke laporan SLIK?',
|
||||||
|
icon: 'question',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: 'Ya, Pindahkan!',
|
||||||
|
cancelButtonText: 'Batal',
|
||||||
|
reverseButtons: true
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
// Tampilkan loading
|
||||||
|
window.Swal.fire({
|
||||||
|
title: 'Memproses...',
|
||||||
|
text: 'Sedang memindahkan data ke laporan SLIK',
|
||||||
|
allowOutsideClick: false,
|
||||||
|
showConfirmButton: false,
|
||||||
|
willOpen: () => {
|
||||||
|
window.Swal.showLoading();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch(`{{ route('admin-kredit.laporan-slik.store') }}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
slik_id: id
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
window.Swal.close();
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
window.Swal.fire({
|
||||||
|
title: 'Berhasil!',
|
||||||
|
text: data.message || 'Data berhasil dipindahkan ke laporan SLIK',
|
||||||
|
icon: 'success',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
}).then(() => {
|
||||||
|
// Disable tombol setelah berhasil
|
||||||
|
const button = document.querySelector(
|
||||||
|
`button[onclick="moveToLaporan(${id})"]`);
|
||||||
|
if (button) {
|
||||||
|
button.disabled = true;
|
||||||
|
button.innerHTML =
|
||||||
|
'<i class="ki-filled ki-check"></i> Sudah di SLIK';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
window.Swal.fire({
|
||||||
|
title: 'Gagal!',
|
||||||
|
text: data.message || 'Gagal memindahkan data',
|
||||||
|
icon: 'error',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
window.Swal.close();
|
||||||
|
window.Swal.fire({
|
||||||
|
title: 'Error!',
|
||||||
|
text: 'Terjadi kesalahan saat memindahkan data',
|
||||||
|
icon: 'error',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add any additional JavaScript for detail page
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Initialize any required components
|
||||||
|
KTApp.init();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
@@ -15,11 +15,11 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
@include('lpj::assetsku.includenya')
|
@include('lpj::assetsku.includenya')
|
||||||
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
|
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
|
||||||
<div class="card border border-agi-100 min-w-full">
|
<div class="min-w-full border card border-agi-100">
|
||||||
<div class="card-header bg-agi-50">
|
<div class="card-header bg-agi-50">
|
||||||
<h3 class="card-title">Denah</h3>
|
<h3 class="card-title">Denah</h3>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex gap-2 items-center">
|
||||||
<a href="{{ route('surveyor.show', ['id' => $permohonan->id]) }}?form=denah" class="btn btn-xs btn-info">
|
<a href="{{ route('surveyor.show', ['id' => $permohonan->id]) }}?form=denah" class="btn btn-xs btn-info">
|
||||||
<i class="ki-filled ki-exit-left"></i> Back
|
<i class="ki-filled ki-exit-left"></i> Back
|
||||||
</a>
|
</a>
|
||||||
@@ -41,13 +41,13 @@
|
|||||||
<div id="denah-container">
|
<div id="denah-container">
|
||||||
@if (isset($formDenah['denahs']) && is_array($formDenah['denahs']) && count($formDenah['denahs']) > 0)
|
@if (isset($formDenah['denahs']) && is_array($formDenah['denahs']) && count($formDenah['denahs']) > 0)
|
||||||
@foreach ($formDenah['denahs'] as $index => $denah)
|
@foreach ($formDenah['denahs'] as $index => $denah)
|
||||||
<div class="denah-item grid gap-5 mb-5 border p-4 rounded">
|
<div class="grid gap-5 p-4 mb-5 rounded border denah-item">
|
||||||
<div class="flex flex-wrap gap-4">
|
<div class="flex flex-wrap gap-4">
|
||||||
<div class="flex w-full items-baseline flex-wrap lg:flex-nowrap gap-4">
|
<div class="flex flex-wrap gap-4 items-baseline w-full lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
<span class="form-label">Upload Denah (Foto/PDF)</span>
|
<span class="form-label">Upload Denah (Foto/PDF)</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="w-full grid gap-5">
|
<div class="grid gap-5 w-full">
|
||||||
<!-- Preview Container -->
|
<!-- Preview Container -->
|
||||||
<div class="preview-container-{{ $index }}">
|
<div class="preview-container-{{ $index }}">
|
||||||
@if (isset($denah['foto_denah']))
|
@if (isset($denah['foto_denah']))
|
||||||
@@ -68,9 +68,9 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-group w-full flex gap-2">
|
<div class="flex gap-2 w-full input-group">
|
||||||
<input type="file" name="foto_denah[]"
|
<input type="file" name="foto_denah[]"
|
||||||
class="file-input file-input-bordered w-full"
|
class="w-full file-input file-input-bordered"
|
||||||
data-index="{{ $index }}" accept=".jpg,.jpeg,.png,.pdf"
|
data-index="{{ $index }}" accept=".jpg,.jpeg,.png,.pdf"
|
||||||
onchange="previewFile(this)">
|
onchange="previewFile(this)">
|
||||||
</div>
|
</div>
|
||||||
@@ -78,26 +78,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap lg:flex-nowrap w-full gap-4">
|
<div class="flex flex-wrap gap-4 w-full lg:flex-nowrap">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="flex flex-wrap gap-4">
|
<div class="flex flex-wrap gap-4">
|
||||||
<div class="flex w-full items-center justify-center gap-4">
|
<div class="flex gap-4 justify-center items-center w-full">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
<span class="form-label">Nama Denah</span>
|
<span class="form-label">Nama Denah</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="nama_denah[]" class="input w-full"
|
<input type="text" name="nama_denah[]" class="w-full input"
|
||||||
value="{{ $denah['nama_denah'] ?? '' }}">
|
value="{{ $denah['nama_denah'] ?? '' }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="flex flex-wrap gap-4">
|
<div class="flex flex-wrap gap-4">
|
||||||
<div class="flex w-full items-center justify-center gap-4">
|
<div class="flex gap-4 justify-center items-center w-full">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
<span class="form-label"> Luas</span>
|
<span class="form-label"> Luas</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="luas_denah[]"
|
<input type="text" name="luas_denah[]"
|
||||||
class="input w-full number-format"
|
class="w-full input number-format"
|
||||||
value="{{ isset($denah['luas_denah']) ? $denah['luas_denah'] . ' m²' : '' }}"
|
value="{{ isset($denah['luas_denah']) ? $denah['luas_denah'] . ' m²' : '' }}"
|
||||||
onkeyup="formatNumber(this)">
|
onkeyup="formatNumber(this)">
|
||||||
</div>
|
</div>
|
||||||
@@ -115,45 +115,45 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
@else
|
@else
|
||||||
<!-- Tambahkan satu elemen default jika tidak ada data -->
|
<!-- Tambahkan satu elemen default jika tidak ada data -->
|
||||||
<div class="denah-item grid gap-5 mb-5 border p-4 rounded">
|
<div class="grid gap-5 p-4 mb-5 rounded border denah-item">
|
||||||
<!-- Isi dengan elemen default seperti sebelumnya -->
|
<!-- Isi dengan elemen default seperti sebelumnya -->
|
||||||
<div class="flex flex-wrap gap-4">
|
<div class="flex flex-wrap gap-4">
|
||||||
<div class="flex w-full items-baseline flex-wrap lg:flex-nowrap gap-4">
|
<div class="flex flex-wrap gap-4 items-baseline w-full lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
<span class="form-label">Upload Denah (Foto/PDF)</span>
|
<span class="form-label">Upload Denah (Foto/PDF)</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="w-full grid gap-5">
|
<div class="grid gap-5 w-full">
|
||||||
<div class="preview-container-0">
|
<div class="preview-container-0">
|
||||||
<!-- Preview akan ditampilkan di sini -->
|
<!-- Preview akan ditampilkan di sini -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-group w-full flex gap-2">
|
<div class="flex gap-2 w-full input-group">
|
||||||
<input type="file" name="foto_denah[]"
|
<input type="file" name="foto_denah[]"
|
||||||
class="file-input file-input-bordered w-full" data-index="0"
|
class="w-full file-input file-input-bordered" data-index="0"
|
||||||
accept=".jpg,.jpeg,.png,.pdf" onchange="previewFile(this)">
|
accept=".jpg,.jpeg,.png,.pdf" onchange="previewFile(this)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap lg:flex-nowrap w-full gap-4">
|
<div class="flex flex-wrap gap-4 w-full lg:flex-nowrap">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="flex flex-wrap gap-4">
|
<div class="flex flex-wrap gap-4">
|
||||||
<div class="flex w-full items-center justify-center gap-4">
|
<div class="flex gap-4 justify-center items-center w-full">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
<span class="form-label">Nama Denah</span>
|
<span class="form-label">Nama Denah</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="nama_denah[]" class="input w-full">
|
<input type="text" name="nama_denah[]" class="w-full input">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="flex flex-wrap gap-4">
|
<div class="flex flex-wrap gap-4">
|
||||||
<div class="flex w-full items-center justify-center gap-4">
|
<div class="flex gap-4 justify-center items-center w-full">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
<span class="form-label"> Luas</span>
|
<span class="form-label"> Luas</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="luas_denah[]" class="input w-full number-format"
|
<input type="text" name="luas_denah[]" class="w-full input number-format"
|
||||||
onkeyup="formatNumber(this)">
|
onkeyup="formatNumber(this)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -164,18 +164,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="w-full p-4">
|
<div class="p-4 w-full">
|
||||||
<div class="flex flex-wrap gap-4">
|
<div class="flex flex-wrap gap-4">
|
||||||
<div class="flex w-full items-center justify-center gap-4">
|
<div class="flex gap-4 justify-center items-center w-full">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
<span class="form-label">Total Luas</span>
|
<span class="form-label">Total Luas</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="total_luas" id="totalLuas" class="input w-full number-format" readonly>
|
<input type="text" name="total_luas" id="totalLuas"
|
||||||
|
class="w-full input number-format" readonly>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-end gap-2" style="margin-right: 20px; margin-top: 20px">
|
<div class="flex gap-2 justify-end" style="margin-right: 20px; margin-top: 20px">
|
||||||
<button type="button" class="btn btn-success" id="saveButton" onclick="submitDenah()">
|
<button type="button" class="btn btn-success" id="saveButton" onclick="submitDenah()">
|
||||||
<span id="saveButtonText">Save</span>
|
<span id="saveButtonText">Save</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -240,23 +241,38 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menghitung total luas dari semua input denah
|
||||||
|
* Mendukung format angka dengan koma sebagai pemisah desimal
|
||||||
|
* dan menghapus format ribuan (titik) sebelum perhitungan
|
||||||
|
*/
|
||||||
function calculateTotalLuas() {
|
function calculateTotalLuas() {
|
||||||
let totalLuas = 0;
|
let totalLuas = 0;
|
||||||
|
|
||||||
const luasInputs = document.querySelectorAll('input[name="luas_denah[]"]');
|
const luasInputs = document.querySelectorAll('input[name="luas_denah[]"]');
|
||||||
luasInputs.forEach(input => {
|
luasInputs.forEach(input => {
|
||||||
const value = parseFloat(input.value.replace(/[^0-9.]/g, ''));
|
// Hapus format ribuan (titik) dan spasi
|
||||||
|
let cleanValue = input.value.replace(/\./g, '').replace(/\s/g, '');
|
||||||
|
|
||||||
|
// Ganti koma dengan titik untuk desimal
|
||||||
|
cleanValue = cleanValue.replace(',', '.');
|
||||||
|
|
||||||
|
// Parse ke float
|
||||||
|
const value = parseFloat(cleanValue);
|
||||||
if (!isNaN(value)) {
|
if (!isNaN(value)) {
|
||||||
totalLuas += value;
|
totalLuas += value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalLuasInput = document.getElementById('totalLuas');
|
const totalLuasInput = document.getElementById('totalLuas');
|
||||||
totalLuasInput.value = totalLuas ? `${totalLuas.toLocaleString()} m²` : '';
|
totalLuasInput.value = totalLuas ? `${totalLuas.toLocaleString('id-ID')} m²` : '';
|
||||||
|
|
||||||
|
// Log untuk debugging
|
||||||
|
console.log('Total luas dihitung:', totalLuas);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tambahkan event listener untuk setiap input luas_denah[]
|
// Tambahkan event listener untuk setiap input luas_denah[]
|
||||||
document.addEventListener('input', function (e) {
|
document.addEventListener('input', function(e) {
|
||||||
if (e.target && e.target.name === 'luas_denah[]') {
|
if (e.target && e.target.name === 'luas_denah[]') {
|
||||||
calculateTotalLuas();
|
calculateTotalLuas();
|
||||||
}
|
}
|
||||||
@@ -271,17 +287,17 @@
|
|||||||
denahItem.className = 'denah-item grid gap-5 mb-5 border p-4 rounded';
|
denahItem.className = 'denah-item grid gap-5 mb-5 border p-4 rounded';
|
||||||
denahItem.innerHTML = `
|
denahItem.innerHTML = `
|
||||||
<div class="flex flex-wrap gap-4">
|
<div class="flex flex-wrap gap-4">
|
||||||
<div class="flex w-full items-baseline flex-wrap lg:flex-nowrap gap-4">
|
<div class="flex flex-wrap gap-4 items-baseline w-full lg:flex-nowrap">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
<span class="form-label">Upload Denah (Foto/PDF)</span>
|
<span class="form-label">Upload Denah (Foto/PDF)</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="w-full grid gap-5">
|
<div class="grid gap-5 w-full">
|
||||||
<div class="preview-container-${index}">
|
<div class="preview-container-${index}">
|
||||||
<!-- Preview akan ditampilkan di sini -->
|
<!-- Preview akan ditampilkan di sini -->
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group w-full flex gap-2">
|
<div class="flex gap-2 w-full input-group">
|
||||||
<input type="file" name="foto_denah[]"
|
<input type="file" name="foto_denah[]"
|
||||||
class="file-input file-input-bordered w-full"
|
class="w-full file-input file-input-bordered"
|
||||||
data-index="${index}"
|
data-index="${index}"
|
||||||
accept=".jpg,.jpeg,.png,.pdf"
|
accept=".jpg,.jpeg,.png,.pdf"
|
||||||
onchange="previewFile(this)">
|
onchange="previewFile(this)">
|
||||||
@@ -289,25 +305,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-wrap lg:flex-nowrap w-full gap-4">
|
<div class="flex flex-wrap gap-4 w-full lg:flex-nowrap">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="flex flex-wrap gap-4">
|
<div class="flex flex-wrap gap-4">
|
||||||
<div class="flex w-full items-center justify-center gap-4">
|
<div class="flex gap-4 justify-center items-center w-full">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
<span class="form-label">Nama Denah</span>
|
<span class="form-label">Nama Denah</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="nama_denah[]" class="input w-full">
|
<input type="text" name="nama_denah[]" class="w-full input">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="flex flex-wrap gap-4">
|
<div class="flex flex-wrap gap-4">
|
||||||
<div class="flex w-full items-center justify-center gap-4">
|
<div class="flex gap-4 justify-center items-center w-full">
|
||||||
<label class="form-label max-w-56">
|
<label class="form-label max-w-56">
|
||||||
<span class="form-label"> Luas</span>
|
<span class="form-label"> Luas</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="luas_denah[]"
|
<input type="text" name="luas_denah[]"
|
||||||
class="input w-full number-format"
|
class="w-full input number-format"
|
||||||
onkeyup="formatNumber(this)">
|
onkeyup="formatNumber(this)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Jakarta {{ formatTanggalIndonesia($permohonan->penilaian->waktu_penilaian) }}
|
{{ $permohonan->debiture->branch->name ?? '' }} {{ formatTanggalIndonesia($permohonan->penilaian->waktu_penilaian) }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|||||||
@@ -9,3 +9,17 @@
|
|||||||
* is assigned the "api" middleware group. Enjoy building your API!
|
* is assigned the "api" middleware group. Enjoy building your API!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
use Modules\Lpj\Http\Controllers\Api\DebiturController;
|
||||||
|
|
||||||
|
// Route untuk pencarian debitur (autocomplete)
|
||||||
|
Route::middleware(['web', 'auth'])->group(function () {
|
||||||
|
Route::get('/debitur/search', [DebiturController::class, 'search'])
|
||||||
|
->name('debitur.search');
|
||||||
|
|
||||||
|
// Route untuk get detail debitur berdasarkan code
|
||||||
|
Route::get('/debitur/detail', [DebiturController::class, 'getByCode'])
|
||||||
|
->name('debitur.detail');
|
||||||
|
});
|
||||||
|
|||||||
@@ -728,13 +728,19 @@ Breadcrumbs::for('basicdata.jenis-lampiran.edit', function (BreadcrumbTrail $tra
|
|||||||
|
|
||||||
// Laporan Admin Kredit
|
// Laporan Admin Kredit
|
||||||
Breadcrumbs::for('laporan-admin-kredit', function ($trail) {
|
Breadcrumbs::for('laporan-admin-kredit', function ($trail) {
|
||||||
$trail->push('Laporan Admin Kredit', route('laporan-admin-kredit.index'));
|
$trail->push('Laporan Admin Kredit', route('admin-kredit.laporan.index'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Laporan Admin Kredit Laporan SLIK
|
||||||
|
Breadcrumbs::for('admin-kredit.laporan-slik', function (BreadcrumbTrail $trail) {
|
||||||
|
$trail->parent('laporan-admin-kredit');
|
||||||
|
$trail->push('Laporan SLIK', route('admin-kredit.laporan-slik.index'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Laporan Admin Kredit Edit
|
// Laporan Admin Kredit Edit
|
||||||
Breadcrumbs::for('laporan-admin-kredit-edit', function (BreadcrumbTrail $trail, $laporanAdminKredit) {
|
Breadcrumbs::for('laporan-admin-kredit-edit', function (BreadcrumbTrail $trail, $laporanAdminKredit) {
|
||||||
$trail->parent('laporan-admin-kredit');
|
$trail->parent('laporan-admin-kredit');
|
||||||
$trail->push('Edit', route('laporan-admin-kredit.edit', $laporanAdminKredit->id));
|
$trail->push('Edit', route('admin-kredit.laporan.edit', $laporanAdminKredit->id));
|
||||||
});
|
});
|
||||||
|
|
||||||
Breadcrumbs::for('bank-data', function ($trail) {
|
Breadcrumbs::for('bank-data', function ($trail) {
|
||||||
@@ -786,5 +792,60 @@ Breadcrumbs::for('laporan-debiture', function ($trail) {
|
|||||||
Breadcrumbs::for('laporan-sla-penilai', function ($trail) {
|
Breadcrumbs::for('laporan-sla-penilai', function ($trail) {
|
||||||
$trail->push('Laporan SLA Penilai', route('laporan-sla-penilai.index'));
|
$trail->push('Laporan SLA Penilai', route('laporan-sla-penilai.index'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Breadcrumbs::for('memo.index', function (BreadcrumbTrail $trail) {
|
||||||
|
$trail->push('Memo Penyelesaian', route('memo.index'));
|
||||||
|
});
|
||||||
|
|
||||||
|
Breadcrumbs::for('memo.show', function (BreadcrumbTrail $trail) {
|
||||||
|
$trail->push('Memo Penyelesaian', route('memo.index'));
|
||||||
|
});
|
||||||
|
|
||||||
|
Breadcrumbs::for('memo.create', function (BreadcrumbTrail $trail) {
|
||||||
|
$trail->parent('memo.index');
|
||||||
|
$trail->push('Create', route('memo.index'));
|
||||||
|
});
|
||||||
|
|
||||||
|
Breadcrumbs::for('memo.preview', function (BreadcrumbTrail $trail) {
|
||||||
|
$trail->parent('memo.create');
|
||||||
|
$trail->push('Preview', route('memo.index'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Breadcrumb untuk Bucok
|
||||||
|
Breadcrumbs::for('bucok', function (BreadcrumbTrail $trail) {
|
||||||
|
$trail->push('Data Bucok', route('bucok.index'));
|
||||||
|
});
|
||||||
|
|
||||||
|
Breadcrumbs::for('bucok.show', function (BreadcrumbTrail $trail, $bucok) {
|
||||||
|
$trail->parent('bucok');
|
||||||
|
$trail->push('Detail Bucok #' . $bucok->nomor_tiket);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Breadcrumb untuk SLIK
|
||||||
|
Breadcrumbs::for('admin-kredit.slik', function (BreadcrumbTrail $trail) {
|
||||||
|
$trail->push('Data SLIK', route('admin-kredit.slik.index'));
|
||||||
|
});
|
||||||
|
|
||||||
|
Breadcrumbs::for('admin-kredit.slik.index', function (BreadcrumbTrail $trail) {
|
||||||
|
$trail->parent('admin-kredit.slik');
|
||||||
|
$trail->push('Data SLIK', route('admin-kredit.slik.index'));
|
||||||
|
});
|
||||||
|
|
||||||
|
Breadcrumbs::for('admin-kredit.slik.show', function (BreadcrumbTrail $trail, $slik) {
|
||||||
|
$trail->parent('admin-kredit.slik');
|
||||||
|
$trail->push('Detail SLIK #' . $slik->id, route('admin-kredit.slik.show', $slik));
|
||||||
|
});
|
||||||
|
|
||||||
|
Breadcrumbs::for('admin-kredit.slik.import-form', function (BreadcrumbTrail $trail) {
|
||||||
|
$trail->parent('admin-kredit.slik');
|
||||||
|
$trail->push('Import Data SLIK', route('admin-kredit.slik.import-form'));
|
||||||
|
});
|
||||||
|
|
||||||
|
Breadcrumbs::for('admin-kredit.laporan-slik.show', function (BreadcrumbTrail $trail, $slik) {
|
||||||
|
$trail->parent('admin-kredit.laporan-slik');
|
||||||
|
$trail->push('Detail SLIK #' . $slik->id, route('admin-kredit.laporan-slik.show', $slik));
|
||||||
|
});
|
||||||
|
|
||||||
// add andy
|
// add andy
|
||||||
require __DIR__ . '/breadcrumbs_registrasi.php';
|
require __DIR__ . '/breadcrumbs_registrasi.php';
|
||||||
|
|||||||
@@ -109,6 +109,11 @@ Breadcrumbs::for('pembayaran', function (BreadcrumbTrail $trail) {
|
|||||||
$trail->push('Pembayaran', route('pembayaran.index'));
|
$trail->push('Pembayaran', route('pembayaran.index'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Breadcrumbs::for('pembayaran.create', function (BreadcrumbTrail $trail) {
|
||||||
|
$trail->parent('pembayaran');
|
||||||
|
$trail->push('Buat Pembayaran');
|
||||||
|
});
|
||||||
|
|
||||||
Breadcrumbs::for('pembayaran.edit', function (BreadcrumbTrail $trail) {
|
Breadcrumbs::for('pembayaran.edit', function (BreadcrumbTrail $trail) {
|
||||||
$trail->parent('pembayaran');
|
$trail->parent('pembayaran');
|
||||||
$trail->push('Lakukan Pembayaran');
|
$trail->push('Lakukan Pembayaran');
|
||||||
|
|||||||
@@ -131,9 +131,17 @@ Route::middleware(['auth'])->group(function () {
|
|||||||
|
|
||||||
Route::controller(PembayaranController::class)->group(function () {
|
Route::controller(PembayaranController::class)->group(function () {
|
||||||
Route::get('/pembayaran', 'index')->name('pembayaran.index');
|
Route::get('/pembayaran', 'index')->name('pembayaran.index');
|
||||||
|
Route::get('/pembayaran/create', 'create')->name('pembayaran.create');
|
||||||
|
Route::get('/pembayaran/kurang', 'kurang')->name('pembayaran.kurang.index');
|
||||||
|
Route::get('/pembayaran/lebih', 'lebih')->name('pembayaran.lebih.index');
|
||||||
Route::get('/pembayaran/{pembayaran}/edit', 'edit')->name('pembayaran.edit');
|
Route::get('/pembayaran/{pembayaran}/edit', 'edit')->name('pembayaran.edit');
|
||||||
Route::post('pembayaran','store')->name('pembayaran.store');
|
Route::post('pembayaran','store')->name('pembayaran.store');
|
||||||
Route::get('/pembayaran/datatables', 'dataForDatatables')->name('pembayaran.datatables');
|
Route::get('/pembayaran/datatables', 'dataForDatatables')->name('pembayaran.datatables');
|
||||||
|
Route::get('/pembayaran/datatables-kurang','dataForDatatablesKurang')->name('pembayaran.kurang.datatables');
|
||||||
|
Route::get('/pembayaran/datatables-lebih','dataForDatatablesLebih')->name('pembayaran.lebih.datatables');
|
||||||
|
|
||||||
|
Route::get('/pembayaran/{pembayaran}/kurang', 'editKurang')->name('pembayaran.kurang');
|
||||||
|
Route::get('/pembayaran/{pembayaran}/lebih', 'editLebih')->name('pembayaran.lebih');
|
||||||
|
|
||||||
Route::put('/pembayaran/{pembayaran}', 'update')->name('pembayaran.update');
|
Route::put('/pembayaran/{pembayaran}', 'update')->name('pembayaran.update');
|
||||||
|
|
||||||
|
|||||||
166
routes/web.php
166
routes/web.php
@@ -1,55 +1,62 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Modules\Lpj\Http\Controllers\ActivityController;
|
|
||||||
use Modules\Lpj\Http\Controllers\ArahMataAnginController;
|
|
||||||
use Modules\Lpj\Http\Controllers\BankDataController;
|
|
||||||
use Modules\Lpj\Http\Controllers\CustomFieldController;
|
|
||||||
use Modules\Lpj\Http\Controllers\DebitureController;
|
|
||||||
use Modules\Lpj\Http\Controllers\DokumenJaminanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\HubunganPemilikJaminanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\HubunganPenghuniJaminanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\IjinUsahaController;
|
|
||||||
use Modules\Lpj\Http\Controllers\JenisDokumenController;
|
|
||||||
use Modules\Lpj\Http\Controllers\JenisFasilitasKreditController;
|
|
||||||
use Modules\Lpj\Http\Controllers\JenisJaminanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\JenisLampiranController;
|
|
||||||
use Modules\Lpj\Http\Controllers\JenisLaporanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\JenisLegalitasJaminanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\JenisPenilaianController;
|
|
||||||
use Modules\Lpj\Http\Controllers\KJPPController;
|
|
||||||
use Modules\Lpj\Http\Controllers\LampiranDokumenController;
|
|
||||||
use Modules\Lpj\Http\Controllers\LaporanAdminKreditController;
|
|
||||||
use Modules\Lpj\Http\Controllers\LaporanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\LaporanExternalController;
|
|
||||||
use Modules\Lpj\Http\Controllers\LaporanHasilPenilaianJaminanInternalExternalController;
|
|
||||||
use Modules\Lpj\Http\Controllers\LaporanPembatalanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\LaporanPenilaianJaminanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\LaporanPermohonanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\NilaiPlafondController;
|
|
||||||
use Modules\Lpj\Http\Controllers\NocController;
|
use Modules\Lpj\Http\Controllers\NocController;
|
||||||
use Modules\Lpj\Http\Controllers\PembatalanController;
|
use Modules\Lpj\Http\Controllers\SLAController;
|
||||||
use Modules\Lpj\Http\Controllers\PemilikJaminanController;
|
use Modules\Lpj\Http\Controllers\KJPPController;
|
||||||
use Modules\Lpj\Http\Controllers\PenilaianController;
|
use Modules\Lpj\Http\Controllers\MemoController;
|
||||||
use Modules\Lpj\Http\Controllers\PenilaiController;
|
use Modules\Lpj\Http\Controllers\SlikController;
|
||||||
use Modules\Lpj\Http\Controllers\PermohonanController;
|
use Modules\Lpj\Http\Controllers\BucokController;
|
||||||
use Modules\Lpj\Http\Controllers\PersetujuanPenawaranController;
|
use Modules\Lpj\Http\Controllers\TeamsController;
|
||||||
use Modules\Lpj\Http\Controllers\RegionController;
|
use Modules\Lpj\Http\Controllers\RegionController;
|
||||||
use Modules\Lpj\Http\Controllers\ResumeController;
|
use Modules\Lpj\Http\Controllers\ResumeController;
|
||||||
use Modules\Lpj\Http\Controllers\SLAController;
|
|
||||||
use Modules\Lpj\Http\Controllers\StatusPermohonanController;
|
|
||||||
use Modules\Lpj\Http\Controllers\SurveyorController;
|
|
||||||
use Modules\Lpj\Http\Controllers\TeamsController;
|
|
||||||
use Modules\Lpj\Http\Controllers\TenderController;
|
use Modules\Lpj\Http\Controllers\TenderController;
|
||||||
use Modules\Lpj\Http\Controllers\TujuanPenilaianController;
|
use Modules\Lpj\Http\Controllers\LaporanController;
|
||||||
use Modules\Lpj\Http\Controllers\TujuanPenilaianKJPPController;
|
use Modules\Lpj\Http\Controllers\PenilaiController;
|
||||||
use Modules\Lpj\Http\Controllers\LaporanPenilaiJaminanController;
|
use Modules\Lpj\Http\Controllers\ActivityController;
|
||||||
use Modules\Lpj\Http\Controllers\RekapHarianSoController;
|
use Modules\Lpj\Http\Controllers\BankDataController;
|
||||||
use Modules\Lpj\Http\Controllers\LaporanBiayaInternalExternalController;
|
use Modules\Lpj\Http\Controllers\DebitureController;
|
||||||
use Modules\Lpj\Http\Controllers\LaporanMonitoringSoController;
|
use Modules\Lpj\Http\Controllers\SurveyorController;
|
||||||
use Modules\Lpj\Http\Controllers\LaporanDebitureController;
|
use Modules\Lpj\Http\Controllers\IjinUsahaController;
|
||||||
|
use Modules\Lpj\Http\Controllers\PenilaianController;
|
||||||
|
use Modules\Lpj\Http\Controllers\PembatalanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\PermohonanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\CustomFieldController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanSlikController;
|
||||||
use Modules\Lpj\Http\Controllers\LaporanUserController;
|
use Modules\Lpj\Http\Controllers\LaporanUserController;
|
||||||
|
use Modules\Lpj\Http\Controllers\JenisDokumenController;
|
||||||
|
use Modules\Lpj\Http\Controllers\JenisJaminanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\JenisLaporanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\NilaiPlafondController;
|
||||||
|
use Modules\Lpj\Http\Controllers\ArahMataAnginController;
|
||||||
|
use Modules\Lpj\Http\Controllers\DaftarPustakaController;
|
||||||
|
use Modules\Lpj\Http\Controllers\JenisLampiranController;
|
||||||
|
use Modules\Lpj\Http\Controllers\RekapHarianSoController;
|
||||||
|
use Modules\Lpj\Http\Controllers\DokumenJaminanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\JenisPenilaianController;
|
||||||
|
use Modules\Lpj\Http\Controllers\PemilikJaminanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LampiranDokumenController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanDebitureController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanExternalController;
|
||||||
|
use Modules\Lpj\Http\Controllers\TujuanPenilaianController;
|
||||||
|
use Modules\Lpj\Http\Controllers\StatusPermohonanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanPembatalanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanPermohonanController;
|
||||||
use Modules\Lpj\Http\Controllers\LaporanSLAPenilaiController;
|
use Modules\Lpj\Http\Controllers\LaporanSLAPenilaiController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanAdminKreditController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanMonitoringSoController;
|
||||||
|
use Modules\Lpj\Http\Controllers\TujuanPenilaianKJPPController;
|
||||||
|
use Modules\Lpj\Http\Controllers\JenisFasilitasKreditController;
|
||||||
|
use Modules\Lpj\Http\Controllers\PersetujuanPenawaranController;
|
||||||
|
use Modules\Lpj\Http\Controllers\CategoryDaftarPustakaController;
|
||||||
|
use Modules\Lpj\Http\Controllers\JenisLegalitasJaminanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanPenilaiJaminanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\HubunganPemilikJaminanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\HubunganPenghuniJaminanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanPenilaianJaminanController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanBiayaInternalExternalController;
|
||||||
|
use Modules\Lpj\Http\Controllers\LaporanHasilPenilaianJaminanInternalExternalController;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -394,6 +401,17 @@ Route::middleware(['auth'])->group(function () {
|
|||||||
});
|
});
|
||||||
Route::resource('laporan', LaporanController::class);
|
Route::resource('laporan', LaporanController::class);
|
||||||
|
|
||||||
|
Route::group(['prefix' => 'memo'], function () {
|
||||||
|
Route::get('datatables', [MemoController::class, 'dataForDatatables'])->name('memo.datatables');
|
||||||
|
Route::get('create-bulk', [MemoController::class, 'create'])->name('memo.create.bulk');
|
||||||
|
Route::post('total-biaya-pj', [MemoController::class, 'getTotalBiayaPJ'])->name('memo.total-biaya-pj');
|
||||||
|
Route::post('preview', [MemoController::class, 'preview'])->name('memo.preview');
|
||||||
|
Route::post('generate-pdf', [MemoController::class, 'generatePdf'])->name('memo.generate-pdf');
|
||||||
|
// Route untuk download PDF memo penyelesaian
|
||||||
|
Route::get('/memo/download-pdf/{id}', [MemoController::class, 'downloadPdf'])
|
||||||
|
->name('memo.download-pdf');
|
||||||
|
});
|
||||||
|
Route::resource('memo', MemoController::class);
|
||||||
|
|
||||||
Route::name('resume.')->prefix('resume')->group(function () {
|
Route::name('resume.')->prefix('resume')->group(function () {
|
||||||
Route::get('/', [ResumeController::class, 'index'])->name('index');
|
Route::get('/', [ResumeController::class, 'index'])->name('index');
|
||||||
@@ -683,17 +701,6 @@ Route::middleware(['auth'])->group(function () {
|
|||||||
Route::post('lampiran/upload', [LampiranDokumenController::class, 'upload'])->name('lampiran.upload');
|
Route::post('lampiran/upload', [LampiranDokumenController::class, 'upload'])->name('lampiran.upload');
|
||||||
Route::delete('lampiran/{lampiran}', [LampiranDokumenController::class, 'delete'])->name('lampiran.delete');
|
Route::delete('lampiran/{lampiran}', [LampiranDokumenController::class, 'delete'])->name('lampiran.delete');
|
||||||
|
|
||||||
|
|
||||||
Route::name('laporan-admin-kredit.')->prefix('laporan-admin-kredit')->group(function () {
|
|
||||||
Route::get('/', [LaporanAdminKreditController::class, 'index'])->name('index');
|
|
||||||
Route::get('datatables', [LaporanAdminKreditController::class, 'dataForDatatables'])->name('datatables');
|
|
||||||
Route::get('export', [LaporanAdminKreditController::class, 'export'])->name('export');
|
|
||||||
|
|
||||||
Route::get('{id}/edit', [LaporanAdminKreditController::class,'edit'])->name('edit');
|
|
||||||
Route::put('{id}', [LaporanAdminKreditController::class,'update'])->name('update');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Route::name('bank-data.')->prefix('bank-data')->group(function () {
|
Route::name('bank-data.')->prefix('bank-data')->group(function () {
|
||||||
Route::get('datatables', [BankDataController::class, 'dataForDatatables'])->name('datatables');
|
Route::get('datatables', [BankDataController::class, 'dataForDatatables'])->name('datatables');
|
||||||
});
|
});
|
||||||
@@ -743,6 +750,7 @@ Route::middleware(['auth'])->group(function () {
|
|||||||
// laporan user
|
// laporan user
|
||||||
Route::prefix('laporan-user')->name('laporan-user.')->group(function () {
|
Route::prefix('laporan-user')->name('laporan-user.')->group(function () {
|
||||||
Route::get('/', [LaporanUserController::class, 'index'])->name('index');
|
Route::get('/', [LaporanUserController::class, 'index'])->name('index');
|
||||||
|
Route::get('export', [LaporanUserController::class, 'export'])->name('export');
|
||||||
Route::get('api/user-pemohon', [LaporanUserController::class, 'searchUserPemohon'])->name('api.user-pemohon');
|
Route::get('api/user-pemohon', [LaporanUserController::class, 'searchUserPemohon'])->name('api.user-pemohon');
|
||||||
Route::get('datatables', [LaporanUserController::class, 'dataTableForUserPemohon'])->name('datatables');
|
Route::get('datatables', [LaporanUserController::class, 'dataTableForUserPemohon'])->name('datatables');
|
||||||
});
|
});
|
||||||
@@ -766,6 +774,56 @@ Route::middleware(['auth'])->group(function () {
|
|||||||
Route::get('datatables', [LaporanSLAPenilaiController::class, 'dataForDatatableSLaPenilai'])->name('datatables');
|
Route::get('datatables', [LaporanSLAPenilaiController::class, 'dataForDatatableSLaPenilai'])->name('datatables');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// daftar pustaka
|
||||||
|
Route::resource('daftar-pustaka', DaftarPustakaController::class);
|
||||||
|
|
||||||
|
// category daftar pustaka
|
||||||
|
Route::prefix('category-daftar-pustaka')->name('category-daftar-pustaka.')->group(function () {
|
||||||
|
Route::get('datatables', [CategoryDaftarPustakaController::class, 'dataForDatatables'])->name('datatables');
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::resource('category-daftar-pustaka', CategoryDaftarPustakaController::class);
|
||||||
|
|
||||||
|
// Route untuk Bucok
|
||||||
|
Route::prefix('bucok')->name('bucok.')->group(function () {
|
||||||
|
Route::get('/', [BucokController::class, 'index'])->name('index');
|
||||||
|
Route::get('/datatables', [BucokController::class, 'dataForDatatables'])->name('datatables');
|
||||||
|
Route::get('/{id}', [BucokController::class, 'show'])->name('show');
|
||||||
|
Route::post('/import', [BucokController::class, 'import'])->name('import');
|
||||||
|
Route::get('/export', [BucokController::class, 'export'])->name('export');
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::prefix('admin-kredit')->name('admin-kredit.')->group(function () {
|
||||||
|
// Route SLIK
|
||||||
|
Route::prefix('slik')->name('slik.')->group(function () {
|
||||||
|
Route::get('/', [SlikController::class, 'index'])->name('index');
|
||||||
|
Route::get('datatables', [SlikController::class, 'dataForDatatables'])->name('datatables');
|
||||||
|
Route::get('{id}', [SlikController::class, 'show'])->name('show');
|
||||||
|
Route::get('import', [SlikController::class, 'importForm'])->name('import-form');
|
||||||
|
Route::post('import', [SlikController::class, 'import'])->name('import');
|
||||||
|
Route::get('download-template', [SlikController::class, 'downloadTemplate'])->name('download-template');
|
||||||
|
Route::get('export', [SlikController::class, 'export'])->name('export');
|
||||||
|
Route::delete('truncate', [SlikController::class, 'truncate'])->name('truncate');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Route Laporan SLIK
|
||||||
|
Route::prefix('laporan-slik')->name('laporan-slik.')->group(function () {
|
||||||
|
Route::get('/', [LaporanSlikController::class, 'index'])->name('index');
|
||||||
|
Route::get('datatables', [LaporanSlikController::class, 'dataForDatatables'])->name('datatables');
|
||||||
|
Route::get('{id}', [LaporanSlikController::class, 'show'])->name('show');
|
||||||
|
Route::post('store', [LaporanSlikController::class, 'store'])->name('store');
|
||||||
|
Route::get('export', [LaporanSlikController::class, 'export'])->name('export');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Laporan Routes
|
||||||
|
Route::prefix('laporan')->name('laporan.')->group(function () {
|
||||||
|
Route::get('/', [LaporanAdminKreditController::class, 'index'])->name('index');
|
||||||
|
Route::get('datatables', [LaporanAdminKreditController::class, 'dataForDatatables'])->name('datatables');
|
||||||
|
Route::get('export', [LaporanAdminKreditController::class, 'export'])->name('export');
|
||||||
|
Route::get('{id}/edit', [LaporanAdminKreditController::class,'edit'])->name('edit');
|
||||||
|
Route::put('{id}', [LaporanAdminKreditController::class,'update'])->name('update');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
require __DIR__ . '/registrasi.php';
|
require __DIR__ . '/registrasi.php';
|
||||||
|
|||||||
Reference in New Issue
Block a user