CHANGE_CLAIM_CHANGES

This commit is contained in:
VENKATESHWARAN 2026-07-21 17:45:17 +05:30
parent 6bfd532d2b
commit 8f1632afbf
3 changed files with 358 additions and 56 deletions

View File

@ -871,6 +871,7 @@ $routes->group("/bdsReport", ["filter" => "authMVC"], function ($routes) {
//New Tickets
$routes->group("/ticket", ["filter" => "authMVC"], function ($routes) {
$routes->match( ['get', 'post'], 'list','TicketController::ticketList');
$routes->post('export','TicketController::exportTickets');
$routes->get('feedback-list','TicketController::feedbackList');
$routes->match(['get', 'post'], 'claim-upload','TicketController::claimDumpUpload');
$routes->get('remove','TicketController::removeTicket');

View File

@ -461,6 +461,155 @@ class TicketController extends BaseController
}
}
public function exportTickets()
{
$format = $this->request->getPost('export_format') ?? 'csv';
$rows = $this->ticketSearch(); // uses same POST filters as the list
// Restrict to DataTables-visible rows when client sends export_ids
if ($this->request->getPost('export_ids') !== null) {
$exportIds = array_values(array_filter(array_map('intval', explode(',', (string) $this->request->getPost('export_ids')))));
if (empty($exportIds)) {
$rows = [];
} else {
$idOrder = array_flip($exportIds);
$rows = array_values(array_filter($rows, function ($row) use ($idOrder) {
return isset($idOrder[(int) ($row['id'] ?? 0)]);
}));
usort($rows, function ($a, $b) use ($idOrder) {
return ($idOrder[(int) $a['id']] ?? 0) <=> ($idOrder[(int) $b['id']] ?? 0);
});
}
}
$headers = [
'Created At', 'Updated At', 'Status', 'Policy Type', 'Claim Number', 'TPA ID', 'Emp ID', 'Emp Name',
'Insured Name', 'Corporate Name', 'ACM', 'Insurer', 'TPA', 'Policy No',
'Priority', 'Relationship', 'Emp Mobile', 'Emp Email', 'Emp Personal Email',
'Mode of Intimation', 'Claim Type', 'Claim Category', 'Hospital Name', 'DOA', 'DOD',
'Claim Amount', 'POD No.', 'Date of Join', 'Date of Inception', 'DOB',
'Date of Accident', 'Date of Death', 'Date of Intimation', 'Sum Insured',
'Raised Date', 'Registration Date', 'Query Received Date', 'Denial Date',
'Approved Date', 'Settled Date', 'Denial Reason', 'Approved Letter',
'Approved Amount', 'UTR Details', 'Settle Letter', 'Return Remark',
'Cancel Remark', 'AWB No & Courier Name', 'Non ID Reason',
'Payment Initiate Date', 'Approved Description', 'TAT', 'Claim Created By',
];
$claimTypeMap = $this->claimType;
$priorityMap = $this->priorityType;
$modeMap = $this->modeOFIntimate;
$ticketTypeMap = $this->ticketType;
$buildRow = function (array $row) use ($claimTypeMap, $priorityMap, $modeMap, $ticketTypeMap): array {
$typeId = (int) ($row['ticket_type_id'] ?? 0);
$claimKey = $row['claim_type'] ?? '';
$claimTypeLabel = $claimTypeMap[$typeId][$claimKey] ?? '';
$claimCreatedBy = strtoupper((string) ($row['claim_created_by'] ?? ''));
$claimCreatedByLabel = $claimCreatedBy === 'CRM' ? 'STAFF' : $claimCreatedBy;
$claimCategory = trim((string) ($row['tpa_claim_type'] ?? ''));
return [
$row['ticket_created_date'] ?? '',
$row['ticket_updated_date'] ?? '',
$row['status'] ?? '',
str_replace('Claim-', '', $ticketTypeMap[$typeId] ?? ''),
$row['claim_no'] ?? '',
$row['tpa_no'] ?? '',
$row['emp_code'] ?? '',
$row['emp_name'] ?? '',
$row['insured_name'] ?? '',
$row['short_name'] ?? '',
$row['acm_name'] ?? '',
$row['insurer_name'] ?? '',
$row['tpa_name'] ?? '',
$row['policy_no'] ?? '',
$priorityMap[$row['priority'] ?? 0] ?? '',
$row['relationship'] ?? '',
$row['emp_mobile'] ?? '',
$row['emp_mail'] ?? '',
$row['emp_personal_mail'] ?? '',
$modeMap[$row['mode_of_intimation'] ?? ''] ?? '',
$claimTypeLabel,
$claimCategory,
$row['hospital_name'] ?? '',
$row['doa'] ?? '',
$row['dod'] ?? '',
$row['claim_amount'] ?? '',
$row['pod_no'] ?? '',
$row['date_of_join'] ?? '',
$row['date_of_incep'] ?? '',
$row['dob'] ?? '',
$row['date_of_accident'] ?? '',
$row['date_of_death'] ?? '',
$row['date_of_intimat'] ?? '',
$row['si_amt'] ?? '',
$row['raised_date'] ?? '',
$row['registration_date'] ?? '',
$row['query_received_date'] ?? '',
$row['denial_date'] ?? '',
$row['approved_date'] ?? '',
$row['settled_date'] ?? '',
$row['denial_reason'] ?? '',
$row['approved_letter'] ?? '',
$row['approved_amount'] ?? '',
$row['utr_details'] ?? '',
$row['settle_letter'] ?? '',
$row['return_remark'] ?? '',
$row['cancel_remark'] ?? '',
$row['awb_no_courier_name'] ?? '',
$row['non_id_reason'] ?? '',
$row['pay_initiate_date'] ?? '',
$row['approved_description'] ?? '',
$row['tat'] ?? '',
$claimCreatedByLabel,
];
};
$filename = 'Claim-List-' . date('Y-m-d');
if ($format === 'excel') {
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('Claim List');
$sheet->fromArray([$headers], null, 'A1');
$rowIndex = 2;
foreach ($rows as $row) {
$sheet->fromArray([$buildRow($row)], null, 'A' . $rowIndex);
$rowIndex++;
}
// Bold header row
$lastCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex(count($headers));
$sheet->getStyle('A1:' . $lastCol . '1')->getFont()->setBold(true);
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="' . $filename . '.xlsx"');
header('Cache-Control: max-age=0');
ob_end_clean();
$writer->save('php://output');
exit;
}
// Default: CSV
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '.csv"');
header('Cache-Control: max-age=0');
ob_end_clean();
$out = fopen('php://output', 'w');
// UTF-8 BOM for Excel compatibility
fwrite($out, "\xEF\xBB\xBF");
fputcsv($out, $headers);
foreach ($rows as $row) {
fputcsv($out, $buildRow($row));
}
fclose($out);
exit;
}
public function ticketSearch($action = null)
{
$db = db_connect();
@ -620,6 +769,12 @@ class TicketController extends BaseController
// print_r($search_data); die()
$where = [];
foreach ($search_data as $search_objects => $key) {
if (stripos((string)$search_objects, 'csrf') !== false) {
continue;
}
if ($search_objects === 'export_format' || $search_objects === 'export_ids') {
continue;
}
if ($key != null && $key != '' && $key != 0 && $search_objects != 'is_dashboard') {
if($search_objects == "date_type" && $search_data[$search_objects] === 'ticket_created_date'){
@ -730,6 +885,15 @@ class TicketController extends BaseController
}
}
$exportIdsRaw = $this->request->getPost('export_ids');
if ($exportIdsRaw !== null) {
$exportIds = array_values(array_filter(array_map('intval', explode(',', (string) $exportIdsRaw))));
if (empty($exportIds)) {
return [];
}
$query->whereIn('tm.id', $exportIds);
}
$data = $query->get()->getResultArray();
// dd($db->getLastQuery()->getQuery());die;
// dd($data);

View File

@ -30,6 +30,15 @@ table.dataTable tbody td {
color: #6c757d !important;
}
.emp-name-cell {
font-weight: 500;
}
.tpa-id-truncate {
cursor: default;
white-space: nowrap;
}
.policy-type-icon {
display: inline-flex;
align-items: center;
@ -93,6 +102,38 @@ table.dataTable tbody td {
white-space: nowrap;
}
#scroll-horizontal-datatable_wrapper .dt-buttons {
position: relative;
}
#scroll-horizontal-datatable_wrapper .dt-button-collection {
z-index: 9999 !important;
}
#scroll-horizontal-datatable_wrapper .ticket-backend-export-menu {
display: none;
background: #00999E;
border: 1px solid #00999E;
border-radius: .25rem;
box-shadow: 0 0.5rem 1rem rgba(0,0,0,.15);
padding: .25rem 0;
}
#scroll-horizontal-datatable_wrapper .ticket-backend-export-menu .dropdown-item {
display: block;
width: 100%;
padding: .4rem .9rem;
clear: both;
color: #fff;
text-decoration: none;
white-space: nowrap;
}
#scroll-horizontal-datatable_wrapper .ticket-backend-export-menu .dropdown-item:hover {
background-color: #007A7E;
color: #fff;
}
</style>
<style>
.table th:nth-child(1),
@ -130,10 +171,10 @@ table.dataTable tbody td {
<th>Policy Type&nbsp;</th>
<th>Claim number&nbsp;</th>
<th>TPA ID&nbsp;</th>
<th>Emp ID&nbsp;</th>
<th>Emp name&nbsp;</th>
<th>Emp Name&nbsp;</th>
<th>Insured Name&nbsp;</th>
<th>Corporate name&nbsp;</th>
<th>Claim Type&nbsp;</th>
<th style="display: none;">ACM</th>
<th style="display: none;">Insurer</th>
@ -145,7 +186,6 @@ table.dataTable tbody td {
<th style="display: none;">Emp Email</th>
<th style="display: none;">Emp Personal Email</th>
<th style="display: none;">Mode of Intimation</th>
<th style="display: none;">Claim Type</th>
<th style="display: none;">Hospital Name</th>
<th style="display: none;">DOA</th>
<th style="display: none;">DOD</th>
@ -244,19 +284,20 @@ table.dataTable tbody td {
];
$claimSrcClass = $claimSrcClassMap[$claimSrc] ?? null;
$policyTypeLabel = str_replace('Claim-', '', $ticket_type[$row['ticket_type_id']] ?? 'N/A');
$tpaClaimTypeRaw = trim((string)($row['tpa_claim_type'] ?? ''));
$tpaClaimType = strtolower($tpaClaimTypeRaw);
$policyTypeIconHtml = '';
// $tpaClaimTypeRaw = trim((string)($row['tpa_claim_type'] ?? ''));
// $tpaClaimType = strtolower($tpaClaimTypeRaw);
// $policyTypeIconHtml = '';
if ($tpaClaimType !== '') {
if (strpos($tpaClaimType, 'cash') !== false) {
$policyTypeIconHtml = '<span class="policy-type-icon policy-type-icon--cashless" title="Cashless"><i class="mdi mdi-hospital-box-outline" aria-hidden="true"></i></span>';
} elseif (strpos($tpaClaimType, 'reimburse') !== false) {
$policyTypeIconHtml = '<span class="policy-type-icon policy-type-icon--reimbursement" title="Reimbursement"><i class="mdi mdi-cash-refund" aria-hidden="true"></i></span>';
}
}
// if ($tpaClaimType !== '') {
// if (strpos($tpaClaimType, 'cash') !== false) {
// $policyTypeIconHtml = '<span class="policy-type-icon policy-type-icon--cashless" title="Cashless"><i class="mdi mdi-hospital-box-outline" aria-hidden="true"></i></span>';
// } elseif (strpos($tpaClaimType, 'reimburse') !== false) {
// $policyTypeIconHtml = '<span class="policy-type-icon policy-type-icon--reimbursement" title="Reimbursement"><i class="mdi mdi-cash-refund" aria-hidden="true"></i></span>';
// }
// }
echo $policyTypeIconHtml . esc($policyTypeLabel);
// echo $policyTypeIconHtml . esc($policyTypeLabel);
echo esc($policyTypeLabel);
if ($claimSrcClass !== null) {
echo '<br><span class="claim-source-badge ' . esc($claimSrcClass, 'attr') . '">' . esc($claimSrc == "CRM" ? "STAFF" : $claimSrc) . '</span>';
}
@ -266,11 +307,31 @@ table.dataTable tbody td {
<span class="text-custom-grey"><br><?= "Created at ".$row['ticket_created_date']; ?></span>
<?php endif; ?>
</td>
<td><?php echo $row['tpa_no'] ?: 'N/A'; ?></td>
<td><?php echo $row['emp_code'] ?: 'N/A'; ?></td>
<td><?php echo $row['emp_name'] ?: 'N/A'; ?></td>
<td><?php
$tpaNo = $row['tpa_no'] ?: 'N/A';
$tpaNoMaxLen = 10;
if ($tpaNo !== 'N/A' && strlen($tpaNo) > $tpaNoMaxLen) {
echo '<span class="tpa-id-truncate" data-toggle="tooltip" data-placement="top" title="' . esc($tpaNo, 'attr') . '">' . esc(substr($tpaNo, 0, $tpaNoMaxLen) . '...') . '</span>';
} else {
echo esc($tpaNo);
}
?></td>
<td class="emp-name-cell"><?php echo $row['emp_name'] ?: 'N/A'; ?>
<span class="text-custom-grey"><br><?php echo $row['emp_code'] ?: 'N/A'; ?></span>
</td>
<td><?php echo $row['insured_name'] ?: 'N/A'; ?></td>
<td><?php echo $row['short_name'] ?: 'N/A'; ?></td>
<td class="emp-name-cell"><?php
$typeId = $row['ticket_type_id'] ?? 0;
$claimKey = $row['claim_type'] ?? '';
if ($typeId == 1) {
echo isset($claimType[1][$claimKey]) ? $claimType[1][$claimKey] : 'N/A';
} else {
echo isset($claimType[2][$claimKey]) ? $claimType[2][$claimKey] : 'N/A';
}
?>
<span class="text-custom-grey"><br><?php echo !empty($row['tpa_claim_type']) ? esc($row['tpa_claim_type']) : 'N/A'; ?></span>
</td>
<td style="display: none;"><?php echo $row['acm_name']; ?></td>
<td style="display: none;"><?php echo $row['insurer_name']; ?></td>
@ -282,17 +343,6 @@ table.dataTable tbody td {
<td style="display: none;"><?php echo $row['emp_mail']; ?></td>
<td style="display: none;"><?php echo $row['emp_personal_mail']; ?></td>
<td style="display: none;"><?php echo ($modeOFIntimate ?? [])[$row['mode_of_intimation'] ?? ''] ?? ''; ?></td>
<td style="display: none;">
<?php
$typeId = $row['ticket_type_id'] ?? 0;
$claimKey = $row['claim_type'] ?? '';
if ($typeId == 1) {
echo isset($claimType[1][$claimKey]) ? $claimType[1][$claimKey] : '';
} else {
echo isset($claimType[2][$claimKey]) ? $claimType[2][$claimKey] : '';
}
?>
</td>
<td style="display: none;"><?php echo $row['hospital_name']; ?></td>
<td style="display: none;"><?php echo change_date_format($row['doa'], null, 'd-m-Y'); ?></td>
<td style="display: none;"><?php echo $row['dod']; ?></td>
@ -385,6 +435,17 @@ function asText(value) {
return escapeHtml(value);
}
function getTruncatedTpaIdHtml(tpaNo) {
var value = (tpaNo === null || tpaNo === undefined || tpaNo === '') ? 'N/A' : String(tpaNo);
var maxLen = 10;
if (value === 'N/A' || value.length <= maxLen) {
return escapeHtml(value);
}
return '<span class="tpa-id-truncate" data-toggle="tooltip" data-placement="top" title="' + escapeHtml(value) + '">' +
escapeHtml(value.substring(0, maxLen) + '...') +
'</span>';
}
function getClaimTypeLabel(row) {
var typeId = Number(row.ticket_type_id || 0);
var claimKey = row.claim_type || '';
@ -478,7 +539,7 @@ function buildTicketRowHtml(row) {
var statusUpdated = row.ticket_updated_date ? '<span class="text-custom-grey"><br>Updated at ' + escapeHtml(row.ticket_updated_date) + '</span>' : '';
var claimCreated = row.ticket_created_date ? '<span class="text-custom-grey"><br>Created at ' + escapeHtml(row.ticket_created_date) + '</span>' : '';
var policyType = (window.ticketTypeMap[row.ticket_type_id] || '').replace('Claim-', '');
var policyTypeIcon = getPolicyTypeIconHtml(row.tpa_claim_type);
// var policyTypeIcon = getPolicyTypeIconHtml(row.tpa_claim_type);
var claimSourceBadge = getClaimSourceBadgeHtml(row.claim_created_by);
var modeOfIntimation = window.modeOfIntimateMap[row.mode_of_intimation] || '';
var priority = window.priorityTypeMap[row.priority || 0] || '';
@ -489,13 +550,14 @@ function buildTicketRowHtml(row) {
'<span class="status-tooltip">' + getStatusDisplay(row) + '</span>' +
statusUpdated +
'</td>' +
'<td>' + policyTypeIcon + asText(policyType) + (claimSourceBadge ? '<br>' + claimSourceBadge : '') + '</td>' +
// '<td>' + policyTypeIcon + asText(policyType) + (claimSourceBadge ? '<br>' + claimSourceBadge : '') + '</td>' +
'<td>' + asText(policyType) + (claimSourceBadge ? '<br>' + claimSourceBadge : '') + '</td>' +
'<td>' + asText(row.claim_no) + claimCreated + '</td>' +
'<td>' + asText(row.tpa_no) + '</td>' +
'<td>' + asText(row.emp_code) + '</td>' +
'<td>' + asText(row.emp_name) + '</td>' +
'<td>' + getTruncatedTpaIdHtml(row.tpa_no) + '</td>' +
'<td class="emp-name-cell">' + asText(row.emp_name) + '<span class="text-custom-grey"><br>' + asText(row.emp_code) + '</span></td>' +
'<td>' + asText(row.insured_name) + '</td>' +
'<td>' + asText(row.short_name) + '</td>' +
'<td class="emp-name-cell">' + asText(getClaimTypeLabel(row)) + '<span class="text-custom-grey"><br>' + asText(row.tpa_claim_type) + '</span></td>' +
'<td style="display: none;">' + escapeHtml(row.acm_name || '') + '</td>' +
'<td style="display: none;">' + escapeHtml(row.insurer_name || '') + '</td>' +
'<td style="display: none;">' + escapeHtml(row.tpa_name || '') + '</td>' +
@ -506,7 +568,6 @@ function buildTicketRowHtml(row) {
'<td style="display: none;">' + escapeHtml(row.emp_mail || '') + '</td>' +
'<td style="display: none;">' + escapeHtml(row.emp_personal_mail || '') + '</td>' +
'<td style="display: none;">' + escapeHtml(modeOfIntimation) + '</td>' +
'<td style="display: none;">' + escapeHtml(getClaimTypeLabel(row)) + '</td>' +
'<td style="display: none;">' + escapeHtml(row.hospital_name || '') + '</td>' +
'<td style="display: none;">' + escapeHtml(row.doa || '') + '</td>' +
'<td style="display: none;">' + escapeHtml(row.dod || '') + '</td>' +
@ -553,7 +614,8 @@ function applyTicketRows(rows) {
if (window.ticketTableInstance) {
window.ticketTableInstance.clear();
tbody.html(html);
window.ticketTableInstance.rows.add(tbody.find('tr')).draw();
window.ticketTableInstance.rows.add(tbody.find('tr')).draw(false);
window.ticketTableInstance.columns.adjust();
} else {
tbody.html(html);
}
@ -618,27 +680,59 @@ $(document).ready(function() {
}
},
{
extend: 'collection',
text: '<span class=" btn-custom"> Export </span><i class="mdi mdi-menu-down"></i>',
className: 'btn app-btn-secondary ',
buttons: [
{
extend: 'csv',
text: '<i class="mdi mdi-file-delimited " ></i><span class=" btn-custom"> CSV </span>',
className: 'app-btn-primary ',
title: 'Claim-List',
},
{
extend: 'excel',
text: '<i class="mdi mdi-file-excel " ></i><span class=" btn-custom"> EXCEL </span>',
title: 'claim-List',
sheetName: 'claim-List',
exportOptions: {
orthogonal: 'sort'
},
className: 'app-btn-primary ',
}
]
text: '<span class="btn-custom"> Export </span><i class="mdi mdi-menu-down"></i>',
className: 'btn app-btn-secondary ticket-backend-export-btn',
name: 'ticketBackendExport',
action: function(e, dt, node, config) {
e.preventDefault();
e.stopPropagation();
var $btn = $(node);
var $wrap = $btn.closest('.dt-buttons');
var $menu = $wrap.find('.ticket-backend-export-menu');
if (!$menu.length) {
$menu = $(
'<div class="dropdown-menu ticket-backend-export-menu show" style="position:absolute;z-index:9999;min-width:140px;display:block;">' +
'<a class="dropdown-item ticket-export-csv" href="javascript:void(0);"><i class="mdi mdi-file-delimited mr-1"></i> CSV</a>' +
'<a class="dropdown-item ticket-export-excel" href="javascript:void(0);"><i class="mdi mdi-file-excel mr-1"></i> Excel</a>' +
'</div>'
);
$wrap.css('position', 'relative').append($menu);
$menu.css({
top: ($btn.position().top + $btn.outerHeight()) + 'px',
left: $btn.position().left + 'px'
});
$menu.on('click', '.ticket-export-csv', function(ev) {
ev.preventDefault();
ev.stopPropagation();
$menu.hide();
triggerTicketExport('csv');
});
$menu.on('click', '.ticket-export-excel', function(ev) {
ev.preventDefault();
ev.stopPropagation();
$menu.hide();
triggerTicketExport('excel');
});
} else {
$menu.toggle();
if ($menu.is(':visible')) {
$menu.css({
top: ($btn.position().top + $btn.outerHeight()) + 'px',
left: $btn.position().left + 'px',
display: 'block'
});
}
}
setTimeout(function() {
$(document).one('click.ticketExportMenu', function() {
$menu.hide();
});
}, 0);
}
}
],
language: {
@ -657,6 +751,7 @@ $(document).ready(function() {
pageLength: 10, // Set default number of rows per page (optional)
ordering: false,
});
window.ticketTableInstance.columns.adjust();
} else if (!ticketsTable.length) {
console.error("Table not found.");
}
@ -827,6 +922,48 @@ function removeClaim(input, ticket_id) {
}
function triggerTicketExport(format) {
var exportUrl = '<?= base_url('ticket/export') ?>';
// Reuse the same filter parameters that were last applied to the table
var stored = localStorage.getItem('filterData');
var filterData = stored ? JSON.parse(stored) : {};
filterData['export_format'] = format;
// Export only rows currently visible in DataTables (respects search box)
if (window.ticketTableInstance) {
var ids = window.ticketTableInstance
.rows({ search: 'applied' })
.nodes()
.to$()
.map(function () {
return $(this).data('id');
})
.get()
.filter(function (id) {
return id !== null && id !== undefined && id !== '';
});
filterData['export_ids'] = ids.join(',');
}
var $form = $('<form method="POST" style="display:none;"></form>').attr('action', exportUrl);
$.each(filterData, function(name, value) {
if (String(name).toLowerCase().indexOf('csrf') !== -1) {
return;
}
if (name === 'export_ids' || (value !== null && value !== undefined && value !== '')) {
$form.append($('<input type="hidden">').attr('name', name).val(value));
}
});
$('body').append($form);
$form.submit();
setTimeout(function() { $form.remove(); }, 3000);
}
$(document).on('click', 'tbody tr', function (e) {
// Exclude clicks on any elements inside the last column (actions)
if ($(e.target).closest('td').index() !== $(this).children('td').length - 1) {