crm-summit/app/Controllers/Certificates.php

771 lines
27 KiB
PHP
Raw Normal View History

2026-02-19 08:53:25 +07:00
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use Dompdf\Dompdf;
use Dompdf\Options;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Writer\PngWriter;
use App\Models\CertificateModel;
2026-02-19 08:53:25 +07:00
class Certificates extends BaseController {
protected array $data;
2026-02-25 09:35:41 +07:00
// Untuk Sertifikat Instalasi [1]
public function installationIndex() { // Index
return view('certificate_installation_index');
}
2026-02-25 09:35:41 +07:00
public function getDataIndexInstallation() { // Untuk API Get Data
// $actid = $this->request->getVar('actid'); Siapa Tahu Buat
2026-02-19 08:53:25 +07:00
$certificates = [
[
2026-02-25 09:35:41 +07:00
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11914',
'certname' => 'Jokoh Calibration Certificate',
'productname' => 'Jokoh',
2026-02-19 08:53:25 +07:00
'productnumber' => 'SN-2024-001',
'issuedate' => '2024-01-15',
'expirydate' => '2025-01-15',
'vendor' => 'Summit Calibration Lab',
'isval' => null
2026-02-19 08:53:25 +07:00
],
[
2026-02-25 09:35:41 +07:00
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11915',
'certname' => 'Electrical Safety Test',
'productname' => 'GE Healthcare VIVID',
'productnumber' => 'GE-VIV-Q992',
'issuedate' => '2024-06-12',
'expirydate' => '2026-03-01',
'vendor' => 'Pramita Medika Service',
'isval' => '2026-03-01'
],
[
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11915',
'certname' => 'Electrical Safety Test',
'productname' => 'GE Healthcare VIVID',
'productnumber' => 'GE-VIV-Q992',
'issuedate' => '2024-06-12',
'expirydate' => '2026-10-01',
'vendor' => 'Pramita Medika Service',
'isval' => '2026-09-01'
],
[
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11915',
'certname' => 'Electrical Safety Test',
'productname' => 'GE Healthcare VIVID',
'productnumber' => 'GE-VIV-Q992',
'issuedate' => '2024-06-12',
'expirydate' => '2026-01-01',
'vendor' => 'Pramita Medika Service',
'isval' => '2026-09-01'
],
2026-02-19 08:53:25 +07:00
];
// If no actid, return all certificates
if (empty($certificates)) {
return $this->response->setJSON(null);
}
return $this->response->setJSON($certificates);
2026-02-19 08:53:25 +07:00
}
public function createinstallationPreview($certid = null) { // Untuk Preview Sertifikat
2026-02-25 09:35:41 +07:00
//Melakukan search data dari database
if (!$certid) {
return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID is required']);
}
// Get certificate data Berdasarkan certid
$certificate = [
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11914',
'certname' => 'Jokoh Calibration Certificate',
'productname' => 'Jokoh',
'productnumber' => 'SN-2024-001',
'issuedate' => '2024-01-15',
'expirydate' => '2025-01-15',
'vendor' => 'Summit Calibration Lab',
'isval' => null
];
if (empty($certificate)) { // JIka Tidak Ada
return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
}
return $this->previewPdf($certificate, 'installation'); // Preview PDF
}
// Untuk Sertifikat Maintenance [2]
public function maintenanceIndex() { // Index
return view('certificate_maintenance_index');
}
public function getDataIndexMaintenance() {
$userPosId = session()->get('userposid');
$userId = session()->get('userid');
$certificateModel = new CertificateModel();
// 1. Mulai Query Builder
$builder = $certificateModel->select('
certificates.cert_id,
certificates.cert_number,
certificates.cert_name,
certificates.cert_type,
certificates.actid,
certificates.issued_date,
certificates.expired_date,
certificates.status,
certificates.user_validation_at,
certificates.spv_validation_at,
certificates.manager_validation_at,
activities.subject as activity_subject,
CONCAT(users.firstname, " ", users.lastname) as fullname
')
->join('activities', 'activities.actid = certificates.actid', 'left')
->join('users', 'users.userid = certificates.user_id', 'left');
// 2. Filter berdasarkan Role
if (in_array($userPosId, [1, 3, 5])) { // Manager & IT: Tidak perlu filter tambahan (lihat semua)
} else if ($userPosId == 2) { // SPV: Melihat data user yang "reportto"-nya adalah ID supervisor ini
$builder->where('users.reportto', $userId);
} else if ($userPosId == 4) { // TSOIVD: Hanya melihat data milik sendiri
$builder->where('certificates.user_id', $userId);
} else {// Role lain: Tidak diberi akses
return $this->response->setJSON([]);
}
// 3. Eksekusi Query
$allData = $builder->findAll();
if (empty($allData)) {
return $this->response->setJSON([]); // Kembalikan array kosong agar frontend tidak error
}
return $this->response->setJSON($allData);
}
public function showDataMaintenance() { // Untuk API Get Data
$certid = $this->request->getPost('certid');
if (!$certid) {
return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID Not Found']);
}
$certificateModel = new CertificateModel();
$data = $certificateModel->select('
certificates.cert_id,
certificates.cert_number,
certificates.cert_name,
certificates.status,
activities.actid,
activities.subject,
productcatalog.productname,
sites.sitename,
products.productnumber,
CASE
WHEN certificates.cert_type = "MC" THEN "Maintenance"
WHEN certificates.cert_type = "IC" THEN "Installation"
WHEN certificates.cert_type = "UTC" THEN "User Training"
WHEN certificates.cert_type = "BAI" THEN "Berita Acara Instalasi"
WHEN certificates.cert_type = "BAP" THEN "Berita Acara Penarikan"
ELSE certificates.cert_type
END AS certtype,
CONCAT(us.firstname, " ", us.lastname) AS username,
certificates.user_validation_at,
CONCAT(spv.firstname, " ", spv.lastname) AS spvname,
certificates.spv_validation_at,
CONCAT(mgr.firstname, " ", mgr.lastname) AS managername,
certificates.manager_validation_at,
certificates.issued_date,
certificates.expired_date
', false)
->join('activities', 'activities.actid = certificates.actid', 'inner')
->join('products', 'products.productid = activities.productid', 'inner')
->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'inner')
->join('sites', 'sites.siteid = activities.siteid', 'left')
->join('users as us', 'us.userid = certificates.user_id', 'left')
->join('users as spv', 'spv.userid = certificates.spv_id', 'left')
->join('users as mgr', 'mgr.userid = certificates.manager_id', 'left')
->join('userposition', 'userposition.userposid = us.userposid', 'left')
->where('certificates.cert_id', $certid)
->first();
$data['issued_date'] = $data['issued_date'] ? date('d M Y', strtotime($data['issued_date'])) : null;
$data['user_validation_at'] = $data['user_validation_at'] ? date('d M Y H:i', strtotime($data['user_validation_at'])) : null;
$data['spv_validation_at'] = $data['spv_validation_at'] ? date('d M Y H:i', strtotime($data['spv_validation_at'])) : null;
$data['manager_validation_at'] = $data['manager_validation_at'] ? date('d M Y H:i', strtotime($data['manager_validation_at'])) : null;
if (empty($data)) { // Jika Tidak Ada
return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
}
return $this->response->setJSON($data);
}
public function createMaintenancePreview($certid = null) { // Untuk Preview Sertifikat
if (!$certid) {
return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID Not Found']);
}
$certificateModel = new CertificateModel();
$data = $certificateModel->select('
certificates.cert_name,
certificates.issued_date,
certificates.expired_date,
certificates.file_url,
productalias.productaliastext as productname,
sites.sitename as sitename,
products.productnumber,
CASE
WHEN certificates.cert_type = "MC" THEN "Maintenance"
WHEN certificates.cert_type = "IC" THEN "Installation"
WHEN certificates.cert_type = "UTC" THEN "User Training"
WHEN certificates.cert_type = "BAI" THEN "Berita Acara Instalasi"
WHEN certificates.cert_type = "BAP" THEN "Berita Acara Penarikan"
ELSE certificates.cert_type
END AS cert_type,
CONCAT(users.firstname, " ", users.lastname) AS fullname,
userposition.texts AS user_position,
certificates.issued_date,
certificates.expired_date,
certificates.cert_number -- Penting agar callback UUID tetap jalan
', false)
->join('users', 'users.userid = certificates.user_id', 'left')
->join('userposition', 'userposition.userposid = users.userposid', 'left')
->join('activities', 'activities.actid = certificates.actid', 'left')
->join('sites', 'sites.siteid = activities.siteid', 'left')
->join('products', 'products.productid = activities.productid', 'left')
->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'left')
->join('productalias', 'productalias.productaliasid = productcatalog.productaliasid', 'left')
->where('certificates.cert_id', $certid)
->first();
$certificate = [
'certname' => $data['cert_name'],
'sitename' => $data['sitename'],
'certtype' => $data['cert_type'],
'fullname' => $data['fullname'],
'userposition' => $data['user_position'],
'productname' => $data['productname'],
'productnumber' => $data['productnumber'],
'issueddate' => $data['issued_date'],
'expireddate' => $data['expired_date']
];
$builder = new Builder(
writer: new PngWriter(),
data: $data['file_url'],
size: 120,
margin: 0
);
$result = $builder->build();
$certificate['qrcode'] = $result->getDataUri();
if (empty($certificate)) { // Jika Tidak Ada
return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
}
2026-02-25 09:35:41 +07:00
return $this->previewPdf($certificate, 'maintenance'); // Preview PDF
}
2026-02-25 09:35:41 +07:00
// Untuk Sertifikat Training [3]
public function trainingIndex() {
return view('certificate_training_index');
}
public function getDataIndexTraining() {
// $actid = $this->request->getVar('actid');
2026-02-19 08:53:25 +07:00
// Sample data - replace with actual database query
2026-02-19 08:53:25 +07:00
$certificates = [
[
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
2026-02-19 08:53:25 +07:00
'certname' => 'Jokoh Calibration Certificate',
'productname' => 'Jokoh',
'productnumber' => 'SN-2024-001',
'issuedate' => '2024-01-15',
'expirydate' => '2025-01-15',
'vendor' => 'Summit Calibration Lab',
'isval' => null
],
[
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
'certname' => 'Electrical Safety Test',
'productname' => 'GE Healthcare VIVID',
'productnumber' => 'GE-VIV-Q992',
'issuedate' => '2024-06-12',
'expirydate' => '2026-10-01',
'vendor' => 'Pramita Medika Service',
'isval' => '2026-03-01'
]
];
// If no actid, return all certificates
if (empty($certificates)) {
return $this->response->setJSON(null);
}
return $this->response->setJSON($certificates);
}
public function createTrainingPreview($certid = null) { // Untuk Preview Sertifikat
//Melakukan search data dari database
if (!$certid) {
return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID is required']);
}
// Get certificate data Berdasarkan certid
$certificate = [
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
'certname' => 'Jokoh Calibration Certificate',
'productname' => 'Jokoh',
'productnumber' => 'SN-2024-001',
'issuedate' => '2024-01-15',
'expirydate' => '2025-01-15',
'vendor' => 'Summit Calibration Lab',
'isval' => null
];
if (empty($certificate)) { // JIka Tidak Ada
return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
}
return $this->previewPdf($certificate, 'training'); // Preview PDF
}
// Untuk Sertifikat Calibrate [4]
public function calibrateIndex() {
return view('certificate_calibrate_index');
}
public function getDataIndexCalibrate() {
// $actid = $this->request->getVar('actid');
// Sample data - replace with actual database query
$certificates = [
[
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
'certname' => 'Jokoh Calibration Certificate',
'productname' => 'Jokoh',
'productnumber' => 'SN-2024-001',
'issuedate' => '2024-01-15',
'expirydate' => '2025-01-15',
'vendor' => 'Summit Calibration Lab',
'isval' => null
],
[
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
'certname' => 'Electrical Safety Test',
'productname' => 'GE Healthcare VIVID',
'productnumber' => 'GE-VIV-Q992',
'issuedate' => '2024-06-12',
'expirydate' => '2026-10-01',
'vendor' => 'Pramita Medika Service',
'isval' => '2026-03-01'
2026-02-19 08:53:25 +07:00
]
];
// If no actid, return all certificates
if (empty($certificates)) {
return $this->response->setJSON(null);
}
return $this->response->setJSON($certificates);
}
public function createCalibratePreview($certid = null) { // Untuk Preview Sertifikat
//Melakukan search data dari database
if (!$certid) {
return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID is required']);
}
// Get certificate data Berdasarkan certid
$certificate = [
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
'certname' => 'Jokoh Calibration Certificate',
'productname' => 'Jokoh',
'productnumber' => 'SN-2024-001',
'issuedate' => '2024-01-15',
'expirydate' => '2025-01-15',
'vendor' => 'Summit Calibration Lab',
'isval' => null
];
if (empty($certificate)) { // JIka Tidak Ada
return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
}
return $this->previewPdf($certificate, 'calibrate', 'tms24i'); // Preview PDF
2026-02-19 08:53:25 +07:00
}
2026-02-25 09:35:41 +07:00
// Helper Function Preview dan Validate
private function previewPdf($certificate, $type) { // Untuk Show/Preview PDF
2026-02-25 09:35:41 +07:00
// Generate PDF
$options = new Options();
$options->set('chroot', FCPATH);
2026-02-25 09:35:41 +07:00
$options->set('isRemoteEnabled', true);
$options->set('isHtml5ParserEnabled', true);
// $options->set('defaultFont', 'Playfair Display');
2026-02-25 09:35:41 +07:00
$dompdf = new Dompdf($options);
2026-02-25 09:35:41 +07:00
// Format dates
$certificate['issueddate'] = date('d-M-Y', strtotime($certificate['issueddate']));
$certificate['expireddate'] = date('d-M-Y', strtotime($certificate['expireddate']));
2026-02-19 08:53:25 +07:00
2026-02-25 09:35:41 +07:00
// Select template and orientation based on type
$template = '';
2026-02-25 09:35:41 +07:00
$orientation = 'portrait';
2026-02-19 08:53:25 +07:00
2026-02-25 09:35:41 +07:00
switch($type) {
case 'training':
$template = 'certificates/certificate_training';
$orientation = 'landscape';
break;
case 'calibration':
if ($productType == 'tms50i') {
$template = 'certificates/callibrations_template/certificate_tms50i_calibration';
} else if ($productType == 'tms24i') {
$template = 'certificates/callibrations_template/certificate_tms24i_calibration';
} else if ($productType == 'tms30i') {
$template = 'certificates/callibrations_template/certificate_tms30i_calibration';
} else if ($productType == 'bs430') {
$template = 'certificates/callibrations_template/certificate_bs430_calibration';
} else if ($productType == 'cl900i') {
$template = 'certificates/callibrations_template/certificate_cl900i_calibration';
} else if ($productType == 'jokoh') {
$template = 'certificates/callibrations_template/certificate_jokoh_calibration';
} else if ($productType == 'bc760r') {
$template = 'certificates/callibrations_template/certificate_bc760r_calibration';
} else if ($productType == 'bc5140') {
$template = 'certificates/callibrations_template/certificate_bc5140_calibration';
} else {
return $this->response->setStatusCode(404)->setJSON(['error' => 'Not Found']);
}
$orientation = 'portrait';
break;
case 'maintenance':
$template = 'certificates/certificate_maintenance';
$orientation = 'landscape';
2026-02-19 08:53:25 +07:00
break;
case 'installation':
$template = 'certificates/certificate_installation';
$orientation = 'landscape';
break;
2026-02-19 08:53:25 +07:00
}
$html = view($template, [ 'certificate' => $certificate]);
2026-02-19 08:53:25 +07:00
2026-02-25 09:35:41 +07:00
$dompdf->loadHtml($html);
2026-03-09 00:42:37 +07:00
$dompdf->set_option('isRemoteEnabled', true);
2026-02-25 09:35:41 +07:00
$dompdf->setPaper('A4', $orientation);
$dompdf->render();
// Output PDF
$filename = $certificate['certname']. '.pdf';
2026-02-25 09:35:41 +07:00
$dompdf->stream($filename, ['Attachment' => false]);
2026-02-19 08:53:25 +07:00
}
public function validateCertificate() {
2026-02-25 09:35:41 +07:00
$certid = $this->request->getPost('certid');
$certificateType = $this->request->getPost('certificateType');
2026-02-19 08:53:25 +07:00
if (!$certid || !$certificateType) {
return $this->response->setJSON(['success' => false, 'message' => 'Parameter tidak lengkap.']);
2026-02-19 08:53:25 +07:00
}
$userId = session()->get('userid');
$userPosId = session()->get('userposid');
$certificateModel = new CertificateModel();
2026-02-25 09:35:41 +07:00
// 1. Ambil data dasar saja dulu untuk pengecekan awal
$currentCert = $certificateModel->find($certid);
2026-02-25 09:35:41 +07:00
if (!$currentCert) {
return $this->response->setJSON(['success' => false, 'message' => 'Data tidak ditemukan.']);
2026-02-19 08:53:25 +07:00
}
$updateData = [];
$currentTime = date('Y-m-d H:i:s');
2026-02-19 08:53:25 +07:00
// 2. Filter Role & Cek Duplikasi
switch ($userPosId) {
case 1: // Manager
if (!empty($currentCert['manager_validation_at']))
return $this->response->setJSON(['success' => false, 'message' => 'Anda sudah Melakukan Validasi.']);
$updateData = ['manager_id' => $userId, 'manager_validation_at' => $currentTime];
break;
case 2: // SPV
if (!empty($currentCert['spv_validation_at']))
return $this->response->setJSON(['success' => false, 'message' => 'Anda sudah Melakukan Validasi.']);
$updateData = ['spv_id' => $userId, 'spv_validation_at' => $currentTime];
break;
case 4: // TSOIVD
if ($currentCert['user_id'] != $userId)
return $this->response->setJSON(['success' => false, 'message' => 'Bukan pemilik sertifikat.']);
if (!empty($currentCert['user_validation_at']))
return $this->response->setJSON(['success' => false, 'message' => 'Anda sudah Melakukan Validasi.']);
$updateData = ['user_validation_at' => $currentTime];
break;
default:
return $this->response->setJSON(['success' => false, 'message' => 'Akses ditolak.'], 403);
2026-02-19 08:53:25 +07:00
}
// 3. Eksekusi Update Validasi Role
if ($certificateModel->update($certid, $updateData)) {
// 4. Cek apakah ini validasi terakhir?
// Ambil ulang data terbaru (cukup kolom validation saja untuk efisiensi)
$checkFinal = $certificateModel->select('user_validation_at, spv_validation_at, manager_validation_at')
->find($certid);
if (!empty($checkFinal['user_validation_at']) &&
2026-03-08 22:40:36 +07:00
(!empty($checkFinal['spv_validation_at']) ||
!empty($checkFinal['manager_validation_at']))) {
2026-03-08 22:40:36 +07:00
// Check
$checkStatus = $certificateModel->select('status')->find($certid);
if ($checkStatus['status'] == 'validated') {
return $this->response->setJSON([
'success' => true,
'message' => 'Semua validasi telah dilakukan'
]);
}
// Update Status Utama
$certificateModel->update($certid, ['status' => 'validated']);
// Baru jalankan query berat JOIN di sini untuk keperluan PDF/Notifikasi
$latestData = $certificateModel->select('
certificates.cert_name,
certificates.issued_date,
certificates.expired_date,
certificates.file_url,
productalias.productaliastext as productname,
sites.sitename as sitename,
products.productnumber,
CASE
WHEN certificates.cert_type = "MC" THEN "Maintenance"
WHEN certificates.cert_type = "IC" THEN "Installation"
WHEN certificates.cert_type = "UTC" THEN "Training"
WHEN certificates.cert_type = "BAI" THEN "Berita Acara Instalasi"
WHEN certificates.cert_type = "BAP" THEN "Berita Acara Penarikan"
ELSE certificates.cert_type
END AS cert_type,
CONCAT(users.firstname, " ", users.lastname) AS fullname,
userposition.texts AS user_position,
certificates.issued_date,
certificates.expired_date,
certificates.cert_number -- Penting agar callback UUID tetap jalan
', false)
->join('users', 'users.userid = certificates.user_id', 'left')
->join('userposition', 'userposition.userposid = users.userposid', 'left')
->join('activities', 'activities.actid = certificates.actid', 'left')
->join('sites', 'sites.siteid = activities.siteid', 'left')
->join('products', 'products.productid = activities.productid', 'left')
->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'left')
->join('productalias', 'productalias.productaliasid = productcatalog.productaliasid', 'left')
->where('certificates.cert_id', $certid)
->first();
2026-03-08 22:40:36 +07:00
$certificate = [
'file_url' => $latestData['file_url'],
'certname' => $latestData['cert_name'],
'sitename' => $latestData['sitename'],
'certtype' => $latestData['cert_type'],
'fullname' => $latestData['fullname'],
'userposition' => $latestData['user_position'],
'productname' => $latestData['productname'],
'productnumber' => $latestData['productnumber'],
2026-03-08 22:40:36 +07:00
'issueddate' => date('d-M-Y', strtotime($latestData['issued_date'])),
'expireddate' => date('d-M-Y', strtotime($latestData['expired_date'])),
'exportToPDF' => true
];
try {
2026-03-08 22:40:36 +07:00
$pdfAfterValidation = $this->savePdf($certificate, $latestData['cert_type'], $latestData['cert_number']); // Simpan ke PDF
$certificateModel->update($certid, [ // Update ke tabel certificates
'file_location' => $pdfAfterValidation['file_relative'],
'metadata_title' => $pdfAfterValidation['metadata_title'],
2026-03-08 22:40:36 +07:00
'metadata_keywords' => $pdfAfterValidation['metadata_keywords'].";".base_url('certificates/number/'.$latestData['cert_number']),
// 'file_url' => base_url('certificates/number/'.$latestData['cert_number'])
]);
return $this->response->setJSON([
'success' => true,
'message' => 'Semua validasi telah dilakukan, PDF sudah di generate'
]);
} catch (\Throwable $e) {
return $this->response->setStatusCode(500)->setJSON([
'success' => false,
'message' => $e->getMessage(),
'line' => $e->getLine(),
'file' => $e->getFile()
]);
}
2026-02-19 08:53:25 +07:00
2026-02-25 09:35:41 +07:00
}
return $this->response->setJSON([
'success' => true,
'message' => "Sertifikat {$certificateType} berhasil divalidasi."
2026-02-25 09:35:41 +07:00
]);
}
2026-02-19 08:53:25 +07:00
return $this->response->setJSON(['success' => false, 'message' => 'Gagal memperbarui data.']);
}
2026-03-08 22:40:36 +07:00
public function savePdf($certificate, $certificateType, $cert_number, $productType = null) {
$certificateType = strtolower($certificateType);
2026-02-25 09:35:41 +07:00
switch ($certificateType) {
2026-02-19 08:53:25 +07:00
case 'training':
$template = 'certificates/certificate_training';
$orientation = 'landscape';
$subDir = 'training';
2026-02-19 08:53:25 +07:00
break;
2026-02-19 08:53:25 +07:00
case 'calibration':
$orientation = 'portrait';
$subDir = 'calibration';
switch ($productType) {
case 'tms50i':
$template = 'certificates/callibrations_template/certificate_tms50i_calibration';
break;
case 'tms24i':
$template = 'certificates/callibrations_template/certificate_tms24i_calibration';
break;
case 'tms30i':
$template = 'certificates/callibrations_template/certificate_tms30i_calibration';
break;
case 'bs430':
$template = 'certificates/callibrations_template/certificate_bs430_calibration';
break;
case 'cl900i':
$template = 'certificates/callibrations_template/certificate_cl900i_calibration';
break;
case 'jokoh':
$template = 'certificates/callibrations_template/certificate_jokoh_calibration';
break;
case 'bc760r':
$template = 'certificates/callibrations_template/certificate_bc760r_calibration';
break;
case 'bc5140':
$template = 'certificates/callibrations_template/certificate_bc5140_calibration';
break;
default:
throw new \Exception('Product type calibration tidak valid');
}
2026-02-19 08:53:25 +07:00
break;
2026-02-19 08:53:25 +07:00
case 'maintenance':
$template = 'certificates/certificate_maintenance';
$orientation = 'landscape';
$subDir = 'maintenance';
2026-02-19 08:53:25 +07:00
break;
case 'installation':
$template = 'certificates/certificate_installation';
$orientation = 'landscape';
$subDir = 'installation';
break;
default:
throw new \Exception('Certificate type tidak valid');
2026-02-19 08:53:25 +07:00
}
if (empty($template)) {
throw new \Exception('Template tidak ditemukan');
}
// Dompdf
$options = new Options();
$options->set('chroot', FCPATH);
$options->set('isRemoteEnabled', true);
$options->set('isHtml5ParserEnabled', true);
// Create QR
$builder = new Builder(
writer: new PngWriter(),
data: $certificate['file_url'],
size: 120,
margin: 0
);
$resultQr = $builder->build();
$certificate['qrcode'] = $resultQr->getDataUri();
$dompdf = new Dompdf($options);
$html = view($template, ['certificate' => $certificate]);
2026-02-19 08:53:25 +07:00
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', $orientation);
$dompdf->render();
// Metadata
$dompdf->addInfo('Title', $certificate['certname']);
2026-03-08 22:40:36 +07:00
$dompdf->addInfo('Keywords', $certificate['certtype'] . ' Certificate;'.base_url('certificates/number/'.$cert_number));
// Folder
$uploadDir = FCPATH . 'upload/documents/' . $subDir;
2026-02-25 09:35:41 +07:00
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
// Safe filename
$cleanName = preg_replace('/[^A-Za-z0-9_\-]/', '_', $certificate['certname']);
$timestamp = date('YmdHis');
$filename = $cleanName . '_' . $timestamp . '.pdf';
2026-02-25 09:35:41 +07:00
$filePath = $uploadDir . DIRECTORY_SEPARATOR . $filename;
if (!file_put_contents($filePath, $dompdf->output())) {
throw new \Exception('Gagal menyimpan file PDF');
}
return [
'file_name' => $filename,
'file_path' => $filePath,
'file_relative' => 'upload/documents/' . $subDir . '/' . $filename,
'metadata_title' => $certificate['certname'],
'metadata_keywords' => $certificate['certtype'] . ' Certificate'
];
2026-02-19 08:53:25 +07:00
}
public function view($uuid) {
try {
$certificateModel = new CertificateModel();
// Ambil dari model (UUID → binary otomatis)
$certificate = $certificateModel->getByUuid($uuid);
if (!$certificate) {
throw new \Exception('Certificate tidak ditemukan');
}
2026-02-25 09:35:41 +07:00
if (empty($certificate['file_location'])) {
throw new \Exception('File PDF belum tersedia');
}
$filePath = FCPATH . $certificate['file_location'];
if (!file_exists($filePath)) {
throw new \Exception('File tidak ditemukan di server');
}
return $this->response
->setHeader('Content-Type', 'application/pdf')
->setHeader(
'Content-Disposition',
'inline; filename="' . basename($filePath) . '"'
)
->setBody(file_get_contents($filePath));
} catch (\Throwable $e) {
return $this->response->setStatusCode(404)->setJSON([
// 'success' => false,
'message' => "404 Not Found"
]);
}
}
2026-02-19 08:53:25 +07:00
}