MERGE_UAT_CLAIMS

This commit is contained in:
Ubuntu 2026-05-04 10:38:57 +05:30
commit 16dccbe723
6 changed files with 281 additions and 17 deletions

View File

@ -87,6 +87,7 @@ $routes->get('download-e-card/(:any)', 'EmployeeController::generateIDCardForEmp
$routes->get('download-kyc-docs/(:segment)', 'ClientController::downloadKYCDocument/$1');
$routes->get('claim-form-download/(:any)', 'TicketController::downloadClaimForm/$1');
$routes->get('downloadClaimFile/(:any)', 'TicketController::downloadClaimFile/$1');
$routes->get('viewClaimFile/(:any)', 'TicketController::viewClaimFile/$1');
$routes->match (['get','post'],"claims-feedback-form/(:any)/(:any)", "TicketController::viewClaimFeedbackForm/$1/$2");
$routes->match (['get','post'],"claims-feedback-form/(:any)", "TicketController::viewClaimFeedbackForm/$1");
$routes->get('downloadEmployeeEcardZip/(:any)', 'EmployeeController::downloadEmployeeEcardZip/$1');
@ -812,6 +813,7 @@ $routes->group("/ticket", ["filter" => "authMVC"], function ($routes) {
$routes->get("getMoreInfo","TicketController::getMoreInfo");
$routes->post('upload_url',"TicketController::upload_url");
$routes->post('getUrlDataByTicketId',"TicketController::getUrlDataByTicketId");
$routes->post('uploadClaimFilesToTPA', 'TicketController::uploadClaimFilesToTPA');
$routes->get('remove_url',"TicketController::remove_url");
$routes->get('fetchVehiclePolicy/(:any)','TicketController::fetchVehiclePolicy/$1');
$routes->post('saveIRDocsJson',"TicketController::saveIRDocsJson");

View File

@ -908,7 +908,7 @@ class MediAssistApiController extends BaseController
return [
'status' => false,
'message' => "ClaimID not found for ticket {$claimId}"
'message' => "Claim Number not found for Claim {$claimId}"
];
}

View File

@ -33,6 +33,8 @@ use Kint\Kint;
use App\Helpers\MailHelper;
use CodeIgniter\Exceptions\PageNotFoundException;
class TicketController extends BaseController
{
use ResponseTrait;
@ -628,7 +630,14 @@ class TicketController extends BaseController
$startDate = date('Y-m-d 00:00:00', strtotime($search_data['start_date']));
$endDate = date('Y-m-d 23:59:59', strtotime($search_data['end_date']));
$rawWhere[] = "tm.updated_at BETWEEN '$startDate' AND '$endDate'";
}elseif($search_objects != "date_type" && $search_objects != "start_date" && $search_objects != "end_date"){
} elseif ($search_objects === 'tpa_claim_type') {
$cat = strtolower(trim((string) $key));
if ($cat === 'cashless') {
$rawWhere[] = "LOWER(COALESCE(tm.tpa_claim_type, '')) LIKE '%cash%'";
} elseif ($cat === 'reimbursement') {
$rawWhere[] = "LOWER(COALESCE(tm.tpa_claim_type, '')) LIKE '%reimburse%'";
}
} elseif($search_objects != "date_type" && $search_objects != "start_date" && $search_objects != "end_date"){
$where[$search_objects] = $key;
}
}
@ -2382,6 +2391,39 @@ class TicketController extends BaseController
}
}
/**
* Inline preview in browser for uploaded claim files (PDF / PNG / JPG / JPEG only).
*/
public function viewClaimFile($claim_file_id = null)
{
if ($claim_file_id === null || $claim_file_id === '') {
throw PageNotFoundException::forPageNotFound();
}
$claimFiles = new ClaimFilesModel();
$file_record = $claimFiles->where('id', $claim_file_id)->where('is_active', 1)->first();
if ($file_record === null || (int) ($file_record['file_type'] ?? 0) !== 2) {
throw PageNotFoundException::forPageNotFound();
}
$url = $file_record['url'];
$parts = explode('/', $url);
$fileName = end($parts);
$filePath = WRITEPATH . '/uploads/claim_files/' . $fileName;
if (! is_file($filePath)) {
throw PageNotFoundException::forPageNotFound();
}
$ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION) ?: '');
if (! in_array($ext, ['pdf', 'png', 'jpg', 'jpeg'], true)) {
throw PageNotFoundException::forPageNotFound();
}
return $this->response->download($filePath, null, true)->inline()->setFileName($fileName);
}
public function convertHtmlToTextOld($html)
{
if(!empty($html)){
@ -3950,7 +3992,9 @@ class TicketController extends BaseController
return $this->respond(['status' => false, 'message' => 'Ticket not found'], 404);
}
if (!empty($ticket_data['approved_letter'])) {
$claimStatusId = (int) ($ticket_data['claim_status_id'] ?? 0);
$approvedLetterReplaceStatuses = [10, 11];
if (!empty($ticket_data['approved_letter']) && !in_array($claimStatusId, $approvedLetterReplaceStatuses, true)) {
return $this->respond([
'status' => false,
'message' => 'Approved letter already available',
@ -4008,6 +4052,29 @@ class TicketController extends BaseController
}
}
public function uploadClaimFilesToTPA()
{
try {
$ticket_id = $this->request->getPost('ticket_id');
if (empty($ticket_id)) {
return $this->respond(['status' => false, 'message' => 'Ticket ID and Status ID are required'], 400);
}
$apiServiceController = new ApiServiceController();
$response = $apiServiceController->pushClaimFiles($ticket_id);
if ($response['status'] ?? false) {
return $this->respond(['status' => true, 'message' => 'Claim files uploaded to TPA successfully'], 200);
} else {
return $this->respond(['status' => false, 'message' => $response['message'] ?? 'Failed to upload claim files to TPA'], 200);
}
} catch (\Exception $e) {
$this->myLogger->logme('error', 'Error in uploadClaimFilesToTPA: ' . $e->getMessage() . ' in file ' . $e->getFile() . ' on line ' . $e->getLine() . $e->getTraceAsString());
return $this->respond(['status' => false, 'message' => 'An error occurred while uploading claim files to TPA'], 500);
}
}
// -------- CLAIM DUMP UPLOAD ----------------------------------------------------------------------------------------------
public function claimDumpUpload()

View File

@ -98,11 +98,16 @@
<div id="file_table" class="card">
<div class="card-body" style="background-color: #F5FFFF !important; border-radius: 10px; box-shadow: 0px 4px 4px 0px #00000040;">
<div class="row" style="padding-bottom: 10px;">
<div class="col-6" style="align-self: center;">
<h4 style="position: relative;">File List</h4>
<div class="row align-items-center" style="padding-bottom: 10px;">
<div class="col-md-6">
<h4 class="mb-0" style="position: relative;">File List</h4>
</div>
<div class="col-md-6 text-md-right mt-2 mt-md-0">
<button type="button" class="btn btn-primary waves-effect waves-light"
id="btn_upload_claim_files_to_tpa">
Upload files to TPA
</button>
</div>
</div>
<div class="table-responsive" style="overflow-x: auto;">
<table data-custom-table-css="table" id="scroll-horizontal-datatable" class="table w-100 nowrap">
@ -111,6 +116,7 @@
<th class="text-center">S.No&nbsp;</th>
<th>Docs Name&nbsp;</th>
<th>File Name&nbsp;</th>
<th class="text-center">Sent to TPA&nbsp;</th>
<th>Action&nbsp;</th>
</tr>
</thead>
@ -167,7 +173,60 @@
let ticket_id = $('#ticket_master_id').val();
$('#ticket_id_url').val(ticket_id);
let urlData = getUrlDataByTicketId(ticket_id);
})
});
function getClaimFileListTicketId() {
var id = $('#ticket_master_id').val();
if (!id) {
id = $('#ticket_id_url').val();
}
return id;
}
$(document).on('click', '#btn_upload_claim_files_to_tpa', function () {
var ticket_id = getClaimFileListTicketId();
if (!ticket_id) {
toastr.warning('Ticket ID is missing. Please reload the page.', 'Validation');
return;
}
var $btn = $(this);
$.ajax({
url: "<?= base_url('ticket/uploadClaimFilesToTPA') ?>",
type: "POST",
data: { ticket_id: ticket_id },
dataType: "json",
beforeSend: function () {
$btn.prop('disabled', true);
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
},
success: function (res) {
if (res && res.status === true) {
toastr.success(res.message || 'Claim files uploaded to TPA successfully', 'Success');
getUrlDataByTicketId(ticket_id);
} else {
toastr.error((res && res.message) ? res.message : 'Failed to upload claim files to TPA', 'Error');
}
},
error: function (xhr) {
if (xhr.status === 400 || xhr.status === 500) {
try {
var r = JSON.parse(xhr.responseText);
toastr.error(r.message || 'Request failed', 'Error');
} catch (e) {
toastr.error('Request failed', 'Error');
}
} else {
toastr.error('An unexpected error occurred. Please try again later.', 'Error');
}
},
complete: function () {
$btn.prop('disabled', false);
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
}
});
});
$("#drive_file_upload_form").submit(function(event) {
@ -386,6 +445,60 @@
return false;
});
function escapeClaimFileListAttr(s) {
return String(s == null ? '' : s)
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/</g, '&lt;')
.replace(/'/g, '&#39;');
}
function claimFileListExtension(name) {
if (!name) {
return '';
}
var m = String(name).toLowerCase().match(/\.([a-z0-9]+)$/);
return m ? m[1] : '';
}
function claimFileListExtensionFromUrl(url) {
if (!url) {
return '';
}
try {
var path = String(url).split(/[?#]/)[0];
var seg = path.split('/').pop() || '';
var m = seg.toLowerCase().match(/\.([a-z0-9]+)$/);
return m ? m[1] : '';
} catch (e) {
return '';
}
}
function claimFileViewSupported(item) {
var mime = String(item.mime_type || '').toLowerCase();
if (mime === 'application/pdf' || mime === 'image/png' || mime === 'image/jpeg') {
return true;
}
var ext = '';
if (item.file_type == 2 || item.file_type === '2') {
ext = claimFileListExtension(item.file_name) || claimFileListExtension(item.doc_name);
} else {
ext = claimFileListExtensionFromUrl(item.url);
if (!ext) {
ext = claimFileListExtension(item.doc_name);
}
}
return ['pdf', 'png', 'jpg', 'jpeg'].indexOf(ext) !== -1;
}
function claimFileViewOpenUrl(item, base_url) {
if (item.file_type == 2 || item.file_type === '2') {
return base_url + 'viewClaimFile/' + encodeURIComponent(item.id);
}
return String(item.url || '');
}
function create_url_list(data) {
$('#table_bd').empty(); // clear existing rows
@ -395,12 +508,29 @@
let html = "";
data.forEach((item, index) => {
const sentToTpa = item.is_file_sent_to_tpa == 1 || item.is_file_sent_to_tpa === true || item.is_file_sent_to_tpa === '1';
const tpaBadgeClass = sentToTpa ? 'badge-success' : 'badge-secondary';
const tpaLabel = sentToTpa ? 'Yes' : 'No';
const viewOk = claimFileViewSupported(item);
const viewHref = escapeClaimFileListAttr(claimFileViewOpenUrl(item, base_url));
const viewSupportedAttr = viewOk ? '1' : '0';
const viewIconClass = viewOk ? 'text-primary' : 'text-muted';
const viewTitle = viewOk ? 'View in new tab' : 'Preview not available for this format';
html += `
<tr>
<td class="text-center">${index + 1}</td>
<td>${item.doc_name}</td>
<td><a href="${item.url}" target="_blank">${item.file_type == 1 ? item.url : item.doc_name}</a></td>
<td class="text-center">
<span class="badge ${tpaBadgeClass}" style="font-size:13px; padding:8px 12px; font-weight:600;">${tpaLabel}</span>
</td>
<td>
<a href="javascript:void(0);" class="view-claim-file ${viewIconClass} mr-2" title="${viewTitle}"
style="${viewOk ? '' : 'opacity:0.7;'}"
data-view-url="${viewHref}"
data-view-supported="${viewSupportedAttr}">
<i class="mdi mdi-eye"></i>
</a>
<a href="javascript:void(0);" class="delete-url"
style="bacolor:black;"
data-href="${base_url}/ticket/remove_url?id=${item.id}">
@ -413,10 +543,23 @@
$('#table_bd').append(html);
} else {
$('#table_bd').html('<tr><td colspan="4">No Data Found</td></tr>');
$('#table_bd').html('<tr><td colspan="5">No Data Found</td></tr>');
}
}
$(document).on('click', '.view-claim-file', function (e) {
e.preventDefault();
var supported = $(this).data('view-supported') == 1 || $(this).data('view-supported') === '1';
var viewUrl = $(this).attr('data-view-url');
if (!supported) {
toastr.warning('Not supported format. Only PDF and images (PNG, JPG, JPEG) can be previewed.', 'View file');
return;
}
if (viewUrl) {
window.open(viewUrl, '_blank', 'noopener,noreferrer');
}
});
$(document).on('click', '.delete-url', function (e) {
e.preventDefault();
const url = $(this).data('href');

View File

@ -6,13 +6,14 @@
<div class="form-row">
<?php
$approvedLetterReplyStatuses = [10, 11];
$showApprovedStatusDropdown =
isset($ticket_data['claim_status_id'], $ticket_data['ticket_type_id']) && (int) $ticket_data['claim_status_id'] === 10 && (int) $ticket_data['ticket_type_id'] === 1 &&
isset($ticket_data['claim_status_id'], $ticket_data['ticket_type_id']) && in_array((int) $ticket_data['claim_status_id'], $approvedLetterReplyStatuses, true) && (int) $ticket_data['ticket_type_id'] === 1 &&
(
(isset($ticket_data['claim_created_by']) && $ticket_data['claim_created_by'] == 'TPA') ||
(array_key_exists('tpa_claim_push_reference_no', $ticket_data) && $ticket_data['tpa_claim_push_reference_no'] !== null)
);
$approvedLetterEmpty = !empty($ticket_data['approved_letter'] ?? null);
?>
<?php if ($showApprovedStatusDropdown): ?>
@ -31,6 +32,13 @@
<input type="text" value="<?= isset($ticket_data['emp_mail'])?$ticket_data['emp_mail']:'' ?>" class="form-control" id="emp_mail_for_to" name="emp_mail" placeholder="Recipient email" readonly>
</div>
<?php if ($showApprovedStatusDropdown && $approvedLetterEmpty): ?>
<div class="form-group col-md-4" style="margin-top: 30px;">
<button type="button" class="btn btn-secondary btn-sm w-100" id="approved_letter_reupload_btn">Re-upload approved letter</button>
</div>
<?php endif; ?>
<!-- Subject Field -->
<div class="form-group col-md-8">
<label for="mail_subject">Subject</label>
@ -223,6 +231,7 @@ const editorConfig = {
$(document).ready(function() {
const replyTicketId = `<?= isset($ticket_data['id']) ? (int) $ticket_data['id'] : 0 ?>`;
const replyClaimStatusId = `<?= isset($ticket_data['claim_status_id']) ? (int) $ticket_data['claim_status_id'] : 0 ?>`;
let replyApprovedLetter = <?= json_encode($ticket_data['approved_letter'] ?? null) ?>;
console.log('Approved Letter from server:', replyApprovedLetter);
@ -457,6 +466,12 @@ $(document).ready(function() {
toastr.success(res.message || 'Approved letter uploaded successfully', 'Success');
cleanup();
approvedLetterModalInstance.hide();
const templateStatusId = String(statusId);
if ($('#status_back_option').length) {
$('#status_back_option').val(templateStatusId);
}
$('#claim_status').val(templateStatusId);
loadClaimTemplateForStatus(ticketId, templateStatusId);
dfd.resolve();
} else {
$uploadBtn.prop('disabled', false);
@ -480,17 +495,25 @@ $(document).ready(function() {
return;
}
if (String(selectedStatusId) === '9' && !hasApprovedLetterValue(replyApprovedLetter)) {
openApprovedLetterUploadModalAndHandle(replyTicketId, selectedStatusId)
.done(function() {
loadClaimTemplateForStatus(replyTicketId, selectedStatusId);
});
const needsApprovedLetterModal =
String(replyClaimStatusId) === '11' || !hasApprovedLetterValue(replyApprovedLetter);
if (String(selectedStatusId) === '9' && needsApprovedLetterModal) {
openApprovedLetterUploadModalAndHandle(replyTicketId, selectedStatusId);
return;
}
loadClaimTemplateForStatus(replyTicketId, selectedStatusId);
}
$('#approved_letter_reupload_btn').on('click', function() {
if (!replyTicketId) {
return;
}
openApprovedLetterUploadModalAndHandle(replyTicketId, '9')
.done(function() {});
});
$('#status_back_option').on('change', function() {
handleStatusTemplateFlow();
});

View File

@ -74,6 +74,15 @@
?>
</select>
</div>
<div class="form-group col-md-12">
<label for="tpa_claim_type">Claim category<span class="text-danger"></span></label>
<select class="form-control" id="tpa_claim_type" name="tpa_claim_type">
<option value="0">Select claim category</option>
<option value="cashless">Cashless</option>
<option value="reimbursement">Reimbursement</option>
</select>
</div>
<div class="form-group col-md-12">
<label for="insurer_id">Insurer<span class="text-danger"></span></label>
<select class="form-control" id="insurer_id" name="insurer_id">
@ -130,6 +139,18 @@
<input type="text" class="form-control" id="emp_mobile_no" name="emp_mobile_no" maxlength="10" pattern="[0-9]{10}" inputmode="numeric" oninput="this.value = this.value.replace(/[^0-9]/g, '')">
</div>
<div class="form-group col-md-12">
<label for="claim_created_by">Claim created by<span class="text-danger"></span></label>
<select class="form-control" id="claim_created_by" name="claim_created_by">
<option value="0">Select claim source</option>
<option value="CRM">CRM</option>
<option value="TPA">TPA</option>
<option value="USER">USER</option>
<option value="DUMP">DUMP</option>
<option value="DUMP_TPA">DUMP_TPA</option>
</select>
</div>
<div class="form-group col-md-12">
<label for="claim_status">Status<span class="text-danger"></span></label>
<select class="form-control" id="claim_status" name="claim_status">
@ -237,6 +258,8 @@
var client_id = $('#client_id').val();
var insurer_id = $('#insurer_id').val();
var tpa_id = $('#tpa_id').val();
var tpa_claim_type = $('#tpa_claim_type').val();
var claim_created_by = $('#claim_created_by').val();
var start_date = $('#startDate').val();
var end_date = $('#endDate').val();
@ -246,7 +269,7 @@
return value === null || value === undefined || value.toString().trim() === '' || value == 0;
}
if (isEmpty(ticket_type) && isEmpty(claim_no) && isEmpty(emp_code) && isEmpty(claim_status) && isEmpty(emp_mobile_no) && isEmpty(tpa_id) && isEmpty(client_id) && isEmpty(insurer_id) && isEmpty(date_type)) {
if (isEmpty(ticket_type) && isEmpty(claim_no) && isEmpty(emp_code) && isEmpty(claim_status) && isEmpty(emp_mobile_no) && isEmpty(tpa_id) && isEmpty(client_id) && isEmpty(insurer_id) && isEmpty(date_type) && isEmpty(tpa_claim_type) && isEmpty(claim_created_by)) {
toastr.warning('Please enter at least one search criteria.');
return false;
}
@ -268,6 +291,8 @@
client_id: client_id,
insurer_id: insurer_id,
tpa_id: tpa_id,
tpa_claim_type: tpa_claim_type,
claim_created_by: claim_created_by,
start_date: start_date,
end_date: end_date,
date_type: date_type,
@ -364,6 +389,8 @@
$('#client_id').val(filterData.client_id);
$('#insurer_id').val(filterData.insurer_id);
$('#tpa_id').val(filterData.tpa_id);
$('#tpa_claim_type').val(filterData.tpa_claim_type || '0');
$('#claim_created_by').val(filterData.claim_created_by || '0');
$('#date_type').val(filterData.date_type);
if(filterData.date_type == '0'){
$('#date_div').hide();
@ -437,6 +464,8 @@
$('#end_date').val('');
$('#claim_status').val('0').select2();
$('#tpa_claim_type').val('0');
$('#claim_created_by').val('0');
$('#tpa_id').val('0').select2();
$('#client_id').val('0').select2();
$('#insurer_id').val('0').select2();