GWM : Manual merge option
This commit is contained in:
parent
413180a565
commit
a2865f1096
@ -818,6 +818,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('manualMergeClaimFiles', 'TicketController::manualMergeClaimFiles');
|
||||
$routes->post('uploadClaimFilesToTPA', 'TicketController::uploadClaimFilesToTPA');
|
||||
$routes->get('remove_url',"TicketController::remove_url");
|
||||
$routes->get('fetchVehiclePolicy/(:any)','TicketController::fetchVehiclePolicy/$1');
|
||||
|
||||
@ -3721,9 +3721,78 @@ class TicketController extends BaseController
|
||||
->where('is_active', 1)
|
||||
->findAll();
|
||||
|
||||
helper('merge_pdf');
|
||||
$mergeUi = merge_ticket_manual_merge_status((int) $ticket_id);
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => true,
|
||||
'data' => $urlData
|
||||
'status' => true,
|
||||
'data' => $urlData,
|
||||
'merge_ui' => $mergeUi,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually merge claim PDF/image files for a ticket (Claim Files tab).
|
||||
*/
|
||||
public function manualMergeClaimFiles()
|
||||
{
|
||||
$ticket_id = (int) $this->request->getPost('ticket_id');
|
||||
|
||||
if ($ticket_id <= 0) {
|
||||
return $this->response->setStatusCode(400)->setJSON([
|
||||
'status' => false,
|
||||
'message' => 'Ticket ID is required',
|
||||
]);
|
||||
}
|
||||
|
||||
helper('merge_pdf');
|
||||
|
||||
$mergeUi = merge_ticket_manual_merge_status($ticket_id);
|
||||
if (! $mergeUi['show_manual_merge'] && $mergeUi['mergeable_count'] < 1) {
|
||||
return $this->response->setStatusCode(400)->setJSON([
|
||||
'status' => false,
|
||||
'message' => 'No PDF or image files available on disk to merge.',
|
||||
]);
|
||||
}
|
||||
|
||||
$ticket = $this->ticketMasterModel
|
||||
->select('id, ticket_type_id')
|
||||
->where('id', $ticket_id)
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
|
||||
if (! $ticket) {
|
||||
return $this->response->setStatusCode(404)->setJSON([
|
||||
'status' => false,
|
||||
'message' => 'Claim not found.',
|
||||
]);
|
||||
}
|
||||
|
||||
try {
|
||||
$result = merge_ticket_pdfs($ticket_id, [
|
||||
'ticket_type' => (int) ($ticket['ticket_type_id'] ?? 1),
|
||||
'created_by' => function_exists('get_session_userid') ? get_session_userid() : null,
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'TicketController::manualMergeClaimFiles | ticket_id=' . $ticket_id . ' | ' . $e->getMessage());
|
||||
return $this->response->setStatusCode(500)->setJSON([
|
||||
'status' => false,
|
||||
'message' => 'Merge failed: ' . $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
|
||||
if (! ($result['status'] ?? false)) {
|
||||
return $this->response->setJSON([
|
||||
'status' => false,
|
||||
'message' => $result['message'] ?? 'Merge failed. Check logs for details.',
|
||||
'data' => $result,
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => true,
|
||||
'message' => $result['message'] ?? 'Documents merged successfully.',
|
||||
'data' => $result,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -86,13 +86,8 @@ if (! function_exists('merge_ticket_pdfs')) {
|
||||
|
||||
$sourceFiles = [];
|
||||
foreach ($rows as $row) {
|
||||
$name = ! empty($row['url']) ? $row['url'] : ($row['file_name'] ?? '');
|
||||
if (empty($name)) {
|
||||
continue;
|
||||
}
|
||||
// url column may sometimes hold a full URL; we only care about the file basename on disk.
|
||||
$full = $uploadDir . basename($name);
|
||||
if (is_file($full) && is_readable($full)) {
|
||||
$full = merge_ticket_pdf_resolve_disk_path($row, $uploadDir);
|
||||
if ($full !== null) {
|
||||
$mime = merge_ticket_pdf_resolve_mime($full, (string) ($row['mime_type'] ?? ''));
|
||||
if (! in_array($mime, $opts['include_mime_types'], true)) {
|
||||
log_message('error', "merge_ticket_pdfs | unsupported source mime {$mime} | claim_file_id={$row['id']} | path={$full}");
|
||||
@ -105,7 +100,8 @@ if (! function_exists('merge_ticket_pdfs')) {
|
||||
'id' => $row['id'] ?? null,
|
||||
];
|
||||
} else {
|
||||
log_message('error', "merge_ticket_pdfs | missing file on disk | claim_file_id={$row['id']} | path={$full}");
|
||||
$name = ! empty($row['url']) ? $row['url'] : ($row['file_name'] ?? '');
|
||||
log_message('error', "merge_ticket_pdfs | missing file on disk | claim_file_id={$row['id']} | path=" . $uploadDir . basename((string) $name));
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,10 +336,50 @@ if (! function_exists('merge_ticket_pdf_resolve_mime')) {
|
||||
return 'image/png';
|
||||
}
|
||||
|
||||
if (in_array($detectedMime, ['application/octet-stream', 'binary/octet-stream'], true)) {
|
||||
if ($ext === 'pdf') {
|
||||
return 'application/pdf';
|
||||
}
|
||||
if (in_array($ext, ['jpg', 'jpeg'], true)) {
|
||||
return 'image/jpeg';
|
||||
}
|
||||
if ($ext === 'png') {
|
||||
return 'image/png';
|
||||
}
|
||||
}
|
||||
|
||||
return $detectedMime ?: ($storedMime ?: 'application/octet-stream');
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('merge_ticket_pdf_resolve_disk_path')) {
|
||||
/**
|
||||
* Resolve on-disk path for a claim_files row (url and/or file_name).
|
||||
*/
|
||||
function merge_ticket_pdf_resolve_disk_path(array $row, string $uploadDir): ?string
|
||||
{
|
||||
$candidates = [];
|
||||
if (! empty($row['url'])) {
|
||||
$candidates[] = basename((string) $row['url']);
|
||||
}
|
||||
if (! empty($row['file_name'])) {
|
||||
$candidates[] = basename((string) $row['file_name']);
|
||||
}
|
||||
|
||||
foreach (array_unique($candidates) as $name) {
|
||||
if ($name === '' || preg_match('#^https?://#i', $name)) {
|
||||
continue;
|
||||
}
|
||||
$full = $uploadDir . $name;
|
||||
if (is_file($full) && is_readable($full)) {
|
||||
return $full;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('merge_ticket_pdf_add_image_page')) {
|
||||
/**
|
||||
* Add an uploaded image as a single PDF page, preserving portrait/landscape
|
||||
@ -397,3 +433,86 @@ if (! function_exists('merge_ticket_pdf_add_image_page')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('merge_ticket_manual_merge_status')) {
|
||||
/**
|
||||
* UI/status helper: whether manual merge should be offered on Claim Files tab.
|
||||
*
|
||||
* @return array{
|
||||
* has_merged_file: bool,
|
||||
* mergeable_count: int,
|
||||
* show_manual_merge: bool,
|
||||
* button_label: string
|
||||
* }
|
||||
*/
|
||||
function merge_ticket_manual_merge_status(int $ticket_master_id, array $opts = []): array
|
||||
{
|
||||
$opts += [
|
||||
'include_file_types' => [1, 2],
|
||||
'include_mime_types' => ['application/pdf', 'image/jpeg', 'image/png'],
|
||||
];
|
||||
|
||||
$status = [
|
||||
'has_merged_file' => false,
|
||||
'mergeable_count' => 0,
|
||||
'show_manual_merge' => false,
|
||||
'button_label' => 'Merge documents',
|
||||
];
|
||||
|
||||
if ($ticket_master_id <= 0) {
|
||||
return $status;
|
||||
}
|
||||
|
||||
$claimFiles = new ClaimFilesModel();
|
||||
$rows = $claimFiles
|
||||
->where('ticket_id', $ticket_master_id)
|
||||
->where('is_active', 1)
|
||||
->whereIn('file_type', array_merge($opts['include_file_types'], [MERGED_CLAIM_FILE_TYPE]))
|
||||
->orderBy('id', 'ASC')
|
||||
->findAll();
|
||||
|
||||
$uploadDir = rtrim(WRITEPATH, '/\\') . DIRECTORY_SEPARATOR
|
||||
. 'uploads' . DIRECTORY_SEPARATOR
|
||||
. 'claim_files' . DIRECTORY_SEPARATOR;
|
||||
|
||||
$mergeableCount = 0;
|
||||
$sourceRowCount = 0;
|
||||
foreach ($rows as $row) {
|
||||
if ((int) ($row['file_type'] ?? 0) === MERGED_CLAIM_FILE_TYPE) {
|
||||
$status['has_merged_file'] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! in_array((int) ($row['file_type'] ?? 0), $opts['include_file_types'], true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sourceRowCount++;
|
||||
|
||||
$full = merge_ticket_pdf_resolve_disk_path($row, $uploadDir);
|
||||
if ($full === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$mime = merge_ticket_pdf_resolve_mime($full, (string) ($row['mime_type'] ?? ''));
|
||||
if (in_array($mime, $opts['include_mime_types'], true)) {
|
||||
$mergeableCount++;
|
||||
}
|
||||
}
|
||||
|
||||
$status['mergeable_count'] = $mergeableCount;
|
||||
|
||||
// Show manual merge when there is no merged file but user has uploaded docs in the list.
|
||||
if (! $status['has_merged_file']) {
|
||||
if ($mergeableCount >= 1 || $sourceRowCount >= 2) {
|
||||
$status['show_manual_merge'] = true;
|
||||
$status['button_label'] = 'Merge documents';
|
||||
}
|
||||
} elseif ($mergeableCount >= 2) {
|
||||
$status['show_manual_merge'] = true;
|
||||
$status['button_label'] = 'Re-merge documents';
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,6 +103,11 @@
|
||||
<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-warning waves-effect waves-light mr-2 d-none"
|
||||
id="btn_manual_merge_claim_files"
|
||||
title="Combine uploaded PDFs and images into one file">
|
||||
Merge documents
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary waves-effect waves-light"
|
||||
id="btn_upload_claim_files_to_tpa">
|
||||
Upload files to TPA
|
||||
@ -170,9 +175,18 @@
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let ticket_id = $('#ticket_master_id').val();
|
||||
let ticket_id = getClaimFileListTicketId();
|
||||
$('#ticket_id_url').val(ticket_id);
|
||||
let urlData = getUrlDataByTicketId(ticket_id);
|
||||
if (ticket_id) {
|
||||
getUrlDataByTicketId(ticket_id);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('shown.bs.tab', 'a[href="#uploads-tab"], #uploads_tab', function () {
|
||||
var ticket_id = getClaimFileListTicketId();
|
||||
if (ticket_id) {
|
||||
getUrlDataByTicketId(ticket_id);
|
||||
}
|
||||
});
|
||||
|
||||
function getClaimFileListTicketId() {
|
||||
@ -183,6 +197,88 @@
|
||||
return id;
|
||||
}
|
||||
|
||||
function resolveManualMergeUi(serverMergeUi, fileListData) {
|
||||
if (serverMergeUi && serverMergeUi.show_manual_merge) {
|
||||
return serverMergeUi;
|
||||
}
|
||||
if (!fileListData || !fileListData.length) {
|
||||
return serverMergeUi || { show_manual_merge: false };
|
||||
}
|
||||
var hasMerged = fileListData.some(function (item) {
|
||||
return item.file_type == 4 || item.file_type === '4';
|
||||
});
|
||||
var sourceCount = fileListData.filter(function (item) {
|
||||
return item.file_type == 1 || item.file_type === '1'
|
||||
|| item.file_type == 2 || item.file_type === '2';
|
||||
}).length;
|
||||
if (!hasMerged && sourceCount >= 1) {
|
||||
return {
|
||||
show_manual_merge: true,
|
||||
button_label: 'Merge documents',
|
||||
mergeable_count: sourceCount
|
||||
};
|
||||
}
|
||||
return serverMergeUi || { show_manual_merge: false };
|
||||
}
|
||||
|
||||
function updateManualMergeButton(mergeUi, fileListData) {
|
||||
var $btn = $('#btn_manual_merge_claim_files');
|
||||
if (!$btn.length) {
|
||||
return;
|
||||
}
|
||||
var resolved = resolveManualMergeUi(mergeUi, fileListData);
|
||||
if (resolved && resolved.show_manual_merge) {
|
||||
$btn.removeClass('d-none').css('display', 'inline-block');
|
||||
$btn.text(resolved.button_label || 'Merge documents');
|
||||
$btn.prop('disabled', false);
|
||||
} else {
|
||||
$btn.addClass('d-none').css('display', '');
|
||||
}
|
||||
}
|
||||
|
||||
$(document).on('click', '#btn_manual_merge_claim_files', 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/manualMergeClaimFiles') ?>",
|
||||
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 || 'Documents merged successfully', 'Success');
|
||||
getUrlDataByTicketId(ticket_id);
|
||||
} else {
|
||||
toastr.error((res && res.message) ? res.message : 'Failed to merge documents', 'Error');
|
||||
}
|
||||
},
|
||||
error: function (xhr) {
|
||||
var msg = 'Failed to merge documents';
|
||||
try {
|
||||
var r = JSON.parse(xhr.responseText);
|
||||
if (r.message) {
|
||||
msg = r.message;
|
||||
}
|
||||
} catch (e) {}
|
||||
toastr.error(msg, 'Error');
|
||||
},
|
||||
complete: function () {
|
||||
$btn.prop('disabled', false);
|
||||
$('.loader').fadeOut();
|
||||
$('.loader-mask').delay(350).fadeOut('slow');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '#btn_upload_claim_files_to_tpa', function () {
|
||||
var ticket_id = getClaimFileListTicketId();
|
||||
if (!ticket_id) {
|
||||
@ -395,10 +491,13 @@
|
||||
console.log('Form submitted response:', response);
|
||||
|
||||
if (response.status === true) {
|
||||
window._claimFilesMergeUi = response.merge_ui || null;
|
||||
create_url_list(response.data);
|
||||
updateManualMergeButton(response.merge_ui, response.data);
|
||||
addHTMLInput();
|
||||
return ;
|
||||
} else {
|
||||
updateManualMergeButton(null, []);
|
||||
addHTMLInput();
|
||||
console.warn("No Data");
|
||||
}
|
||||
@ -555,6 +654,7 @@
|
||||
} else {
|
||||
$('#table_bd').html('<tr><td colspan="5">No Data Found</td></tr>');
|
||||
}
|
||||
updateManualMergeButton(window._claimFilesMergeUi || null, data || []);
|
||||
}
|
||||
|
||||
$(document).on('click', '.delete-url', function (e) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user