forked from mahdahar/crm-summit
Update Fitur Certificate Training
This commit is contained in:
parent
038e5e74db
commit
799edf9588
@ -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/getvendor/(:num)', 'Activities::getvendor/$1');
|
||||||
$routes->get('/activities/getconsumable/(:num)', 'Activities::getconsumable/$1');
|
$routes->get('/activities/getconsumable/(:num)', 'Activities::getconsumable/$1');
|
||||||
$routes->get('/activities/getcontact/(:num)', 'Activities::getcontact/$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/newtextarea', 'Activities::newtextarea');
|
||||||
$routes->get('/activities/activitiesproduct/(:num)', 'Activities::activitiesproduct/$1');
|
$routes->get('/activities/activitiesproduct/(:num)', 'Activities::activitiesproduct/$1');
|
||||||
$routes->get('/activities/dummy', 'Activities::dummy');
|
$routes->get('/activities/dummy', 'Activities::dummy');
|
||||||
@ -212,23 +214,24 @@ $routes->group('certificates', function($routes) {
|
|||||||
// Untuk Index Tiap Menu
|
// Untuk Index Tiap Menu
|
||||||
$routes->get('maintenance', 'Certificates::maintenanceIndex'); // OK
|
$routes->get('maintenance', 'Certificates::maintenanceIndex'); // OK
|
||||||
$routes->get('installation', 'Certificates::installationIndex'); // 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
|
// $routes->get('calibration', 'Certificates::calibrateIndex'); // OK
|
||||||
|
|
||||||
// Untuk Get API
|
// Untuk Get API
|
||||||
$routes->get('api/getindexmaintenance', 'Certificates::getDataIndexMaintenance'); // OK
|
$routes->get('api/getindexmaintenance', 'Certificates::getDataIndexMaintenance'); // OK
|
||||||
$routes->get('api/getindexinstallation', 'Certificates::getDataIndexInstallation'); // 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');
|
// $routes->get('api/getindexcalibrate', 'Certificates::getDataIndexCalibrate');
|
||||||
|
|
||||||
// Untuk Get Modal Data
|
// Untuk Get Modal Data
|
||||||
$routes->post('api/showmaintenance', 'Certificates::showDataMaintenance'); // OK
|
$routes->post('api/showmaintenance', 'Certificates::showDataMaintenance'); // OK
|
||||||
$routes->post('api/showinstallation', 'Certificates::showDataInstallation'); // OK
|
$routes->post('api/showinstallation', 'Certificates::showDataInstallation'); // OK
|
||||||
|
$routes->post('api/showtraining', 'Certificates::showDataTraining'); // OK
|
||||||
|
|
||||||
// Untuk Preview Cerificate
|
// Untuk Preview Cerificate
|
||||||
$routes->get('maintenance/show/(:any)', 'Certificates::createMaintenancePreview/$1'); // OK
|
$routes->get('maintenance/show/(:any)', 'Certificates::createMaintenancePreview/$1'); // OK
|
||||||
$routes->get('installation/show/(:any)', 'Certificates::createInstallationPreview/$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->get('calibration/show/(:any)/(:any)', 'Certificates::createCalibratePreview/$1/$2');
|
||||||
|
|
||||||
$routes->post('api/validatecertificate', 'Certificates::validateCertificate'); // OK
|
$routes->post('api/validatecertificate', 'Certificates::validateCertificate'); // OK
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
namespace App\Controllers;
|
namespace App\Controllers;
|
||||||
|
|
||||||
use App\Models\CertificateModel;
|
use App\Models\CertificateModel;
|
||||||
|
use App\Models\CertificateTrainingModel;
|
||||||
use App\Models\ActivitiesModel;
|
use App\Models\ActivitiesModel;
|
||||||
use App\Models\ActdetailModel;
|
use App\Models\ActdetailModel;
|
||||||
use App\Models\InvTransModel;
|
use App\Models\InvTransModel;
|
||||||
@ -376,6 +377,14 @@ class Activities extends Controller {
|
|||||||
$query = $db->query($sql);
|
$query = $db->query($sql);
|
||||||
$results = $query->getResultArray();
|
$results = $query->getResultArray();
|
||||||
$data['vendors'] = $results;
|
$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'); }
|
if( $this->request->getVar('siteid') != '' ) { $siteid = $this->request->getVar('siteid'); }
|
||||||
|
|
||||||
@ -408,7 +417,13 @@ class Activities extends Controller {
|
|||||||
'attachment' => $this->request->getVar('attachment'),
|
'attachment' => $this->request->getVar('attachment'),
|
||||||
'actdetailid' => $this->request->getVar('actdetailid'),
|
'actdetailid' => $this->request->getVar('actdetailid'),
|
||||||
'acttextid' => $this->request->getVar('acttextid'),
|
'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');
|
$actby = $this->request->getVar('actby');
|
||||||
@ -470,11 +485,17 @@ class Activities extends Controller {
|
|||||||
$userid_owner = $data['new_value']['userid_owner'];
|
$userid_owner = $data['new_value']['userid_owner'];
|
||||||
$this->createCertificate($actid, $issuedDate, $userid_owner, 'MC');
|
$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;
|
$issuedDate = $data['new_value']['closedate'] ?? null;
|
||||||
$userid_owner = $data['new_value']['userid_owner'];
|
$userid_owner = $data['new_value']['userid_owner'];
|
||||||
$this->createCertificate($actid, $issuedDate, $userid_owner, 'IC');
|
$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 {
|
} else {
|
||||||
// update edit
|
// update edit
|
||||||
@ -550,33 +571,43 @@ class Activities extends Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // UNTUK CERTIFICATES
|
||||||
// UNTUK CERTIFICATES
|
// $certificateTypes = [
|
||||||
$certificateTypes = [
|
// 'maintenance' => 'MC',
|
||||||
'maintenance' => 'MC',
|
// 'installation' => 'IC'
|
||||||
'installation' => 'IC',
|
// ];
|
||||||
];
|
// $hasAnyAction = false;
|
||||||
$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;
|
$issuedDate = $data['new_value']['closedate'] ?? null;
|
||||||
$userid_owner = $data['new_value']['userid_owner'];
|
$userid_owner = $data['new_value']['userid_owner'];
|
||||||
foreach ($certificateTypes as $requestName => $certCode) { //perulangan untuk mengecek semua checkbox
|
if ($reqMaintenance) {// MC
|
||||||
if ($this->request->getVar($requestName)) {
|
$this->updateCertificate($actid, $issuedDate, $userid_owner, 'MC');
|
||||||
$hasAnyAction = true; // Jika checkbox dicentang, tandai bahwa ada aksi
|
} else {
|
||||||
$this->updateCertificate($actid, $issuedDate, $userid_owner, $certCode);
|
$this->deleteCertificate($actid, 'MC');
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!$hasAnyAction) { // Jika setelah dicek semua ternyata tidak ada satupun yang dicentang, baru jalankan delete
|
if ($reqInstallation) {// IC
|
||||||
$this->deleteCertificate($actid);
|
$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
|
// act by consumables
|
||||||
@ -1692,7 +1723,7 @@ class Activities extends Controller {
|
|||||||
return view('invtrans_index', $data);
|
return view('invtrans_index', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Untuk CRUD Sertifikat
|
// Untuk CRUD Sertifikat Installation dan Maintenance
|
||||||
public function createCertificate ($actid, $issuedDate, $userid_owner, $certificate_type) {
|
public function createCertificate ($actid, $issuedDate, $userid_owner, $certificate_type) {
|
||||||
|
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
@ -1744,6 +1775,7 @@ class Activities extends Controller {
|
|||||||
$existingCerts = $certificateModel->withDeleted()
|
$existingCerts = $certificateModel->withDeleted()
|
||||||
->select('status')
|
->select('status')
|
||||||
->where('actid', $actid)
|
->where('actid', $actid)
|
||||||
|
->where('cert_type', $certificate_type)
|
||||||
->findAll();
|
->findAll();
|
||||||
|
|
||||||
// Variabel penanda apakah data sudah pernah ada di database
|
// Variabel penanda apakah data sudah pernah ada di database
|
||||||
@ -1807,22 +1839,25 @@ class Activities extends Controller {
|
|||||||
$newCertificate = $certificateModel->find($certid);
|
$newCertificate = $certificateModel->find($certid);
|
||||||
$certificateModel->update($certid, ['file_url' => base_url('certificates/number/'.$newCertificate['cert_number'])]);
|
$certificateModel->update($certid, ['file_url' => base_url('certificates/number/'.$newCertificate['cert_number'])]);
|
||||||
} else {
|
} else {
|
||||||
|
// dd($isDataExist);
|
||||||
// Jika data sudah ada, eksekusi UPDATE
|
// Jika data sudah ada, eksekusi UPDATE
|
||||||
// Catatan: Karena bisa ada lebih dari 1 data dengan actid yang sama (karena findAll),
|
// Catatan: Karena bisa ada lebih dari 1 data dengan actid yang sama (karena findAll),
|
||||||
// Update ini akan menimpa semua baris yang punya actid tersebut.
|
// Update ini akan menimpa semua baris yang punya actid tersebut.
|
||||||
$certificateModel->withDeleted()
|
$certificateModel->withDeleted()
|
||||||
->where('actid', $actid)
|
->where('actid', $actid)
|
||||||
|
->where('cert_type', $certificate_type)
|
||||||
->set($certPayload)
|
->set($certPayload)
|
||||||
->update();
|
->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public function deleteCertificate($actid) {
|
public function deleteCertificate($actid, $certificate_type) {
|
||||||
$certificateModel = new CertificateModel();
|
$certificateModel = new CertificateModel();
|
||||||
|
|
||||||
// 1. Cek apakah data sudah ada menggunakan findAll()
|
// 1. Cek apakah data sudah ada menggunakan findAll()
|
||||||
$existingCerts = $certificateModel->withDeleted()
|
$existingCerts = $certificateModel->withDeleted()
|
||||||
->select('status')
|
->select('status')
|
||||||
->where('actid', $actid)
|
->where('actid', $actid)
|
||||||
|
->where('cert_type', $certificate_type)
|
||||||
->findAll();
|
->findAll();
|
||||||
|
|
||||||
// Variabel penanda apakah data sudah pernah ada di database
|
// Variabel penanda apakah data sudah pernah ada di database
|
||||||
@ -1837,8 +1872,307 @@ class Activities extends Controller {
|
|||||||
return;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ class Certificates extends BaseController {
|
|||||||
')
|
')
|
||||||
->join('activities', 'activities.actid = certificates.actid', 'left')
|
->join('activities', 'activities.actid = certificates.actid', 'left')
|
||||||
->join('users', 'users.userid = certificates.user_id', 'left')
|
->join('users', 'users.userid = certificates.user_id', 'left')
|
||||||
->where('certificates.cert_type', 'IC');;
|
->where('certificates.cert_type', 'IC');
|
||||||
|
|
||||||
// 2. Filter berdasarkan Role
|
// 2. Filter berdasarkan Role
|
||||||
if (in_array($userPosId, [1, 3, 5])) { // Manager & IT: Tidak perlu filter tambahan (lihat semua)
|
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('activities', 'activities.actid = certificates.actid', 'left')
|
||||||
->join('users', 'users.userid = certificates.user_id', 'left')
|
->join('users', 'users.userid = certificates.user_id', 'left')
|
||||||
->where('certificates.cert_type', 'MC');;
|
->where('certificates.cert_type', 'MC');
|
||||||
|
|
||||||
// 2. Filter berdasarkan Role
|
// 2. Filter berdasarkan Role
|
||||||
if (in_array($userPosId, [1, 3, 5])) { // Manager & IT: Tidak perlu filter tambahan (lihat semua)
|
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]
|
// Untuk Sertifikat Training [3]
|
||||||
// public function trainingIndex() {
|
public function trainingIndex() {
|
||||||
// return view('certificate_training_index');
|
return view('certificate_training_index');
|
||||||
// }
|
}
|
||||||
// public function getDataIndexTraining() {
|
public function getDataIndexTraining() {
|
||||||
// // $actid = $this->request->getVar('actid');
|
$userPosId = session()->get('userposid');
|
||||||
|
$userId = session()->get('userid');
|
||||||
|
|
||||||
|
$certificateModel = new CertificateModel();
|
||||||
|
|
||||||
// // Sample data - replace with actual database query
|
// 1. Mulai Query Builder
|
||||||
// $certificates = [
|
$builder = $certificateModel->select('
|
||||||
// [
|
certificates.cert_id,
|
||||||
// 'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
certificates.cert_number,
|
||||||
// 'certname' => 'Jokoh Calibration Certificate',
|
certificates.cert_name,
|
||||||
// 'productname' => 'Jokoh',
|
certificates.cert_type,
|
||||||
// 'productnumber' => 'SN-2024-001',
|
certificates.actid,
|
||||||
// 'issuedate' => '2024-01-15',
|
certificates.issued_date,
|
||||||
// 'expirydate' => '2025-01-15',
|
certificates.expired_date,
|
||||||
// 'vendor' => 'Summit Calibration Lab',
|
certificates.status,
|
||||||
// 'isval' => null
|
certificates.user_validation_at,
|
||||||
// ],
|
certificates.spv_validation_at,
|
||||||
// [
|
certificates.manager_validation_at,
|
||||||
// 'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
activities.subject as activity_subject,
|
||||||
// 'certname' => 'Electrical Safety Test',
|
CONCAT(users.firstname, " ", users.lastname) as fullname
|
||||||
// 'productname' => 'GE Healthcare VIVID',
|
')
|
||||||
// 'productnumber' => 'GE-VIV-Q992',
|
->join('activities', 'activities.actid = certificates.actid', 'left')
|
||||||
// 'issuedate' => '2024-06-12',
|
->join('users', 'users.userid = certificates.user_id', 'left')
|
||||||
// 'expirydate' => '2026-10-01',
|
->where('certificates.cert_type', 'UTC');
|
||||||
// 'vendor' => 'Pramita Medika Service',
|
|
||||||
// 'isval' => '2026-03-01'
|
|
||||||
// ]
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// // If no actid, return all certificates
|
// 2. Filter berdasarkan Role
|
||||||
// if (empty($certificates)) {
|
if (in_array($userPosId, [1, 3, 5])) { // Manager & IT: Tidak perlu filter tambahan (lihat semua)
|
||||||
// return $this->response->setJSON(null);
|
} 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);
|
// 3. Eksekusi Query
|
||||||
// }
|
$allData = $builder->findAll();
|
||||||
// public function createTrainingPreview($certid = null) { // Untuk Preview Sertifikat
|
|
||||||
// //Melakukan search data dari database
|
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->previewPdf($certificate, 'training'); // Preview PDF
|
||||||
// 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]
|
// Untuk Sertifikat Calibrate [4]
|
||||||
// public function calibrateIndex() {
|
// public function calibrateIndex() {
|
||||||
@ -490,10 +610,12 @@ class Certificates extends BaseController {
|
|||||||
|
|
||||||
$dompdf = new Dompdf($options);
|
$dompdf = new Dompdf($options);
|
||||||
|
|
||||||
// Format dates
|
if ($type == 'training') {
|
||||||
$certificate['issueddate'] = date('d-M-Y', strtotime($certificate['issueddate']));
|
$certificate['issueddate'] = date('F d, Y', strtotime($certificate['issueddate']));
|
||||||
|
} else {
|
||||||
if(isset($certificate['expireddate'])) {
|
$certificate['issueddate'] = date('d-M-Y', strtotime($certificate['issueddate']));
|
||||||
|
}
|
||||||
|
if (isset($certificate['expireddate'])) {
|
||||||
$certificate['expireddate'] = date('d-M-Y', strtotime($certificate['expireddate']));
|
$certificate['expireddate'] = date('d-M-Y', strtotime($certificate['expireddate']));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,51 +741,95 @@ class Certificates extends BaseController {
|
|||||||
$certificateModel->update($certid, ['status' => 'validated']);
|
$certificateModel->update($certid, ['status' => 'validated']);
|
||||||
|
|
||||||
// Baru jalankan query berat JOIN di sini untuk keperluan PDF/Notifikasi
|
// 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('
|
$latestData = $certificateModel->select('
|
||||||
certificates.cert_name,
|
certificates.cert_name,
|
||||||
certificates.issued_date,
|
certificates.issued_date,
|
||||||
certificates.expired_date,
|
certificates.expired_date,
|
||||||
certificates.file_url,
|
certificates.file_url,
|
||||||
productalias.productaliastext as productname,
|
productalias.productaliastext as productname,
|
||||||
sites.sitename as sitename,
|
sites.sitename as sitename,
|
||||||
products.productnumber,
|
products.productnumber,
|
||||||
CASE
|
CASE
|
||||||
WHEN certificates.cert_type = "MC" THEN "Maintenance"
|
WHEN certificates.cert_type = "MC" THEN "maintenance"
|
||||||
WHEN certificates.cert_type = "IC" THEN "Installation"
|
WHEN certificates.cert_type = "IC" THEN "installation"
|
||||||
WHEN certificates.cert_type = "UTC" THEN "Training"
|
WHEN certificates.cert_type = "UTC" THEN "training"
|
||||||
WHEN certificates.cert_type = "BAI" THEN "Berita Acara Instalasi"
|
WHEN certificates.cert_type = "BAI" THEN "Berita Acara Instalasi"
|
||||||
WHEN certificates.cert_type = "BAP" THEN "Berita Acara Penarikan"
|
WHEN certificates.cert_type = "BAP" THEN "Berita Acara Penarikan"
|
||||||
ELSE certificates.cert_type
|
ELSE certificates.cert_type
|
||||||
END AS cert_type,
|
END AS cert_type,
|
||||||
CONCAT(users.firstname, " ", users.lastname) AS fullname,
|
CONCAT(users.firstname, " ", users.lastname) AS fullname,
|
||||||
userposition.texts AS user_position,
|
userposition.texts AS user_position,
|
||||||
certificates.issued_date,
|
certificates.issued_date,
|
||||||
certificates.expired_date,
|
certificates.expired_date,
|
||||||
certificates.cert_number -- Penting agar callback UUID tetap jalan
|
CONCAT(contacts.firstname, " ", contacts.lastname) AS fullname,
|
||||||
', false)
|
contacts.title,
|
||||||
->join('users', 'users.userid = certificates.user_id', 'left')
|
certificates.cert_number -- Penting agar callback UUID tetap jalan
|
||||||
->join('userposition', 'userposition.userposid = users.userposid', 'left')
|
', false)
|
||||||
->join('activities', 'activities.actid = certificates.actid', 'left')
|
->join('users', 'users.userid = certificates.user_id', 'left')
|
||||||
->join('sites', 'sites.siteid = activities.siteid', 'left')
|
->join('userposition', 'userposition.userposid = users.userposid', 'left')
|
||||||
->join('products', 'products.productid = activities.productid', 'left')
|
->join('activities', 'activities.actid = certificates.actid', 'left')
|
||||||
->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'left')
|
->join('sites', 'sites.siteid = activities.siteid', 'left')
|
||||||
->join('productalias', 'productalias.productaliasid = productcatalog.productaliasid', 'left')
|
->join('accounts', 'accounts.accountid = sites.accountid', 'left')
|
||||||
->where('certificates.cert_id', $certid)
|
->join('zones', 'zones.zoneid = accounts.zoneid', 'left')
|
||||||
->first();
|
->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 = [
|
$certificate = [
|
||||||
|
'title' => empty($latestData['title']) ? '' : ', ' . $latestData['title'],
|
||||||
'file_url' => $latestData['file_url'],
|
'file_url' => $latestData['file_url'],
|
||||||
'certname' => $latestData['cert_name'],
|
'certname' => $latestData['cert_name'],
|
||||||
'sitename' => $latestData['sitename'],
|
'sitename' => $latestData['sitename'],
|
||||||
|
'city' => empty($data['city']) ? '' : $data['city'],
|
||||||
'certtype' => $latestData['cert_type'],
|
'certtype' => $latestData['cert_type'],
|
||||||
'fullname' => $latestData['fullname'],
|
'fullname' => $latestData['fullname'],
|
||||||
'userposition' => $latestData['user_position'],
|
'userposition' => $latestData['user_position'],
|
||||||
'productname' => $latestData['productname'],
|
'productname' => $latestData['productname'],
|
||||||
'productnumber' => $latestData['productnumber'],
|
'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'])),
|
'expireddate' => date('d-M-Y', strtotime($latestData['expired_date'])),
|
||||||
'exportToPDF' => true
|
'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 {
|
try {
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
namespace App\Controllers;
|
namespace App\Controllers;
|
||||||
|
|
||||||
use App\Models\ContactsModel;
|
use App\Models\ContactsModel;
|
||||||
|
use App\Models\SiteContactModel;
|
||||||
use CodeIgniter\Controller;
|
use CodeIgniter\Controller;
|
||||||
|
|
||||||
class Contacts extends Controller {
|
class Contacts extends Controller {
|
||||||
@ -38,7 +39,7 @@ class Contacts extends Controller {
|
|||||||
}
|
}
|
||||||
if ($this->request->getMethod() === 'POST') {
|
if ($this->request->getMethod() === 'POST') {
|
||||||
$rules = [
|
$rules = [
|
||||||
'contactid' => 'required',
|
// 'contactid' => 'required',
|
||||||
'firstname' => 'required',
|
'firstname' => 'required',
|
||||||
'email_1' => 'required',
|
'email_1' => 'required',
|
||||||
'initial' => 'required'
|
'initial' => 'required'
|
||||||
@ -53,7 +54,8 @@ class Contacts extends Controller {
|
|||||||
'email_2' => $this->request->getVar('email_2'),
|
'email_2' => $this->request->getVar('email_2'),
|
||||||
'phone' => $this->request->getVar('phone'),
|
'phone' => $this->request->getVar('phone'),
|
||||||
'mobile_1' => $this->request->getVar('mobile_1'),
|
'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)){
|
if($this->validate($rules)){
|
||||||
@ -67,6 +69,18 @@ class Contacts extends Controller {
|
|||||||
$contactsModel->set('createdate', 'NOW()', FALSE);
|
$contactsModel->set('createdate', 'NOW()', FALSE);
|
||||||
$contactsModel->set('enddate', NULL);
|
$contactsModel->set('enddate', NULL);
|
||||||
$contactsModel->insert($data['new_value']);
|
$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');
|
return view('form_success');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
63
app/Models/CertificateTrainingModel.php
Normal file
63
app/Models/CertificateTrainingModel.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use CodeIgniter\Model;
|
||||||
|
|
||||||
|
class CertificateTrainingModel extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'certificates_training';
|
||||||
|
protected $primaryKey = 'cert_training_id';
|
||||||
|
protected $useAutoIncrement = true;
|
||||||
|
protected $returnType = 'array'; // Bisa diubah ke 'object' jika lebih suka
|
||||||
|
|
||||||
|
// Fitur Soft Delete
|
||||||
|
protected $useSoftDeletes = true;
|
||||||
|
|
||||||
|
// Field yang boleh diisi (Mass Assignment)
|
||||||
|
protected $allowedFields = ['cert_id', 'contact_id'];
|
||||||
|
|
||||||
|
// Fitur Otomatisasi Timestamp
|
||||||
|
protected $useTimestamps = true;
|
||||||
|
protected $dateFormat = 'datetime';
|
||||||
|
protected $createdField = 'created_at';
|
||||||
|
protected $updatedField = 'updated_at';
|
||||||
|
protected $deletedField = 'deleted_at';
|
||||||
|
|
||||||
|
// Validasi Sederhana
|
||||||
|
protected $validationRules = [
|
||||||
|
'cert_id' => '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();
|
||||||
|
// }
|
||||||
|
}
|
||||||
@ -26,6 +26,7 @@ foreach($products as $qdata) {
|
|||||||
|
|
||||||
$now = date('Y-m-d\TH:i');
|
$now = date('Y-m-d\TH:i');
|
||||||
$siteid = '';
|
$siteid = '';
|
||||||
|
$contactid = '';
|
||||||
$productid = '';
|
$productid = '';
|
||||||
$vendorid = '';
|
$vendorid = '';
|
||||||
$swversion = '';
|
$swversion = '';
|
||||||
@ -62,6 +63,7 @@ if(isset($data)) {
|
|||||||
$acttypeid = $data['acttypeid'];
|
$acttypeid = $data['acttypeid'];
|
||||||
$userid_owner = $data['userid_owner'];
|
$userid_owner = $data['userid_owner'];
|
||||||
$activitystatus = $data['activitystatus'];
|
$activitystatus = $data['activitystatus'];
|
||||||
|
$contactid = $data['contactid'];
|
||||||
|
|
||||||
// Untuk REFF : Menentukan mana yg dipakai untuk actid_ref
|
// Untuk REFF : Menentukan mana yg dipakai untuk actid_ref
|
||||||
if ($refer_page) {
|
if ($refer_page) {
|
||||||
@ -109,6 +111,9 @@ if(isset($data)) {
|
|||||||
<form method="post" enctype="multipart/form-data">
|
<form method="post" enctype="multipart/form-data">
|
||||||
|
|
||||||
<input type='hidden' name='userid_creator' value='<?=$_SESSION['userid'];?>' />
|
<input type='hidden' name='userid_creator' value='<?=$_SESSION['userid'];?>' />
|
||||||
|
|
||||||
|
<!-- Untuk Training -->
|
||||||
|
<input type='hidden' id='current_actid' value='<?= isset($data['actid']) ? $data['actid'] : '' ?>' />
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -194,7 +199,7 @@ if(isset($data)) {
|
|||||||
<div class="col-12 col-md-6">
|
<div class="col-12 col-md-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="owner" class="form-label border-start border-5 border-primary ps-1">Activity Owner</label>
|
<label for="owner" class="form-label border-start border-5 border-primary ps-1">Activity Owner</label>
|
||||||
<select name="userid_owner" class="form-select form-select-sm select2">
|
<select id="userid_owner" name="userid_owner" class="form-select form-select-sm select2">
|
||||||
<option value="">-- Choose one --</option>
|
<option value="">-- Choose one --</option>
|
||||||
<?php
|
<?php
|
||||||
foreach ($users as $data) {
|
foreach ($users as $data) {
|
||||||
@ -250,7 +255,7 @@ if(isset($data)) {
|
|||||||
Berita Acara Instalasi
|
Berita Acara Instalasi
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<div class="col-md-6 mb-2">
|
<div class="col-md-6 mb-2">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
@ -259,7 +264,7 @@ if(isset($data)) {
|
|||||||
User Training Certificate
|
User Training Certificate
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -269,7 +274,8 @@ if(isset($data)) {
|
|||||||
<div class="col-12 col-md-6">
|
<div class="col-12 col-md-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="status" class="form-label border-start border-5 border-primary ps-1">Activity Status</label>
|
<label for="status" class="form-label border-start border-5 border-primary ps-1">Activity Status</label>
|
||||||
<select name="activitystatus" id="status" class="form-select form-select-sm" onchange='changestatus()' required>
|
<!-- <select name="activitystatus" id="status" class="form-select form-select-sm" onchange='changestatus()' required> -->
|
||||||
|
<select name="activitystatus" id="status" class="form-select form-select-sm" required>
|
||||||
<option value="" disabled>-- Choose one --</option>
|
<option value="" disabled>-- Choose one --</option>
|
||||||
<?php
|
<?php
|
||||||
foreach ($stats as $statcode => $stat) {
|
foreach ($stats as $statcode => $stat) {
|
||||||
@ -633,51 +639,7 @@ if(isset($data)) {
|
|||||||
</h2>
|
</h2>
|
||||||
<div id="trainingAccordion" class="accordion-collapse collapse bg-white" aria-labelledby="trainingHeading" data-bs-parent="#accordionTraining">
|
<div id="trainingAccordion" class="accordion-collapse collapse bg-white" aria-labelledby="trainingHeading" data-bs-parent="#accordionTraining">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<input type='hidden' name='trainingid_delete' id='trainingid_delete' />
|
<span id='training_form'></span>
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-12 col-lg-5">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="trainingname" class="form-label">Nama</label>
|
|
||||||
<input type='text' class="form-control form-control-sm trainingname" placeholder="Masukkan nama" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-lg-5">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="trainingdate" class="form-label">Tanggal</label>
|
|
||||||
<input type='text' class="form-control form-control-sm trainingdate" placeholder="YYYY-MM-DD" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-grid gap-2 col-12 col-lg-2 mt-2">
|
|
||||||
<button type='button' class='btn btn-sm btn-success' onclick='addTrainingRow();'>Tambah</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
<div class='table-responsive'>
|
|
||||||
<table class='table table-bordered table-sm' id='training_table'>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style='width:45%;'>Nama Analis</th>
|
|
||||||
<th style='width:45%;'>Tanggal</th>
|
|
||||||
<th style='width:10%;'>Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
if(isset($trainingdata)) {
|
|
||||||
foreach($trainingdata as $data) {
|
|
||||||
$trainingid = $data['trainingid'];
|
|
||||||
$qname = $data['trainingname'];
|
|
||||||
$qdate = $data['trainingdate'];
|
|
||||||
echo "<tr> <input type='hidden' name='trainingnames[]' value='".$qname."'> <input type='hidden' name='trainingdates[]' value='".$qdate."' /> <td>$qname</td> <td>$qdate</td>".
|
|
||||||
"<td> <button type='button' class='btn btn-sm btn-warning' onclick='deleteTrainingRow(this, $trainingid)'>Hapus</button> </td>".
|
|
||||||
"</tr>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -804,14 +766,14 @@ $(document).ready(function() {
|
|||||||
// $("#calibration").prop('disabled', true);
|
// $("#calibration").prop('disabled', true);
|
||||||
$("#installation").prop('disabled', true);
|
$("#installation").prop('disabled', true);
|
||||||
// $("#offreport").prop('disabled', true);
|
// $("#offreport").prop('disabled', true);
|
||||||
// $("#training").prop('disabled', true);
|
$("#training").prop('disabled', true);
|
||||||
}
|
}
|
||||||
else if (this.value == '3') {
|
else if (this.value == '3') {
|
||||||
$("#maintenance").prop('disabled', true);
|
$("#maintenance").prop('disabled', true);
|
||||||
// $("#calibration").prop('disabled', false);
|
// $("#calibration").prop('disabled', false);
|
||||||
$("#installation").prop('disabled', false);
|
$("#installation").prop('disabled', false);
|
||||||
// $("#offreport").prop('disabled', false);
|
// $("#offreport").prop('disabled', false);
|
||||||
// $("#training").prop('disabled', false);
|
$("#training").prop('disabled', false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Ini akan menjadi default jika #acttypeid kosong atau bukan 5 dan 3
|
// Ini akan menjadi default jika #acttypeid kosong atau bukan 5 dan 3
|
||||||
@ -819,9 +781,30 @@ $(document).ready(function() {
|
|||||||
// $("#calibration").prop('disabled', true);
|
// $("#calibration").prop('disabled', true);
|
||||||
$("#installation").prop('disabled', true);
|
$("#installation").prop('disabled', true);
|
||||||
// $("#offreport").prop('disabled', true);
|
// $("#offreport").prop('disabled', true);
|
||||||
// $("#training").prop('disabled', true);
|
$("#training").prop('disabled', true);
|
||||||
}
|
}
|
||||||
}).trigger('change');
|
}).trigger('change');
|
||||||
|
|
||||||
|
let siteid = $('#siteid').val();
|
||||||
|
let current_actid = $('#current_actid').val();
|
||||||
|
|
||||||
|
// Perbaikan di sini: '!current_actid' otomatis mengecek null, undefined, atau string kosong ('')
|
||||||
|
if (!current_actid) {
|
||||||
|
current_actid = '';
|
||||||
|
} else {
|
||||||
|
current_actid = '/' + current_actid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Untuk Training
|
||||||
|
if (siteid !== '') {
|
||||||
|
$.get("<?=base_url();?>activities/getsitecontact/" + siteid + current_actid, function(data) {
|
||||||
|
$('#training_form').html(data);
|
||||||
|
$('.select2').select2({
|
||||||
|
theme: 'bootstrap-5',
|
||||||
|
width: '100%'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// acttext
|
// acttext
|
||||||
@ -832,7 +815,7 @@ function acttext_del(e, actdetailid) {
|
|||||||
var actdetailid = actdetailid.toString();
|
var actdetailid = actdetailid.toString();
|
||||||
var d = $('#actdetailid_delete');
|
var d = $('#actdetailid_delete');
|
||||||
d.val(d.val()+' '+actdetailid);
|
d.val(d.val()+' '+actdetailid);
|
||||||
console.log(d.val());
|
// console.log(d.val());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -884,35 +867,6 @@ function acttext_add() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// $('#actby').change(function() {
|
|
||||||
// var actby=this.value;
|
|
||||||
// if(actby == 'P') {
|
|
||||||
// var siteid=$('#siteid').val();
|
|
||||||
// $.get("<?=base_url();?>/activities/getproduct/"+siteid, function(data) {
|
|
||||||
// $('#actby_item').html(data);
|
|
||||||
// $('.select2').select2({
|
|
||||||
// theme: 'bootstrap-5',
|
|
||||||
// width: '100%'
|
|
||||||
// });
|
|
||||||
// })
|
|
||||||
// } else if (actby == 'V') {
|
|
||||||
// $.get("<?=base_url();?>/activities/getvendor/0", function(data) {
|
|
||||||
// $('#actby_item').html(data);
|
|
||||||
// })
|
|
||||||
// } else if (actby == 'C') {
|
|
||||||
// $.get("<?=base_url();?>/activities/getconsumable/0", function(data) {
|
|
||||||
// $('#actby_item').html(data);
|
|
||||||
// $('.select2').select2({
|
|
||||||
// theme: 'bootstrap-5',
|
|
||||||
// width: '100%'
|
|
||||||
// });
|
|
||||||
// })
|
|
||||||
// }else {
|
|
||||||
// $('#actby_item').html('');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// })
|
|
||||||
|
|
||||||
// 1. Event ketika 'Activity by' diubah (Kode asli Anda dengan sedikit penyesuaian)
|
// 1. Event ketika 'Activity by' diubah (Kode asli Anda dengan sedikit penyesuaian)
|
||||||
$('#actby').change(function() {
|
$('#actby').change(function() {
|
||||||
var actby = this.value;
|
var actby = this.value;
|
||||||
@ -949,8 +903,27 @@ $('#actby').change(function() {
|
|||||||
// 2. --- MODIFIKASI TAMBAHAN ---
|
// 2. --- MODIFIKASI TAMBAHAN ---
|
||||||
// Event ketika 'Site' diubah
|
// Event ketika 'Site' diubah
|
||||||
$('#siteid').change(function() {
|
$('#siteid').change(function() {
|
||||||
var actby = $('#actby').val(); // Cek status Activity by saat ini
|
let actby = $('#actby').val(); // Cek status Activity by saat ini
|
||||||
var siteid = this.value; // Ambil nilai siteid yang baru dipilih
|
|
||||||
|
let siteid = $('#siteid').val();
|
||||||
|
let current_actid = $('#current_actid').val();
|
||||||
|
if (!current_actid) {
|
||||||
|
current_actid = '';
|
||||||
|
} else {
|
||||||
|
current_actid = '/' + current_actid;
|
||||||
|
}
|
||||||
|
// Khusus Untuk Training
|
||||||
|
if(siteid == '') {
|
||||||
|
$('#training_form').html('<div class="text-center">Please Fill Site First!</div>');
|
||||||
|
} else {
|
||||||
|
$.get("<?=base_url();?>activities/getsitecontact/" + siteid + current_actid, function(data) {
|
||||||
|
$('#training_form').html(data);
|
||||||
|
$('.select2').select2({
|
||||||
|
theme: 'bootstrap-5',
|
||||||
|
width: '100%'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Hanya jalankan AJAX ulang JIKA Activity by sedang memilih 'P'
|
// Hanya jalankan AJAX ulang JIKA Activity by sedang memilih 'P'
|
||||||
if (actby == 'P') {
|
if (actby == 'P') {
|
||||||
@ -988,12 +961,11 @@ $('#status').change(function() {
|
|||||||
// else { $("#maintenance").prop('disabled', true); $("#calibration").prop('disabled', true); $("#installation").prop('disabled', true); $("#offreport").prop('disabled', true); $("#training").prop('disabled', true);}
|
// else { $("#maintenance").prop('disabled', true); $("#calibration").prop('disabled', true); $("#installation").prop('disabled', true); $("#offreport").prop('disabled', true); $("#training").prop('disabled', true);}
|
||||||
// })
|
// })
|
||||||
$('#acttypeid').change(function() {
|
$('#acttypeid').change(function() {
|
||||||
if (this.value=='5'){ $("#maintenance").prop('disabled', false); $("#installation").prop('disabled', true);}
|
if (this.value=='5'){ $("#maintenance").prop('disabled', false); $("#installation").prop('disabled', true); $("#training").prop('disabled', true);}
|
||||||
else if (this.value=='3'){ $("#maintenance").prop('disabled', true); $("#installation").prop('disabled', false);}
|
else if (this.value=='3'){ $("#maintenance").prop('disabled', true); $("#installation").prop('disabled', false); $("#training").prop('disabled', false); }
|
||||||
else { $("#maintenance").prop('disabled', true); $("#installation").prop('disabled', true);}
|
else { $("#maintenance").prop('disabled', true); $("#installation").prop('disabled', true); $("#training").prop('disabled', true);}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// reportdate change => opendate.value = reportdate.value
|
// reportdate change => opendate.value = reportdate.value
|
||||||
$('#reportdate').change(function() {
|
$('#reportdate').change(function() {
|
||||||
$('#opendate').val(this.value);
|
$('#opendate').val(this.value);
|
||||||
@ -1012,7 +984,7 @@ function deleteRow(btn, itxid) {
|
|||||||
var itxid = itxid.toString();
|
var itxid = itxid.toString();
|
||||||
var d = $('#itxid_delete');
|
var d = $('#itxid_delete');
|
||||||
d.val(d.val()+' '+itxid);
|
d.val(d.val()+' '+itxid);
|
||||||
console.log(d.val());
|
// console.log(d.val());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1097,41 +1069,10 @@ function triggerChange(element){
|
|||||||
element.dispatchEvent(changeEvent);
|
element.dispatchEvent(changeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Training Analyst
|
|
||||||
function addTrainingRow() {
|
|
||||||
var trainingname = $('.trainingname').val();
|
|
||||||
var trainingdate = $('.trainingdate').val();
|
|
||||||
|
|
||||||
if (trainingname == "" || trainingdate == "") {
|
|
||||||
alert("Nama dan tanggal tidak boleh kosong");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newRow = "<tr> <input type='hidden' name='trainingnames[]' value='"+trainingname+"'> <input type='hidden' name='trainingdates[]' value='"+trainingdate+"' />"+
|
|
||||||
" <td>"+trainingname+"</td> <td>"+trainingdate+"</td>"+
|
|
||||||
" <td class='text-center'> <button type='button' class='btn btn-sm btn-warning' onclick='deleteTrainingRow(this, 0)'>Hapus</button> </td> </tr>";
|
|
||||||
$("#training_table").append(newRow);
|
|
||||||
|
|
||||||
$('.trainingname').val('');
|
|
||||||
}
|
|
||||||
function deleteTrainingRow(btn, trainingid) {
|
|
||||||
if(confirm('Are you sure?')) {
|
|
||||||
var row = btn.parentNode.parentNode;
|
|
||||||
row.parentNode.removeChild(row);
|
|
||||||
if (trainingid > 0) {
|
|
||||||
var trainingid = trainingid.toString();
|
|
||||||
var d = $('#trainingid_delete');
|
|
||||||
d.val(d.val()+' '+trainingid);
|
|
||||||
console.log(d.val());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// flatpickr for training date
|
|
||||||
flatpickr(".trainingdate", { allowInput: true, dateFormat: "Y-m-d" });
|
|
||||||
// Training checkbox enable/disable accordion
|
// Training checkbox enable/disable accordion
|
||||||
function toggleTrainingAccordion() {
|
function toggleTrainingAccordion() {
|
||||||
var trainingChecked = $('#training').prop('checked');
|
let trainingChecked = $('#training').prop('checked');
|
||||||
var trainingDisabled = $('#training').prop('disabled');
|
let trainingDisabled = $('#training').prop('disabled');
|
||||||
if (trainingChecked && !trainingDisabled) {
|
if (trainingChecked && !trainingDisabled) {
|
||||||
// Enable accordion
|
// Enable accordion
|
||||||
$('#accordionTraining').find('button').prop('disabled', false);
|
$('#accordionTraining').find('button').prop('disabled', false);
|
||||||
@ -1140,6 +1081,7 @@ function toggleTrainingAccordion() {
|
|||||||
$('#accordionTraining').find('button').removeClass('disabled');
|
$('#accordionTraining').find('button').removeClass('disabled');
|
||||||
$('#accordionTraining').removeClass('opacity-50').removeClass('pointer-events-none');
|
$('#accordionTraining').removeClass('opacity-50').removeClass('pointer-events-none');
|
||||||
$('#accordionTraining').find('.accordion-button').attr('data-bs-toggle', 'collapse');
|
$('#accordionTraining').find('.accordion-button').attr('data-bs-toggle', 'collapse');
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Disable accordion
|
// Disable accordion
|
||||||
$('#accordionTraining').find('button').prop('disabled', true);
|
$('#accordionTraining').find('button').prop('disabled', true);
|
||||||
@ -1184,53 +1126,48 @@ function toggleCalibrateAccordion() {
|
|||||||
$('#accordionCalibrate').find('.accordion-button').removeAttr('data-bs-toggle');
|
$('#accordionCalibrate').find('.accordion-button').removeAttr('data-bs-toggle');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize on page load
|
// Initialize on page load
|
||||||
toggleCalibrateAccordion();
|
// toggleCalibrateAccordion();
|
||||||
|
|
||||||
// Event listener for calibration checkbox change
|
// Event listener for calibration checkbox change
|
||||||
$('#calibration').change(function() {
|
// $('#calibration').change(function() {
|
||||||
toggleCalibrateAccordion();
|
// toggleCalibrateAccordion();
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Event listener for calibration checkbox disable/enable (when acttypeid changes)
|
// Event listener for calibration checkbox disable/enable (when acttypeid changes)
|
||||||
$('#acttypeid').change(function() {
|
// $('#acttypeid').change(function() {
|
||||||
toggleCalibrateAccordion();
|
// toggleCalibrateAccordion();
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Calibrate
|
// Calibrate
|
||||||
function addCalibrateRow() {
|
// function addCalibrateRow() {
|
||||||
var calibratename = $('.calibratename').val();
|
// var calibratename = $('.calibratename').val();
|
||||||
var calibratevalue = $('.calibratevalue').val();
|
// var calibratevalue = $('.calibratevalue').val();
|
||||||
var calibrateunit = $('.calibrateunit').val();
|
// var calibrateunit = $('.calibrateunit').val();
|
||||||
|
|
||||||
if (calibratename == "" || calibratevalue == "" || calibrateunit == "") {
|
// if (calibratename == "" || calibratevalue == "" || calibrateunit == "") {
|
||||||
alert("Nama parameter, nilai, dan satuan tidak boleh kosong");
|
// alert("Nama parameter, nilai, dan satuan tidak boleh kosong");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
var newRow = "<tr> <input type='hidden' name='calibratenames[]' value='"+calibratename+"'> <input type='hidden' name='calibratevalues[]' value='"+calibratevalue+"' /> <input type='hidden' name='calibrateunits[]' value='"+calibrateunit+"' />"+
|
// var newRow = "<tr> <input type='hidden' name='calibratenames[]' value='"+calibratename+"'> <input type='hidden' name='calibratevalues[]' value='"+calibratevalue+"' /> <input type='hidden' name='calibrateunits[]' value='"+calibrateunit+"' />"+
|
||||||
" <td>"+calibratename+"</td> <td>"+calibratevalue+"</td> <td>"+calibrateunit+"</td>"+
|
// " <td>"+calibratename+"</td> <td>"+calibratevalue+"</td> <td>"+calibrateunit+"</td>"+
|
||||||
" <td class='text-center'> <button type='button' class='btn btn-sm btn-warning' onclick='deleteCalibrateRow(this, 0)'>Hapus</button> </td> </tr>";
|
// " <td class='text-center'> <button type='button' class='btn btn-sm btn-warning' onclick='deleteCalibrateRow(this, 0)'>Hapus</button> </td> </tr>";
|
||||||
$("#calibrate_table").append(newRow);
|
// $("#calibrate_table").append(newRow);
|
||||||
|
|
||||||
$('.calibratename').val('');
|
// $('.calibratename').val('');
|
||||||
$('.calibratevalue').val('');
|
// $('.calibratevalue').val('');
|
||||||
$('.calibrateunit').val('');
|
// $('.calibrateunit').val('');
|
||||||
}
|
// }
|
||||||
|
// function deleteCalibrateRow(btn, calibrateid) {
|
||||||
function deleteCalibrateRow(btn, calibrateid) {
|
// if(confirm('Are you sure?')) {
|
||||||
if(confirm('Are you sure?')) {
|
// var row = btn.parentNode.parentNode;
|
||||||
var row = btn.parentNode.parentNode;
|
// row.parentNode.removeChild(row);
|
||||||
row.parentNode.removeChild(row);
|
// if (calibrateid > 0) {
|
||||||
if (calibrateid > 0) {
|
// var calibrateid = calibrateid.toString();
|
||||||
var calibrateid = calibrateid.toString();
|
// var d = $('#calibrateid_delete');
|
||||||
var d = $('#calibrateid_delete');
|
// d.val(d.val()+' '+calibrateid);
|
||||||
d.val(d.val()+' '+calibrateid);
|
// console.log(d.val());
|
||||||
console.log(d.val());
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="<?=base_url();?>/assets/uppy/uppy-full.js"></script>
|
<script src="<?=base_url();?>/assets/uppy/uppy-full.js"></script>
|
||||||
|
|||||||
319
app/Views/activities_getsitecontacts.php
Normal file
319
app/Views/activities_getsitecontacts.php
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
<div class='row mb-2'>
|
||||||
|
<div class="col-12 text-end">
|
||||||
|
<button type="button" class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#createContactModal">
|
||||||
|
<i class="fa-solid fa-plus"></i> Tambah Analyst Baru
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="createContactModal" tabindex="-1" aria-labelledby="createContactModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title fw-bold" id="createContactModalLabel">Contact Editor</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form id="formCreateContact" action="<?= base_url('/contacts/create'); ?>" method="POST">
|
||||||
|
<div class="modal-body">
|
||||||
|
<input type='hidden' name='siteid' id='siteid' value='<?= $siteid; ?>' />
|
||||||
|
|
||||||
|
<div class="row mb-3 align-items-center">
|
||||||
|
<label for="firstname" class="col-sm-3 col-form-label">First Name <span class="text-danger">*</span></label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control form-control-sm" id="firstname" name="firstname" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3 align-items-center">
|
||||||
|
<label for="lastname" class="col-sm-3 col-form-label">Last Name <span class="text-danger">*</span></label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control form-control-sm" id="lastname" name="lastname" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3 align-items-center">
|
||||||
|
<label for="initial" class="col-sm-3 col-form-label">Initial <span class="text-danger">*</span></label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control form-control-sm" id="initial" name="initial" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3 align-items-center">
|
||||||
|
<label for="title" class="col-sm-3 col-form-label">Title</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control form-control-sm" id="title" name="title">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3 align-items-center">
|
||||||
|
<label for="birthdate" class="col-sm-3 col-form-label">Birthdate</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="date" class="form-control form-control-sm" id="birthdate" name="birthdate">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3 align-items-center">
|
||||||
|
<label for="email_1" class="col-sm-3 col-form-label">Email 1 <span class="text-danger">*</span></label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="email" class="form-control form-control-sm" id="email_1" name="email_1" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3 align-items-center">
|
||||||
|
<label for="email_2" class="col-sm-3 col-form-label">Email 2</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="email" class="form-control form-control-sm" id="email_2" name="email_2">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3 align-items-center">
|
||||||
|
<label for="phone" class="col-sm-3 col-form-label">Phone</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control form-control-sm" id="phone" name="phone">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3 align-items-center">
|
||||||
|
<label for="mobile_1" class="col-sm-3 col-form-label">Mobile 1</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control form-control-sm" id="mobile_1" name="mobile_1">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3 align-items-center">
|
||||||
|
<label for="mobile_2" class="col-sm-3 col-form-label">Mobile 2</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control form-control-sm" id="mobile_2" name="mobile_2">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer border-top-0">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Save Contact</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type='hidden' name='trainingid_delete' id='trainingid_delete' />
|
||||||
|
<div class="row g-3 align-items-end mb-3">
|
||||||
|
<div class="col-12 col-md-4">
|
||||||
|
<label for="trainingname" class="form-label border-start border-5 border-primary ps-1 mb-1">Analyst Name</label>
|
||||||
|
<select name="trainingname" id="trainingname" class="form-select form-select-sm select2 trainingname">
|
||||||
|
<option value="">-- Choose one --</option>
|
||||||
|
<?php
|
||||||
|
if(!empty($sitecontacts)) {
|
||||||
|
foreach ($sitecontacts as $data) {
|
||||||
|
$qcontactid = $data['contactid'];
|
||||||
|
$qcontactname = $data['firstname'] . " " . $data['lastname'];
|
||||||
|
|
||||||
|
// Siapkan data tambahannya
|
||||||
|
$qcontactinitial = $data['initial'];
|
||||||
|
$qcontacttitle = $data['title'];
|
||||||
|
$qcontactemail = $data['email_1'];
|
||||||
|
|
||||||
|
// Simpan di data-attribute
|
||||||
|
echo "<option value='$qcontactid' data-name='$qcontactname' data-initial='$qcontactinitial' data-title='$qcontacttitle' data-email='$qcontactemail'>$qcontactname</option>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-3">
|
||||||
|
<label for="trainingdate" class="form-label mb-1">Tanggal</label>
|
||||||
|
<input type="text" name="trainingdate" id="trainingdate" class="form-control form-control-sm trainingdate"
|
||||||
|
placeholder="YYYY-MM-DD" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 col-md-2">
|
||||||
|
<div class="form-check mb-md-1">
|
||||||
|
<input class="form-check-input" type="checkbox" value="1" id="validatealltraining"
|
||||||
|
name="validatealltraining" checked>
|
||||||
|
<label class="form-check-label" for="validatealltraining" style="font-size: 0.875rem;">
|
||||||
|
Validasi Semua Peserta
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-3 d-grid">
|
||||||
|
<button type="button" class="btn btn-sm btn-success" onclick="addTrainingRow();">Tambah</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class='table-responsive'>
|
||||||
|
<table class='table table-bordered table-sm' id='training_table'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style='width:2%;'>No</th>
|
||||||
|
<th style='width:8%;'>Initial</th>
|
||||||
|
<th style='width:30%;'>Nama Analyst</th>
|
||||||
|
<th style='width:15%;'>Title</th>
|
||||||
|
<th style='width:25%;'>Email</th>
|
||||||
|
<th style='width:15%;'>Tanggal</th>
|
||||||
|
<th style='width:11%;' class='text-center'>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
// Cek apakah ada data $traininguser
|
||||||
|
if(isset($traininguser) && !empty($traininguser)):
|
||||||
|
$no = 1;
|
||||||
|
foreach ($traininguser as $tu):
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td class="text-center"><?= $no++ ?></td>
|
||||||
|
<td><?= esc($tu['initial']) ?></td>
|
||||||
|
<td>
|
||||||
|
<?= esc($tu['firstname']) ?> <?= esc($tu['lastname']) ?>
|
||||||
|
<input type="hidden" name="trainingids[]" value="<?= esc($tu['contactid']) ?>">
|
||||||
|
<input type="hidden" name="trainingnames[]" value="<?= esc($tu['firstname']) ?> <?= esc($tu['lastname']) ?>">
|
||||||
|
<input type="hidden" name="trainingdates[]" value="<?= esc($tu['issued_date']) ?>">
|
||||||
|
</td>
|
||||||
|
<td><?= esc($tu['title']) ?></td>
|
||||||
|
<td><?= esc($tu['email_1']) ?></td>
|
||||||
|
<td><?= esc($tu['issued_date']) ?></td>
|
||||||
|
<td class="text-center">
|
||||||
|
<button type="button" class="btn btn-sm btn-danger" onclick="deleteTrainingRow(this, '<?= esc($tu['contactid']) ?>')">Hapus</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
endforeach;
|
||||||
|
endif;
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function addTrainingRow() {
|
||||||
|
var selectEl = $('#trainingname');
|
||||||
|
var selectedOption = selectEl.find('option:selected');
|
||||||
|
|
||||||
|
var contactid = selectEl.val();
|
||||||
|
var trainingname = selectedOption.data('name');
|
||||||
|
var trainingdate = $('#trainingdate').val();
|
||||||
|
|
||||||
|
if (!contactid || !trainingdate) {
|
||||||
|
alert("Nama Analyst atau Tanggal tidak boleh kosong.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Agar Tidak Double Check
|
||||||
|
var exists = false;
|
||||||
|
// Selektor ini tetap berfungsi dengan baik karena mencari awalan 'trainingids'
|
||||||
|
$("input[name^='trainingids']").each(function(){
|
||||||
|
if($(this).val() == contactid){
|
||||||
|
exists = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(exists){
|
||||||
|
alert("Analyst sudah ditambahkan.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var initial = selectedOption.data('initial') || '-';
|
||||||
|
var title = selectedOption.data('title') || '-';
|
||||||
|
var email = selectedOption.data('email') || '-';
|
||||||
|
|
||||||
|
var rowIndex = $('#training_table tbody tr').length;
|
||||||
|
|
||||||
|
var newRow = `
|
||||||
|
<tr>
|
||||||
|
<td class="text-center">${rowIndex + 1}</td>
|
||||||
|
<td>${initial}</td>
|
||||||
|
<td>
|
||||||
|
${trainingname}
|
||||||
|
<input type="hidden" name="trainingids[]" value="${contactid}">
|
||||||
|
<input type="hidden" name="trainingnames[]" value="${trainingname}">
|
||||||
|
<input type="hidden" name="trainingdates[]" value="${trainingdate}">
|
||||||
|
</td>
|
||||||
|
<td>${title}</td>
|
||||||
|
<td>${email}</td>
|
||||||
|
<td>${trainingdate}</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<button type="button" class="btn btn-sm btn-danger" onclick="deleteTrainingRow(this)">Hapus</button>
|
||||||
|
</td>
|
||||||
|
</tr>`;
|
||||||
|
|
||||||
|
$("#training_table tbody").append(newRow);
|
||||||
|
|
||||||
|
// reset input
|
||||||
|
selectEl.val('').trigger('change');
|
||||||
|
}
|
||||||
|
function deleteTrainingRow(btn, contactid) {
|
||||||
|
if(confirm('Apakah Anda yakin ingin menghapus data ini?')) {
|
||||||
|
$(btn).closest('tr').remove();
|
||||||
|
|
||||||
|
// Update nomor urut tabel otomatis untuk tampilan
|
||||||
|
$('#training_table tbody tr').each(function(index) {
|
||||||
|
$(this).find('td:first').text(index + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Memasukkan ID yang dihapus ke input hidden 'trainingid_delete'
|
||||||
|
if (contactid > 0) {
|
||||||
|
var d = $('#trainingid_delete');
|
||||||
|
var currentVal = d.val();
|
||||||
|
d.val(currentVal ? currentVal + ',' + contactid : contactid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flatpickr(".trainingdate", { allowInput: true, dateFormat: "Y-m-d" });
|
||||||
|
|
||||||
|
|
||||||
|
$('#formCreateContact').submit(function(e) {
|
||||||
|
// 1. Cegah form melakukan reload halaman bawaan HTML
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// 2. Ambil URL action dan data dari form
|
||||||
|
var url = $(this).attr('action');
|
||||||
|
var formData = $(this).serialize();
|
||||||
|
|
||||||
|
// 3. Kirim data ke controller menggunakan AJAX POST
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: url,
|
||||||
|
data: formData,
|
||||||
|
success: function(response) {
|
||||||
|
// Tutup modal dan bersihkan isian formnya
|
||||||
|
$('#createContactModal').modal('hide');
|
||||||
|
$('#formCreateContact')[0].reset();
|
||||||
|
|
||||||
|
// Tampilkan pesan sukses
|
||||||
|
alert('Contact berhasil ditambahkan!');
|
||||||
|
|
||||||
|
// --- INI BAGIAN REFRESH-NYA ---
|
||||||
|
var siteid = $('#siteid').val();
|
||||||
|
var current_actid = $('#current_actid').val();
|
||||||
|
|
||||||
|
// Siapkan format url untuk current_actid (sama seperti logika sebelumnya)
|
||||||
|
if (current_actid !== '' && current_actid !== undefined) {
|
||||||
|
current_actid = '/' + current_actid;
|
||||||
|
} else {
|
||||||
|
current_actid = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jalankan ulang $.get milikmu khusus untuk training_form
|
||||||
|
if(siteid !== '') {
|
||||||
|
$.get("<?=base_url();?>/activities/getsitecontact/" + siteid + current_actid, function(data) {
|
||||||
|
$('#training_form').html(data);
|
||||||
|
|
||||||
|
// Re-inisialisasi select2 agar tampilannya kembali rapi
|
||||||
|
$('.select2').select2({
|
||||||
|
theme: 'bootstrap-5',
|
||||||
|
width: '100%'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
alert('Terjadi kesalahan saat menyimpan data!');
|
||||||
|
console.error(xhr.responseText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@ -3,209 +3,166 @@
|
|||||||
<?= $this->section('content') ?>
|
<?= $this->section('content') ?>
|
||||||
|
|
||||||
<div class="page-wrapper">
|
<div class="page-wrapper">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row page-titles">
|
<div class="row page-titles">
|
||||||
<div class="col-md-5 align-self-center">
|
<div class="col-md-5 align-self-center">
|
||||||
<h4 class="text-themecolor">Certificates Training Management</h4>
|
<h4 class="text-themecolor">Certificates Training Management</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<div class="col-12 mb-3">
|
<div class="col-12 mb-3">
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
||||||
<input type="text" id="searchInput" class="form-control"
|
<input type="text" id="searchInput" class="form-control"
|
||||||
placeholder="Search certificates by name, product, type, vendor, or dates...">
|
placeholder="Search certificates by name, product, type, vendor, or dates...">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 mb-2">
|
<div class="col-md-4 mb-2">
|
||||||
<select id="statusFilter" class="form-select form-select-sm">
|
<select id="productFilter" class="form-select form-select-sm">
|
||||||
<option value="">All Status</option>
|
<option value="">--Product Filter--</option>
|
||||||
<option value="active">Active</option>
|
<option value="tms">TMS</option>
|
||||||
<option value="expired">Expired</option>
|
<option value="jokoh">Jokoh</option>
|
||||||
<option value="expiring">Expiring Soon</option>
|
<option value="mindray">Mindray</option>
|
||||||
<option value="isval">Need Validation</option>
|
</select>
|
||||||
</select>
|
</div>
|
||||||
</div>
|
<div class="col-md-4 mb-2">
|
||||||
<div class="col-md-4 mb-2">
|
<select id="validationFilter" class="form-select form-select-sm">
|
||||||
<select id="typeFilter" class="form-select form-select-sm">
|
<option value="">--Validation Filter--</option>
|
||||||
<option value="">All Types</option>
|
<option value="valid">Validated</option>
|
||||||
<option value="tms">TMS</option>
|
<option value="unval">Unvalidated</option>
|
||||||
<option value="joko">Jokoh</option>
|
</select>
|
||||||
<option value="boeki">Tokyo Boeki</option>
|
</div>
|
||||||
</select>
|
<div class="col-md-4 mb-2">
|
||||||
</div>
|
<button onclick="resetFilters()" class="btn btn-secondary btn-sm w-100">
|
||||||
<div class="col-md-4 mb-2">
|
<i class="fas fa-redo"></i> Reset Filters
|
||||||
<button onclick="resetFilters()" class="btn btn-secondary btn-sm w-100">
|
</button>
|
||||||
<i class="fas fa-redo"></i> Reset Filters
|
</div>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- TABLE -->
|
|
||||||
<div class="table-responsive" style="width: 100%;">
|
<div class="table-responsive" style="width: 100%;">
|
||||||
<table id="certificatesTable" class="table table-striped table-hover border" style="width: 100%;">
|
<table id="certificatesTable" class="table table-striped table-hover border" style="width: 100%;">
|
||||||
<thead class="table-primary">
|
<thead class="table-primary">
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width:20%">Certificate Name</th>
|
<th style="width: 32%">Certificate</th>
|
||||||
<th style="width:20%">Product/Equipment</th>
|
<th style="width: 38%">Act Report</th>
|
||||||
<th style="width:20%">Activity Report</th>
|
<th style="width: 10%">Issue Date</th>
|
||||||
<th style="width:10%">Issue Date</th>
|
<th style="width: 8%">Validation</th>
|
||||||
<th style="width:10%">Expiry Date</th>
|
<th class="text-center" style="width: 12%">Action</th>
|
||||||
<th style="width:10%">Status</th>
|
|
||||||
<th class="text-center" style="width:10%">Action</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Validate Modal -->
|
|
||||||
<div class="modal fade" id="validateModal" tabindex="-1" aria-labelledby="validateModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog modal-xl modal-dialog-centered">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header bg-warning text-dark">
|
|
||||||
<h5 class="modal-title" id="validateModalLabel">
|
|
||||||
<i class="fa-solid fa-check-double"></i> Validate Certificate
|
|
||||||
</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal"
|
|
||||||
aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<label class="form-label fw-bold">Certificate ID</label>
|
|
||||||
<p id="modalCertId" class="form-control-plaintext">-</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<label class="form-label fw-bold">Certificate Name</label>
|
|
||||||
<p id="modalCertName" class="form-control-plaintext">-</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<label class="form-label fw-bold">Product/Equipment</label>
|
|
||||||
<p id="modalProductName" class="form-control-plaintext">-</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<label class="form-label fw-bold">Serial Number</label>
|
|
||||||
<p id="modalProductNumber" class="form-control-plaintext">-</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<label class="form-label fw-bold">Issue Date</label>
|
|
||||||
<p id="modalIssueDate" class="form-control-plaintext">-</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<label class="form-label fw-bold">Expiry Date</label>
|
|
||||||
<p id="modalExpiryDate" class="form-control-plaintext">-</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<label class="form-label fw-bold">Vendor</label>
|
|
||||||
<p id="modalVendor" class="form-control-plaintext">-</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<label class="form-label fw-bold">Activity Report</label>
|
|
||||||
<p id="modalExpiryDate" class="form-control-plaintext">
|
|
||||||
<a href="javascript:void(0)" class="activity-report-link text-decoration-none" data-certid="${certid}" style="color:#d43215b0;">Act ID - Nama AR - Nama User <i class="fa-solid fa-up-right-from-square"></i></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='row mb-3'>
|
|
||||||
<label class='form-label fw-bold'>User Analyst yang ditraining</label>
|
|
||||||
<div class='table-responsive'>
|
|
||||||
<table class='table table-bordered table-sm'>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style='width:10%'>No</th>
|
|
||||||
<th style='width:45%'>Nama</th>
|
|
||||||
<th style='width:45%'>Tanggal</th>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id='training-table'>
|
|
||||||
<tr>
|
|
||||||
<td>1</td>
|
|
||||||
<td>Ahmad Fauzi</td>
|
|
||||||
<td>2024-01-15</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>2</td>
|
|
||||||
<td>Budi Santoso</td>
|
|
||||||
<td>2024-01-16</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>3</td>
|
|
||||||
<td>Citra Dewi</td>
|
|
||||||
<td>2024-01-17</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>4</td>
|
|
||||||
<td>Dian Pratama</td>
|
|
||||||
<td>2024-01-18</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>5</td>
|
|
||||||
<td>Eko Wijaya</td>
|
|
||||||
<td>2024-01-19</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-warning">
|
</div>
|
||||||
<i class="fa-solid fa-info-circle"></i>
|
</div>
|
||||||
<strong>Validation Information:</strong> Please review the certificate details above before validating. Once validated, the certificate status will change from "Need Validation" to "Active".
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="modal fade" id="validateModal" tabindex="-1" aria-labelledby="validateModalLabel" aria-hidden="true">
|
||||||
<div class="col-md-12 mb-3">
|
<div class="modal-dialog modal-xl modal-dialog-centered">
|
||||||
<label class="form-label fw-bold">Certificate Preview</label>
|
<div class="modal-content">
|
||||||
<div class="border rounded p-2" style="height: 500px; overflow: hidden;">
|
<div class="modal-header bg-warning text-dark" id='modalHeader'>
|
||||||
<iframe id="certificatePreview" src="" style="width: 100%; height: 100%; border: none;"></iframe>
|
<h5 class="modal-title" id="validateModalLabel">
|
||||||
</div>
|
Validate Training Certificate
|
||||||
</div>
|
</h5>
|
||||||
</div>
|
<button type="button" class="btn-close" data-bs-dismiss="modal"
|
||||||
|
aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row border-bottom mb-3 pb-2">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<label class="form-label "><i class="fa-solid fa-certificate me-2"></i>Certificate Name</label>
|
||||||
|
<h5 id="modalCertName" class="mt-2 fw-bolder">-</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 text-md-end">
|
||||||
|
<h5 id="modalValidation">-</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
<div class="row">
|
||||||
<div class="modal-footer">
|
<div class="col-md-6 mb-3">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
<label class="form-label "><i class="fa-solid fa-book-medical me-2"></i>Certificate Number</label>
|
||||||
<i class="fa-solid fa-times"></i> Cancel
|
<p id="modalCertNumber" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||||
</button>
|
</div>
|
||||||
<button type="button" class="btn btn-warning text-dark" id="confirmValidateBtn">
|
<div class="col-md-6 mb-3">
|
||||||
<i class="fa-solid fa-check"></i> Validate Certificate
|
<label class="form-label "><i class="fa-solid fa-microchip me-2"></i>Product/Equipment</label>
|
||||||
</button>
|
<p id="modalProductName" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-md-6 mb-3">
|
||||||
</div>
|
<label class="form-label "><i class="fa-solid fa-hashtag me-2"></i>Serial Number</label>
|
||||||
|
<p id="modalProductNumber" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label "><i class="fa-regular fa-hospital me-2"></i>Site</label>
|
||||||
|
<p id="modalSiteName" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label "><i class="fa-solid fa-calendar-check me-2"></i>Analyst Name</label>
|
||||||
|
<p id="modalAnalystName" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label "><i class="fa-solid fa-calendar-check me-2"></i>Issue Date</label>
|
||||||
|
<p id="modalIssueDate" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-12 mb-4">
|
||||||
|
<label class="form-label "><i class="fa-solid fa-file-lines me-2"></i>Activity Report Reference</label>
|
||||||
|
<a href="javascript:void(0)" id="modalActivityLink" class="activity-report-link text-decoration-none fw-bolder" style="color:#d43215b0;">
|
||||||
|
<div class="p-2 border rounded bg-light">
|
||||||
|
<i class="fa-solid fa-up-right-from-square me-2"></i>
|
||||||
|
<span id="modalActivity">-</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4 mb-3">
|
||||||
|
<label class="form-label"><i class="fa-solid fa-user me-2"></i>Owner Validation</label>
|
||||||
|
<p id="modalValOwner" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 mb-3">
|
||||||
|
<label class="form-label"><i class="fa-solid fa-user me-2"></i>SPV Validation</label>
|
||||||
|
<p id="modalValSpv" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 mb-3">
|
||||||
|
<label class="form-label"><i class="fa-solid fa-user me-2"></i>Manager Validation</label>
|
||||||
|
<p id="modalValManager" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id='modalInfo'></div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 mb-3">
|
||||||
|
<div class="border rounded p-2" style="height: 500px; overflow: hidden;">
|
||||||
|
<iframe id="certificatePreview" src="" style="width: 100%; height: 100%; border: none;"></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||||
|
<i class="fa-solid fa-times"></i> Cancel
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-warning text-dark" id="confirmValidateBtn">
|
||||||
|
<i class="fa-solid fa-check"></i> Validate Certificate
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?= $this->endSection() ?>
|
<?= $this->endSection() ?>
|
||||||
|
|
||||||
<?= $this->section('style') ?>
|
<?= $this->section('style') ?>
|
||||||
<style>
|
|
||||||
#certificatesTable {
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
#certificatesTable_wrapper {
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<?= $this->endSection() ?>
|
<?= $this->endSection() ?>
|
||||||
|
|
||||||
<?= $this->section('script') ?>
|
<?= $this->section('script') ?>
|
||||||
@ -213,7 +170,7 @@
|
|||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
let table = $('#certificatesTable').DataTable({
|
let table = $('#certificatesTable').DataTable({
|
||||||
order: [[5, 'asc']],
|
order: [[3, 'asc']], // Order by Validation Column
|
||||||
pageLength: 25,
|
pageLength: 25,
|
||||||
dom: '<"row"<"col-md-6"l>>rtip',
|
dom: '<"row"<"col-md-6"l>>rtip',
|
||||||
responsive: true,
|
responsive: true,
|
||||||
@ -224,53 +181,43 @@ $(function () {
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(result => {
|
.then(result => {
|
||||||
callback({
|
callback({
|
||||||
data: result.map(cert => {
|
data: result.map((cert, index) => {
|
||||||
let certid = cert.certid || '';
|
|
||||||
let certname = cert.certname || '-';
|
let certid = cert.cert_id || '';
|
||||||
let productname = cert.productname || '-';
|
let certname = cert.cert_name || '-';
|
||||||
let productnumber = cert.productnumber || '';
|
let certnumber = cert.cert_number || '';
|
||||||
let issuedateRaw = cert.issuedate || '';
|
let actid = cert.actid || '';
|
||||||
let expirydateRaw = cert.expirydate || '';
|
let issuedateRaw = cert.issued_date || '';
|
||||||
let vendor = cert.vendor || '-';
|
let status = cert.status; // Validation status
|
||||||
let isval = cert.isval || null;
|
let fullname = cert.fullname;
|
||||||
|
let activity_subject = cert.activity_subject;
|
||||||
|
|
||||||
let issuedate = '-';
|
let issuedate = '-';
|
||||||
let expirydate = '-';
|
let validationBadge = '';
|
||||||
let statusBadge = '<span class="badge bg-warning text-dark">Need Validation</span>';
|
|
||||||
|
|
||||||
if (isval != null) {
|
if (issuedateRaw && issuedateRaw !== '0000-00-00') {
|
||||||
if (issuedateRaw && issuedateRaw !== '0000-00-00') {
|
let date = new Date(issuedateRaw);
|
||||||
issuedate = new Date(issuedateRaw).toLocaleDateString('en-US', { month: 'short', day: '2-digit', year: 'numeric' });
|
let day = String(date.getDate()).padStart(2, '0');
|
||||||
}
|
let month = date.toLocaleString('en-US', { month: 'short' });
|
||||||
|
let year = date.getFullYear();
|
||||||
|
issuedate = `${day} ${month} ${year}`;
|
||||||
|
}
|
||||||
|
|
||||||
if (expirydateRaw && expirydateRaw !== '0000-00-00') {
|
if (status == 'unvalidated') {
|
||||||
expirydate = new Date(expirydateRaw).toLocaleDateString('en-US', { month: 'short', day: '2-digit', year: 'numeric' });
|
validationBadge = '<div class=""><span class="badge bg-warning text-dark">unvalidated</span></div>';
|
||||||
let today = new Date();
|
} else {
|
||||||
let expiryDate = new Date(expirydateRaw);
|
validationBadge = '<div class=""><span class="badge bg-success">validated</span></div>';
|
||||||
let days = Math.ceil((expiryDate - today) / (1000 * 60 * 60 * 24));
|
|
||||||
|
|
||||||
if (days < 0) {
|
|
||||||
statusBadge = '<span class="badge bg-danger">Expired</span>';
|
|
||||||
} else if (days <= 30) {
|
|
||||||
statusBadge = '<span class="badge bg-info">Expiring Soon</span>';
|
|
||||||
} else {
|
|
||||||
statusBadge = '<span class="badge bg-success">Active</span>';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
statusBadge = '<span class="badge bg-secondary">N/A</span>';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
`<strong>${certname}</strong><br><small class="text-muted">ID: ${certid}</small>`,
|
`<strong>${certname}</strong><br><small class="text-muted">Cert# : ${certnumber}</small>`,
|
||||||
`${productname}${productnumber ? '<br><small class="text-muted">SN: ' + productnumber + '</small>' : ''}`,
|
`<a href="javascript:void(0)" class="activity-report-link text-decoration-none" data-certid="${certid}" data-actid="${actid}" style="color:#d43215b0;">#${actid} - ${activity_subject} <i class="fa-solid fa-up-right-from-square"></i></strong><br><small class="text-muted">Owner : ${fullname}</small></a>`,
|
||||||
`<a href="javascript:void(0)" class="activity-report-link text-decoration-none" data-certid="${certid}" style="color:#d43215b0;">Act ID - Nama AR - Nama User <i class="fa-solid fa-up-right-from-square"></i></a>`,
|
|
||||||
issuedate,
|
issuedate,
|
||||||
expirydate,
|
validationBadge,
|
||||||
statusBadge,
|
status == 'unvalidated'
|
||||||
isval == null
|
? `<div class="text-center"><button type="button" class="btn btn-sm btn-warning text-dark btn-validate-modal" data-certid="${certid}"><i class="fa-solid fa-triangle-exclamation me-2"></i>Need Validation</button></div>`
|
||||||
? `<div class="text-center"><button type="button" class="btn btn-warning text-dark btn-validate" data-certid="${certid}" data-certname="${certname}" data-productname="${productname}" data-productnumber="${productnumber}" data-issuedate="${issuedate}" data-expirydate="${expirydate}" data-vendor="${vendor}"><i class="fa-solid fa-check-double"></i></button></div>`
|
: `<div class="text-center mb-1"><button type="button" class="btn btn-sm btn-info btn-validate-modal" data-certid="${certid}"><i class="fa-regular fa-eye me-2"></i>Detail</button></div>
|
||||||
: `<div class="text-center"><button type="button" class="btn btn-success btn-view" data-certid="${certid}"><i class="fa-regular fa-file-pdf"></i></button></div>`
|
<div class="text-center"><button type="button" class="btn btn-sm btn-success btn-view" data-certnumber="${certnumber}"><i class="fa-regular fa-file-pdf me-2"></i>Generated PDF</button></div>`
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -280,19 +227,26 @@ $(function () {
|
|||||||
callback({ data: [] });
|
callback({ data: [] });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
columnDefs: [{
|
columnDefs: [
|
||||||
targets: 5,
|
{
|
||||||
render: function (data, type) {
|
// Kondisi untuk Kolom 3 (Validation)
|
||||||
if (type === 'sort') {
|
targets: 3,
|
||||||
if (data.includes('Need Validation')) return 1;
|
render: function (data, type) {
|
||||||
if (data.includes('Expired')) return 2;
|
if (type === 'sort') {
|
||||||
if (data.includes('Expiring Soon')) return 3;
|
let val = data.toLowerCase();
|
||||||
if (data.includes('Active')) return 4;
|
if (val.includes('unvalidated')) return 1;
|
||||||
return 5;
|
if (val.includes('validated')) return 2;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
return data;
|
},
|
||||||
|
{
|
||||||
|
// Kondisi untuk Kolom 4 (Action)
|
||||||
|
targets: [4],
|
||||||
|
orderable: false
|
||||||
}
|
}
|
||||||
}]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#certificatesTable_filter').hide();
|
$('#certificatesTable_filter').hide();
|
||||||
@ -303,70 +257,111 @@ $(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Type filter using DataTables column filter
|
// Type filter using DataTables column filter
|
||||||
$('#typeFilter').on('change', function () {
|
$('#productFilter').on('change', function () {
|
||||||
let type = $(this).val();
|
let type = $(this).val();
|
||||||
|
|
||||||
// Filter by type column (index 1 - Certificate Name contains type info)
|
|
||||||
if (type === '') {
|
if (type === '') {
|
||||||
table.column(1).search('').draw();
|
table.column(0).search('').draw();
|
||||||
} else {
|
} else {
|
||||||
// Capitalize first letter for search
|
|
||||||
let typeText = type.charAt(0).toUpperCase() + type.slice(1);
|
let typeText = type.charAt(0).toUpperCase() + type.slice(1);
|
||||||
table.column(1).search(typeText).draw();
|
table.column(0).search(typeText).draw();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Status filter
|
$('#validationFilter').on('change', function () {
|
||||||
$('#statusFilter').on('change', function () {
|
let validation = $(this).val();
|
||||||
let map = {
|
if (validation === '') {
|
||||||
active: 'Active',
|
table.column(3).search('').draw();
|
||||||
expired: 'Expired',
|
} else if (validation === 'unval') {
|
||||||
expiring: 'Expiring Soon',
|
table.column(3).search('unv').draw();
|
||||||
isval: 'Need Validation'
|
} else if (validation === 'valid') {
|
||||||
};
|
table.column(3).search('^validated$', true, false).draw();
|
||||||
table.column(5).search(map[this.value] || '').draw();
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
window.resetFilters = function () {
|
window.resetFilters = function () {
|
||||||
$('#searchInput, #statusFilter').val('');
|
$('#searchInput, #productFilter, #validationFilter').val('');
|
||||||
table.search('').columns().search('').order([5,'asc']).draw();
|
table.search('').columns().search('').draw();
|
||||||
};
|
};
|
||||||
|
|
||||||
// View PDF
|
// View PDF
|
||||||
$(document).on('click', '.btn-view', function () {
|
$(document).on('click', '.btn-view', function () {
|
||||||
let certid = $(this).data('certid');
|
let certnumber = $(this).data('certnumber');
|
||||||
window.open('<?= base_url('certificates/training/show/') ?>' + certid, '_blank');
|
window.open('<?= base_url('certificates/number/') ?>' + certnumber, '_blank');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Activity report
|
// Activity report
|
||||||
$(document).on('click', '.activity-report-link', function () {
|
$(document).on('click', '.activity-report-link', function () {
|
||||||
let certid = $(this).data('certid');
|
let actid = $(this).data('actid');
|
||||||
window.open(
|
window.open(
|
||||||
'<?= base_url('certificates/training/activity/') ?>' + certid,
|
'<?= base_url('activities/detail/') ?>' + actid,
|
||||||
'_blank',
|
'_blank',
|
||||||
'width=1200,height=800,scrollbars=yes,resizable=yes'
|
'width=1200,height=800,scrollbars=yes,resizable=yes'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Open modal
|
// Open modal
|
||||||
$(document).on('click', '.btn-validate', function () {
|
$(document).on('click', '.btn-validate-modal', function () {
|
||||||
|
|
||||||
let btn = $(this);
|
let btn = $(this);
|
||||||
|
let certid = btn.data('certid');
|
||||||
|
|
||||||
$('#modalCertId').text(btn.data('certid'));
|
// POST API call to fetch certificate data
|
||||||
$('#modalCertName').text(btn.data('certname'));
|
$.post(
|
||||||
$('#modalProductName').text(btn.data('productname'));
|
'<?= base_url('certificates/api/showtraining') ?>',
|
||||||
$('#modalProductNumber').text(btn.data('productnumber'));
|
{ certid },
|
||||||
$('#modalIssueDate').text(btn.data('issuedate'));
|
function (data) {
|
||||||
$('#modalExpiryDate').text(btn.data('expirydate'));
|
|
||||||
$('#modalVendor').text(btn.data('vendor'));
|
|
||||||
|
|
||||||
$('#confirmValidateBtn').data('certid', btn.data('certid'));
|
// console.log(data);
|
||||||
$('#certificatePreview').attr(
|
$('#modalCertName').text(data.cert_name || '-');
|
||||||
'src',
|
$('#modalCertNumber').text(data.cert_number || '-');
|
||||||
'<?= base_url('certificates/training/show/') ?>' + btn.data('certid')
|
$('#modalProductName').text(data.productname || '-');
|
||||||
);
|
$('#modalProductNumber').text(data.productnumber || '-');
|
||||||
|
$('#modalIssueDate').text(data.issued_date || '-');
|
||||||
|
$('#modalAnalystName').text(data.fullname || '-');
|
||||||
|
$('#modalSiteName').text(data.sitename || '-');
|
||||||
|
|
||||||
|
// Cek status validasi
|
||||||
|
const isValid = data.status === 'validated';
|
||||||
|
const theme = isValid ? 'success' : 'warning';
|
||||||
|
const icon = isValid ? 'fa-regular fa-circle-check' : 'fa-solid fa-triangle-exclamation';
|
||||||
|
const note = isValid
|
||||||
|
? 'Sertifikat Sudah Divalidasi'
|
||||||
|
: 'Review data berikut dengan teliti, setelah divalidasi maka sertifikat akan dinyatakan <strong>Valid</strong> dan <strong>sah secara sistem.</strong>';
|
||||||
|
|
||||||
|
$('#modalHeader').removeClass('bg-warning bg-success').addClass(`bg-${theme} text-dark`);
|
||||||
|
$('#modalValidation').html(
|
||||||
|
`<span class="badge bg-${theme} text-dark py-2 px-3">
|
||||||
|
<i class="${icon} me-2"></i>${data.status || '-'}
|
||||||
|
</span>`
|
||||||
|
);
|
||||||
|
|
||||||
|
$('#modalInfo').html(
|
||||||
|
`<div class="alert alert-${theme} border-0 shadow-sm d-flex align-items-center">
|
||||||
|
<i class="${icon} fs-4 me-3"></i>
|
||||||
|
<div>
|
||||||
|
<strong>Validation Note:</strong><br>
|
||||||
|
${note}
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
);
|
||||||
|
|
||||||
|
$('#modalActivity').text(data.actid ? `#${data.actid} - ${data.subject || '-'}` : '-');
|
||||||
|
$('#modalActivityLink').attr('data-actid', data.actid || '');
|
||||||
|
$('#modalValOwner').html(data.user_validation_at ? `${data.username} - ${data.user_validation_at}<i class="fa-solid fa-circle-check text-success ms-2"></i>` : '-');
|
||||||
|
$('#modalValSpv').html(data.spv_validation_at ? `${data.spvname} - ${data.spv_validation_at}<i class="fa-solid fa-circle-check text-success ms-2"></i>` : '-');
|
||||||
|
$('#modalValManager').html(data.manager_validation_at ? `${data.managername} - ${data.manager_validation_at}<i class="fa-solid fa-circle-check text-success ms-2"></i>` : '-');
|
||||||
|
},
|
||||||
|
'json'
|
||||||
|
).fail(function (xhr) {
|
||||||
|
console.log(xhr);
|
||||||
|
alert(xhr.responseText);
|
||||||
|
});
|
||||||
|
|
||||||
|
// INI JANGAN DIUBAH
|
||||||
|
$('#confirmValidateBtn').data('certid', certid);
|
||||||
|
$('#certificatePreview').attr('src','<?= base_url('certificates/training/show/') ?>' + certid);
|
||||||
|
|
||||||
$('#validateModal').modal('show');
|
$('#validateModal').modal('show');
|
||||||
});
|
});
|
||||||
@ -379,63 +374,25 @@ $(function () {
|
|||||||
if (!confirm('Are you sure?')) return;
|
if (!confirm('Are you sure?')) return;
|
||||||
|
|
||||||
$.post(
|
$.post(
|
||||||
'<?= base_url('certificates/api/validateCertificate') ?>',
|
'<?= base_url('certificates/api/validatecertificate') ?>',
|
||||||
{ certid, certificateType},
|
{ certid, certificateType},
|
||||||
function (response) {
|
function (response) {
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
$('#validateModal').modal('hide');
|
$('#validateModal').modal('hide');
|
||||||
alert(response.message);
|
alert(response.message);
|
||||||
|
location.reload();
|
||||||
// Generate and save PDF after successful validation
|
|
||||||
$.post(
|
|
||||||
'<?= base_url('certificates/api/generatepdf') ?>',
|
|
||||||
{ certid, certificateType },
|
|
||||||
function (pdfResponse) {
|
|
||||||
if (pdfResponse.success) {
|
|
||||||
alert('PDF generated and saved successfully!');
|
|
||||||
location.reload();
|
|
||||||
} else {
|
|
||||||
alert('Validation successful but PDF generation failed: ' + (pdfResponse.message || 'Unknown error'));
|
|
||||||
location.reload();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'json'
|
|
||||||
).fail(function () {
|
|
||||||
alert('Validation successful but failed to generate PDF');
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
alert(response.message || 'Validation failed');
|
alert(response.message || 'Validation failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
}, 'json'
|
}, 'json'
|
||||||
).fail(function () {
|
).fail(function (xhr) {
|
||||||
$('#validateModal').modal('hide');
|
console.log(xhr);
|
||||||
alert('Server error.');
|
alert(xhr.responseText);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Delete training user
|
|
||||||
window.deleteTrainingUser = function(btn) {
|
|
||||||
if(confirm('Are you sure you want to delete this user?')) {
|
|
||||||
var row = btn.closest('tr');
|
|
||||||
row.remove();
|
|
||||||
updateRowNumbers();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update row numbers after deletion
|
|
||||||
function updateRowNumbers() {
|
|
||||||
var tbody = $('#training-table');
|
|
||||||
var rows = tbody.find('tr');
|
|
||||||
rows.each(function(index) {
|
|
||||||
$(this).find('td:first').text(index + 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<?= $this->endSection() ?>
|
<?= $this->endSection() ?>
|
||||||
@ -2,14 +2,15 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Maintenance Certificate - <?= $certificate['certname'] ?></title>
|
<title><?= $certificate['certname'] ?></title>
|
||||||
<style>
|
<style>
|
||||||
@page {
|
@page {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
font-family: Arial;
|
/* font-family: Arial; */
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
/* font-size: 12px; */
|
/* font-size: 12px; */
|
||||||
@ -42,6 +43,18 @@
|
|||||||
color:#336600;
|
color:#336600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin :0;
|
||||||
|
padding:0;
|
||||||
|
color:#336600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.instrument-font {
|
||||||
|
margin :0;
|
||||||
|
padding:0;
|
||||||
|
color:black;
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -51,16 +64,17 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-top: 230px;
|
margin-top: 235px;
|
||||||
margin-bottom: 25px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
.site-name {
|
.site-name {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 55px;
|
margin-bottom: 40px;
|
||||||
}
|
}
|
||||||
.detail-information {
|
.detail-information {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 67px;
|
/* margin-bottom: 137px; */
|
||||||
|
margin-bottom: 26px;
|
||||||
}
|
}
|
||||||
h4 {
|
h4 {
|
||||||
margin :0;
|
margin :0;
|
||||||
@ -73,12 +87,11 @@
|
|||||||
.signature-table {
|
.signature-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin-left: 17%;
|
margin-bottom: 20px;
|
||||||
margin-bottom: 0px;
|
|
||||||
}
|
}
|
||||||
.signature-table td {
|
.signature-table td {
|
||||||
width: 50%; /* Membagi dua sisi sama rata */
|
width: 50%; /* Membagi dua sisi sama rata */
|
||||||
text-align: left;
|
text-align: center;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
.name {
|
.name {
|
||||||
@ -98,57 +111,104 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<!-- Untuk DEV -->
|
||||||
|
<!-- <div class="bg-container">
|
||||||
|
<img src="<?=base_url();?>/assets/images/background_certificate/maintenance.jpeg">
|
||||||
|
</div> -->
|
||||||
|
|
||||||
<?php for($i=0; $i<$count; $i++) : ?>
|
<!-- Untuk PROD -->
|
||||||
|
<div class="bg-container">
|
||||||
|
<?php $bgPath = FCPATH . 'assets/images/background_certificate/maintenance.jpeg'; ?>
|
||||||
|
<img src="<?php echo($bgPath) ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="instument-name">
|
<div class="instument-name">
|
||||||
<h1> <<Nama Analis>> </h1>
|
<h1><?= $certificate['fullname'] ?><?= $certificate['title'] ?></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="site-name">
|
<div class="site-name">
|
||||||
<h1> at <<Nama Rumah Sakit / Laboratorium - Kota>> </h1>
|
<h2> <?= $certificate['sitename'] ?> ~ <?= $certificate['city'] ?></h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="detail-information">
|
<div class="detail-information">
|
||||||
<h4>In Recording of Participation and Successful</h4>
|
<!-- <h4>Serial Number: <?= $certificate['productnumber'] ?></h4> -->
|
||||||
<h4>Completion of Mindray Hematology Analyzer Training</h4>
|
|
||||||
<h2>BC5140</h2>
|
<!-- <h4>has completed through a series of <?= $certificate['certtype'] ?></h4> -->
|
||||||
<h3>Date : February 05, 2026</h3>
|
<h3>In Recording of Participation and Successful Completion of</h3>
|
||||||
|
<h3>User Training</h3>
|
||||||
|
<h2 class='instrument-font'><?= $certificate['productname'] ?></h2>
|
||||||
|
<h3>Date: <?= $certificate['issueddate'] ?></h3>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="signature-table">
|
<table class="signature-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<span class="name"><br></span>
|
<img src="<?= $certificate['qrcode'] ?>">
|
||||||
<span class="name"><br></span>
|
</td>
|
||||||
<span class="name"><br></span>
|
<!-- <td>
|
||||||
<span class="name"><br></span>
|
|
||||||
<span class="name">Adhitya Pranata Putra</span>
|
<span class="name">Adhitya Pranata Putra</span>
|
||||||
<span class="position">Technical Support Manager</span>
|
<span class="position">Technical Support Manager</span>
|
||||||
</td>
|
</td> -->
|
||||||
|
|
||||||
<td>
|
<!-- <td>
|
||||||
<span class="position">Trainer,</span>
|
<span class="name"></span>
|
||||||
<span class="name"><br></span>
|
<span class="position"></span>
|
||||||
<span class="name"><br></span>
|
</td> -->
|
||||||
<span class="name"><br></span>
|
|
||||||
<span class="name"><<Nama TSO>></span>
|
|
||||||
<span class="position"><<Jabatan>></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div class="fo-wrapper">
|
<div class="fo-wrapper">
|
||||||
<p><<FO>></p>
|
<p>FO.III.12/14.00/2020</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-container">
|
<!-- Untuk Tanda Export PDF atau tidak -->
|
||||||
<img src="<?=base_url();?>/assets/images/background_certificate/maintenance.jpeg">
|
<?php if (!isset($certificate['exportToPDF'])) : ?>
|
||||||
|
<div class="container">
|
||||||
|
<div class="instument-name">
|
||||||
|
<h1><?= $certificate['fullname'] ?><?= $certificate['title'] ?></h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="site-name">
|
||||||
|
<h2> <?= $certificate['sitename'] ?> ~ <?= $certificate['city'] ?></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-information">
|
||||||
|
<!-- <h4>Serial Number: <?= $certificate['productnumber'] ?></h4> -->
|
||||||
|
|
||||||
|
<!-- <h4>has completed through a series of <?= $certificate['certtype'] ?></h4> -->
|
||||||
|
<h3>In Recording of Participation and Successful Completion of</h3>
|
||||||
|
<h3>User Training</h3>
|
||||||
|
<h2 class='instrument-font'><?= $certificate['productname'] ?></h2>
|
||||||
|
<h3>Date: <?= $certificate['issueddate'] ?></h3>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="signature-table">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img src="<?= $certificate['qrcode'] ?>">
|
||||||
|
</td>
|
||||||
|
<!-- <td>
|
||||||
|
<span class="name">Adhitya Pranata Putra</span>
|
||||||
|
<span class="position">Technical Support Manager</span>
|
||||||
|
</td> -->
|
||||||
|
|
||||||
|
<!-- <td>
|
||||||
|
<span class="name"></span>
|
||||||
|
<span class="position"></span>
|
||||||
|
</td> -->
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="fo-wrapper">
|
||||||
|
<p>FO.III.12/14.00/2020</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<?php endfor ?>
|
<?php endif ?>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -42,11 +42,15 @@
|
|||||||
<ul aria-expanded="false" class="collapse">
|
<ul aria-expanded="false" class="collapse">
|
||||||
<li><a href="<?=base_url();?>certificates/installation">Installation</a></li>
|
<li><a href="<?=base_url();?>certificates/installation">Installation</a></li>
|
||||||
<li><a href="<?=base_url();?>certificates/maintenance">Maintenance</a></li>
|
<li><a href="<?=base_url();?>certificates/maintenance">Maintenance</a></li>
|
||||||
<!-- <li><a href="<?=base_url();?>certificates/training">Training</a></li> -->
|
<li><a href="<?=base_url();?>certificates/training">Training</a></li>
|
||||||
<!-- <li><a href="<?=base_url();?>certificates/calibration">Callibration</a></li> -->
|
<!-- <li><a href="<?=base_url();?>certificates/calibration">Callibration</a></li> -->
|
||||||
<!-- <li><a href="<?=base_url();?>certificates/official-report">Official Report</a></li> -->
|
<!-- <li><a href="<?=base_url();?>certificates/official-report">Official Report</a></li> -->
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<?php if ( !($isTSM || $isPS) ): ?>
|
||||||
|
<li> <a class="waves-effect waves-dark" href='<?=base_url();?>contacts' aria-expanded="false"> <i class="fa-solid fa-address-book"></i><span class="hide-menu">Contact</span></a> </li>
|
||||||
|
<?php endif ?>
|
||||||
|
|
||||||
<li> <a class="waves-effect waves-dark" href='<?=base_url();?>guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li>
|
<li> <a class="waves-effect waves-dark" href='<?=base_url();?>guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li>
|
||||||
<li> <a class="waves-effect waves-dark" href='https://clqms.services-summit.my.id/' aria-expanded="false"> <i class="fa-solid fa-microscope"></i><span class='hide-menu'>CLQMS</span> </a> </li>
|
<li> <a class="waves-effect waves-dark" href='https://clqms.services-summit.my.id/' aria-expanded="false"> <i class="fa-solid fa-microscope"></i><span class='hide-menu'>CLQMS</span> </a> </li>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user