diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 0de9b3b..b06b371 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -161,6 +161,8 @@ $routes->get('/activities/getproduct/(:num)', 'Activities::getproduct/$1/$2/$3') $routes->get('/activities/getvendor/(:num)', 'Activities::getvendor/$1'); $routes->get('/activities/getconsumable/(:num)', 'Activities::getconsumable/$1'); $routes->get('/activities/getcontact/(:num)', 'Activities::getcontact/$1'); +$routes->get('/activities/getsitecontact/(:num)', 'Activities::getsitecontact/$1'); +$routes->get('/activities/getsitecontact/(:num)/(:num)', 'Activities::getsitecontact/$1/$2'); $routes->get('/activities/newtextarea', 'Activities::newtextarea'); $routes->get('/activities/activitiesproduct/(:num)', 'Activities::activitiesproduct/$1'); $routes->get('/activities/dummy', 'Activities::dummy'); @@ -212,23 +214,24 @@ $routes->group('certificates', function($routes) { // Untuk Index Tiap Menu $routes->get('maintenance', 'Certificates::maintenanceIndex'); // OK $routes->get('installation', 'Certificates::installationIndex'); // OK - // $routes->get('training', 'Certificates::trainingIndex'); // OK + $routes->get('training', 'Certificates::trainingIndex'); // OK // $routes->get('calibration', 'Certificates::calibrateIndex'); // OK // Untuk Get API $routes->get('api/getindexmaintenance', 'Certificates::getDataIndexMaintenance'); // OK $routes->get('api/getindexinstallation', 'Certificates::getDataIndexInstallation'); // OK - // $routes->get('api/getindextraining', 'Certificates::getDataIndexTraining'); // OK + $routes->get('api/getindextraining', 'Certificates::getDataIndexTraining'); // OK // $routes->get('api/getindexcalibrate', 'Certificates::getDataIndexCalibrate'); // Untuk Get Modal Data $routes->post('api/showmaintenance', 'Certificates::showDataMaintenance'); // OK $routes->post('api/showinstallation', 'Certificates::showDataInstallation'); // OK + $routes->post('api/showtraining', 'Certificates::showDataTraining'); // OK // Untuk Preview Cerificate $routes->get('maintenance/show/(:any)', 'Certificates::createMaintenancePreview/$1'); // OK $routes->get('installation/show/(:any)', 'Certificates::createInstallationPreview/$1'); // OK - // $routes->get('training/show/(:any)', 'Certificates::createTrainingPreview/$1'); // OK + $routes->get('training/show/(:any)', 'Certificates::createTrainingPreview/$1'); // OK // $routes->get('calibration/show/(:any)/(:any)', 'Certificates::createCalibratePreview/$1/$2'); $routes->post('api/validatecertificate', 'Certificates::validateCertificate'); // OK diff --git a/app/Controllers/Activities.php b/app/Controllers/Activities.php index 5c7ee31..d716442 100644 --- a/app/Controllers/Activities.php +++ b/app/Controllers/Activities.php @@ -3,6 +3,7 @@ namespace App\Controllers; use App\Models\CertificateModel; +use App\Models\CertificateTrainingModel; use App\Models\ActivitiesModel; use App\Models\ActdetailModel; use App\Models\InvTransModel; @@ -376,6 +377,14 @@ class Activities extends Controller { $query = $db->query($sql); $results = $query->getResultArray(); $data['vendors'] = $results; + + // $sql = "select c.* from contacts c + // Left join sitecontact sc on sc.contactid=c.contactid + // where sc.siteid = 2"; + $sql = "SELECT contactid, firstname, lastname, initial, title, email_1 FROM contacts"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['contacts'] = $results; if( $this->request->getVar('siteid') != '' ) { $siteid = $this->request->getVar('siteid'); } @@ -408,7 +417,13 @@ class Activities extends Controller { 'attachment' => $this->request->getVar('attachment'), 'actdetailid' => $this->request->getVar('actdetailid'), 'acttextid' => $this->request->getVar('acttextid'), - 'textvalue' => $this->request->getVar('textvalue') + 'textvalue' => $this->request->getVar('textvalue'), + ]; + $data['training_certificates'] = [ + 'trainingids' => $this->request->getVar('trainingids'), + 'trainingnames' => $this->request->getVar('trainingnames'), + 'trainingdates' => $this->request->getVar('trainingdates'), + 'validatealltraining' => $this->request->getVar('validatealltraining'), ]; $actby = $this->request->getVar('actby'); @@ -470,11 +485,17 @@ class Activities extends Controller { $userid_owner = $data['new_value']['userid_owner']; $this->createCertificate($actid, $issuedDate, $userid_owner, 'MC'); } - if ($this->request->getVar('installation')) { // Jika Maintenance Dicentang + if ($this->request->getVar('installation')) { // Jika Installation Dicentang $issuedDate = $data['new_value']['closedate'] ?? null; $userid_owner = $data['new_value']['userid_owner']; $this->createCertificate($actid, $issuedDate, $userid_owner, 'IC'); } + if ($this->request->getVar('training')) { // Jika User Training Dicentang + if ($data['training_certificates']['trainingids'] != null) { + $userid_owner = $data['new_value']['userid_owner']; + $this->createCertificateTraining($actid, $userid_owner, $data['training_certificates']); + } + } } else { // update edit @@ -550,33 +571,43 @@ class Activities extends Controller { } } - - // UNTUK CERTIFICATES - $certificateTypes = [ - 'maintenance' => 'MC', - 'installation' => 'IC', - ]; - $hasAnyAction = false; + // // UNTUK CERTIFICATES + // $certificateTypes = [ + // 'maintenance' => 'MC', + // 'installation' => 'IC' + // ]; + // $hasAnyAction = false; + // $issuedDate = $data['new_value']['closedate'] ?? null; + // $userid_owner = $data['new_value']['userid_owner']; + // foreach ($certificateTypes as $requestName => $certCode) { //perulangan untuk mengecek semua checkbox + // if ($this->request->getVar($requestName)) { + // $hasAnyAction = true; // Jika checkbox dicentang, tandai bahwa ada aksi + // $this->updateCertificate($actid, $issuedDate, $userid_owner, $certCode); + // } + // } + // if (!$hasAnyAction) { // Jika setelah dicek semua ternyata tidak ada satupun yang dicentang, baru jalankan delete + // $this->deleteCertificate($actid); + // } + $reqMaintenance = $this->request->getPost('maintenance') !== null; + $reqInstallation = $this->request->getPost('installation') !== null; + $reqTraining = $this->request->getPost('training') !== null; $issuedDate = $data['new_value']['closedate'] ?? null; $userid_owner = $data['new_value']['userid_owner']; - foreach ($certificateTypes as $requestName => $certCode) { //perulangan untuk mengecek semua checkbox - if ($this->request->getVar($requestName)) { - $hasAnyAction = true; // Jika checkbox dicentang, tandai bahwa ada aksi - $this->updateCertificate($actid, $issuedDate, $userid_owner, $certCode); - } + if ($reqMaintenance) {// MC + $this->updateCertificate($actid, $issuedDate, $userid_owner, 'MC'); + } else { + $this->deleteCertificate($actid, 'MC'); } - if (!$hasAnyAction) { // Jika setelah dicek semua ternyata tidak ada satupun yang dicentang, baru jalankan delete - $this->deleteCertificate($actid); + if ($reqInstallation) {// IC + $this->updateCertificate($actid, $issuedDate, $userid_owner, 'IC'); + } else { + $this->deleteCertificate($actid, 'IC'); + } + if ($reqTraining) {// UTC + $this->updateCertificateTraining($actid, $userid_owner, $data['training_certificates']); + } else { + $this->deleteCertificateTraining(null, $actid); } - // if ($this->request->getVar('maintenance')) { // Maintenance - // // Maintenance sertifikat create or update - // $issuedDate = $data['new_value']['closedate'] ?? null; - // $userid_owner = $data['new_value']['userid_owner']; - // $this->updateCertificate($actid, $issuedDate, $userid_owner, 'MC'); - // } else { - // // Hapus softdelete sertifikat - // $this->deleteCertificate($actid); - // } } // act by consumables @@ -1692,7 +1723,7 @@ class Activities extends Controller { return view('invtrans_index', $data); } - // Untuk CRUD Sertifikat + // Untuk CRUD Sertifikat Installation dan Maintenance public function createCertificate ($actid, $issuedDate, $userid_owner, $certificate_type) { $db = \Config\Database::connect(); @@ -1744,6 +1775,7 @@ class Activities extends Controller { $existingCerts = $certificateModel->withDeleted() ->select('status') ->where('actid', $actid) + ->where('cert_type', $certificate_type) ->findAll(); // Variabel penanda apakah data sudah pernah ada di database @@ -1807,22 +1839,25 @@ class Activities extends Controller { $newCertificate = $certificateModel->find($certid); $certificateModel->update($certid, ['file_url' => base_url('certificates/number/'.$newCertificate['cert_number'])]); } else { + // dd($isDataExist); // Jika data sudah ada, eksekusi UPDATE // Catatan: Karena bisa ada lebih dari 1 data dengan actid yang sama (karena findAll), // Update ini akan menimpa semua baris yang punya actid tersebut. $certificateModel->withDeleted() ->where('actid', $actid) + ->where('cert_type', $certificate_type) ->set($certPayload) ->update(); } } - public function deleteCertificate($actid) { + public function deleteCertificate($actid, $certificate_type) { $certificateModel = new CertificateModel(); // 1. Cek apakah data sudah ada menggunakan findAll() $existingCerts = $certificateModel->withDeleted() ->select('status') ->where('actid', $actid) + ->where('cert_type', $certificate_type) ->findAll(); // Variabel penanda apakah data sudah pernah ada di database @@ -1837,8 +1872,307 @@ class Activities extends Controller { return; } } - $certificateModel->where('actid', $actid)->delete(); + $certificateModel->where('actid', $actid)->where('cert_type', $certificate_type)->delete(); } - + public function createCertificateTraining ($actid, $userid_owner, $training_data) { + + $db = \Config\Database::connect(); + $sql = "SELECT prl.productaliastext as productname + FROM `activities` act + LEFT JOIN products pr ON pr.productid = act.productid + LEFT JOIN productcatalog prc ON prc.catalogid = pr.catalogid + LEFT JOIN productalias prl ON prl.productaliasid = prc.productaliasid + WHERE act.actid = $actid"; + $query = $db->query($sql); + $result = $query->getRowArray(); + + $insertCert = [ + 'cert_type' => "UTC", + 'actid' => $actid, + 'user_id' => $userid_owner + ]; + + $certificateModel = new CertificateModel(); + $CertificateTrainingModel = new CertificateTrainingModel(); + + // Apakah Validasi Semuanya Dicentang + if($training_data['validatealltraining'] != null) { + $currentTime = date('Y-m-d H:i:s'); + } else { + $currentTime = null; + } + + foreach ($training_data['trainingids'] as $index => $id) { + + // Ambil data berdasarkan index yang sama + $contact_id = $id; + $name = $training_data['trainingnames'][$index]; + $issued_date = $training_data['trainingdates'][$index]; + + $insertCert['cert_name'] = "UTC_" . ($result['productname'] ?? 'UNKNOWN') . "_" . $name . "_" . $actid; + $insertCert['issued_date'] = $issued_date; + $insertCert['user_validation_at'] = $currentTime; + + $certificateModel->insert($insertCert); + $certid = $certificateModel->getInsertID(); + + $newCertificate = $certificateModel->find($certid); + $certificateModel->update($certid, ['file_url' => base_url('certificates/number/'.$newCertificate['cert_number'])]); + + $CertificateTrainingModel->insert(['cert_id' => (int)$certid, 'contact_id' => (int)$contact_id]); + } + + } + public function updateCertificateTraining($actid, $userid_owner, $new_training_data) { + $certificateModel = new CertificateModel(); + + $existingTrainingCerts = $certificateModel->withDeleted() // 1. Ambil data existing dari database + ->select(' + Certificates.cert_id, + Certificates.cert_name, + Certificates.status, + Certificates_Training.contact_id + ') + ->join('Certificates_Training', 'Certificates_Training.cert_id = Certificates.cert_id', 'join') + ->where('Certificates.actid', $actid) + ->where('Certificates.cert_type', 'UTC') + ->findAll(); + + + $existingMap = []; // 2. Buat Map untuk data existing + foreach ($existingTrainingCerts as $cert) { + $contactId = is_object($cert) ? $cert->contact_id : $cert['contact_id']; + $existingMap[$contactId] = $cert; + } + + // Temp + $dataToInsert = []; + $dataToUpdate = []; + $dataToDelete = []; + + $currentTime = date('Y-m-d H:i:s'); + + // 3. Looping data baru dari form + if (!empty($new_training_data['trainingids']) && is_array($new_training_data['trainingids'])) { + foreach ($new_training_data['trainingids'] as $index => $contactId) { + + $trainingName = $new_training_data['trainingnames'][$index] ?? null; + $trainingDate = $new_training_data['trainingdates'][$index] ?? null; + + // Cek apakah data sudah ada di database + if (array_key_exists($contactId, $existingMap)) { + $existingData = $existingMap[$contactId]; + $certId = is_object($existingData) ? $existingData->cert_id : $existingData['cert_id']; + + // if ($new_training_data['validatealltraining'] != null) { + // $certificatesUpdate['user_validation_at'] = $currentTime; + // } else { + // $certificatesUpdate['user_validation_at'] = null; + // } + $certificatesUpdate['cert_id'] = $certId; + // $certificatesUpdate['actid'] = $actid; + $certificatesUpdate['issued_date'] = $trainingDate; + $certificatesUpdate['deleted_at'] = null; + + $certificatesTrainingUpdate['cert_id'] = $certId; + $certificatesTrainingUpdate['contact_id'] = $contactId; + $certificatesTrainingUpdate['deleted_at'] = null; + + $certificatesUpdates[] = $certificatesUpdate; + $certificatesTrainingUpdates[] = $certificatesTrainingUpdate; + + unset($existingMap[$contactId]); // ELIMINASI: Hapus dari map karena data ini dipertahankan + } else { + // Insert Temp + $dataToInsert['trainingids'][] = $contactId; + $dataToInsert['trainingnames'][] = $trainingName; + $dataToInsert['trainingdates'][] = $trainingDate; + } + } + } + + // 4. Proses Sisa Data di Map menjadi DELETE + // Apapun yang tersisa di $existingMap berarti tidak ada di $new_training_data + foreach ($existingMap as $contactId => $existingData) { + $certId = is_object($existingData) ? $existingData->cert_id : $existingData['cert_id']; + + // Memasukkan cert_id, contact_id, (dan actid jika itu parameter ke-3 yang dimaksud) + $dataToDelete[] = [ + 'cert_id' => $certId, + 'contact_id' => $contactId, + 'actid' => $actid + ]; + } + + // Cek hasil klasifikasinya: + // dd(['Insert' => $dataToInsert, 'Update' => $dataToUpdate, 'Delete' => $dataToDelete]); + + // OK + if (!empty($dataToInsert)) { + $dataToInsert['validatealltraining'] = $new_training_data['validatealltraining']; + $this->createCertificateTraining($actid, $userid_owner, $dataToInsert); + } + + if (!empty($certificatesUpdates)) { + + $certificateModel = new CertificateModel(); + $CertificateTrainingModel = new CertificateTrainingModel(); + + $db = \Config\Database::connect(); + $db->transStart(); + + $certificateModel->builder() + ->where('cert_type', 'UTC') + ->where('status', 'unvalidated') + ->updateBatch($certificatesUpdates, 'cert_id'); + + foreach ($certificatesTrainingUpdates as $trainingUpdate) { + $CertificateTrainingModel->builder() + ->where('cert_id', $trainingUpdate['cert_id']) + ->where('contact_id', $trainingUpdate['contact_id']) + ->set([ + 'deleted_at' => null // Paksa restore data + ])->update(); + } + + $db->transComplete(); + + if ($db->transStatus() === false) { + // Handle jika transaksi gagal + log_message('error', 'Gagal melakukan update sertifikat training.'); + } + } + + // OK + if (!empty($dataToDelete)) { + $this->deleteCertificateTraining($dataToDelete, null); + } + } + public function deleteCertificateTraining($updateToDelete, $deleteActid) { + + $certificateModel = new CertificateModel(); + $CertificateTrainingModel = new CertificateTrainingModel(); + + // if (!empty($updateToDelete)) { + // foreach ($updateToDelete as $key => $value) { + + // // 1. Cari data sertifikat terlebih dahulu untuk mendapatkan cert_id + // $certificate = $certificateModel + // ->where('actid', $value['actid']) + // ->where('status', 'unvalidated') + // ->where('cert_type', 'UTC') + // ->first(); // Gunakan first() jika Laravel, atau get()->getRowArray() jika CI4 + + // // 2. Pastikan data ditemukan sebelum melakukan penghapusan + // if ($certificate) { + + // // Ambil cert_id dari hasil query (sesuaikan dengan format return object/array framework Anda) + // $certId = $certificate['cert_id']; // atau $certificate->cert_id jika berupa object + + // // 3. Hapus data di CertificateTrainingModel menggunakan $certId yang baru didapat + // $CertificateTrainingModel + // ->where('cert_id', $certId) + // ->where('contact_id', $value['contact_id']) + // ->delete(); + + // // 4. Hapus data di certificateModel + // // Kita cukup gunakan cert_id karena itu sudah spesifik (Primary Key) + // $certificateModel + // ->where('cert_id', $certId) + // ->delete(); + // } + // } + // } + if (!empty($updateToDelete)) { + + foreach ($updateToDelete as $key => $value) { + + $isSuccess = $certificateModel + ->where('actid', $value['actid']) + ->where('cert_id', $value['cert_id']) + ->where('status', 'unvalidated') + ->where('cert_type', 'UTC')->delete(); + + // Cek apakah ada baris yang benar-benar dihapus di database + if ($isSuccess && $certificateModel->affectedRows() > 0) { + $CertificateTrainingModel + ->where('cert_id', $value['cert_id']) + ->where('contact_id', $value['contact_id'])->delete(); + } + + } + } + + if ($deleteActid != null) { + // 1. Ambil (SELECT) dulu daftar cert_id yang memenuhi syarat sebelum dihapus + $certsToDelete = $certificateModel + ->select('cert_id') // Kita hanya butuh kolom cert_id + ->where('actid', $deleteActid) + ->where('status', 'unvalidated') + ->where('cert_type', 'UTC') + ->findAll(); + + // Pastikan ada data yang ditemukan sebelum mengeksekusi delete + if (!empty($certsToDelete)) { + + // Ekstrak hasil query menjadi array 1 dimensi berisi kumpulan cert_id + // Contoh hasil: [10, 15, 22] + $certIds = array_column($certsToDelete, 'cert_id'); + + // Gunakan Transaction agar jika salah satu gagal, semuanya batal (aman) + $db = \Config\Database::connect(); + $db->transStart(); + + // 2. Hapus data relasi di tabel Certificates_Training (Pivot) + // Gunakan whereIn karena kita menghapus banyak cert_id sekaligus + $CertificateTrainingModel + ->whereIn('cert_id', $certIds) + ->delete(); + + // 3. Hapus data utama di tabel Certificates + // Kita bisa langsung pakai $certIds yang sudah didapat + $certificateModel + ->whereIn('cert_id', $certIds) + ->delete(); + + $db->transComplete(); + + if ($db->transStatus() === false) { + // Logika jika proses delete gagal + } + } + } + } + // Untuk Training Contact + public function getsitecontact($siteid=null, $actid=null){ + $db = \Config\Database::connect(); + + if($siteid == null) { + $filterquery = ''; + } else { + $filterquery = "where sc.siteid=$siteid"; + } + $sql = "SELECT sc.siteid, c.contactid, c.firstname, c.lastname, c.title, c.initial, c.email_1 from contacts c + Left join sitecontact sc on sc.contactid=c.contactid + $filterquery"; + $query = $db->query($sql); + $results = $query->getResultArray(); + $data['sitecontacts'] = $results; + + $data['siteid'] = $siteid; + + // Get Data Training User + if($actid != null) { + $certificateTrainingModel = new CertificateTrainingModel(); + $traininguser = $certificateTrainingModel->select('contacts.contactid, contacts.firstname, contacts.lastname, contacts.title, contacts.initial, contacts.email_1, certificates.issued_date') + ->join('certificates', 'certificates.cert_id = certificates_training.cert_id', 'inner') + ->join('contacts', 'contacts.contactid = certificates_training.contact_id', 'inner') + ->where('certificates.actid', $actid) + ->findAll(); + $data['traininguser'] = $traininguser; + } + + return view('activities_getsitecontacts', $data); + } } \ No newline at end of file diff --git a/app/Controllers/Certificates.php b/app/Controllers/Certificates.php index bc9c740..b110560 100644 --- a/app/Controllers/Certificates.php +++ b/app/Controllers/Certificates.php @@ -43,7 +43,7 @@ class Certificates extends BaseController { ') ->join('activities', 'activities.actid = certificates.actid', 'left') ->join('users', 'users.userid = certificates.user_id', 'left') - ->where('certificates.cert_type', 'IC');; + ->where('certificates.cert_type', 'IC'); // 2. Filter berdasarkan Role if (in_array($userPosId, [1, 3, 5])) { // Manager & IT: Tidak perlu filter tambahan (lihat semua) @@ -208,7 +208,7 @@ class Certificates extends BaseController { ') ->join('activities', 'activities.actid = certificates.actid', 'left') ->join('users', 'users.userid = certificates.user_id', 'left') - ->where('certificates.cert_type', 'MC');; + ->where('certificates.cert_type', 'MC'); // 2. Filter berdasarkan Role if (in_array($userPosId, [1, 3, 5])) { // Manager & IT: Tidak perlu filter tambahan (lihat semua) @@ -350,69 +350,189 @@ class Certificates extends BaseController { // Untuk Sertifikat Training [3] - // public function trainingIndex() { - // return view('certificate_training_index'); - // } - // public function getDataIndexTraining() { - // // $actid = $this->request->getVar('actid'); + public function trainingIndex() { + return view('certificate_training_index'); + } + public function getDataIndexTraining() { + $userPosId = session()->get('userposid'); + $userId = session()->get('userid'); + + $certificateModel = new CertificateModel(); - // // 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' - // ] - // ]; + // 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') + ->where('certificates.cert_type', 'UTC'); - // // If no actid, return all certificates - // if (empty($certificates)) { - // return $this->response->setJSON(null); - // } + // 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([]); + } - // return $this->response->setJSON($certificates); - // } - // public function createTrainingPreview($certid = null) { // Untuk Preview Sertifikat - // //Melakukan search data dari database + // 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 showDataTraining() { // 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, + CONCAT(contacts.firstname, " ", contacts.lastname) AS fullname + ', 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') + ->join('certificates_training', 'certificates_training.cert_id = certificates.cert_id', 'left') + ->join('contacts', 'contacts.contactid = certificates_training.contact_id', '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 createTrainingPreview($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 "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, + CONCAT(contacts.firstname, " ", contacts.lastname) AS fullname, + contacts.title, + zones.zonename as city, + 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('accounts', 'accounts.accountid = sites.accountid', 'left') + ->join('zones', 'zones.zoneid = accounts.zoneid', 'left') + ->join('products', 'products.productid = activities.productid', 'left') + ->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'left') + ->join('productalias', 'productalias.productaliasid = productcatalog.productaliasid', 'left') + ->join('certificates_training', 'certificates_training.cert_id = certificates.cert_id', 'left') + ->join('contacts', 'contacts.contactid = certificates_training.contact_id', 'left') + ->where('certificates.cert_id', $certid) + ->first(); + $certificate = [ + 'certname' => trim($data['cert_name']), + 'sitename' => $data['sitename'], + 'title' => empty($data['title']) ? '' : ', ' . $data['title'], + 'city' => empty($data['city']) ? '' : $data['city'], + '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'] + ]; + if ($certificate['certtype'] == 'training') { + $certificate['issueddate'] = date('F d, Y', strtotime($data['issued_date'])); + } else { + $certificate['issueddate'] = date('d-M-Y', strtotime($data['issued_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']); + } - // 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 - // } - + return $this->previewPdf($certificate, 'training'); // Preview PDF + } // Untuk Sertifikat Calibrate [4] // public function calibrateIndex() { @@ -490,10 +610,12 @@ class Certificates extends BaseController { $dompdf = new Dompdf($options); - // Format dates - $certificate['issueddate'] = date('d-M-Y', strtotime($certificate['issueddate'])); - - if(isset($certificate['expireddate'])) { + if ($type == 'training') { + $certificate['issueddate'] = date('F d, Y', strtotime($certificate['issueddate'])); + } else { + $certificate['issueddate'] = date('d-M-Y', strtotime($certificate['issueddate'])); + } + if (isset($certificate['expireddate'])) { $certificate['expireddate'] = date('d-M-Y', strtotime($certificate['expireddate'])); } @@ -619,51 +741,95 @@ class Certificates extends BaseController { $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(); $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(); + 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, + CONCAT(contacts.firstname, " ", contacts.lastname) AS fullname, + contacts.title, + 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('accounts', 'accounts.accountid = sites.accountid', 'left') + ->join('zones', 'zones.zoneid = accounts.zoneid', 'left') + ->join('products', 'products.productid = activities.productid', 'left') + ->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'left') + ->join('productalias', 'productalias.productaliasid = productcatalog.productaliasid', 'left') + ->join('certificates_training', 'certificates_training.cert_id = certificates.cert_id', 'left') + ->join('contacts', 'contacts.contactid = certificates_training.contact_id', 'left') + ->where('certificates.cert_id', $certid) + ->first(); $certificate = [ + 'title' => empty($latestData['title']) ? '' : ', ' . $latestData['title'], 'file_url' => $latestData['file_url'], 'certname' => $latestData['cert_name'], 'sitename' => $latestData['sitename'], + 'city' => empty($data['city']) ? '' : $data['city'], 'certtype' => $latestData['cert_type'], 'fullname' => $latestData['fullname'], 'userposition' => $latestData['user_position'], 'productname' => $latestData['productname'], 'productnumber' => $latestData['productnumber'], - 'issueddate' => date('d-M-Y', strtotime($latestData['issued_date'])), + // 'issueddate' => date('d-M-Y', strtotime($latestData['issued_date'])), 'expireddate' => date('d-M-Y', strtotime($latestData['expired_date'])), 'exportToPDF' => true ]; + if ($latestData['cert_type'] == 'training') { + $certificate['issueddate'] = date('F d, Y', strtotime($latestData['issued_date'])); + } else { + $certificate['issueddate'] = date('d-M-Y', strtotime($latestData['issued_date'])); + } try { diff --git a/app/Controllers/Contacts.php b/app/Controllers/Contacts.php index 0ec61e1..d1463a7 100644 --- a/app/Controllers/Contacts.php +++ b/app/Controllers/Contacts.php @@ -3,6 +3,7 @@ namespace App\Controllers; use App\Models\ContactsModel; +use App\Models\SiteContactModel; use CodeIgniter\Controller; class Contacts extends Controller { @@ -38,7 +39,7 @@ class Contacts extends Controller { } if ($this->request->getMethod() === 'POST') { $rules = [ - 'contactid' => 'required', + // 'contactid' => 'required', 'firstname' => 'required', 'email_1' => 'required', 'initial' => 'required' @@ -53,7 +54,8 @@ class Contacts extends Controller { 'email_2' => $this->request->getVar('email_2'), 'phone' => $this->request->getVar('phone'), 'mobile_1' => $this->request->getVar('mobile_1'), - 'mobile_2' => $this->request->getVar('mobile_2') + 'mobile_2' => $this->request->getVar('mobile_2'), + 'siteid' => $this->request->getVar('siteid') ?? null //Untuk Create dari AR ]; if($this->validate($rules)){ @@ -67,6 +69,18 @@ class Contacts extends Controller { $contactsModel->set('createdate', 'NOW()', FALSE); $contactsModel->set('enddate', NULL); $contactsModel->insert($data['new_value']); + $contactid = $contactsModel->getInsertID(); + + if($this->request->getVar('siteid') != null) { + $siteContactModel = new SiteContactModel(); + $siteContactValue = [ + 'siteid' => $this->request->getVar('siteid'), + 'contactid' => $contactid, + 'contactemail' => $this->request->getVar('email_1'), + ]; + $siteContactModel->insert($siteContactValue); + } + return view('form_success'); } } else { diff --git a/app/Models/CertificateTrainingModel.php b/app/Models/CertificateTrainingModel.php new file mode 100644 index 0000000..0c31dd6 --- /dev/null +++ b/app/Models/CertificateTrainingModel.php @@ -0,0 +1,63 @@ + 'required|numeric', + 'contact_id' => 'required|numeric', + ]; + + protected $validationMessages = [ + 'cert_id' => [ + 'required' => 'ID Sertifikat wajib diisi.', + 'numeric' => 'ID Sertifikat harus berupa angka.' + ], + 'contact_id' => [ + 'required' => 'ID Contact wajib diisi.', + 'numeric' => 'ID Contact harus berupa angka.' + ] + ]; + + protected $skipValidation = false; + + // /** + // * Contoh Method untuk mengambil data training lengkap dengan nama sertifikat dan contact + // */ + // public function getTrainingDetails($id = null) + // { + // $builder = $this->db->table($this->table); + // $builder->select('Certificates_Training.*, Certificates.cert_name, Contacts.contact_name'); // Asumsi nama tabel Contacts + // $builder->join('Certificates', 'Certificates.cert_id = Certificates_Training.cert_id'); + // $builder->join('Contacts', 'Contacts.contact_id = Certificates_Training.contact_id'); + // $builder->where('Certificates_Training.deleted_at', null); // Pastikan yang belum dihapus + + // if ($id) { + // return $builder->where('cert_training_id', $id)->get()->getRowArray(); + // } + + // return $builder->get()->getResultArray(); + // } +} \ No newline at end of file diff --git a/app/Views/activities_editor.php b/app/Views/activities_editor.php index 924c348..fe0ef5c 100644 --- a/app/Views/activities_editor.php +++ b/app/Views/activities_editor.php @@ -26,6 +26,7 @@ foreach($products as $qdata) { $now = date('Y-m-d\TH:i'); $siteid = ''; +$contactid = ''; $productid = ''; $vendorid = ''; $swversion = ''; @@ -62,6 +63,7 @@ if(isset($data)) { $acttypeid = $data['acttypeid']; $userid_owner = $data['userid_owner']; $activitystatus = $data['activitystatus']; + $contactid = $data['contactid']; // Untuk REFF : Menentukan mana yg dipakai untuk actid_ref if ($refer_page) { @@ -109,6 +111,9 @@ if(isset($data)) {