crm-summit/app/Views/certificate_installation_index.php

426 lines
22 KiB
PHP

<?= $this->extend('layouts/main.php') ?>
<?= $this->section('content') ?>
<div class="page-wrapper">
<div class="container-fluid">
<div class="row page-titles">
<div class="col-md-5 align-self-center">
<h4 class="text-themecolor">Certificates Installation Management</h4>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="row mb-3">
<div class="col-12 mb-3">
<div class="input-group input-group-sm">
<span class="input-group-text"><i class="fas fa-search"></i></span>
<input type="text" id="searchInput" class="form-control"
placeholder="Search certificates by name, product, type, vendor, or dates...">
</div>
</div>
<div class="col-md-4 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-4 mb-2">
<select id="validationFilter" class="form-select form-select-sm">
<option value="">--Validation Filter--</option>
<option value="valid">Validated</option>
<option value="unval">Unvalidated</option>
</select>
</div>
<div class="col-md-4 mb-2">
<button onclick="resetFilters()" class="btn btn-secondary btn-sm w-100">
<i class="fas fa-redo"></i> Reset Filters
</button>
</div>
</div>
<div class="table-responsive" style="width: 100%;">
<table id="certificatesTable" class="table table-striped table-hover border" style="width: 100%;">
<thead class="table-primary">
<tr>
<th style="width: 35%">Certificate</th>
<th style="width: 35%">Act Report</th>
<th style="width: 10%">Issue Date</th>
<th style="width: 8%">Validation</th>
<th class="text-center" style="width: 12%">Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<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" id='modalHeader'>
<h5 class="modal-title" id="validateModalLabel">
Validate installation Certificate
</h5>
<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 class="row">
<div class="col-md-6 mb-3">
<label class="form-label "><i class="fa-solid fa-book-medical me-2"></i>Certificate Number</label>
<p id="modalCertNumber" 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-microchip me-2"></i>Product/Equipment</label>
<p id="modalProductName" 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-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-12 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>
<?= $this->endSection() ?>
<?= $this->section('style') ?>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
$(function () {
let table = $('#certificatesTable').DataTable({
order: [[3, 'asc']], // Order by Validation Column
pageLength: 25,
dom: '<"row"<"col-md-6"l>>rtip',
responsive: true,
serverSide: false,
autoWidth: false,
ajax: function (data, callback, settings) {
fetch('<?= base_url('certificates/api/getindexinstallation') ?>')
.then(response => response.json())
.then(result => {
callback({
data: result.map((cert, index) => {
let certid = cert.cert_id || '';
let certname = cert.cert_name || '-';
let certnumber = cert.cert_number || '';
let actid = cert.actid || '';
let issuedateRaw = cert.issued_date || '';
let status = cert.status; // Validation status
let fullname = cert.fullname;
let activity_subject = cert.activity_subject;
let user_check = cert.user_validation_at ? 'checked' : '';
let spv_check = cert.spv_validation_at ? 'checked' : '';
let manager_check = cert.manager_validation_at ? 'checked' : '';
let issuedate = '-';
let validationBadge = '';
let statusBadge = '';
if (issuedateRaw && issuedateRaw !== '0000-00-00') {
let date = new Date(issuedateRaw);
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 (status == 'unvalidated') {
// validationBadge = "<div class=''><span class='badge bg-warning text-dark'>unvalidated</span><br></div>";
validationBadge = '<div class="">' +
'<span class="badge bg-warning text-dark mb-1 p-1 px-2">unvalidated</span><br>' +
'<div class="form-check text-sm">' +
'<input class="form-check-input" type="checkbox" ' + user_check + ' disabled>' +
'<label class="form-check-label small">TSO</label>' +
'</div>' +
'<div class="form-check">' +
'<input class="form-check-input" type="checkbox" ' + spv_check + ' disabled>' +
'<label class="form-check-label small">SPV</label>' +
'</div>' +
'<div class="form-check">' +
'<input class="form-check-input" type="checkbox" ' + manager_check + ' disabled>' +
'<label class="form-check-label small">Manager</label>' +
'</div>' +
'</div>';
statusBadge = '<span class="text-danger">❋</span>';
} else {
// validationBadge = '<div class=""><span class="badge bg-success">validated</span></div>';
validationBadge = '<div class="">' +
'<span class="badge bg-success mb-1 p-1 px-2">validated</span><br>' +
'<div class="form-check">' +
'<input class="form-check-input" type="checkbox" ' + user_check + ' disabled>' +
'<label class="form-check-label small">TSO</label>' +
'</div>' +
'<div class="form-check">' +
'<input class="form-check-input" type="checkbox" ' + spv_check + ' disabled>' +
'<label class="form-check-label small">SPV</label>' +
'</div>' +
'<div class="form-check">' +
'<input class="form-check-input" type="checkbox" ' + manager_check + ' disabled>' +
'<label class="form-check-label small">Manager</label>' +
'</div>' +
'</div>';
}
return [
`<strong>${statusBadge} ${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>`,
issuedate,
validationBadge,
status == 'unvalidated'
? `<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 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>`
];
})
});
})
.catch(error => {
console.error('Error fetching data:', error);
callback({ data: [] });
});
},
columnDefs: [
{
// Kondisi untuk Kolom 3 (Validation)
targets: 3,
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;
}
},
{
// Kondisi untuk Kolom 4 (Action)
targets: [4],
orderable: false
}
]
});
$('#certificatesTable_filter').hide();
// Search
$('#searchInput').on('keyup', function () {
table.search(this.value).draw();
});
// Type filter using DataTables column filter
$('#productFilter').on('change', function () {
let type = $(this).val();
if (type === '') {
table.column(0).search('').draw();
} else {
let typeText = type.charAt(0).toUpperCase() + type.slice(1);
table.column(0).search(typeText).draw();
}
});
$('#validationFilter').on('change', function () {
let validation = $(this).val();
if (validation === '') {
table.column(3).search('').draw();
} else if (validation === 'unval') {
table.column(3).search('unv').draw();
} else if (validation === 'valid') {
table.column(3).search('^validated$', true, false).draw();
}
});
// Reset
window.resetFilters = function () {
$('#searchInput, #productFilter, #validationFilter').val('');
table.search('').columns().search('').draw();
};
// View PDF
$(document).on('click', '.btn-view', function () {
let certnumber = $(this).data('certnumber');
window.open('<?= base_url('certificates/number/') ?>' + certnumber, '_blank');
});
// Activity report
$(document).on('click', '.activity-report-link', function () {
let actid = $(this).data('actid');
window.open(
'<?= base_url('activities/detail/') ?>' + actid,
'_blank',
'width=1200,height=800,scrollbars=yes,resizable=yes'
);
});
// Open modal
$(document).on('click', '.btn-validate-modal', function () {
let btn = $(this);
let certid = btn.data('certid');
// POST API call to fetch certificate data
$.post(
'<?= base_url('certificates/api/showinstallation') ?>',
{ certid },
function (data) {
$('#modalCertName').text(data.cert_name || '-');
$('#modalCertNumber').text(data.cert_number || '-');
$('#modalProductName').text(data.productname || '-');
$('#modalProductNumber').text(data.productnumber || '-');
$('#modalIssueDate').text(data.issued_date || '-');
$('#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 () {
console.error('Error fetching certificate data');
});
// INI JANGAN DIUBAH
$('#confirmValidateBtn').data('certid', certid);
$('#certificatePreview').attr('src','<?= base_url('certificates/installation/show/') ?>' + certid);
$('#validateModal').modal('show');
});
// Confirm validate
$('#confirmValidateBtn').on('click', function () {
let certid = $(this).data('certid');
let certificateType = 'installation';
if (!confirm('Are you sure?')) return;
$.post(
'<?= base_url('certificates/api/validatecertificate') ?>',
{ certid, certificateType},
function (response) {
if (response.success) {
$('#validateModal').modal('hide');
alert(response.message);
location.reload();
} else {
alert(response.message || 'Validation failed');
}
}, 'json'
).fail(function (xhr) {
console.log(xhr);
alert(xhr.responseText);
});
});
});
</script>
<?= $this->endSection() ?>