900 lines
37 KiB
PHP
900 lines
37 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\AksesFile;
|
|
use App\Models\AksesFileDetail;
|
|
use App\Models\FileDirectory;
|
|
use App\Models\LogActivity;
|
|
use App\Models\MasterKategori;
|
|
use App\Models\MasterKlasifikasi;
|
|
use App\Models\SubUnitKerja;
|
|
use App\Models\UnitKerja;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
use setasign\Fpdi\Fpdi;
|
|
use ZipArchive;
|
|
|
|
use function PHPUnit\Framework\isEmpty;
|
|
|
|
class DashboardController extends Controller
|
|
{
|
|
public function index(){
|
|
$katDok = MasterKategori::where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get();
|
|
$klasifikasiDok = MasterKlasifikasi::where('statusenabled', true)->select('master_klasifikasi_directory_id', 'nama_klasifikasi_directory')->get();
|
|
|
|
$authMapping = auth()->user()?->dataUser?->mappingUnitKerjaPegawai[0];
|
|
$authUnitKerja = $authMapping->objectunitkerjapegawaifk;
|
|
$authSubUnitKerja = $authMapping->objectsubunitkerjapegawaifk;
|
|
|
|
$allAkses = AksesFile::where(['statusenabled' => true, 'pegawai_id' => auth()->user()?->dataUser->id])->first();
|
|
$payload = [
|
|
'title' => 'Dashboard',
|
|
'katDok' => $katDok,
|
|
'klasifikasiDok' => $klasifikasiDok,
|
|
'authUnitKerja' => $authUnitKerja,
|
|
'authSubUnitKerja' => $authSubUnitKerja,
|
|
'allAkses' => $allAkses ?? null
|
|
];
|
|
return view('dashboard.index', $payload);
|
|
}
|
|
|
|
public function dataUnitKerja(){
|
|
$user = auth()->user()?->dataUser;
|
|
$akses = AksesFile::where(['pegawai_id' => $user->id, 'statusenabled' => true])->first();
|
|
$aksesAll = $akses?->akses ?? $akses?->all_akses ?? false;
|
|
$detailUnitIds = collect();
|
|
if ($akses?->akses_file_id) {
|
|
$detailUnitIds = AksesFileDetail::where('akses_file_id', $akses->akses_file_id)
|
|
->where('statusenabled', true)
|
|
->pluck('id_unit_kerja')
|
|
->unique()
|
|
->values();
|
|
}
|
|
$allowedUnitIds = null;
|
|
if (!$aksesAll) {
|
|
if ($detailUnitIds->isNotEmpty()) {
|
|
$allowedUnitIds = $detailUnitIds;
|
|
} elseif (!empty($akses?->unit_akses)) {
|
|
$allowedUnitIds = collect([$akses->unit_akses]);
|
|
}
|
|
}
|
|
|
|
$kategori = request('kategori');
|
|
$filterUnit = request('unitKerja');
|
|
$subUnit = request('subUnit');
|
|
$keyword = request('keyword');
|
|
$subArray = $subUnit ? explode(',', $subUnit) : [];
|
|
$katArray = $kategori ? explode(',', $kategori) : [];
|
|
$katDok = MasterKategori::when($katArray, fn($q) => $q->whereIn('master_kategori_directory_id', $katArray))->where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get();
|
|
if ($katArray && $filterUnit && $subArray) {
|
|
/* mode pencarian lengkap */
|
|
if ($allowedUnitIds && !$allowedUnitIds->contains((int) $filterUnit)) {
|
|
$unitKerja = collect();
|
|
} else {
|
|
$unitKerja = UnitKerja::where('statusenabled', true)
|
|
->where('id', $filterUnit)
|
|
->with(['subUnitKerja' => fn($q) => $q->whereIn('id', $subArray)
|
|
->with(['fileDirectory' => fn($q) => $q
|
|
->where('id_unit_kerja', $filterUnit)->whereNotNull('status_action')
|
|
->when($subArray, fn($q) => $q->whereIn('id_sub_unit_kerja', $subArray))
|
|
->when($katArray, fn($q) => $q->whereIn('master_kategori_directory_id', $katArray))
|
|
->when($keyword, fn($q) =>
|
|
$q->where(function($query) use ($keyword) {
|
|
$query->where('file', 'ilike', "%{$keyword}%");
|
|
})
|
|
)
|
|
])
|
|
])
|
|
->select('id', 'name')
|
|
->get();
|
|
}
|
|
|
|
} elseif ($aksesAll) {
|
|
/* all akses */
|
|
$unitKerja = UnitKerja::where('statusenabled', true)->with([ // muat relasi
|
|
'subUnitKerja' => fn($q) => $q->with([ // sub-unit
|
|
'fileDirectory' => fn($f) => $f->whereNotNull('status_action')->when($keyword, fn($q) =>
|
|
$q->where('file', 'ilike', "%{$keyword}%")
|
|
)
|
|
])
|
|
])
|
|
->select('id', 'name')
|
|
->get();
|
|
|
|
} elseif ($allowedUnitIds) {
|
|
$unitKerja = UnitKerja::where('statusenabled', true)
|
|
->whereIn('id', $allowedUnitIds)
|
|
->with([
|
|
'subUnitKerja' => fn($q) => $q->with([
|
|
'fileDirectory' => fn($f) => $f->whereNotNull('status_action')->when($keyword, fn($q) =>
|
|
$q->where(function($query) use ($keyword) {
|
|
$query->where('file', 'ilike', "%{$keyword}%");
|
|
})
|
|
)
|
|
])
|
|
])
|
|
->select('id', 'name')
|
|
->get();
|
|
|
|
} else {
|
|
$authUnit = $user?->mappingUnitKerjaPegawai[0]?->objectunitkerjapegawaifk;
|
|
$authSub = $user?->mappingUnitKerjaPegawai[0]?->objectsubunitkerjapegawaifk;
|
|
|
|
$unitKerja = UnitKerja::where('statusenabled', true)
|
|
->where('id', $authUnit)
|
|
->with([ // 1. sub-unit milik user
|
|
'subUnitKerja' => fn($q) => $q->where('id', $authSub)
|
|
->with([ // 2. file-directory + filter keyword
|
|
'fileDirectory' => fn($f) => $f->whereNotNull('status_action')->when($keyword, fn($q) =>
|
|
$q->where(function($query) use ($keyword) {
|
|
$query->where('file', 'ilike', "%{$keyword}%");
|
|
})
|
|
)
|
|
])
|
|
])
|
|
->select('id', 'name')
|
|
->get();
|
|
}
|
|
|
|
$data = [
|
|
'unitKerja' => $unitKerja ?? null,
|
|
'katDok' => $katDok ?? null
|
|
];
|
|
return response()->json([
|
|
'status' => true,
|
|
'data' => $data,
|
|
], 200);
|
|
}
|
|
|
|
public function store(){
|
|
DB::connection('dbDirectory')->beginTransaction();
|
|
try {
|
|
$datas = request()->input('data');
|
|
$result = [];
|
|
foreach($datas as $index => $value){
|
|
$files = request()->file("data.fileUpload$index");
|
|
if(!empty($files)){
|
|
foreach ($files['file'] as $file) {
|
|
list($id_unit_kerja, $nama_unit_kerja) = explode('/', $value['id_unit_kerja'],2);
|
|
list($id_sub_unit_kerja, $nama_sub_unit_kerja) = explode('/', $value['id_sub_unit_kerja'],2);
|
|
list($master_kategori_directory_id, $nama_kategori) = explode('/', $value['master_kategori_directory_id'],2);
|
|
list($klasifikasi, $nama_klasifikasi) = explode('/', $value['klasifikasi'],2);
|
|
$payload = [
|
|
'master_klasifikasi_directory_id' => $klasifikasi,
|
|
'id_unit_kerja' => $id_unit_kerja,
|
|
'id_sub_unit_kerja' => $id_sub_unit_kerja,
|
|
'master_kategori_directory_id' => $master_kategori_directory_id,
|
|
'pegawai_id_entry' => auth()->user()->dataUser->id ?? 1,
|
|
'pegawai_nama_entry' => auth()->user()->dataUser->namalengkap ?? 'tes',
|
|
];
|
|
if($file){
|
|
$imageName = $file->getClientOriginalName();
|
|
$path = "{$nama_unit_kerja}/{$nama_sub_unit_kerja}/{$nama_kategori}/{$nama_klasifikasi}";
|
|
$file->storeAs($path, $imageName, 'file_directory');
|
|
$payload['file'] =$path .'/' .$imageName;
|
|
}
|
|
FileDirectory::create($payload);
|
|
}
|
|
}
|
|
}
|
|
DB::connection('dbDirectory')->commit();
|
|
return response()->json([
|
|
'status' => true,
|
|
'message' => 'Data berhasil disimpan',
|
|
'data' => count($result) == 1 ? $result[0] : $result
|
|
], 200);
|
|
} catch (\Throwable $th) {
|
|
DB::connection('dbDirectory')->rollBack();
|
|
return response()->json([
|
|
'status' => false,
|
|
'message' => $th->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function OptionUnitKerja(){
|
|
$q = request()->get('q');
|
|
$query = UnitKerja::where('statusenabled', true);
|
|
|
|
$data = $query->when($q, function ($query, $q){
|
|
$query->where('name', 'ILIKE', '%' .$q . '%');
|
|
})
|
|
->select('id', 'name')->get();
|
|
return response()->json([
|
|
'status' => true,
|
|
'data' => $data
|
|
], 200);
|
|
}
|
|
|
|
public function deleteFile(string $id){
|
|
DB::connection('dbDirectory')->beginTransaction();
|
|
try {
|
|
$data = FileDirectory::where('file_directory_id', $id)->first();
|
|
if(!$data){
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'File tidak ditemukan'
|
|
]);
|
|
}
|
|
$oldPath= public_path('file/' . $data->file);
|
|
$fileInfo = pathinfo($data->file);
|
|
$newFileName = $fileInfo['filename'] . '_deleted.' . $fileInfo['extension'];
|
|
$newPath = public_path('file/' . $fileInfo['dirname'] . '/' . $newFileName);
|
|
if (file_exists($oldPath)) {
|
|
// pastikan folder tujuan ada
|
|
if (!is_dir(dirname($newPath))) {
|
|
mkdir(dirname($newPath), 0777, true);
|
|
}
|
|
rename($oldPath, $newPath);
|
|
}
|
|
|
|
$data->update(['statusenabled' => false, 'file' => $fileInfo['dirname'].'/'. $newFileName]);
|
|
|
|
$payloadLog = [
|
|
'file_directory_id' => $data->file_directory_id,
|
|
'pegawai_id_entry' => $data->pegawai_id_entry,
|
|
'pegawai_nama_entry' => $data->pegawai_nama_entry,
|
|
'entry_at' => $data->entry_at,
|
|
'action_type' => 'Hapus Dokumen',
|
|
'statusenabled' => true,
|
|
'mod_change' => $data->entry_at,
|
|
'id_unit_kerja' => $data->id_unit_kerja,
|
|
'id_sub_unit_kerja' => $data->id_sub_unit_kerja,
|
|
'file' => $data->file,
|
|
'tanggal_terbit' => $data->tanggal_terbit,
|
|
'no_dokumen' => $data->no_dokumen,
|
|
'permission_file' => $data->permission_file,
|
|
];
|
|
LogActivity::create($payloadLog);
|
|
|
|
DB::connection('dbDirectory')->commit();
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Berhasil menghapus data'
|
|
]);
|
|
} catch (\Throwable $th) {
|
|
DB::connection('dbDirectory')->rollBack();
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Gagal menghapus data'
|
|
]);
|
|
//throw $th;
|
|
}
|
|
|
|
}
|
|
|
|
public function optionSubUnitKerja(string $id){
|
|
$data = SubUnitKerja::where('statusenabled', true)->where('objectunitkerjapegawaifk', $id)->get();
|
|
return response()->json([
|
|
'status' => true,
|
|
'data' => $data,
|
|
]);
|
|
}
|
|
|
|
|
|
public function getFile($id_unit_kerja, $id_sub_unit_kerja, $master_kategori_directory_id){
|
|
$klasifikasi = request('klasifikasi');
|
|
$klaArray = explode(',', $klasifikasi);
|
|
$data = FileDirectory::where(['statusenabled' => true, 'id_unit_kerja' => $id_unit_kerja, 'id_sub_unit_kerja' => $id_sub_unit_kerja, 'master_kategori_directory_id' => $master_kategori_directory_id])->whereIn('master_klasifikasi_directory_id', $klaArray)->get();
|
|
return response()->json([
|
|
'data' => $data,
|
|
'status' => true,
|
|
]);
|
|
}
|
|
|
|
public function downloadDataMultiple(){
|
|
try {
|
|
$rows = request('ids', []); // [[unit_id=>u, sub_unit_id=>s], ...]
|
|
if (empty($rows)) {
|
|
return response()->json(['message' => 'Tidak ada data'], 422);
|
|
}
|
|
$paths = [];
|
|
foreach ($rows as $r) {
|
|
if(!empty($r['sub_unit_id'])){
|
|
$files = FileDirectory::where('id_sub_unit_kerja', $r['sub_unit_id'])->where('statusenabled', true)->pluck('file');
|
|
|
|
$paths = array_merge($paths, $files->toArray());
|
|
}
|
|
}
|
|
$paths = array_unique($paths);
|
|
|
|
if (empty($paths)) {
|
|
return response()->json(['message' => 'File tidak ditemukan'], 404);
|
|
}
|
|
|
|
$zipName = 'files_' . time() . '.zip';
|
|
$zipPath = public_path('zip/' . $zipName);
|
|
$zip = new ZipArchive;
|
|
$tempFiles = [];
|
|
if($zip->open($zipPath, ZipArchive::CREATE) === TRUE){
|
|
foreach ($paths as $path) {
|
|
$fullPath = public_path('file/' . $path);
|
|
if(!file_exists($fullPath)){
|
|
throw new \Exception("File tidak ditemukan: " . $path);
|
|
}
|
|
|
|
$relativePathInZip = $path;
|
|
$fileToAdd = $this->prepareFileWithWatermark($fullPath, $tempFiles);
|
|
$zip->addFile($fileToAdd, $relativePathInZip);
|
|
}
|
|
$zip->close();
|
|
}
|
|
$this->cleanupTempFiles($tempFiles);
|
|
return response()->download(public_path('zip/' . $zipName))->deleteFileAfterSend(true);
|
|
//code...
|
|
} catch (\Throwable $th) {
|
|
return response()->json([
|
|
'message' => 'Terjadi kesalahan',
|
|
'error' => $th->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function downloadDataFolder(){
|
|
try {
|
|
$id = request('id');
|
|
$type = request('type');
|
|
|
|
if($type === "unit"){
|
|
$data = FileDirectory::where('id_unit_kerja', $id)->where('statusenabled', true)->pluck('file');
|
|
}else{
|
|
$data = FileDirectory::where('id_sub_unit_kerja', $id)->where('statusenabled', true)->pluck('file');
|
|
}
|
|
if (empty($data)) {
|
|
return response()->json(['message' => 'File tidak ditemukan'], 404);
|
|
}
|
|
$zipName = 'files_' . time() . '.zip';
|
|
$zipPath = public_path('zip/' . $zipName);
|
|
$zip = new ZipArchive;
|
|
$tempFiles = [];
|
|
if($zip->open($zipPath, ZipArchive::CREATE) === TRUE){
|
|
foreach ($data as $path) {
|
|
$fullPath = public_path('file/' . $path);
|
|
if(!file_exists($fullPath)){
|
|
throw new \Exception("File tidak ditemukan: " . $path);
|
|
}
|
|
|
|
$relativePathInZip = $path;
|
|
$fileToAdd = $this->prepareFileWithWatermark($fullPath, $tempFiles);
|
|
$zip->addFile($fileToAdd, $relativePathInZip);
|
|
}
|
|
$zip->close();
|
|
}
|
|
$this->cleanupTempFiles($tempFiles);
|
|
return response()->download(public_path('zip/' . $zipName))->deleteFileAfterSend(true);
|
|
} catch (\Throwable $th) {
|
|
return response()->json([
|
|
'message' => 'Terjadi kesalahan',
|
|
'error' => $th->getMessage()
|
|
], 500);
|
|
}
|
|
|
|
}
|
|
|
|
public function dashboardVersion2(){
|
|
$katDok = MasterKategori::where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get();
|
|
$authMapping = auth()->user()?->dataUser?->mappingUnitKerjaPegawai[0];
|
|
$authUnitKerja = $authMapping->objectunitkerjapegawaifk;
|
|
$authSubUnitKerja = $authMapping->objectsubunitkerjapegawaifk;
|
|
$data = [
|
|
'title' => 'Dashboard',
|
|
'katDok' => $katDok,
|
|
'authUnitKerja' => $authUnitKerja,
|
|
'authSubUnitKerja' => $authSubUnitKerja,
|
|
];
|
|
return view('dashboardV2.index', $data);
|
|
}
|
|
|
|
public function dataDocumentLast(){
|
|
$perPage = (int) request('per_page', 10);
|
|
$authUnitId = auth()->user()->dataUser?->mappingUnitKerjaPegawai[0]?->objectunitkerjapegawaifk;
|
|
$user = auth()->user()?->dataUser;
|
|
$akses = AksesFile::where(['pegawai_id' => $user->id, 'statusenabled' => true])->first();
|
|
$keyword = request('keyword');
|
|
|
|
$query = FileDirectory::where('statusenabled', true)->whereNotNull('status_action')
|
|
->when($keyword, function ($q) use ($keyword) {
|
|
$q->where(function ($sub) use ($keyword) {
|
|
$sub->where('file', 'ILIKE', "%{$keyword}%")
|
|
->orWhere('no_dokumen', 'ILIKE', "%{$keyword}%");
|
|
});
|
|
});
|
|
if($akses){
|
|
if(!$akses->all_akses){
|
|
$aksesFile = AksesFileDetail::where('akses_file_id', $akses->akses_file_id)->pluck('id_unit_kerja');
|
|
$query->where(function ($query) use ($authUnitId, $aksesFile) {
|
|
$query->where('permission_file', true)
|
|
->orWhere(function ($sub) use ($authUnitId, $aksesFile) {
|
|
$sub->where('permission_file', false)
|
|
->whereIn('id_unit_kerja', $aksesFile);
|
|
});
|
|
});
|
|
}else{
|
|
$query;
|
|
}
|
|
}else{
|
|
$query->where(function ($query) use ($authUnitId) {
|
|
$query->where('permission_file', true)
|
|
->orWhere(function ($sub) use ($authUnitId) {
|
|
$sub->where('permission_file', false)
|
|
->where('id_unit_kerja', $authUnitId);
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
|
|
$data = $query->orderBy('entry_at', 'desc')
|
|
->paginate($perPage);
|
|
|
|
$payload = [
|
|
'status' => true,
|
|
'message' => 'Berhasil mendapatkan data',
|
|
'data' => $data->items(),
|
|
'pagination' => [
|
|
'current_page' => $data->currentPage(),
|
|
'next_page' => $data->hasMorePages() ? $data->currentPage() + 1 : null,
|
|
'has_more' => $data->hasMorePages(),
|
|
'last_page' => $data->lastPage(),
|
|
'per_page' => $data->perPage(),
|
|
'total' => $data->total(),
|
|
]
|
|
];
|
|
return response()->json($payload);
|
|
}
|
|
|
|
public function storeVersion2(){
|
|
DB::connection('dbDirectory')->beginTransaction();
|
|
try {
|
|
$datas = request('data');
|
|
foreach ($datas as $index => $data) {
|
|
list($id_unit_kerja, $nama_unit_kerja) = explode('/', $data['id_unit_kerja'],2);
|
|
list($id_sub_unit_kerja, $nama_sub_unit_kerja) = explode('/', $data['id_sub_unit_kerja'],2);
|
|
list($master_kategori_directory_id, $nama_kategori) = explode('/', $data['master_kategori_directory_id'],2);
|
|
|
|
$uploadedFile = request()->file("data.$index.file");
|
|
if(!$uploadedFile){
|
|
throw new \RuntimeException('File wajib diunggah pada baris ke-' . ($index+1));
|
|
}
|
|
|
|
$payload = [
|
|
'id_unit_kerja' => $id_unit_kerja,
|
|
'id_sub_unit_kerja' => $id_sub_unit_kerja,
|
|
'master_kategori_directory_id' => $master_kategori_directory_id,
|
|
'pegawai_id_entry' => auth()->user()->dataUser->id ?? 1,
|
|
'pegawai_nama_entry' => auth()->user()->dataUser->namalengkap ?? null,
|
|
'tanggal_terbit' => $data['date_active'] ?? null,
|
|
'no_dokumen' => $data['no_dokumen'] ?? null,
|
|
'permission_file' => ($data['is_permission'] ?? null) == "1",
|
|
];
|
|
|
|
$imageName = $uploadedFile->getClientOriginalName();
|
|
$path = "{$nama_unit_kerja}/{$nama_sub_unit_kerja}/{$nama_kategori}";
|
|
$uploadedFile->storeAs($path, $imageName, 'file_directory');
|
|
$payload['file'] =$path .'/' .$imageName;
|
|
|
|
$fd = FileDirectory::create($payload);
|
|
|
|
$payloadLog = [
|
|
'file_directory_id' => $fd->file_directory_id,
|
|
'pegawai_id_entry' => $fd->pegawai_id_entry,
|
|
'pegawai_nama_entry' => $fd->pegawai_nama_entry,
|
|
'entry_at' => $fd->entry_at,
|
|
'action_type' => 'Upload Dokumen',
|
|
'statusenabled' => true,
|
|
'mod_change' => $fd->entry_at,
|
|
'id_unit_kerja' => $fd->id_unit_kerja,
|
|
'id_sub_unit_kerja' => $fd->id_sub_unit_kerja,
|
|
'file' => $fd->file,
|
|
'tanggal_terbit' => $fd->tanggal_terbit,
|
|
'no_dokumen' => $fd->no_dokumen,
|
|
'permission_file' => $fd->permission_file,
|
|
];
|
|
LogActivity::create($payloadLog);
|
|
}
|
|
DB::connection('dbDirectory')->commit();
|
|
return response()->json([
|
|
'status' => true,
|
|
'message' => 'Data berhasil disimpan'
|
|
], 200);
|
|
} catch (\Throwable $th) {
|
|
DB::connection('dbDirectory')->rollback();
|
|
return response()->json([
|
|
'status' => false,
|
|
'message' => $th->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function dataPdf($fileDirectoryId)
|
|
{
|
|
$data = FileDirectory::where('file_directory_id', $fileDirectoryId)->first();
|
|
|
|
$filePath = public_path('file/' . $data->file);
|
|
|
|
if (!file_exists($filePath)) {
|
|
abort(404, 'PDF Tidak ditemukan');
|
|
}
|
|
|
|
$stampFile = public_path('assets/copy.png');
|
|
if (!file_exists($stampFile)) {
|
|
// kalau watermark tidak ada, tampilkan file asli
|
|
return response()->file($filePath, [
|
|
'Content-Type' => 'application/pdf',
|
|
'Content-Disposition' => 'inline; filename="preview.pdf"',
|
|
'Cache-Control' => 'no-store, no-cache, must-revalidate, max-age=0',
|
|
]);
|
|
}
|
|
|
|
$tempConverted = storage_path('app/temp/' . uniqid('conv_') . '.pdf');
|
|
|
|
try {
|
|
// coba watermark langsung
|
|
return $this->watermarkCenterAndStream($filePath, $stampFile);
|
|
|
|
} catch (\Throwable $e) {
|
|
// kalau gagal (PDF modern) -> convert dulu
|
|
// dd($e);
|
|
$this->convertWithGhostscript($filePath, $tempConverted);
|
|
|
|
$resp = $this->watermarkCenterAndStream($tempConverted, $stampFile);
|
|
|
|
@unlink($tempConverted);
|
|
return $resp;
|
|
}
|
|
}
|
|
|
|
private function watermarkCenterAndStream(string $pdfPath, string $stampFile)
|
|
{
|
|
$pdf = new Fpdi();
|
|
$pageCount = $pdf->setSourceFile($pdfPath);
|
|
|
|
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
|
|
$tplId = $pdf->importPage($pageNo);
|
|
$size = $pdf->getTemplateSize($tplId);
|
|
|
|
$pdf->AddPage($size['orientation'], [$size['width'], $size['height']]);
|
|
$pdf->useTemplate($tplId);
|
|
|
|
// watermark tengah (skala adaptif)
|
|
$stampW = $size['width'] * 0.60;
|
|
$stampH = $stampW * 0.75; // sesuaikan rasio gambar kalau perlu
|
|
|
|
$x = ($size['width'] - $stampW) / 2;
|
|
$y = ($size['height'] - $stampH) / 2;
|
|
|
|
$pdf->Image($stampFile, $x, $y, $stampW, $stampH);
|
|
}
|
|
|
|
$output = $pdf->Output('S');
|
|
|
|
return response($output, 200, [
|
|
'Content-Type' => 'application/pdf',
|
|
'Content-Disposition' => 'inline; filename="preview.pdf"',
|
|
'Cache-Control' => 'no-store, no-cache, must-revalidate, max-age=0',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Generate watermarked PDF to temp file (or return original) for zipping.
|
|
*/
|
|
private function prepareFileWithWatermark(string $fullPath, array &$tempFiles = [])
|
|
{
|
|
$stampFile = public_path('assets/copy.png');
|
|
$ext = strtolower(pathinfo($fullPath, PATHINFO_EXTENSION));
|
|
|
|
if ($ext !== 'pdf' || !file_exists($stampFile)) {
|
|
return $fullPath;
|
|
}
|
|
|
|
$tempDir = storage_path('app/temp');
|
|
if (!is_dir($tempDir)) {
|
|
@mkdir($tempDir, 0777, true);
|
|
}
|
|
$tempOut = $tempDir . '/' . uniqid('wm_') . '.pdf';
|
|
|
|
try {
|
|
$this->watermarkCenterToFile($fullPath, $stampFile, $tempOut);
|
|
} catch (\Throwable $e) {
|
|
// fallback convert then watermark
|
|
$converted = $tempDir . '/' . uniqid('conv_') . '.pdf';
|
|
$this->convertWithGhostscript($fullPath, $converted);
|
|
$this->watermarkCenterToFile($converted, $stampFile, $tempOut);
|
|
$tempFiles[] = $converted;
|
|
}
|
|
|
|
$tempFiles[] = $tempOut;
|
|
return $tempOut;
|
|
}
|
|
|
|
private function watermarkCenterToFile(string $pdfPath, string $stampFile, string $outputPath): void
|
|
{
|
|
$pdf = new Fpdi();
|
|
$pageCount = $pdf->setSourceFile($pdfPath);
|
|
|
|
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
|
|
$tplId = $pdf->importPage($pageNo);
|
|
$size = $pdf->getTemplateSize($tplId);
|
|
|
|
$pdf->AddPage($size['orientation'], [$size['width'], $size['height']]);
|
|
$pdf->useTemplate($tplId);
|
|
|
|
$stampW = $size['width'] * 0.60;
|
|
$stampH = $stampW * 0.75;
|
|
|
|
$x = ($size['width'] - $stampW) / 2;
|
|
$y = ($size['height'] - $stampH) / 2;
|
|
|
|
$pdf->Image($stampFile, $x, $y, $stampW, $stampH);
|
|
}
|
|
|
|
$pdf->Output($outputPath, 'F');
|
|
}
|
|
|
|
private function cleanupTempFiles(array $tempFiles): void
|
|
{
|
|
foreach ($tempFiles as $file) {
|
|
if (is_string($file) && file_exists($file)) {
|
|
@unlink($file);
|
|
}
|
|
}
|
|
}
|
|
|
|
private function convertWithGhostscript(string $inputPdf, string $outputPdf): void
|
|
{
|
|
$gs = config('services.ghostscript.path');
|
|
|
|
if (!$gs || !file_exists($gs)) {
|
|
throw new \RuntimeException('Ghostscript tidak ditemukan. Cek GHOSTSCRIPT_PATH di .env');
|
|
}
|
|
|
|
$cmd = "\"{$gs}\" -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress "
|
|
. "-dNOPAUSE -dBATCH -dQUIET -sOutputFile=\"{$outputPdf}\" \"{$inputPdf}\"";
|
|
|
|
exec($cmd, $out, $code);
|
|
|
|
if ($code !== 0 || !file_exists($outputPdf)) {
|
|
throw new \RuntimeException('Convert Ghostscript gagal (code=' . $code . ')');
|
|
}
|
|
}
|
|
|
|
public function recapData(){
|
|
try {
|
|
$perPage = (int) request('per_page', 10);
|
|
$page = max(1, (int) request('page', 1));
|
|
$keyword = strtolower(request('keyword', ''));
|
|
$authUnit = auth()->user()->masterPersetujuan->details->pluck('unit_pegawai_id')->unique()->toArray();
|
|
$rows = FileDirectory::where('statusenabled', true)->whereNotNull('status_action')->whereIn('id_unit_kerja', $authUnit)->pluck('file');
|
|
|
|
$grouped = [];
|
|
foreach ($rows as $path) {
|
|
$parts = array_values(array_filter(explode('/', $path)));
|
|
if(count($parts) < 4){
|
|
continue;
|
|
}
|
|
|
|
$unit = $parts[0];
|
|
$folder = $parts[1]. '/' . $parts[2];
|
|
if($keyword){
|
|
$hit = str_contains(strtolower($unit), $keyword) || str_contains(strtolower($folder), $keyword);
|
|
if(!$hit) continue;
|
|
}
|
|
if(!isset($grouped[$unit])){
|
|
$grouped[$unit] = [];
|
|
}
|
|
if (!isset($grouped[$unit][$folder])) {
|
|
$grouped[$unit][$folder] = 0;
|
|
}
|
|
$grouped[$unit][$folder]++;
|
|
}
|
|
$result = [];
|
|
foreach ($grouped as $unitName => $folders) {
|
|
$data = [];
|
|
foreach ($folders as $folder => $count) {
|
|
$sliceText = array_values(array_filter(explode('/', $folder)));
|
|
$data[] = [
|
|
'subUnit' => $sliceText[0],
|
|
'folder'=> $sliceText[1],
|
|
'count' => $count,
|
|
];
|
|
}
|
|
|
|
usort($data, fn($a, $b) => $b['count'] <=> $a['count']);
|
|
$result[] = [
|
|
'unit' => $unitName,
|
|
'data' => $data,
|
|
];
|
|
}
|
|
// paginate manually
|
|
$total = count($result);
|
|
$chunks = array_chunk($result, $perPage);
|
|
$currentData = $chunks[$page-1] ?? [];
|
|
|
|
return response()->json([
|
|
'status' => true,
|
|
'data' => $currentData,
|
|
'message' => 'Berhasil mendapatkan data',
|
|
'pagination' => [
|
|
'current_page' => $page,
|
|
'per_page' => $perPage,
|
|
'total' => $total,
|
|
'last_page' => max(1, ceil($total / $perPage)),
|
|
'has_more' => $page < max(1, ceil($total / $perPage)),
|
|
]
|
|
]);
|
|
} catch (\Throwable $th) {
|
|
return response()->json([
|
|
'status' => false,
|
|
'message' => 'Gagal! mendapatkan data'
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function recapView(){
|
|
return view('dashboard.recap', ['title' => 'Rekap Dokumen']);
|
|
}
|
|
|
|
public function pendingFile(){
|
|
return view('pendingFile.index', ['title' => 'Data Pending']);
|
|
}
|
|
|
|
public function dataPendingFile(){
|
|
$perPage = (int) request('per_page', 10);
|
|
$keyword = request('keyword');
|
|
$start = request('start_date');
|
|
$end = request('end_date');
|
|
$authUnit = auth()->user()->masterPersetujuan->details->pluck('unit_pegawai_id')->unique()->toArray();
|
|
|
|
$query = FileDirectory::where('statusenabled', true)->whereNull('status_action')->whereIn('id_unit_kerja', $authUnit)->orderBy('entry_at','desc');
|
|
if($keyword){
|
|
$query->where(function($q) use ($keyword){
|
|
$q->where('file', 'ILIKE', "%{$keyword}%")
|
|
->orWhere('no_dokumen', 'ILIKE', "%{$keyword}%");
|
|
});
|
|
}
|
|
if($start){
|
|
$query->whereDate('entry_at','>=',$start);
|
|
}
|
|
if($end){
|
|
$query->whereDate('entry_at','<=',$end);
|
|
}
|
|
|
|
$paginated = $query->paginate($perPage);
|
|
$data = $paginated->getCollection()->map(function($item){
|
|
$dataSlice = array_values(array_filter(explode('/', $item->file)));
|
|
return [
|
|
'file_directory_id' => $item->file_directory_id,
|
|
'pegawai_nama_entry' => $item->pegawai_nama_entry,
|
|
'part' => $dataSlice[0] . '/' . $dataSlice[1],
|
|
'folder' => $dataSlice[2],
|
|
'fileName' =>$dataSlice[3],
|
|
'file' => $item->file,
|
|
'no_dokumen' => $item->no_dokumen,
|
|
'entry_at' => $item->entry_at,
|
|
'tanggal_terbit' => $item->tanggal_terbit,
|
|
'permission_file' => $item->permission_file,
|
|
];
|
|
});
|
|
return response()->json([
|
|
'status' => true,
|
|
'data' => $data,
|
|
'pagination' => [
|
|
'current_page' => $paginated->currentPage(),
|
|
'next_page' => $paginated->hasMorePages() ? $paginated->currentPage() + 1 : null,
|
|
'has_more' => $paginated->hasMorePages(),
|
|
'last_page' => $paginated->lastPage(),
|
|
'per_page' => $paginated->perPage(),
|
|
'total' => $paginated->total(),
|
|
]
|
|
]);
|
|
|
|
}
|
|
|
|
public function approvePendingFile(string $id){
|
|
try {
|
|
$data = FileDirectory::where('file_directory_id', $id)->first();
|
|
if(!$data){
|
|
return response()->json([
|
|
'status' => false,
|
|
'message' => 'Data tidak ditemukan'
|
|
], 404);
|
|
}
|
|
$data->update([
|
|
'status_action' => 'approved',
|
|
'action_at' => Carbon::now(),
|
|
'action_by' => auth()->user()->dataUser->id,
|
|
]);
|
|
$payloadLog = [
|
|
'file_directory_id' => $data->file_directory_id,
|
|
'pegawai_id_entry' => $data->action_by,
|
|
'pegawai_nama_entry' => auth()->user()->dataUser->namalengkap,
|
|
'entry_at' => $data->action_at,
|
|
'action_type' => 'Approval Dokumen',
|
|
'statusenabled' => true,
|
|
'mod_change' => $data->entry_at,
|
|
'id_unit_kerja' => $data->id_unit_kerja,
|
|
'id_sub_unit_kerja' => $data->id_sub_unit_kerja,
|
|
'file' => $data->file,
|
|
'tanggal_terbit' => $data->tanggal_terbit,
|
|
'no_dokumen' => $data->no_dokumen,
|
|
'permission_file' => $data->permission_file,
|
|
];
|
|
LogActivity::create($payloadLog);
|
|
return response()->json([
|
|
'status' => true,
|
|
'message' => 'File berhasil di-approve'
|
|
], 200);
|
|
} catch (\Throwable $th) {
|
|
return response()->json([
|
|
'status' => false,
|
|
'message' => $th->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function rejectPendingFile(string $id){
|
|
try {
|
|
$data = FileDirectory::where('file_directory_id', $id)->first();
|
|
if(!$data){
|
|
return response()->json([
|
|
'status' => false,
|
|
'message' => 'Data tidak ditemukan'
|
|
], 404);
|
|
}
|
|
$data->update([
|
|
'status_action' => 'rejected',
|
|
'action_at' => Carbon::now(),
|
|
'action_by' => auth()->user()->dataUser->id,
|
|
]);
|
|
$payloadLog = [
|
|
'file_directory_id' => $data->file_directory_id,
|
|
'pegawai_id_entry' => $data->action_by,
|
|
'pegawai_nama_entry' => auth()->user()->dataUser->namalengkap,
|
|
'entry_at' => $data->action_at,
|
|
'action_type' => 'Reject Dokumen',
|
|
'statusenabled' => true,
|
|
'mod_change' => $data->entry_at,
|
|
'id_unit_kerja' => $data->id_unit_kerja,
|
|
'id_sub_unit_kerja' => $data->id_sub_unit_kerja,
|
|
'file' => $data->file,
|
|
'tanggal_terbit' => $data->tanggal_terbit,
|
|
'no_dokumen' => $data->no_dokumen,
|
|
'permission_file' => $data->permission_file,
|
|
];
|
|
LogActivity::create($payloadLog);
|
|
return response()->json([
|
|
'status' => true,
|
|
'message' => 'File berhasil di-reject'
|
|
], 200);
|
|
} catch (\Throwable $th) {
|
|
return response()->json([
|
|
'status' => false,
|
|
'message' => $th->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function countDataPending(){
|
|
try {
|
|
$query = FileDirectory::where('statusenabled', true)
|
|
->whereNull('status_action');
|
|
$authUnit = auth()->user()->masterPersetujuan->details->pluck('unit_pegawai_id')->unique()->toArray();
|
|
$count= $query->whereIn('id_unit_kerja', $authUnit)->count();
|
|
return response()->json([
|
|
'status' => true,
|
|
'count' => $count,
|
|
'message' => 'Berhasil mendapatkan data'
|
|
]);
|
|
} catch (\Throwable $th) {
|
|
return response()->json([
|
|
'status' => false,
|
|
'message' => 'Terdapat kesalahan!'
|
|
]);
|
|
}
|
|
}
|
|
}
|