Update Alur

This commit is contained in:
mikael-zakaria 2026-03-08 22:40:36 +07:00
parent 9c3cac52dc
commit b3a577eeac
8 changed files with 379 additions and 144 deletions

View File

@ -294,6 +294,19 @@ class Activities extends Controller {
$results = $query->getResultArray(); $results = $query->getResultArray();
$data['reff'] = $results; $data['reff'] = $results;
} }
// Untuk Sertifikat
$certificatesArray = [];
$certificateModel = new CertificateModel();
$results = $certificateModel->select('cert_type')
->where('actid', $actid)
->findAll();
if (!empty($results)) {
foreach ($results as $row) {
$certificatesArray[] = $row['cert_type'];
}
$data['activities'][0]['cert_types'] = $certificatesArray;
}
$sql = "select actdetailid, acttextid, textvalue from actdetail where actid=$actid order by acttextid, createdate desc"; $sql = "select actdetailid, acttextid, textvalue from actdetail where actid=$actid order by acttextid, createdate desc";
$query = $db->query($sql); $query = $db->query($sql);
@ -450,31 +463,13 @@ class Activities extends Controller {
$query = $db->query($sql); $query = $db->query($sql);
} }
// UNTUK CERTIFICATES
$sql = "SELECT prl.productaliastext as productname, pr.productnumber as snnumber, st.sitename
FROM `activities` act
LEFT JOIN sites st ON st.siteid = act.siteid
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();
if ($this->request->getVar('maintenance')) { // Maintenance
$issuedDate = $data['new_value']['closedate'] ?? null;
$expiredDate = date('Y-m-d', strtotime($issuedDate . ' + 6 months'));
$insertCert = [
'cert_name' => "MC_" . ($result['productname'] ?? 'UNKNOWN') . "_" . ($result['snnumber'] ?? '0') . "_" . $actid,
'cert_type' => "MC",
'actid' => $actid,
'issued_date' => $issuedDate,
'expired_date' => $expiredDate,
'user_id' => $data['new_value']['userid_owner']
];
$certificateModel = new CertificateModel();
$certificateModel->insert($insertCert);
}
// UNTUK CERTIFICATES
if ($this->request->getVar('maintenance')) { // Jika Maintenance Dicentang
$issuedDate = $data['new_value']['closedate'] ?? null;
$userid_owner = $data['new_value']['userid_owner'];
$this->createCertificateMaintenance($actid, $issuedDate, $userid_owner);
}
} else { } else {
// update edit // update edit
@ -549,6 +544,19 @@ class Activities extends Controller {
$query = $db->query($sql); $query = $db->query($sql);
} }
} }
// UNTUK CERTIFICATES
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->updateCertificateMaintenance($actid, $issuedDate, $userid_owner);
} else {
// Hapus softdelete sertifikat
$this->deleteCertificateMaintenance($actid);
}
} }
// act by consumables // act by consumables
@ -1054,7 +1062,17 @@ class Activities extends Controller {
$data['content'] = $this->act_content($actid); $data['content'] = $this->act_content($actid);
$db = \Config\Database::connect(); $db = \Config\Database::connect();
$sql = "select attachment from activities where actid='$actid'";
$sql = "SELECT cert_name,file_url from certificates where actid=$actid AND deleted_at IS NULL";
$query = $db->query($sql);
$result = $query->getResultArray();
if (!empty($result)){
$data['certificates'] = $result;
} else {
$data['certificates'] = [];
}
$sql = "SELECT attachment from activities where actid='$actid'";
$query = $db->query($sql); $query = $db->query($sql);
$result = $query->getResultArray(); $result = $query->getResultArray();
$data['attachment'] = $result[0]; $data['attachment'] = $result[0];
@ -1647,4 +1665,119 @@ class Activities extends Controller {
return view('invtrans_index', $data); return view('invtrans_index', $data);
} }
public function createCertificateMaintenance ($actid, $issuedDate, $userid_owner) {
$db = \Config\Database::connect();
$sql = "SELECT prl.productaliastext as productname, pr.productnumber as snnumber, st.sitename
FROM `activities` act
LEFT JOIN sites st ON st.siteid = act.siteid
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();
$expiredDate = $issuedDate ? date('Y-m-d', strtotime($issuedDate . ' + 6 months')) : null;
$insertCert = [
'cert_name' => "MC_" . ($result['productname'] ?? 'UNKNOWN') . "_" . ($result['snnumber'] ?? '0') . "_" . $actid,
'cert_type' => "MC",
'actid' => $actid,
'issued_date' => $issuedDate,
'expired_date' => $expiredDate,
'user_id' => $userid_owner
];
$certificateModel = new CertificateModel();
$certificateModel->insert($insertCert);
}
public function updateCertificateMaintenance($actid, $issuedDate, $userid_owner) {
$certificateModel = new CertificateModel();
// 1. Cek apakah data sudah ada menggunakan findAll()
$existingCerts = $certificateModel->withDeleted()
->select('status')
->where('actid', $actid)
->findAll();
// Variabel penanda apakah data sudah pernah ada di database
$isDataExist = !empty($existingCerts);
if ($isDataExist) {
// Ambil semua nilai 'status' dari array hasil findAll()
$statuses = array_column($existingCerts, 'status');
// Jika di antara status tersebut ada yang 'validated', hentikan proses
if (in_array('validated', $statuses)) {
return;
}
}
// 2. Definisi $db (Pastikan instance database sudah dipanggil)
$db = \Config\Database::connect();
// Query binding (?) untuk keamanan
$sql = "SELECT prl.productaliastext as productname, pr.productnumber as snnumber, st.sitename
FROM `activities` act
LEFT JOIN sites st ON st.siteid = act.siteid
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 = ?";
$query = $db->query($sql, [$actid]);
$result = $query->getRowArray();
// 3. Setelan Tanggal
$validIssuedDate = $issuedDate;
$expiredDate = $validIssuedDate ? date('Y-m-d', strtotime($validIssuedDate . ' + 6 months')) : null;
// Siapkan Payload
$certPayload = [
'cert_name' => "MC_" . ($result['productname'] ?? 'UNKNOWN') . "_" . ($result['snnumber'] ?? '0') . "_" . $actid,
'cert_type' => "MC",
'actid' => $actid,
'issued_date' => $validIssuedDate,
'expired_date' => $expiredDate,
'user_id' => $userid_owner,
'deleted_at' => null
];
// 4. Logika Insert atau Update menggunakan penanda $isDataExist
if (!$isDataExist) {
// Jika data belum ada sama sekali (array kosong), eksekusi INSERT
$certificateModel->insert($certPayload);
} else {
// Jika data sudah ada, eksekusi UPDATE
// Catatan: Karena bisa ada lebih dari 1 data dengan actid yang sama (karena findAll),
// Update ini akan menimpa semua baris yang punya actid tersebut.
$certificateModel->withDeleted()
->where('actid', $actid)
->set($certPayload)
->update();
}
}
public function deleteCertificateMaintenance($actid) {
$certificateModel = new CertificateModel();
// 1. Cek apakah data sudah ada menggunakan findAll()
$existingCerts = $certificateModel->withDeleted()
->select('status')
->where('actid', $actid)
->findAll();
// Variabel penanda apakah data sudah pernah ada di database
$isDataExist = !empty($existingCerts);
if ($isDataExist) {
// Ambil semua nilai 'status' dari array hasil findAll()
$statuses = array_column($existingCerts, 'status');
// Jika di antara status tersebut ada yang 'validated', hentikan proses
if (in_array('validated', $statuses)) {
return;
}
}
$certificateModel->where('actid', $actid)->delete();
}
} }

View File

@ -503,9 +503,18 @@ class Certificates extends BaseController {
->find($certid); ->find($certid);
if (!empty($checkFinal['user_validation_at']) && if (!empty($checkFinal['user_validation_at']) &&
!empty($checkFinal['spv_validation_at']) && (!empty($checkFinal['spv_validation_at']) ||
!empty($checkFinal['manager_validation_at'])) { !empty($checkFinal['manager_validation_at']))) {
// Check
$checkStatus = $certificateModel->select('status')->find($certid);
if ($checkStatus['status'] == 'validated') {
return $this->response->setJSON([
'success' => true,
'message' => 'Semua validasi telah dilakukan'
]);
}
// Update Status Utama // Update Status Utama
$certificateModel->update($certid, ['status' => 'validated']); $certificateModel->update($certid, ['status' => 'validated']);
@ -514,6 +523,7 @@ class Certificates extends BaseController {
certificates.cert_name, certificates.cert_name,
certificates.issued_date, certificates.issued_date,
certificates.expired_date, certificates.expired_date,
certificates.status,
productcatalog.productname as productname, productcatalog.productname as productname,
sites.sitename as sitename, sites.sitename as sitename,
products.productnumber, products.productnumber,
@ -539,7 +549,9 @@ class Certificates extends BaseController {
->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'left') ->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'left')
->where('certificates.cert_id', $certid) ->where('certificates.cert_id', $certid)
->first(); ->first();
$certificate = [ $certificate = [
'status' => $latestData['status'],
'certname' => $latestData['cert_name'], 'certname' => $latestData['cert_name'],
'sitename' => $latestData['sitename'], 'sitename' => $latestData['sitename'],
'certtype' => $latestData['cert_type'], 'certtype' => $latestData['cert_type'],
@ -547,17 +559,19 @@ class Certificates extends BaseController {
'userposition' => $latestData['user_position'], 'userposition' => $latestData['user_position'],
'productname' => $latestData['productname'], 'productname' => $latestData['productname'],
'productnumber' => $latestData['productnumber'], 'productnumber' => $latestData['productnumber'],
'issueddate' => $latestData['issued_date'], 'issueddate' => date('d-M-Y', strtotime($latestData['issued_date'])),
'expireddate' => $latestData['expired_date'] 'expireddate' => date('d-M-Y', strtotime($latestData['expired_date'])),
'exportToPDF' => true
]; ];
try { try {
$pdfAfterValidation = $this->savePdf($certificate, $latestData['cert_type']); // Simpan ke PDF
$pdfAfterValidation = $this->savePdf($certificate, $latestData['cert_type'], $latestData['cert_number']); // Simpan ke PDF
$certificateModel->update($certid, [ // Update ke tabel certificates $certificateModel->update($certid, [ // Update ke tabel certificates
'file_location' => $pdfAfterValidation['file_relative'], 'file_location' => $pdfAfterValidation['file_relative'],
'metadata_title' => $pdfAfterValidation['metadata_title'], 'metadata_title' => $pdfAfterValidation['metadata_title'],
'metadata_keywords' => $pdfAfterValidation['metadata_keywords'], 'metadata_keywords' => $pdfAfterValidation['metadata_keywords'].";".base_url('certificates/number/'.$latestData['cert_number']),
'file_url' => base_url('certificates/number/'.$latestData['cert_number']) 'file_url' => base_url('certificates/number/'.$latestData['cert_number'])
]); ]);
@ -583,7 +597,7 @@ class Certificates extends BaseController {
return $this->response->setJSON(['success' => false, 'message' => 'Gagal memperbarui data.']); return $this->response->setJSON(['success' => false, 'message' => 'Gagal memperbarui data.']);
} }
public function savePdf($certificate, $certificateType, $productType = null) { public function savePdf($certificate, $certificateType, $cert_number, $productType = null) {
$certificateType = strtolower($certificateType); $certificateType = strtolower($certificateType);
switch ($certificateType) { switch ($certificateType) {
@ -661,7 +675,7 @@ class Certificates extends BaseController {
// Metadata // Metadata
$dompdf->addInfo('Title', $certificate['certname']); $dompdf->addInfo('Title', $certificate['certname']);
$dompdf->addInfo('Keywords', $certificate['certtype'] . ' Certificate'); $dompdf->addInfo('Keywords', $certificate['certtype'] . ' Certificate;'.base_url('certificates/number/'.$cert_number));
// Folder // Folder
$uploadDir = FCPATH . 'upload/documents/' . $subDir; $uploadDir = FCPATH . 'upload/documents/' . $subDir;

View File

@ -16,7 +16,7 @@ class CertificateModel extends Model
'cert_number', 'cert_name', 'cert_type', 'actid', 'issued_date', 'cert_number', 'cert_name', 'cert_type', 'actid', 'issued_date',
'expired_date', 'user_id', 'user_validation_at', 'spv_id', 'expired_date', 'user_id', 'user_validation_at', 'spv_id',
'spv_validation_at', 'manager_id', 'manager_validation_at', 'spv_validation_at', 'manager_id', 'manager_validation_at',
'status', 'file_location', 'file_url', 'metadata_title', 'metadata_keywords' 'status', 'file_location', 'file_url', 'metadata_title', 'metadata_keywords', 'deleted_at'
]; ];
// Timestamps // Timestamps

View File

@ -11,6 +11,12 @@ foreach ($file_array as $value){
echo "<a href='".base_url()."upload/$value' target='_blank'>$value </a><br/>"; echo "<a href='".base_url()."upload/$value' target='_blank'>$value </a><br/>";
$i++; $i++;
} }
$i = 1;
// foreach ($certificates as $value){
// if($i == 1) {echo "<b>Certificates : </b><br/>";}
// echo "<a href='".$value['file_url']."' target='_blank'>".$value['cert_name']."</a><br/>";
// $i++;
// }
echo "<hr/>"; echo "<hr/>";
foreach ($actsend_log as $data) { foreach ($actsend_log as $data) {
$logdate = $data['logdate']; $logdate = $data['logdate'];

View File

@ -3,7 +3,7 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?php <?php
// dd($reff); // dd($cert_types);
$dests = array(); $dests = array();
$origins = array(); $origins = array();
foreach($invcounters as $qdata) { foreach($invcounters as $qdata) {
@ -30,6 +30,7 @@ $productid = '';
$vendorid = ''; $vendorid = '';
$swversion = ''; $swversion = '';
$acttypeid = ''; $acttypeid = '';
$cert_types = [];
$userid_owner = ''; $userid_owner = '';
$activitystatus = 'O'; $activitystatus = 'O';
$actid_ref = $actid_ref ?? 0; // Ini untuk edit dan create biasa $actid_ref = $actid_ref ?? 0; // Ini untuk edit dan create biasa
@ -50,6 +51,9 @@ if(isset($activities)) { $data = $activities[0]; }
if(isset($new_value)) { $data = $new_value; } if(isset($new_value)) { $data = $new_value; }
if(isset($data)) { if(isset($data)) {
// dd($data); // dd($data);
$cert_types = isset($data['cert_types']) && is_array($data['cert_types']) ? $data['cert_types'] : [];
if(isset($data['actid'])) { $productid = $data['productid']; } if(isset($data['actid'])) { $productid = $data['productid']; }
$siteid = $data['siteid']; $siteid = $data['siteid'];
$productid = $data['productid']; $productid = $data['productid'];
@ -211,46 +215,52 @@ if(isset($data)) {
<div class="form-group"> <div class="form-group">
<label class="form-label border-start border-5 border-primary ps-1">Certificate</label> <label class="form-label border-start border-5 border-primary ps-1">Certificate</label>
<div class="row"> <div class="row">
<div class="col-md-6 mb-2"> <div class="col-md-6 mb-2">
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" name="calibration" id="calibration" value="1"> <input class="form-check-input" type="checkbox" name="calibration" id="calibration" value="1" <?= in_array('CC', $cert_types) ? 'checked' : '' ?>>
<label class="form-check-label" for="calibration"> <label class="form-check-label" for="calibration">
Calibration Certificate Calibration Certificate
</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">
<input class="form-check-input" type="checkbox" name="installation" id="installation" value="1"> <input class="form-check-input" type="checkbox" name="installation" id="installation" value="1" <?= in_array('IC', $cert_types) ? 'checked' : '' ?>>
<label class="form-check-label" for="installation"> <label class="form-check-label" for="installation">
Installation Certificate Installation Certificate
</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">
<input class="form-check-input" type="checkbox" name="maintenance" value="1" id="maintenance" > <input class="form-check-input" type="checkbox" name="maintenance" value="1" id="maintenance" <?= in_array('MC', $cert_types) ? 'checked' : '' ?>>
<label class="form-check-label" for="maintenance"> <label class="form-check-label" for="maintenance">
Maintenance Certificate Maintenance Certificate
</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">
<input class="form-check-input" type="checkbox" name="offreport" value="1" id="offreport" > <input class="form-check-input" type="checkbox" name="offreport" value="1" id="offreport" <?= (in_array('BAI', $cert_types) || in_array('BAP', $cert_types)) ? 'checked' : '' ?>>
<label class="form-check-label" for="offreport"> <label class="form-check-label" for="offreport">
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">
<input class="form-check-input" type="checkbox" name="training" value="1" id="training" > <input class="form-check-input" type="checkbox" name="training" value="1" id="training" <?= in_array('UTC', $cert_types) ? 'checked' : '' ?>>
<label class="form-check-label" for="training"> <label class="form-check-label" for="training">
User Training Certificate User Training Certificate
</label> </label>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -786,7 +796,32 @@ $(document).ready(function() {
theme: 'bootstrap-5', theme: 'bootstrap-5',
width: '100%' width: '100%'
}); });
// 2. Logika Aktif/Nonaktif Checkbox
$('#acttypeid').change(function() {
if (this.value == '5') {
$("#maintenance").prop('disabled', false);
$("#calibration").prop('disabled', true);
$("#installation").prop('disabled', true);
$("#offreport").prop('disabled', true);
$("#training").prop('disabled', true);
}
else if (this.value == '3') {
$("#maintenance").prop('disabled', true);
$("#calibration").prop('disabled', false);
$("#installation").prop('disabled', false);
$("#offreport").prop('disabled', false);
$("#training").prop('disabled', false);
}
else {
// Ini akan menjadi default jika #acttypeid kosong atau bukan 5 dan 3
$("#maintenance").prop('disabled', true);
$("#calibration").prop('disabled', true);
$("#installation").prop('disabled', true);
$("#offreport").prop('disabled', true);
$("#training").prop('disabled', true);
}
}).trigger('change');
}); });
// acttext // acttext
@ -947,7 +982,6 @@ $('#status').change(function() {
else { $(".closedate").prop('disabled', false); $("#opendate").prop('disabled', false);} else { $(".closedate").prop('disabled', false); $("#opendate").prop('disabled', false);}
}) })
$("#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); $("#calibration").prop('disabled', true); $("#installation").prop('disabled', true); $("#offreport").prop('disabled', true); $("#training").prop('disabled', true);} if (this.value=='5'){ $("#maintenance").prop('disabled', false); $("#calibration").prop('disabled', true); $("#installation").prop('disabled', true); $("#offreport").prop('disabled', true); $("#training").prop('disabled', true);}
else if (this.value=='3'){ $("#maintenance").prop('disabled', true); $("#calibration").prop('disabled', false); $("#installation").prop('disabled', false); $("#offreport").prop('disabled', false); $("#training").prop('disabled', false); } else if (this.value=='3'){ $("#maintenance").prop('disabled', true); $("#calibration").prop('disabled', false); $("#installation").prop('disabled', false); $("#offreport").prop('disabled', false); $("#training").prop('disabled', false); }

View File

@ -22,27 +22,28 @@
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-3 mb-2">
<select id="productFilter" class="form-select form-select-sm">
<option value="">--Product Filter--</option>
<option value="tms">TMS</option>
<option value="jokoh">Jokoh</option>
<option value="mindray">Mindray</option>
</select>
</div>
<div class="col-md-3 mb-2"> <div class="col-md-3 mb-2">
<select id="statusFilter" class="form-select form-select-sm"> <select id="statusFilter" class="form-select form-select-sm">
<option value="">--Status Filter--</option> <option value="">--Status Filter--</option>
<option value="active">Active</option> <option value="active">Active</option>
<option value="expired">Expired</option> <option value="expired">Expired</option>
<option value="expiring">Expiring Soon</option> <option value="expiring">Expiring Soon</option>
<option value="not">Not Available</option>
</select> </select>
</div> </div>
<div class="col-md-3 mb-2"> <div class="col-md-3 mb-2">
<select disabled id="validationFilter" class="form-select form-select-sm"> <select id="validationFilter" class="form-select form-select-sm">
<option value="">--Validation Filter--</option> <option value="">--Validation Filter--</option>
<option value="validated">Validated</option> <option value="valid">Validated</option>
<option value="unvalidated">Unvalidated</option> <option value="unval">Unvalidated</option>
</select>
</div>
<div class="col-md-3 mb-2">
<select id="typeFilter" class="form-select form-select-sm">
<option value="">--Product Filter--</option>
<option value="tms">TMS</option>
<option value="jokoh">Jokoh</option>
<option value="boeki">Tokyo Boeki</option>
</select> </select>
</div> </div>
<div class="col-md-3 mb-2"> <div class="col-md-3 mb-2">
@ -57,14 +58,14 @@
<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 class="text-center" style="width: 3%">No</th> <!-- <th class="text-center" style="width: 3%">No</th> -->
<th style="width: 20%">Certificate</th> <th style="width: 23%">Certificate</th>
<th style="width: 28%">Act Report</th> <th style="width: 28%">Act Report</th>
<th style="width: 10%">Issue Date</th> <th style="width: 10%">Issue Date</th>
<th style="width: 10%">Expiry Date</th> <th style="width: 10%">Expiry Date</th>
<th class="text-center" style="width: 7%">Status</th> <th style="width: 9%">Status</th>
<th class="text-center" style="width: 7%">Validation</th> <th style="width: 8%">Validation</th>
<th class="text-center" style="width: 5%">Action</th> <th class="text-center" style="width: 12%">Action</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -82,9 +83,9 @@
<div class="modal fade" id="validateModal" tabindex="-1" aria-labelledby="validateModalLabel" aria-hidden="true"> <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-dialog modal-xl modal-dialog-centered">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header bg-warning text-dark"> <div class="modal-header bg-warning text-dark" id='modalHeader'>
<h5 class="modal-title" id="validateModalLabel"> <h5 class="modal-title" id="validateModalLabel">
<i class="fa-solid fa-check-double"></i> &nbsp;Validate Maintenance Certificate Validate Maintenance Certificate
</h5> </h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" <button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button> aria-label="Close"></button>
@ -97,7 +98,7 @@
<h5 id="modalCertName" class="mt-2 fw-bolder">-</h5> <h5 id="modalCertName" class="mt-2 fw-bolder">-</h5>
</div> </div>
<div class="col-md-4 text-md-end"> <div class="col-md-4 text-md-end">
<h5><span id="modalValidation" class="badge bg-warning text-dark">-</span></h5> <h5 id="modalValidation">-</h5>
</div> </div>
</div> </div>
@ -119,16 +120,16 @@
<p id="modalSiteName" class="form-control-plaintext border-bottom fw-bolder">-</p> <p id="modalSiteName" class="form-control-plaintext border-bottom fw-bolder">-</p>
</div> </div>
<div class="col-md-4 mb-3"> <div class="col-md-4 mb-3">
<label class="form-label text-success"><i class="fa-solid fa-calendar-check me-2"></i>Issue Date</label> <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> <p id="modalIssueDate" class="form-control-plaintext border-bottom fw-bolder">-</p>
</div> </div>
<div class="col-md-4 mb-3"> <div class="col-md-4 mb-3">
<label class="form-label text-danger"><i class="fa-solid fa-calendar-xmark me-2"></i>Expiry Date</label> <label class="form-label "><i class="fa-solid fa-calendar-xmark me-2"></i>Expiry Date</label>
<p id="modalExpiryDate" class="form-control-plaintext border-bottom fw-bolder">-</p> <p id="modalExpiryDate" class="form-control-plaintext border-bottom fw-bolder">-</p>
</div> </div>
<div class="col-md-4 mb-3"> <div class="col-md-4 mb-3">
<label class="form-label">Expired Status</label> <label class="form-label">Expired Status</label>
<p id="modalExpiryStatus" class="form-control-plaintext border-bottom">-</p> <p id="modalExpiredStatus" class="form-control-plaintext border-bottom">-</p>
</div> </div>
<div class="col-md-12 mb-4"> <div class="col-md-12 mb-4">
@ -155,17 +156,10 @@
</div> </div>
</div> </div>
<div class="alert alert-warning border-0 shadow-sm d-flex align-items-center"> <div id='modalInfo'></div>
<i class="fa-solid fa-circle-info fa-2xl me-3"></i>
<div>
<strong>Validation Note:</strong>
Review data di berikut dengan teliti, setelah divalidasi maka sertifikat akan dinyatakan <strong>Valid</strong> dan <strong>sah secara sistem.</strong>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-md-12 mb-3"> <div class="col-md-12 mb-3">
<label class="form-label ">Certificate Preview</label>
<div class="border rounded p-2" style="height: 500px; overflow: hidden;"> <div class="border rounded p-2" style="height: 500px; overflow: hidden;">
<iframe id="certificatePreview" src="" style="width: 100%; height: 100%; border: none;"></iframe> <iframe id="certificatePreview" src="" style="width: 100%; height: 100%; border: none;"></iframe>
</div> </div>
@ -195,7 +189,7 @@
$(function () { $(function () {
let table = $('#certificatesTable').DataTable({ let table = $('#certificatesTable').DataTable({
order: [[4, 'asc']], order: [[5, 'asc'], [4, 'asc']],
pageLength: 25, pageLength: 25,
dom: '<"row"<"col-md-6"l>>rtip', dom: '<"row"<"col-md-6"l>>rtip',
responsive: true, responsive: true,
@ -245,25 +239,25 @@ $(function () {
let expiryDate = new Date(expirydateRaw); let expiryDate = new Date(expirydateRaw);
let days = Math.ceil((expiryDate - today) / (1000 * 60 * 60 * 24)); let days = Math.ceil((expiryDate - today) / (1000 * 60 * 60 * 24));
if (days < 0) { if (days < 0) {
statusBadge = '<div class="text-center"><span class="badge bg-danger">Expired</span></div>'; statusBadge = '<div class=""><span class="badge bg-danger">Expired</span></div>';
} else if (days <= 30) { } else if (days <= 30) {
statusBadge = '<div class="text-center"><span class="badge bg-info">Expiring Soon</span></div>'; statusBadge = '<div class=""><span class="badge bg-info">Expiring Soon</span></div>';
} else { } else {
statusBadge = '<div class="text-center"><span class="badge bg-success">Active</span></div>'; statusBadge = '<div class=""><span class="badge bg-success">Active</span></div>';
} }
} else { } else {
statusBadge = '<div class="text-center"><span class="badge bg-secondary">n/a</span></div>'; statusBadge = '<div class=""><span class="badge bg-dark">Not Available</span></div>';
} }
if (status == 'unvalidated') { if (status == 'unvalidated') {
validationBadge = '<div class="text-center"><span class="badge bg-warning text-dark">unvalidated</span></div>'; validationBadge = '<div class=""><span class="badge bg-warning text-dark">unvalidated</span></div>';
} else { } else {
validationBadge = '<div class="text-center"><span class="badge bg-success">validated</span></div>'; validationBadge = '<div class=""><span class="badge bg-success">validated</span></div>';
} }
return [ return [
index + 1, // index + 1,
`<strong>${certname}</strong><br><small class="text-muted">Cert# : ${certnumber}</small>`, `<strong>${certname}</strong><br><small class="text-muted">Cert# : ${certnumber}</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} &nbsp;<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}" data-actid="${actid}" style="color:#d43215b0;">#${actid} - ${activity_subject} &nbsp;<i class="fa-solid fa-up-right-from-square"></i></strong><br><small class="text-muted">Owner : ${fullname}</small></a>`,
issuedate, issuedate,
@ -271,8 +265,9 @@ $(function () {
statusBadge, statusBadge,
validationBadge, validationBadge,
status == 'unvalidated' status == 'unvalidated'
? `<div class="text-center"><button type="button" class="btn btn-warning text-dark btn-validate-modal" data-certid="${certid}"><i class="fa-solid fa-check-double"></i></button></div>` ? `<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-exclamation me-2"></i>Need Validation</button></div>`
: `<div class="text-center"><button type="button" class="btn btn-success btn-view" data-certnumber="${certnumber}"><i class="fa-regular fa-file-pdf"></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-sm btn-success btn-view" data-certnumber="${certnumber}"><i class="fa-regular fa-file-pdf me-2"></i>Generated PDF</button></div>`
]; ];
}) })
}); });
@ -284,26 +279,38 @@ $(function () {
}, },
columnDefs: [ columnDefs: [
{ {
// Kondisi untuk Kolom 4 (Status Masa Berlaku)
targets: 4, targets: 4,
render: function (data, type) { render: function (data, type) {
if (type === 'sort') { if (type === 'sort') {
if (data.includes('need validation')) return 1; let val = data.toLowerCase();
if (data.includes('expired')) return 2; if (val.includes('not available')) return 1;
if (data.includes('expiring soon')) return 3; if (val.includes('expired')) return 2; // Merah - Paling kritis
if (data.includes('active')) return 4; if (val.includes('expiring soon')) return 3; // Biru/Kuning
return 5; // if (val.includes('active')) return 4; // Hijau
return 4;
} }
return data; return data;
} }
}, },
{ {
targets: [5, 6], // Kondisi untuk Kolom 5 (Validation)
orderable: false targets: 5,
render: function (data, type) {
if (type === 'sort') {
let val = data.toLowerCase();
if (val.includes('unvalidated')) return 1;
if (val.includes('validated')) return 2;
return 3;
}
return data;
}
}, },
{ {
targets: 7, // Hapus angka 4 dari sini agar kolom 4 bisa di-klik untuk sorting
targets: [6],
orderable: false orderable: false
} },
] ]
}); });
@ -315,37 +322,50 @@ $(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) // 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 // 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();
} }
}); });
$('#statusFilter').on('change', function () { $('#statusFilter').on('change', function () { // OK
let status = $(this).val(); let status = $(this).val();
if (status === '') { if (status === '') {
table.column(5).search('').draw(); table.column(4).search('').draw();
} else if (status === 'active') { } else if (status === 'active') {
table.column(5).search('active').draw(); table.column(4).search('active').draw();
} else if (status === 'expired') { } else if (status === 'expired') {
table.column(5).search('expired').draw(); table.column(4).search('expired').draw();
} else if (status === 'expiring') { } else if (status === 'expiring') {
table.column(5).search('expiring soon').draw(); table.column(4).search('expiring soon').draw();
} else if (status === 'not') {
table.column(4).search('not available').draw();
}
});
$('#validationFilter').on('change', function () { // OK
let validation = $(this).val();
if (validation === '') {
table.column(5).search('').draw();
} else if (validation === 'unval') {
table.column(5).search('unv').draw();
} else if (validation === 'valid') {
table.column(5).search('^validated$', true, false).draw();
} }
}); });
// Reset // Reset
window.resetFilters = function () { window.resetFilters = function () {
$('#searchInput, #statusFilter, #typeFilter').val(''); $('#searchInput, #statusFilter, #productFilter, #validationFilter').val('');
table.search('').columns().search('').order([4,'asc']).draw(); table.search('').columns().search('').draw();
}; };
// View PDF // View PDF
@ -389,30 +409,56 @@ $(function () {
$('#modalExpiryDate').text(formattedDate); $('#modalExpiryDate').text(formattedDate);
$('#modalSiteName').text(data.sitename || '-'); $('#modalSiteName').text(data.sitename || '-');
$('#modalValidation').html(`<i class="fa-solid fa-triangle-exclamation me-2"></i>${data.status || '-'}`);
// 1. Cek status validasi
const isValid = data.status === 'validated';
// 2. Siapkan variabel dinamis berdasarkan status
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>';
// 3. Terapkan ke dalam HTML (struktur HTML ditulis satu kali saja)
$('#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>`
);
let badge = '';
const today = new Date(); const today = new Date();
today.setHours(0, 0, 0, 0); today.setHours(0, 0, 0, 0);
const expiryDate = new Date(data.expired_date); if (data.expired_date == null) {
expiryDate.setHours(0, 0, 0, 0); badge = '<span class="badge bg-dark">Not Available</span>';
const diffTime = expiryDate - today;
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
let badge = '';
if (diffDays < 0) {
// Sudah melewati tanggal expired
badge = '<span class="badge bg-danger">Expired</span>';
} else if (diffDays <= 30) {
// Masih aktif tapi sisa 30 hari atau kurang
badge = '<span class="badge bg-warning">Expiring Soon</span>';
} else { } else {
// Lebih dari 30 hari const expiryDate = new Date(data.expired_date);
badge = '<span class="badge bg-success">Active</span>'; expiryDate.setHours(0, 0, 0, 0);
const diffTime = expiryDate - today;
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
if (diffDays < 0) {
badge = '<span class="badge bg-danger">Expired</span>';
}
else if (diffDays <= 30) {
badge = '<span class="badge bg-warning text-dark">Expiring Soon</span>';
} else {
badge = '<span class="badge bg-success">Active</span>';
}
} }
$('#modalExpiryStatus').html(badge);
$('#modalExpiredStatus').html(badge);
$('#modalActivity').text(data.actid ? `#${data.actid} - ${data.subject || '-'}` : '-'); $('#modalActivity').text(data.actid ? `#${data.actid} - ${data.subject || '-'}` : '-');
$('#modalActivityLink').attr('data-actid', data.actid || ''); $('#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>` : '-'); $('#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>` : '-'); $('#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>` : '-'); $('#modalValManager').html(data.manager_validation_at ? `${data.managername} - ${data.manager_validation_at}<i class="fa-solid fa-circle-check text-success ms-2"></i>` : '-');

View File

@ -73,7 +73,7 @@
.signature-table { .signature-table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
margin-bottom: 0px; margin-bottom: 41px;
} }
.signature-table td { .signature-table td {
width: 50%; /* Membagi dua sisi sama rata */ width: 50%; /* Membagi dua sisi sama rata */
@ -103,34 +103,34 @@
<div class="container"> <div class="container">
<div class="instument-name"> <div class="instument-name">
<h1> &lt;&lt;<?= $certificate['productname'] ?>&gt;&gt; </h1> <h1><?= $certificate['productname'] ?></h1>
</div> </div>
<div class="site-name"> <div class="site-name">
<h1> at &lt;&lt;<?= $certificate['sitename'] ?>&gt;&gt; </h1> <h1> at <?= $certificate['sitename'] ?> </h1>
</div> </div>
<div class="detail-information"> <div class="detail-information">
<h4>Serial Number: &lt;&lt;<?= $certificate['productnumber'] ?>&gt;&gt;</h4> <h4>Serial Number: <?= $certificate['productnumber'] ?></h4>
<h4>has completed through a series of &lt;&lt;<?= $certificate['certtype'] ?>&gt;&gt;</h4> <h4>has completed through a series of <?= $certificate['certtype'] ?></h4>
<h4>and the final result:</h4> <h4>and the final result:</h4>
<h2>PASSED</h2> <h2>PASSED</h2>
<h4>Date of Instrument Maintenance and Inspection: &lt;&lt;<?= $certificate['issueddate'] ?>&gt;&gt;</h4> <h4>Date of Instrument Maintenance and Inspection: <?= $certificate['issueddate'] ?></h4>
<h4>Valid until &lt;&lt;<?= $certificate['expireddate'] ?>&gt;&gt;</h4> <h4>Valid until <?= $certificate['expireddate'] ?></h4>
</div> </div>
<table class="signature-table"> <table class="signature-table">
<tr> <tr>
<td> <!-- <td>
<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="name">&lt;&lt;<?= $certificate['fullname'] ?>&gt;&gt;</span> <span class="name"><?= $certificate['fullname'] ?></span>
<span class="position">&lt;&lt;<?= $certificate['userposition'] ?>&gt;&gt;</span> <span class="position"><?= $certificate['userposition'] ?></span>
</td> </td> -->
</tr> </tr>
</table> </table>
@ -140,36 +140,38 @@
</div> </div>
<!-- Untuk Tanda Export PDF atau tidak -->
<?php if (!isset($certificate['exportToPDF'])) : ?>
<div class="container"> <div class="container">
<div class="instument-name"> <div class="instument-name">
<h1> &lt;&lt;<?= $certificate['productname'] ?>&gt;&gt; </h1> <h1><?= $certificate['productname'] ?></h1>
</div> </div>
<div class="site-name"> <div class="site-name">
<h1> at &lt;&lt;<?= $certificate['sitename'] ?>&gt;&gt; </h1> <h1> at <?= $certificate['sitename'] ?> </h1>
</div> </div>
<div class="detail-information"> <div class="detail-information">
<h4>Serial Number: &lt;&lt;<?= $certificate['productnumber'] ?>&gt;&gt;</h4> <h4>Serial Number: <?= $certificate['productnumber'] ?></h4>
<h4>has completed through a series of &lt;&lt;<?= $certificate['certtype'] ?>&gt;&gt;</h4> <h4>has completed through a series of <?= $certificate['certtype'] ?></h4>
<h4>and the final result:</h4> <h4>and the final result:</h4>
<h2>PASSED</h2> <h2>PASSED</h2>
<h4>Date of Instrument Maintenance and Inspection: &lt;&lt;<?= $certificate['issueddate'] ?>&gt;&gt;</h4> <h4>Date of Instrument Maintenance and Inspection: <?= $certificate['issueddate'] ?></h4>
<h4>Valid until &lt;&lt;<?= $certificate['expireddate'] ?>&gt;&gt;</h4> <h4>Valid until <?= $certificate['expireddate'] ?></h4>
</div> </div>
<table class="signature-table"> <table class="signature-table">
<tr> <tr>
<td> <!-- <td>
<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="name">&lt;&lt;<?= $certificate['fullname'] ?>&gt;&gt;</span> <span class="name"><?= $certificate['fullname'] ?></span>
<span class="position">&lt;&lt;<?= $certificate['userposition'] ?>&gt;&gt;</span> <span class="position"><?= $certificate['userposition'] ?></span>
</td> </td> -->
</tr> </tr>
</table> </table>
@ -178,6 +180,6 @@
</div> </div>
</div> </div>
<?php endif ?>
</body> </body>
</html> </html>

View File

@ -41,10 +41,10 @@
<li> <a class="has-arrow waves-effect waves-dark" href='javascript:void(0)' aria-expanded="false"> <i class="fa-solid fa-certificate"></i><span class='hide-menu'>Certificates</span> </a> <li> <a class="has-arrow waves-effect waves-dark" href='javascript:void(0)' aria-expanded="false"> <i class="fa-solid fa-certificate"></i><span class='hide-menu'>Certificates</span> </a>
<ul aria-expanded="false" class="collapse"> <ul aria-expanded="false" class="collapse">
<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/installation">Installation</a></li> <!-- <li><a href="<?=base_url();?>certificates/installation">Installation</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>