fix(so/penilai) : perbaikkan paparan dan resume

This commit is contained in:
majid
2025-02-27 10:18:31 +07:00
parent 6102205900
commit 2a475a9ea7
18 changed files with 960 additions and 888 deletions

View File

@@ -1,282 +1,298 @@
<?php <?php
namespace Modules\Lpj\Http\Controllers; namespace Modules\Lpj\Http\Controllers;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Exception; use Exception;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel; use Maatwebsite\Excel\Facades\Excel;
use Modules\Lpj\Http\Requests\PersetujuanPenawaranRequest; use Modules\Lpj\Http\Requests\PersetujuanPenawaranRequest;
use Modules\Lpj\Models\PenawaranTender; use Modules\Lpj\Models\PenawaranTender;
use Modules\Lpj\Models\Permohonan; use Modules\Lpj\Models\Permohonan;
use Modules\Lpj\Models\PersetujuanPenawaran; use Modules\Lpj\Models\PersetujuanPenawaran;
// use Modules\Lpj\Models\JenisPenilaian; // use Modules\Lpj\Models\JenisPenilaian;
// use Modules\Lpj\Models\Regions; // use Modules\Lpj\Models\Regions;
class PembayaranController extends Controller class PembayaranController extends Controller
{
public $user;
public function index()
{ {
public $user; return view('lpj::pembayaran.index');
public function index()
{
return view('lpj::pembayaran.index');
}
public function approval() {
return view('lpj::pembayaran.approval');
}
public function dataApprovalForDatatables(Request $request) {
if (is_null($this->user) || !$this->user->can('noc.view')) {
//abort(403, 'Sorry! You are not allowed to view persetujuan penawaran.');
}
// Retrieve data from the database
$query = PersetujuanPenawaran::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->orWhereRelation('penawaran', 'nomor_registrasi', '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
->with(
[
'penawaran.permohonan.user',
'penawaran.permohonan.debiture',
'penawaran.permohonan.branch',
'permohonan.debiture',
'permohonan.branch',
'permohonan.user',
'permohonan.approveBayar',
'penawaran.permohonan.approveBayar',
'penawaran.detail',
'penawaran.persetujuan',
],
)->get();
// Calculate the page count
$pageCount = ceil($totalRecords / $request->get('size'));
// Calculate the current page number
$currentPage = $request->get('page', 1);
// Return the response data as a JSON object
return response()->json([
'draw' => $request->get('draw'),
'recordsTotal' => $totalRecords,
'recordsFiltered' => $filteredRecords,
'pageCount' => $pageCount,
'page' => $currentPage,
'totalCount' => $totalRecords,
'data' => $data,
]);
}
function edit($id)
{
$permohonan = Permohonan::find($id);
return view('lpj::pembayaran.form', compact('permohonan'));
}
public function store(PersetujuanPenawaranRequest $request)
{
$validated = $request->validated();
$validated['created_by'] = Auth::id();
$validated['status'] = '0';
if (isset($validated['penawaran_id'])) {
$persetujuanPenawaran = PersetujuanPenawaran::create(
['penawaran_id' => $validated['penawaran_id']],
$validated,
);
} else {
$persetujuanPenawaran = PersetujuanPenawaran::create(
$validated
);
}
$folderPath = 'persetujuan_penawaran/' . $validated['penawaran_id'];
if ($request->hasFile('bukti_bayar')) {
$persetujuanPenawaran->bukti_bayar = $request->file('bukti_bayar')->store($folderPath, 'public');
}
$persetujuanPenawaran->save();
// Update the status of the related permohonan to 'spk'
$permohonan = Permohonan::find(request()->get('permohonan_id'));
if ($permohonan) {
$permohonan->status_bayar = request()->get('status_bayar');
$permohonan->save();
// andy add, update status penawaran.status='spk'
// $penawaran = PenawaranTender::where('nomor_registrasi',$permohonan->nomor_registrasi)->first();
PenawaranTender::where('nomor_registrasi', $permohonan->nomor_registrasi)->update([
'status' => 'noc',
'updated_by' => Auth::id(),
'updated_at' => now(),
]);
// andy add, update status penawaran.status='spk'
}
return redirect()
->route('pembayaran.index')->with('success', 'Pembayaran berhasil disimpan.');
}
public function update(Request $request, $id)
: JsonResponse {
// init
$data = [];
$output = [];
$tindakan = null;
if (request()->ajax()) {
try {
$data = [
'approve_bayar_by' => Auth::id(),
'approve_bayar_at' => now(),
];
if ($request->keterangan) {
$data['approve_keterangan_bayar'] = $request->keterangan;
}
$output['data'] = $data;
// Update the status of the related permohonan to 'spk'
$permohonan = Permohonan::find($id);
if ($permohonan) {
$data['status_bayar'] = 'sudah_bayar';
if($permohonan->jenis_penilaian_id == 2) {
$data['status'] = 'spk';
}
$permohonan->update($data);
if($permohonan->jenis_penilaian_id == 2) {
PenawaranTender::where('nomor_registrasi', $permohonan->nomor_registrasi)->update([
'status' => 'spk',
'updated_by' => Auth::id(),
'updated_at' => now(),
]);
}
}
$output['status'] = 'success';
$output['message'] = ['Otorisasi' . $permohonan->nomor_registrasi . 'berhasil di lakukan'];
} catch (Exception $e) {
$output['status'] = 'error';
$output['message'] = ['Otorisasi gagal di lakukan.'];
}
}
return response()->json($output);
}
public function dataForDatatables(Request $request)
{
if (is_null($this->user) || !$this->user->can('debitur.view')) {
// abort(403, 'Sorry! You are not allowed to view users.');
}
$query = Permohonan::query()->where(['status_bayar' => 'belum_bayar', 'jenis_penilaian_id' => 1])
->whereNotIn('id', function($subquery) {
$subquery->select('permohonan_id')
->from('persetujuan_penawaran')
->whereNotNull('permohonan_id');
});
// Pencarian berdasarkan parameter search
if ($request->has('search') && !empty($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
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->with(['user', 'debiture', 'branch', 'jenisPenilaian'])->get();
// 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 approval()
{
return view('lpj::pembayaran.approval');
}
public function dataApprovalForDatatables(Request $request)
{
if (is_null($this->user) || !$this->user->can('noc.view')) {
//abort(403, 'Sorry! You are not allowed to view persetujuan penawaran.');
}
// Retrieve data from the database
$query = PersetujuanPenawaran::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->orWhereRelation('penawaran', 'nomor_registrasi', '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
->with(
[
'penawaran.permohonan.user',
'penawaran.permohonan.debiture',
'penawaran.permohonan.branch',
'permohonan.debiture',
'permohonan.branch',
'permohonan.user',
'permohonan.approveBayar',
'penawaran.permohonan.approveBayar',
'penawaran.detail',
'penawaran.persetujuan',
],
)->get();
// Calculate the page count
$pageCount = ceil($totalRecords / $request->get('size'));
// Calculate the current page number
$currentPage = $request->get('page', 1);
// Return the response data as a JSON object
return response()->json([
'draw' => $request->get('draw'),
'recordsTotal' => $totalRecords,
'recordsFiltered' => $filteredRecords,
'pageCount' => $pageCount,
'page' => $currentPage,
'totalCount' => $totalRecords,
'data' => $data,
]);
}
public function edit($id)
{
$permohonan = Permohonan::find($id);
return view('lpj::pembayaran.form', compact('permohonan'));
}
public function store(PersetujuanPenawaranRequest $request)
{
$validated = $request->validated();
$validated['created_by'] = Auth::id();
$validated['status'] = '0';
if (isset($validated['penawaran_id'])) {
$persetujuanPenawaran = PersetujuanPenawaran::create(
['penawaran_id' => $validated['penawaran_id']],
$validated,
);
} else {
$persetujuanPenawaran = PersetujuanPenawaran::create(
$validated
);
}
$folderPath = 'persetujuan_penawaran/' . $validated['penawaran_id'];
if ($request->hasFile('bukti_bayar')) {
$persetujuanPenawaran->bukti_bayar = $request->file('bukti_bayar')->store($folderPath, 'public');
}
$persetujuanPenawaran->save();
// Update the status of the related permohonan to 'spk'
$permohonan = Permohonan::find(request()->get('permohonan_id'));
if ($permohonan) {
$permohonan->status_bayar = request()->get('status_bayar');
$permohonan->save();
// andy add, update status penawaran.status='spk'
// $penawaran = PenawaranTender::where('nomor_registrasi',$permohonan->nomor_registrasi)->first();
PenawaranTender::where('nomor_registrasi', $permohonan->nomor_registrasi)->update([
'status' => 'noc',
'updated_by' => Auth::id(),
'updated_at' => now(),
]);
// andy add, update status penawaran.status='spk'
}
return redirect()
->route('pembayaran.index')->with('success', 'Pembayaran berhasil disimpan.');
}
public function update(Request $request, $id): JsonResponse
{
// init
$data = [];
$output = [];
$tindakan = null;
if (request()->ajax()) {
try {
$data = [
'approve_bayar_by' => Auth::id(),
'approve_bayar_at' => now(),
];
if ($request->keterangan) {
$data['approve_keterangan_bayar'] = $request->keterangan;
}
$output['data'] = $data;
// Update the status of the related permohonan to 'spk'
$permohonan = Permohonan::find($id);
if ($permohonan) {
$data['status_bayar'] = 'sudah_bayar';
if ($permohonan->jenis_penilaian_id == 2) {
$data['status'] = 'spk';
}
if ($permohonan->jenis_penilaian_id == 1) {
unset(
$data['approval_so'],
$data['approval_so_at'],
$data['approval_eo'],
$data['approval_eo_at'],
$data['approval_dd'],
$data['approval_dd_at'],
$data['keterangan']
);
$data['status'] = 'proses-laporan';
}
$permohonan->update($data);
if ($permohonan->jenis_penilaian_id == 2) {
PenawaranTender::where('nomor_registrasi', $permohonan->nomor_registrasi)->update([
'status' => 'spk',
'updated_by' => Auth::id(),
'updated_at' => now(),
]);
}
}
$output['status'] = 'success';
$output['message'] = ['Otorisasi' . $permohonan->nomor_registrasi . 'berhasil di lakukan'];
} catch (Exception $e) {
$output['status'] = 'error';
$output['message'] = ['Otorisasi gagal di lakukan.'];
}
}
return response()->json($output);
}
public function dataForDatatables(Request $request)
{
if (is_null($this->user) || !$this->user->can('debitur.view')) {
// abort(403, 'Sorry! You are not allowed to view users.');
}
$query = Permohonan::query()->where(['status_bayar' => 'belum_bayar', 'jenis_penilaian_id' => 1])
->whereNotIn('id', function ($subquery) {
$subquery->select('permohonan_id')
->from('persetujuan_penawaran')
->whereNotNull('permohonan_id');
});
// Pencarian berdasarkan parameter search
if ($request->has('search') && !empty($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
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->with(['user', 'debiture', 'branch', 'jenisPenilaian'])->get();
// 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,
]);
}
}

View File

@@ -497,7 +497,7 @@ class PenilaiController extends Controller
}); });
} }
$query->whereRaw('LOWER(status) IN (?, ?, ?, ?, ?, ?,?)', ['assign','survey-completed', 'proses-laporan', 'paparan', 'proses-paparan','paparan', 'revisi-laporan', 'done']); $query->whereRaw('LOWER(status) IN (?, ?, ?, ?, ?, ?,?)', ['assign','survey-completed', 'proses-laporan', 'paparan', 'proses-paparan','paparan', 'revisi-laporan']);
if (!Auth::user()->hasRole('administrator')) { if (!Auth::user()->hasRole('administrator')) {
$query->whereHas('penilaian.userPenilai', function ($q) { $query->whereHas('penilaian.userPenilai', function ($q) {

View File

@@ -27,7 +27,6 @@ use Modules\Lpj\Http\Controllers\SurveyorController;
use Modules\Lpj\Http\Controllers\PenilaiController; use Modules\Lpj\Http\Controllers\PenilaiController;
use Modules\Lpj\Http\Requests\FormSurveyorRequest; use Modules\Lpj\Http\Requests\FormSurveyorRequest;
class PenilaianController extends Controller class PenilaianController extends Controller
{ {
public $user; public $user;
@@ -573,7 +572,7 @@ class PenilaianController extends Controller
]); ]);
} elseif (Auth::user()->roles[0]->name === 'EO Appraisal') { } elseif (Auth::user()->roles[0]->name === 'EO Appraisal') {
$status = '2'; $status = '2';
if (!in_array($permohonan->nilai_plafond_id, [1, 4])) { if (!in_array($permohonan->nilai_plafond_id, [1,4])) {
$status = '1'; $status = '1';
$permohonan->update([ $permohonan->update([
'status' => $authorization->request 'status' => $authorization->request
@@ -680,11 +679,11 @@ class PenilaianController extends Controller
// }); // });
// } // }
// } else { // } else {
if (Auth::user()->hasRole('senior-officer')) { if (Auth::user()->hasRole('senior-officer')) {
$query->whereHas('region.teams.teamsUsers', function ($q) { $query->whereHas('region.teams.teamsUsers', function ($q) {
$q->where('user_id', Auth::id()); $q->where('user_id', Auth::id());
}); });
} }
// } // }

View File

@@ -674,6 +674,51 @@ class SurveyorController extends Controller
]); ]);
} }
public function saveEditedImage(Request $request)
{
try {
$request->validate([
'edited_image' => 'required|string',
'original_path' => 'required|string',
]);
// Decode base64 image
$base64Image = $request->input('edited_image');
if (str_contains($base64Image, ';base64,')) {
[$metadata, $base64Image] = explode(';base64,', $base64Image);
}
$decodedImage = base64_decode($base64Image);
if (!$decodedImage) {
return response()->json([
'status' => 'error',
'message' => 'Gambar tidak valid',
], 400);
}
// Path asli
$originalPath = $request->input('original_path');
$fileName = basename($originalPath);
$newFilePath = 'edited_images/' . $fileName;
// Simpan file ke storage
Storage::disk('public')->put($newFilePath, $decodedImage);
return response()->json([
'status' => 'success',
'message' => 'Gambar berhasil disimpan',
'file_path' => $newFilePath,
], 200);
} catch (\Exception $e) {
return response()->json([
'status' => 'error',
'message' => 'Terjadi kesalahan: ' . $e->getMessage(),
], 500);
}
}
private function findFotoByParamName($fotoForm, $paramName) private function findFotoByParamName($fotoForm, $paramName)
{ {
// Mapping parameter name ke struktur JSON // Mapping parameter name ke struktur JSON

View File

@@ -103,6 +103,7 @@
"roles": [ "roles": [
"administrator", "administrator",
"senior-officer", "senior-officer",
"EO Appraisal",
"DD Appraisal" "DD Appraisal"
] ]
} }

View File

@@ -1,82 +1,5 @@
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto"> <div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
{{-- <div class="card border border-agi-100 min-w-full">
<div class="card border border-agi-100 min-w-full">
<div class="card-header bg-agi-50">
<h3 class="card-title">
{{ $title ?? 'Data Jaminan' }}
</h3>
@php
use Illuminate\Support\Facades\Route;
@endphp
<div class="flex items-center gap-2">
@if (Auth::user()->hasAnyRole(['administrator', 'senior-officer', 'EO Appraisal', 'DD Appraisal']) &&
Route::currentRouteName('otorisator.show'))
<a href="{{ route('otorisator.show', ['id' => $permohonan->id, 'type' => 'Pelaporan']) }}"
class="btn btn-xs btn-info">
<i class="ki-filled ki-exit-left"></i> Back
</a>
@elseif (Auth::user()->hasAnyRole(['administrator', 'surveyor']) && Route::currentRouteName('penilai.show'))
<a href="{{ route('penilai.show', $permohonan->id) }}" class="btn btn-xs btn-info">
<i class="ki-filled ki-exit-left"></i> Back
</a>
@endif
</div>
</div>
<div class="card-body grid gap-5 grid-cols-2">
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">Nama Debitur</label>
<div class="flex flex-wrap items-baseline w-full">
@if (isset($permohonan->debiture))
<p class="text-2sm text-gray-700">{{ $permohonan->debiture->name }}</p>
@endif
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">Alamat Object</label>
<div class="flex flex-wrap items-baseline w-full">
@foreach ($permohonan->documents as $dokumen)
<span class="text-2sm text-gray-700">
{{ formatAlamat($dokumen->pemilik) }}
{{ formatAlamat($dokumen->pemilik) }}
</span>
@endforeach
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">Nomor Registrasi</label>
<div class="flex flex-wrap items-base line w-full">
<p class="text-2sm text-gray-700">{{ $permohonan->nomor_registrasi }}</p>
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">Cab/Direktorat</label>
<div class="flex flex-wrap items-baseline w-full">
@if (isset($permohonan->branch))
<p class="text-2sm text-gray-700">{{ $permohonan->branch->name }}</p>
@endif
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">Nomor Laporan</label>
<div class="flex flex-wrap items-base line w-full">
<p class="text-2sm text-gray-700">{{ $permohonan->nomor_registrasi }}</p>
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">AO</label>
<div class="flex flex-wrap items-baseline w-full">
@if (isset($permohonan->user))
<p class="text-2sm text-gray-700">{{ $permohonan->user->name }}</p>
@endif
</div>
</div>
</div>
</div>
</div> --}}
@foreach ($permohonan->documents as $dokumen) @foreach ($permohonan->documents as $dokumen)
@if ($dokumen->jenisJaminan) @if ($dokumen->jenisJaminan)
@@ -290,60 +213,12 @@
</div> </div>
</div> </div>
<div class="card">
<div class="card-header bg-agi-50">
<h3 class="card-title uppercase">
nilai asuransi
</h3>
</div>
<div class="card-body">
<div>
<label for="total_nilai_pasar_wajar" class="form-label uppercase">TOTAL NILAI ASURANSI</label>
<div class="card-body grid gap-2.5 w-full">
<div class="flex grid-col-3 gap-2.5 w-full">
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5 w-full">
<label for="province" class="form-label">Luas Bangunan</label>
<input type="text" class="input w-full" id="asuransi_luas_bangunan"
name="asuransi_luas_bangunan"
value="{{ old('asuransi_luas_bangunan', $lpjData['asuransi_luas_bangunan'] ?? null) }}"
oninput="calculateTotal()">
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5 w-full">
<label for="province" class="">X</label>
<label class="input">
<i class="">Rp
</i>
<input type="text" class="input w-full currency" id="asuransi_nilai_1"
name="asuransi_nilai_1"
value="{{ old('asuransi_nilai_1', $lpjData['asuransi_nilai_1'] ?? null) }}"
oninput="calculateTotal()">
</label>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5 w-full">
<label class="input">
<i class="">Rp
</i>
<input type="text" class="input w-full currency-format" name="asuransi_nilai_2"
value="{{ old('asuransi_nilai_2', $lpjData['asuransi_nilai_2'] ?? null) }}">
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
const datas = @json($forminspeksi); const datas = @json($forminspeksi);
console.log(datas); console.log(datas);
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
const tambahNPWButton = document.getElementById('tambah-npw'); const tambahNPWButton = document.getElementById('tambah-npw');
const addPasarWajarContainer = document.getElementById('add_pasar_wajar'); const addPasarWajarContainer = document.getElementById('add_pasar_wajar');
let npwCounter = 0; let npwCounter = 0;

View File

@@ -8,7 +8,7 @@
Input Nilai Liquidasi (LPJ) Input Nilai Liquidasi (LPJ)
</div> </div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<a href="{{ route('pembayaran.index') }}" class="btn btn-xs btn-info"><i class="ki-filled ki-exit-left"></i> Back</a> <a href="{{ route('laporan.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">

View File

@@ -16,17 +16,17 @@
<tr> <tr>
<td style=" width:25%; padding: 2px; vertical-align: top;">Jarak Jalan Utama</td> <td style=" width:25%; padding: 2px; vertical-align: top;">Jarak Jalan Utama</td>
<td style=" width:1%; padding: 2px; vertical-align: top;">:</td> <td style=" width:1%; padding: 2px; vertical-align: top;">:</td>
<td style="padding: 2px; vertical-align: top;">{{ $lingkungan['jarak_jalan_utama'] ?? '-' }} m</td> <td style="padding: 2px; vertical-align: top;">{{ $lingkungan['jarak_jalan_utama'] ?? '-' }}</td>
</tr> </tr>
<tr> <tr>
<td style="padding: 2px; vertical-align: top;">Jalan Lingkungan</td> <td style="padding: 2px; vertical-align: top;">Jalan Lingkungan</td>
<td style="padding: 2px; vertical-align: top;">:</td> <td style="padding: 2px; vertical-align: top;">:</td>
<td style="padding: 2px; vertical-align: top;">{{ $lingkungan['jalan_linkungan'] ?? '-' }} m</td> <td style="padding: 2px; vertical-align: top;">{{ $lingkungan['jalan_linkungan'] ?? '-' }}</td>
<tr> <tr>
<td style="padding: 2px; vertical-align: top;">Jarak CBD</td> <td style="padding: 2px; vertical-align: top;">Jarak CBD</td>
<td style="padding: 2px; vertical-align: top;">:</td> <td style="padding: 2px; vertical-align: top;">:</td>
<td style="padding: 2px; vertical-align: top;">{{ $lingkungan['jarak_cbd_point'] ?? '-' }} m <td style="padding: 2px; vertical-align: top;">{{ $lingkungan['jarak_cbd_point'] ?? '-' }}
({{ $lingkungan['nama_cbd_point'] ?? '-' }})</td> ({{ $lingkungan['nama_cbd_point'] ?? '-' }})</td>
</tr> </tr>
<tr> <tr>

View File

@@ -391,10 +391,12 @@
</div> </div>
<div class="flex justify-end gap-2" style="margin-right: 20px; margin-top: 20px"> <div class="flex justify-end gap-2" style="margin-right: 20px; margin-top: 20px">
@if (Auth::user()->hasAnyRole(['senior-officer', 'surveyor', 'administrator']))
<button type="button" class="btn btn-primary" id="saveButton" onclick="submitData()"> <button type="button" class="btn btn-primary" id="saveButton" onclick="submitData()">
<i class="ki-filled ki-save-2"></i> <i class="ki-filled ki-save-2"></i>
<span id="saveButtonText">Save</span> <span id="saveButtonText">Save</span>
</button> </button>
@endif
@if (Auth::user()->hasAnyRole(['senior-officer', 'EO Appraisal', 'DD Appraisal'])) @if (Auth::user()->hasAnyRole(['senior-officer', 'EO Appraisal', 'DD Appraisal']))
<a class="btn btn-info" <a class="btn btn-info"
href="{{ route('penilai.lampiran') }}?permohonanId={{ request('permohonanId') }}&documentId={{ request('documentId') }}&inspeksiId={{ request('inspeksiId') }}&jaminanId={{ request('jaminanId') }}&statusLpj=1"> href="{{ route('penilai.lampiran') }}?permohonanId={{ request('permohonanId') }}&documentId={{ request('documentId') }}&inspeksiId={{ request('inspeksiId') }}&jaminanId={{ request('jaminanId') }}&statusLpj=1">

View File

@@ -44,10 +44,12 @@
</div> </div>
</div> </div>
<div class="flex card-footer justify-end gap-5"> <div class="flex card-footer justify-end gap-5">
@if (Auth::user()->hasAnyRole(['senior-officer', 'surveyor', 'administrator']))
<button type="button" class="btn btn-primary" id="saveButton" onclick="saveLpjSederhanadanStandard()"> <button type="button" class="btn btn-primary" id="saveButton" onclick="saveLpjSederhanadanStandard()">
<i class="ki-filled ki-save-2"></i> <i class="ki-filled ki-save-2"></i>
<span id="saveButtonText">Save</span> <span id="saveButtonText">Save</span>
</button> </button>
@endif
@if (Auth::user()->hasAnyRole(['senior-officer', 'EO Appraisal', 'DD Appraisal', 'administrator'])) @if (Auth::user()->hasAnyRole(['senior-officer', 'EO Appraisal', 'DD Appraisal', 'administrator']))
<a class="btn btn-info" <a class="btn btn-info"
href="{{ route('penilai.lampiran') }}?permohonanId={{ request('permohonanId') }}&documentId={{ request('documentId') }}&inspeksiId={{ request('inspeksiId') }}&jaminanId={{ request('jaminanId') }}&statusLpj=1"> href="{{ route('penilai.lampiran') }}?permohonanId={{ request('permohonanId') }}&documentId={{ request('documentId') }}&inspeksiId={{ request('inspeksiId') }}&jaminanId={{ request('jaminanId') }}&statusLpj=1">

View File

@@ -292,10 +292,12 @@
{{-- @include('lpj::penilai.components.foto-lampiran') --}} {{-- @include('lpj::penilai.components.foto-lampiran') --}}
<div class="flex card-footer justify-end gap-5"> <div class="flex card-footer justify-end gap-5">
@if (Auth::user()->hasAnyRole(['senior-officer', 'surveyor', 'administrator']))
<a class="btn btn-primary" onclick="saveMemo()"> <a class="btn btn-primary" onclick="saveMemo()">
<i class="ki-filled ki-save-2"></i> <i class="ki-filled ki-save-2"></i>
SAVE SAVE
</a> </a>
@endif
@if (Auth::user()->hasAnyRole(['senior-officer', 'EO Appraisal', 'DD Appraisal'])) @if (Auth::user()->hasAnyRole(['senior-officer', 'EO Appraisal', 'DD Appraisal']))
<a class="btn btn-info" <a class="btn btn-info"
href="{{ route('penilai.lampiran') }}?permohonanId={{ request('permohonanId') }}&documentId={{ request('documentId') }}&inspeksiId={{ request('inspeksiId') }}&jaminanId={{ request('jaminanId') }}&statusLpj=1"> href="{{ route('penilai.lampiran') }}?permohonanId={{ request('permohonanId') }}&documentId={{ request('documentId') }}&inspeksiId={{ request('inspeksiId') }}&jaminanId={{ request('jaminanId') }}&statusLpj=1">

View File

@@ -109,7 +109,7 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="width: 25%; padding: 2px; vertical-align: top;">Pihak Bank selain Apraisal</td> <td style="width: 25%; padding: 2px; vertical-align: top;">Pihak Bank selain Appraisal</td>
<td style="width: 1%; vertical-align: top;">:</td> <td style="width: 1%; vertical-align: top;">:</td>
<td style="vertical-align: top;">{{ $forminspeksi['asset']['pihak_bank'] ?? '' }} <td style="vertical-align: top;">{{ $forminspeksi['asset']['pihak_bank'] ?? '' }}
</td> </td>
@@ -231,7 +231,7 @@
? $forminspeksi['asset']['hub_cadeb']['tidak sesuai'] ? $forminspeksi['asset']['hub_cadeb']['tidak sesuai']
: $forminspeksi['asset']['hub_cadeb']['sesuai']; : $forminspeksi['asset']['hub_cadeb']['sesuai'];
@endphp @endphp
<td style="width:25%; padding: 2px; vertical-align: top;">Hubungan Pemilik Jaminan dengan Debitu</td> <td style="width:25%; padding: 2px; vertical-align: top;">Hubungan Pemilik Jaminan dengan Debitur</td>
<td style="width:1%; padding: 2px; vertical-align: top;">:</td> <td style="width:1%; padding: 2px; vertical-align: top;">:</td>
<td style=" padding: 2px; vertical-align: top;">{{ $hubCadeb ?? '' }}</td> <td style=" padding: 2px; vertical-align: top;">{{ $hubCadeb ?? '' }}</td>
</tr> </tr>

View File

@@ -332,101 +332,8 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Demikian Kami Sampaikan, atas perhatiannya kami ucapkan terimakasih</td> <td>Resume ini sudah di setujui</td>
</tr> </tr>
<table style="width: 100%;">
<tr>
<td>
<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>
</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>
</td>
</tr>
</table>
</table> </table>
<div class="page-break"></div> <div class="page-break"></div>

View File

@@ -65,6 +65,7 @@
</div> </div>
</div> </div>
<div class="flex justify-end gap-2" style="margin-right: 20px; margin-top: 20px"> <div class="flex justify-end gap-2" style="margin-right: 20px; margin-top: 20px">
@if (Auth::user()->hasAnyRole(['senior-officer', 'surveyor', 'administrator']))
<button type="button" class="btn btn-primary" id="saveButton" onclick="submitData()"> <button type="button" class="btn btn-primary" id="saveButton" onclick="submitData()">
<i class="ki-filled ki-save-2"></i> <i class="ki-filled ki-save-2"></i>
<span id="saveButtonText">Save</span> <span id="saveButtonText">Save</span>
@@ -73,6 +74,7 @@
</div> </div>
</button> </button>
@endif
@if (Auth::user()->hasAnyRole(['senior-officer', 'EO Appraisal', 'DD Appraisal', 'administrator'])) @if (Auth::user()->hasAnyRole(['senior-officer', 'EO Appraisal', 'DD Appraisal', 'administrator']))
<a class="btn btn-info" <a class="btn btn-info"
href="{{ route('penilai.lampiran') }}?permohonanId={{ request('permohonanId') }}&documentId={{ request('documentId') }}&inspeksiId={{ request('inspeksiId') }}&jaminanId={{ request('jaminanId') }}&statusLpj=1"> href="{{ route('penilai.lampiran') }}?permohonanId={{ request('permohonanId') }}&documentId={{ request('documentId') }}&inspeksiId={{ request('inspeksiId') }}&jaminanId={{ request('jaminanId') }}&statusLpj=1">

View File

@@ -423,10 +423,11 @@
<div class="flex card-footer justify-end gap-5"> <div class="flex card-footer justify-end gap-5">
@if (Auth::user()->hasAnyRole(['senior-officer', 'surveyor', 'administrator']))
<button type="button" class="btn btn-primary" onclick="saveResume()"> <button type="button" class="btn btn-primary" onclick="saveResume()">
<i class="ki-filled ki-save-2"></i> <i class="ki-filled ki-save-2"></i>
Save</button> Save</button>
@endif
@if (Auth::user()->hasAnyRole(['senior-officer', 'EO Appraisal', 'DD Appraisal', 'administrator'])) @if (Auth::user()->hasAnyRole(['senior-officer', 'EO Appraisal', 'DD Appraisal', 'administrator']))
<a class="btn btn-info" <a class="btn btn-info"

View File

@@ -95,7 +95,7 @@
</td> </td>
</tr> </tr>
@endif @endif
@if (in_array($permohonan->nilai_plafond_id, [1,2, 4]) && $permohonan->approval_dd != null) @if (in_array($permohonan->nilai_plafond_id, [1, 2, 4]) && $permohonan->approval_dd != null)
<tr> <tr>
<td>Disetujui Oleh (DD)</td> <td>Disetujui Oleh (DD)</td>
<td>{{ getUser($permohonan->approval_dd)->name ?? 'N/A' }}</td> <td>{{ getUser($permohonan->approval_dd)->name ?? 'N/A' }}</td>
@@ -157,38 +157,46 @@
Otorisator {{ $header ?? '' }} Otorisator {{ $header ?? '' }}
</button> </button>
@endif @endif
@elseif($dataHeader == 'paparan') @elseif($dataHeader == 'paparan')
@if($permohonan->penilai->file_paparan) @if ($permohonan->penilai->file_paparan)
<span class="btn btn-success btn-outline" <span class="btn btn-success btn-outline"
onclick="viewPDF('{{ Storage::url($permohonan->penilai->file_paparan) }}')"><i onclick="viewPDF('{{ Storage::url($permohonan->penilai->file_paparan) }}')"><i
class="ki-filled ki-eye mr-2"></i>Lihat Data Paparan</span> class="ki-filled ki-eye mr-2"></i>Lihat Data Paparan</span>
@endif @endif
@if($permohonan->penilai->kertas_kerja) @if ($permohonan->penilai->kertas_kerja)
<span class="btn btn-warning btn-outline" <span class="btn btn-warning btn-outline"
onclick="viewPDF('{{ Storage::url($permohonan->penilai->kertas_kerja) }}')"><i onclick="viewPDF('{{ Storage::url($permohonan->penilai->kertas_kerja) }}')"><i
class="ki-filled ki-eye mr-2"></i>Lihat Kertas Kerja</span> class="ki-filled ki-eye mr-2"></i>Lihat Kertas Kerja</span>
@endif @endif
<a class="btn btn-success" <a class="btn btn-success"
href="{{ route('otorisator.view-laporan') }}?permohonanId={{ $permohonan->id }}&documentId={{ $documentId }}&inspeksiId={{ $inspeksiId }}&jaminanId={{ $jenisJaminanId }}&statusLpj={{ true }}"> href="{{ route('otorisator.view-laporan') }}?permohonanId={{ $permohonan->id }}&documentId={{ $documentId }}&inspeksiId={{ $inspeksiId }}&jaminanId={{ $jenisJaminanId }}&statusLpj={{ true }}">
Lihat Laporan Lihat resume
</a> </a>
@if(Auth::user()->hasAnyRole(['administrator','senior-officer']) && $authorization->approve_so==null) @if (Auth::user()->hasAnyRole(['administrator', 'senior-officer']) && $authorization->approve_so == null)
<button onclick="otorisatorData({{ $authorization->id }},'SO')" type="button" class="btn btn-primary"> <button onclick="otorisatorData({{ $authorization->id }},'SO')" type="button"
class="btn btn-primary">
<i class="ki-filled ki-double-check"></i> <i class="ki-filled ki-double-check"></i>
Otorisator {{ $header ?? '' }} Otorisator {{ $header ?? '' }}
</button> </button>
@endif @endif
@if(Auth::user()->hasAnyRole(['administrator', 'DD Appraisal']) && @if (Auth::user()->hasAnyRole(['administrator', 'EO Appraisal']) &&
$authorization->approve_so && $authorization->approve_eo == null)
$authorization->approve_dd == null) <button onclick="otorisatorData({{ $authorization->id }},'EO')" type="button"
<button onclick="otorisatorData({{ $authorization->id }},'DD')" type="button" class="btn btn-primary"> class="btn btn-primary">
<i class="ki-filled ki-double-check"></i>
Otorisator {{ $header ?? '' }}
</button>
@endif
@if (Auth::user()->hasAnyRole(['administrator', 'DD Appraisal']) && $authorization->approve_dd == null)
<button onclick="otorisatorData({{ $authorization->id }},'DD')" type="button"
class="btn btn-primary">
<i class="ki-filled ki-double-check"></i> <i class="ki-filled ki-double-check"></i>
Otorisator {{ $header ?? '' }} Otorisator {{ $header ?? '' }}
</button> </button>
@@ -201,116 +209,192 @@
@push('scripts') @push('scripts')
<script> <script>
function otorisatorData(dataId, role='') { function otorisatorData(dataId, role = '') {
const dataHeader = @json($header); const dataHeader = @json($header);
if(dataHeader == 'Paparan'){ if (dataHeader == 'Paparan') {
if(role == 'SO'){ const showSwalConfirmation = (title, text, html, confirmText, denyText, cancelText, preConfirm) => {
return Swal.fire({
title: title,
text: text,
html: html,
focusConfirm: false,
preConfirm: preConfirm,
showCancelButton: true,
showDenyButton: !!denyText,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
denyButtonColor: '#f39c12',
confirmButtonText: confirmText,
denyButtonText: denyText,
cancelButtonText: cancelText,
});
};
const handleAjaxRequest = (url, data, successMessage, errorMessage) => {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
});
$.ajax({
url: url,
type: 'POST',
data: data,
success: (response) => {
Swal.fire('Berhasil!', successMessage, 'success').then(() => {
window.location.reload();
});
console.log(response);
},
error: (error) => {
console.error('Error:', error);
Swal.fire('Gagal!', errorMessage, 'error');
}
});
};
const handleRejection = (dataId) => {
Swal.fire({ Swal.fire({
title: 'Apakah Anda yakin?', title: 'Masukkan alasan penolakan:',
text: `Untuk melakukan otorisator ${dataHeader}!`, input: 'textarea',
icon: 'warning', inputPlaceholder: 'Tuliskan alasan...',
html: ` showCancelButton: true,
<input id="swal-keterangan" class="swal2-input input" placeholder="Keterangan"> confirmButtonColor: '#f39c12',
<input id="swal-tanggal-paparan" class="swal2-input input" type="date" placeholder="Tanggal paparan"> cancelButtonColor: '#d33',
`, confirmButtonText: 'Kirim',
focusConfirm: false, cancelButtonText: 'Batal',
preConfirm: () => { preConfirm: (alasan) => {
if (!alasan) {
Swal.showValidationMessage('Alasan harus diisi!');
return false;
}
return alasan;
}
}).then((rejectResult) => {
if (rejectResult.isConfirmed) {
handleAjaxRequest(
`/otorisator/revisi/${dataId}`, {
message: rejectResult.value
},
'Data berhasil ditolak.',
'Terjadi kesalahan saat melakukan penolakan.'
);
}
});
};
// Main logic based on role
if (role === 'SO') {
showSwalConfirmation(
'Apakah Anda yakin?',
`Untuk melakukan otorisator ${dataHeader}!`,
`
<div class="text-left space-y-4">
<p class="text-gray-700 text-center">Untuk melakukan otorisator ${dataHeader}!</p>
<div>
<label for="swal-keterangan" class="block text-sm font-medium text-gray-700 mb-1">Keterangan</label>
<input id="swal-keterangan" class="input" placeholder="Masukkan Keterangan">
</div>
<div>
<label for="swal-tanggal-paparan" class="block text-sm font-medium text-gray-700 mb-1">Tanggal Paparan</label>
<input id="swal-tanggal-paparan" class="input" type="date" placeholder="Tanggal paparan">
</div>
</div>
`,
'Ya, Lanjutkan!', 'Rejected', 'Batal',
() => {
const keterangan = document.getElementById('swal-keterangan').value; const keterangan = document.getElementById('swal-keterangan').value;
const tanggalPaparan = document.getElementById('swal-tanggal-paparan').value; const tanggalPaparan = document.getElementById('swal-tanggal-paparan').value;
if (!keterangan || !tanggalPaparan) { if (!keterangan || !tanggalPaparan) {
Swal.showValidationMessage('Keterangan atau Tanggal Paparan Harus diisi!'); Swal.showValidationMessage('Keterangan atau Tanggal Paparan Harus diisi!');
return false; return false;
} }
return {
return { keterangan, tanggalPaparan }; keterangan,
}, tanggalPaparan
showCancelButton: true, };
confirmButtonColor: '#3085d6', }
cancelButtonColor: '#d33', ).then((result) => {
confirmButtonText: 'Ya, Lanjutkan!',
cancelButtonText: 'Batal',
}).then((result) => {
if (result.isConfirmed) { if (result.isConfirmed) {
const keterangan = result.value.keterangan || ''; handleAjaxRequest(
const tanggalPaparan = result.value.tanggalPaparan || ''; `/otorisator/otorisator/${dataId}/${dataHeader}`, {
message: result.value.keterangan,
$.ajaxSetup({ tanggalPaparan: result.value.tanggalPaparan
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}, },
}); 'Data berhasil diotorisasi.',
$.ajax({ 'Terjadi kesalahan saat melakukan otorisator.'
url: `/otorisator/otorisator/${dataId}/${dataHeader}`, );
type: 'POST', } else if (result.isDenied) {
data: { handleRejection(dataId);
message: keterangan,
tanggalPaparan: tanggalPaparan
},
success: (response) => {
Swal.fire('Berhasil!',
'Data berhasil diotorisasi.',
'success').then(() => {
window.location.reload();
});
console.log(response);
},
error: (error) => {
console.error('Error:', error);
Swal.fire('Gagal!', 'Terjadi kesalahan saat melakukan otorisator.',
'error');
}
});
} }
}); });
}else{ } else if (role === 'EO') {
Swal.fire({ showSwalConfirmation(
title: 'Apakah Yakin?', 'Apakah Yakin?',
text: `Pastikan bahwa paparan sudah dilakukan!`, 'Anda akan menyetujui data ini?',
icon: 'warning', `
input: 'textarea', <p class="text-gray-700 text-center">Anda akan menyetujui data ini?</p>
inputLabel: 'Keterangan', <textarea id="swal-keterangan" class="block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm" placeholder="Masukkan keterangan..."></textarea>
inputPlaceholder: 'Masukkan keterangan...', `,
inputAttributes: { 'Ya, Lanjutkan!', 'Rejected', 'Batal',
'aria-label': 'Masukkan keterangan' () => {
}, const keterangan = document.getElementById('swal-keterangan').value;
showCancelButton: true, if (!keterangan) {
confirmButtonColor: '#3085d6', Swal.showValidationMessage('Keterangan harus diisi!');
cancelButtonColor: '#d33', return false;
confirmButtonText: 'Ya, Lanjutkan!', }
cancelButtonText: 'Batal', return {
}).then((result) => { keterangan
};
}
).then((result) => {
if (result.isConfirmed) { if (result.isConfirmed) {
const userMessage = result.value || ''; // Ambil pesan dari textarea handleAjaxRequest(
$.ajaxSetup({ `/otorisator/otorisator/${dataId}/${dataHeader}`, {
headers: { message: result.value.keterangan
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}, },
}); 'Data berhasil diotorisasi.',
$.ajax({ 'Terjadi kesalahan saat melakukan otorisator.'
url: `/otorisator/otorisator/${dataId}/${dataHeader}`, );
type: 'POST', } else if (result.isDenied) {
data: { handleRejection(dataId);
message: userMessage }
});
} else {
showSwalConfirmation(
'Apakah Yakin?',
'Pastikan bahwa paparan sudah dilakukan!',
`
<p class="text-gray-700 text-center">Pastikan bahwa paparan sudah dilakukan!</p>
<textarea id="swal-keterangan" class="block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm" placeholder="Masukkan keterangan..."></textarea>
`,
'Ya, Lanjutkan!', 'Rejected', 'Batal',
() => {
const keterangan = document.getElementById('swal-keterangan').value;
if (!keterangan) {
Swal.showValidationMessage('Keterangan harus diisi!');
return false;
}
return {
keterangan
};
}
).then((result) => {
if (result.isConfirmed) {
handleAjaxRequest(
`/otorisator/otorisator/${dataId}/${dataHeader}`, {
message: result.value.keterangan
}, },
success: (response) => { 'Data berhasil diotorisasi.',
Swal.fire('Berhasil!', 'Terjadi kesalahan saat melakukan otorisator.'
'Data berhasil diotorisasi', );
'success').then(() => { } else if (result.isDenied) {
window.location.reload(); handleRejection(dataId);
});
console.log(response);
},
error: (error) => {
console.error('Error:', error);
Swal.fire('Gagal!', 'Terjadi kesalahan saat melakukan otorisator.',
'error');
}
});
} }
}); });
} }
}else{
} else {
Swal.fire({ Swal.fire({
title: 'Apakah Anda yakin?', title: 'Apakah Anda yakin?',
text: `Untuk melakukan otorisator ${dataHeader}!`, text: `Untuk melakukan otorisator ${dataHeader}!`,
@@ -393,10 +477,10 @@
}, },
success: (response) => { success: (response) => {
Swal.fire('Berhasil!', 'Data berhasil Revisi Laporan', 'success').then( Swal.fire('Berhasil!', 'Data berhasil Revisi Laporan', 'success').then(
() => { () => {
window.location.href = window.location.href =
'{{ route('otorisator.pelaporan.index') }}'; '{{ route('otorisator.pelaporan.index') }}';
}); });
console.log(response); console.log(response);
}, },
error: (error) => { error: (error) => {

View File

@@ -82,6 +82,10 @@
<span class="sort"> <span class="sort-label"> Approval SO </span> <span class="sort"> <span class="sort-label"> Approval SO </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[150px]" data-datatable-column="approval_eo">
<span class="sort"> <span class="sort-label"> Approval EO </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="approval_dd"> <th class="min-w-[150px]" data-datatable-column="approval_dd">
<span class="sort"> <span class="sort-label"> Approval DD </span> <span class="sort"> <span class="sort-label"> Approval DD </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
@@ -251,6 +255,15 @@
return ''; return '';
}, },
}, },
approval_eo: {
title: 'Approval EO',
render: (item, data) => {
if (data.approve_eo) {
return `${data.approve_eo.name} | ${window.formatTanggalIndonesia(data.approval_eo_at)}`;
}
return '';
},
},
approval_dd: { approval_dd: {
title: 'Approval DD', title: 'Approval DD',
render: (item, data) => { render: (item, data) => {

View File

@@ -234,8 +234,8 @@
<div class="flex gap-2.5"> <div class="flex gap-2.5">
<button id="saveEditDataButton" type="button" class="btn btn-primary" <button id="saveEditDataButton" type="button" class="btn btn-primary"
onclick="saveEditedFoto()">Simpan</button> onclick="saveEditedFoto()">Simpan</button>
{{-- <button type="button" class="btn btn-light" data-modal-toggle="#modal_10" <button type="button" class="btn btn-light" data-modal-toggle="#modal_10"
data-drawer-dismiss="true" onclick="openEditPhotoModal(file)">Edit Foto</button> --}} data-drawer-dismiss="true">Edit Foto</button>
<button type="button" class="btn btn-danger" data-drawer-dismiss="true">Batal</button> <button type="button" class="btn btn-danger" data-drawer-dismiss="true">Batal</button>
</div> </div>
</form> </form>
@@ -244,7 +244,7 @@
<div class="modal" data-modal="true" id="modal_10"> <div class="modal" data-modal="true" id="modal_10">
<div class="modal-content modal-overlay"> <div class="modal-content modal-overlay">
<div class="modal-header"> {{-- <div class="modal-header">
<h3 class="modal-title"> <h3 class="modal-title">
Edit Foto Edit Foto
</h3> </h3>
@@ -252,9 +252,9 @@
<i class="ki-outline ki-cross"> <i class="ki-outline ki-cross">
</i> </i>
</button> </button>
</div> </div> --}}
<div class="modal-body scrollable-y-auto"> <div class="modal-body scrollable-y-auto">
<div id="tui-image-editor"></div> <div id="editor_container" class="w-full h-full"></div>
</div> </div>
</div> </div>
</div> </div>
@@ -266,224 +266,225 @@
@include('lpj::surveyor.js.fotojs') @include('lpj::surveyor.js.fotojs')
@include('lpj::surveyor.js.utils') @include('lpj::surveyor.js.utils')
@push('scripts') @push('scripts')
{{-- <script src="https://uicdn.toast.com/tui-image-editor/latest/tui-image-editor.js"></script> --}}
<script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script> <script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>
<script src="https://scaleflex.cloudimg.io/v7/plugins/filerobot-image-editor/latest/filerobot-image-editor.min.js">
</script>
<script> <script>
let jsonDataContoh = @json($formFoto); let jsonDataContoh = @json($formFoto);
Dropzone.autoDiscover = false; Dropzone.autoDiscover = false;
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
let myDropzone = null; let myDropzone = null;
let uploadQueue = 0; let uploadQueue = 0;
let uploadBatch = []; let uploadBatch = [];
function initDropzone(selector, paramName) { function initDropzone(selector, paramName) {
try { try {
const dropzoneElement = document.querySelector(selector); const dropzoneElement = document.querySelector(selector);
if (!dropzoneElement) { if (!dropzoneElement) {
console.error(`Dropzone element not found: ${selector}`); console.error(`Dropzone element not found: ${selector}`);
return null; return null;
}
const processedFiles = new Set();
// Track files that are already on the server
const existingFiles = new Set();
myDropzone = new Dropzone(selector, {
url: "{{ route('surveyor.storeFoto') }}",
paramName: paramName,
acceptedFiles: 'image/*',
uploadMultiple: false,
parallelUploads: 1,
autoProcessQueue: true,
dictDefaultMessage: 'Seret foto atau klik untuk unggah',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
params: {
permohonan_id: {{ $permohonan->id ?? 0 }},
dokument_id: '{{ request('dokument') ?? '' }}',
param_name: paramName,
nomor_registrasi: '{{ $permohonan->nomor_registrasi ?? '' }}',
},
accept: function(file, done) {
// Generate a unique identifier for the file - use hash or content-based ID if possible
const fileId = file.name + '_' + file.size;
// If file is already being processed, reject it
if (processedFiles.has(fileId)) {
done('File sudah dalam antrian upload.');
return;
} }
const processedFiles = new Set();
// Check if file already exists on server // Track files that are already on the server
if (existingFiles.has(file.name)) { const existingFiles = new Set();
done('File dengan nama ini sudah ada.');
return;
}
// Add file to processed set myDropzone = new Dropzone(selector, {
processedFiles.add(fileId); url: "{{ route('surveyor.storeFoto') }}",
done(); paramName: paramName,
}, acceptedFiles: 'image/*',
uploadMultiple: false,
parallelUploads: 1,
autoProcessQueue: true,
dictDefaultMessage: 'Seret foto atau klik untuk unggah',
addedfiles: function(files) { headers: {
const validFiles = Array.from(files).filter(file => { 'X-CSRF-TOKEN': '{{ csrf_token() }}'
// Only count files that haven't been rejected },
return !file.rejected;
params: {
permohonan_id: {{ $permohonan->id ?? 0 }},
dokument_id: '{{ request('dokument') ?? '' }}',
param_name: paramName,
nomor_registrasi: '{{ $permohonan->nomor_registrasi ?? '' }}',
},
accept: function(file, done) {
// Generate a unique identifier for the file - use hash or content-based ID if possible
const fileId = file.name + '_' + file.size;
// If file is already being processed, reject it
if (processedFiles.has(fileId)) {
done('File sudah dalam antrian upload.');
return;
}
// Check if file already exists on server
if (existingFiles.has(file.name)) {
done('File dengan nama ini sudah ada.');
return;
}
// Add file to processed set
processedFiles.add(fileId);
done();
},
addedfiles: function(files) {
const validFiles = Array.from(files).filter(file => {
// Only count files that haven't been rejected
return !file.rejected;
});
uploadQueue += validFiles.length;
uploadBatch = validFiles;
if (validFiles.length > 0) showLoadingOverlay();
},
error: function(file, response) {
// Remove file from processed list on error
const fileId = file.name + '_' + file.size;
processedFiles.delete(fileId);
// Format error message
let errorMsg = typeof response === 'string' ? response :
(response.message || 'Gagal mengupload file');
handleUploadComplete(file, false, errorMsg);
},
success: function(file, response) {
if (response.success) {
const fileData = {
path: response.path || file.path,
name: file.name,
description: '',
category: 'lainnya',
sub: '',
param_name: paramName
};
// Add file to existing files set to prevent duplicates
existingFiles.add(file.name);
addEditAndDeleteButtons(file, fileData);
handleUploadComplete(file, true);
} else {
handleUploadComplete(file, false, response.message);
}
},
init: function() {
const dz = this;
// Clear processed files when all uploads complete
this.on("queuecomplete", function() {
processedFiles.clear();
});
// Load existing photos
loadExistingPhotos(this, paramName, existingFiles);
}
}); });
uploadQueue += validFiles.length; return myDropzone;
uploadBatch = validFiles; } catch (error) {
console.error('Dropzone initialization error:', error);
return null;
}
}
if (validFiles.length > 0) showLoadingOverlay(); function loadExistingPhotos(dropzone, paramName, existingFilesSet) {
}, showLoadingOverlay();
error: function(file, response) { $.ajax({
// Remove file from processed list on error url: "{{ route('surveyor.getFoto') }}",
const fileId = file.name + '_' + file.size; method: 'GET',
processedFiles.delete(fileId); data: {
permohonan_id: {{ $permohonan->id ?? 0 }},
dokument_id: '{{ request('dokument') ?? '' }}',
param_name: paramName
},
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
success: function(response) {
if (response.fotos && response.fotos.length) {
response.fotos.forEach(function(foto) {
var mockFile = {
name: foto.name,
size: foto.size || 12345,
originalPath: foto.path
};
// Format error message // Add to existing files set to prevent duplicates
let errorMsg = typeof response === 'string' ? response : existingFilesSet.add(foto.name);
(response.message || 'Gagal mengupload file');
handleUploadComplete(file, false, errorMsg); dropzone.emit("addedfile", mockFile);
}, dropzone.emit("thumbnail", mockFile, foto.path);
dropzone.emit("complete", mockFile);
addEditAndDeleteButtons(mockFile, {
path: foto.path,
name: foto.name,
description: foto.description || '',
category: foto.category || 'lainnya',
sub: foto.sub || '',
param_name: paramName
});
});
}
},
error: function(xhr, status, error) {
console.error('Gagal memuat foto:', error);
showErrorMessage('Gagal memuat foto yang ada');
},
complete: function() {
hideLoadingOverlay();
}
});
}
success: function(file, response) { function handleUploadComplete(file, isSuccess, errorMessage = null) {
if (response.success) { uploadQueue--;
const fileData = { const index = uploadBatch.indexOf(file);
path: response.path || file.path, if (index > -1) {
name: file.name, uploadBatch.splice(index, 1);
description: '', }
category: 'lainnya',
sub: '',
param_name: paramName
};
// Add file to existing files set to prevent duplicates // Show individual error if any
existingFiles.add(file.name); if (!isSuccess && errorMessage) {
showErrorMessage(errorMessage);
}
addEditAndDeleteButtons(file, fileData); // If all uploads are complete
handleUploadComplete(file, true); if (uploadQueue === 0) {
hideLoadingOverlay();
// Show final status message
const totalFiles = uploadBatch.length + 1; // +1 for current file
if (totalFiles === 1) {
// Single file upload
if (isSuccess) {
showSuccessMessage('Foto berhasil diupload');
}
} else { } else {
handleUploadComplete(file, false, response.message); // Multiple files upload
showSuccessMessage(`${totalFiles} foto berhasil diupload`);
} }
},
init: function() { // Reset batch
const dz = this; uploadBatch = [];
// Clear processed files when all uploads complete
this.on("queuecomplete", function() {
processedFiles.clear();
});
// Load existing photos
loadExistingPhotos(this, paramName, existingFiles);
} }
});
return myDropzone;
} catch (error) {
console.error('Dropzone initialization error:', error);
return null;
}
}
function loadExistingPhotos(dropzone, paramName, existingFilesSet) {
showLoadingOverlay();
$.ajax({
url: "{{ route('surveyor.getFoto') }}",
method: 'GET',
data: {
permohonan_id: {{ $permohonan->id ?? 0 }},
dokument_id: '{{ request('dokument') ?? '' }}',
param_name: paramName
},
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
success: function(response) {
if (response.fotos && response.fotos.length) {
response.fotos.forEach(function(foto) {
var mockFile = {
name: foto.name,
size: foto.size || 12345,
originalPath: foto.path
};
// Add to existing files set to prevent duplicates
existingFilesSet.add(foto.name);
dropzone.emit("addedfile", mockFile);
dropzone.emit("thumbnail", mockFile, foto.path);
dropzone.emit("complete", mockFile);
addEditAndDeleteButtons(mockFile, {
path: foto.path,
name: foto.name,
description: foto.description || '',
category: foto.category || 'lainnya',
sub: foto.sub || '',
param_name: paramName
});
});
}
},
error: function(xhr, status, error) {
console.error('Gagal memuat foto:', error);
showErrorMessage('Gagal memuat foto yang ada');
},
complete: function() {
hideLoadingOverlay();
}
});
}
function handleUploadComplete(file, isSuccess, errorMessage = null) {
uploadQueue--;
const index = uploadBatch.indexOf(file);
if (index > -1) {
uploadBatch.splice(index, 1);
}
// Show individual error if any
if (!isSuccess && errorMessage) {
showErrorMessage(errorMessage);
}
// If all uploads are complete
if (uploadQueue === 0) {
hideLoadingOverlay();
// Show final status message
const totalFiles = uploadBatch.length + 1; // +1 for current file
if (totalFiles === 1) {
// Single file upload
if (isSuccess) {
showSuccessMessage('Foto berhasil diupload');
}
} else {
// Multiple files upload
showSuccessMessage(`${totalFiles} foto berhasil diupload`);
} }
// Reset batch function showLoadingOverlay() {
uploadBatch = []; const overlay = document.querySelector('.loading-overlay');
} if (!overlay) {
} // Buat elemen overlay
const loadingOverlay = document.createElement('div');
function showLoadingOverlay() { loadingOverlay.className = 'loading-overlay';
const overlay = document.querySelector('.loading-overlay'); loadingOverlay.style.cssText = `
if (!overlay) {
// Buat elemen overlay
const loadingOverlay = document.createElement('div');
loadingOverlay.className = 'loading-overlay';
loadingOverlay.style.cssText = `
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
@@ -496,54 +497,54 @@ document.addEventListener('DOMContentLoaded', function() {
z-index: 9999; z-index: 9999;
`; `;
// Tambahkan loader di dalam overlay // Tambahkan loader di dalam overlay
loadingOverlay.innerHTML = '<div class="loader"></div>'; loadingOverlay.innerHTML = '<div class="loader"></div>';
// Tambahkan overlay ke dalam <body> // Tambahkan overlay ke dalam <body>
document.body.appendChild(loadingOverlay); document.body.appendChild(loadingOverlay);
} else { } else {
// Tampilkan overlay jika sudah ada // Tampilkan overlay jika sudah ada
overlay.style.display = 'flex'; overlay.style.display = 'flex';
} }
}
function hideLoadingOverlay() {
const overlay = document.querySelector('.loading-overlay');
if (overlay) overlay.style.display = 'none';
}
function showSuccessMessage(message) {
Swal.fire({
icon: 'success',
title: message,
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 1500
});
}
function showErrorMessage(message) {
Swal.fire({
icon: 'error',
title: 'Upload Gagal',
text: message || 'Error tidak diketahui'
});
}
// Inisialisasi Dropzone untuk elemen awal dengan pengecekan
function safeInitDropzone(selector, paramName) {
setTimeout(() => {
const dropzone = initDropzone(selector, paramName);
if (!dropzone) {
console.error(`Failed to initialize Dropzone for ${selector}`);
} }
}, 100);
}
// Inisialisasi dropzone untuk elemen awal function hideLoadingOverlay() {
safeInitDropzone('#upload-dropzone', 'upload_foto'); const overlay = document.querySelector('.loading-overlay');
}); if (overlay) overlay.style.display = 'none';
}
function showSuccessMessage(message) {
Swal.fire({
icon: 'success',
title: message,
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 1500
});
}
function showErrorMessage(message) {
Swal.fire({
icon: 'error',
title: 'Upload Gagal',
text: message || 'Error tidak diketahui'
});
}
// Inisialisasi Dropzone untuk elemen awal dengan pengecekan
function safeInitDropzone(selector, paramName) {
setTimeout(() => {
const dropzone = initDropzone(selector, paramName);
if (!dropzone) {
console.error(`Failed to initialize Dropzone for ${selector}`);
}
}, 100);
}
// Inisialisasi dropzone untuk elemen awal
safeInitDropzone('#upload-dropzone', 'upload_foto');
});
let fotoObjekJaminan = @json($fotoObjekJaminan); let fotoObjekJaminan = @json($fotoObjekJaminan);
@@ -589,35 +590,109 @@ document.addEventListener('DOMContentLoaded', function() {
} }
} }
document.addEventListener('DOMContentLoaded', function() {
// Create container for Filerobot editor
const editorContainer = document.createElement('div');
editorContainer.id = 'editor_container';
editorContainer.style.width = '100%';
editorContainer.style.height = '100%';
function openEditPhotoModal() { // Add container to modal body
const imageEditorContainer = document.getElementById('tui-image-editor'); const modalBody = document.querySelector('#modal_10 .modal-body');
modalBody.innerHTML = '';
modalBody.appendChild(editorContainer);
// Inisialisasi TUI Image Editor // Update the Edit Foto button event handler
const imageEditor = new tui.ImageEditor(imageEditorContainer, { const editFotoButton = document.querySelector('[data-modal-toggle="#modal_10"]');
includeUI: { if (editFotoButton) {
loadImage: { editFotoButton.addEventListener('click', function(e) {
path: file.dataURL, e.preventDefault();
name: 'Uploaded Photo' // Get the file path from hidden input
}, const filePath = document.getElementById('editDataFilePath').value;
theme: {
'common.bi.image': '', if (filePath) {
'common.bisize.width': '25px', openFilerobotEditor(filePath);
'common.bisize.height': '25px', } else {
'common.backgroundImage': 'none', alert('Tidak ada foto untuk diedit');
'common.backgroundColor': '#fff', }
'common.border': '1px solid #ccc' });
}, }
menu: ['crop', 'flip', 'rotate', 'draw', 'shape', 'icon', 'text', 'filter'], });
initMenu: 'filter'
function openFilerobotEditor(imagePath) {
// Get the editor container
const editorContainer = document.getElementById('editor_container');
if (!editorContainer) {
console.error('Editor container not found');
return;
}
// Configuration for the editor
const config = {
source: imagePath || '',
onSave: (editedImageObject, designState) => {
console.log('Image saved', editedImageObject);
// Save the edited image
saveEditedImage(editedImageObject, document.getElementById('editDataFilePath').value);
// Close the editor
FilerobotImageEditor.terminate();
// Hide the modal
document.getElementById('modal_10').setAttribute('data-modal-dismiss', 'true');
// Update the preview if needed
updateImagePreview(editedImageObject.imageBase64 || editedImageObject.imageCanvas.toDataURL());
}, },
cssMaxWidth: 700, annotationsCommon: {
cssMaxHeight: 500 fill: '#ff0000'
},
Text: {
text: 'Tambahkan teks...'
},
Rotate: {
angle: 90,
componentType: 'slider'
},
tabsIds: [
window.FilerobotImageEditor.TABS.ADJUST,
window.FilerobotImageEditor.TABS.FILTERS,
window.FilerobotImageEditor.TABS.FINETUNE,
window.FilerobotImageEditor.TABS.ANNOTATE,
window.FilerobotImageEditor.TABS.WATERMARK,
window.FilerobotImageEditor.TABS.RESIZE,
],
defaultTabId: window.FilerobotImageEditor.TABS.ADJUST,
Language: {
Save: 'Simpan',
Cancel: 'Batal',
Reset: 'Reset',
Edit: 'Edit',
Delete: 'Hapus'
}
};
// Initialize the Filerobot Image Editor
const filerobotImageEditor = new FilerobotImageEditor(
editorContainer,
config
);
// Render the editor
filerobotImageEditor.render({
onClose: (closingReason) => {
console.log('Editor closed:', closingReason);
filerobotImageEditor.terminate();
// Hide the modal
document.querySelector('#modal_10').setAttribute('data-modal-dismiss', 'true');
}
}); });
// openModal('editPhotoModal');
} }
window.addEditAndDeleteButtons = function(file, response) { window.addEditAndDeleteButtons = function(file, response) {
const filePreviewElement = file.previewElement; const filePreviewElement = file.previewElement;
@@ -694,8 +769,6 @@ document.addEventListener('DOMContentLoaded', function() {
filePreviewElement.appendChild(buttonContainer); filePreviewElement.appendChild(buttonContainer);
} }
async function saveEditedFoto() { async function saveEditedFoto() {
$.ajax({ $.ajax({
url: `{{ route('surveyor.updateFoto') }}`, url: `{{ route('surveyor.updateFoto') }}`,
@@ -736,6 +809,56 @@ document.addEventListener('DOMContentLoaded', function() {
} }
}); });
} }
function saveEditedImage(editedImageObject, originalFilePath) {
// Get the image data (base64 or canvas)
const imageData = editedImageObject.imageBase64 ||
(editedImageObject.imageCanvas ? editedImageObject.imageCanvas.toDataURL() : null);
if (!imageData) {
Swal.fire({
icon: 'error',
title: 'Gagal Menyimpan',
text: 'Tidak ada data gambar untuk disimpan',
});
return;
}
const formData = new FormData();
formData.append('edited_image', imageData);
formData.append('original_path', originalFilePath);
formData.forEach((value, key) => {
console.log(`${key}:`, value);
});
fetch('/api/save-edited-image', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
Swal.fire({
icon: 'success',
title: 'Perubahan Disimpan',
text: response.message,
confirmButtonText: 'OK'
}).then((response) => {
if (response.isConfirmed) {
window.location.reload();
}
});;
})
.catch(error => {
const errorMessage = xhr.responseJSON?.message || 'Terjadi kesalahan';
Swal.fire({
icon: 'error',
title: 'Gagal Menyimpan',
text: errorMessage,
});
});
}
</script> </script>
@include('lpj::surveyor.js.camera-editor')
@endpush @endpush