1091 lines
44 KiB
PHP
1091 lines
44 KiB
PHP
<div class="tab-pane" id="fileupload">
|
|
|
|
<div id="required_id_docs_div" class="card">
|
|
<div class="card-body" style="background-color: #F5FFFF !important; border-radius: 10px; box-shadow: 0px 4px 4px 0px #00000040;">
|
|
<div class="form-group">
|
|
<!-- Header Row: Title + Switch + Save -->
|
|
<div class="row mb-3 align-items-center">
|
|
<div class="col-md-6">
|
|
<h5 class="mb-0"><strong>IR Documents</strong></h5>
|
|
</div>
|
|
<div class="col-md-6 text-right">
|
|
<div class="d-inline-block mr-3">
|
|
<div class="custom-control custom-switch d-inline-block">
|
|
<input type="checkbox" class="custom-control-input"
|
|
id="action_freeze_switch"
|
|
onchange="toggleActionFreeze()">
|
|
<label class="custom-control-label" for="action_freeze_switch">
|
|
<strong>Freeze User Actions</strong>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<button type="button"
|
|
class="btn btn-success waves-effect waves-light"
|
|
onclick="saveConfiguration()"> Save
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Document List Container (same Document Name rules as claim upload card: ticketdocname) -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-12">
|
|
<form id="ir_documents_form" class="parsley-examples" novalidate
|
|
data-parsley-validation-threshold="0">
|
|
<!-- Header Row -->
|
|
<div class="form-row mb-2">
|
|
<div class="col-md-7"><strong>Document Name</strong></div>
|
|
<div class="col-md-3"><strong>Status</strong></div>
|
|
<div class="col-md-2 text-center"><strong>Action</strong></div>
|
|
</div>
|
|
|
|
<!-- Dynamic Document Rows -->
|
|
<div id="document-list-container"></div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Hidden field to store JSON data for form submission -->
|
|
<input type="hidden" id="document_config_json" name="document_config">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-xl-12">
|
|
<div id="accordion" class="mb-3">
|
|
<div class="card mb-1" style="background-color: #F5FFFF !important; border-radius: 10px; box-shadow: 0px 4px 4px 0px #00000040;">
|
|
<h5 class="m-1">
|
|
<a id="toggleIcon" class="text-dark float-right" data-toggle="collapse" href="#collapseOne"
|
|
aria-expanded="true">
|
|
<i id="icon" class="mdi mdi-chevron-down mr-1 text-primary" style="font-size: 28px;color:black;"></i>
|
|
</a>
|
|
</h5>
|
|
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
|
|
<div class="card-body">
|
|
<form class="parsley-examples" id="drive_file_upload_form" method="post"
|
|
enctype="multipart/form-data" novalidate
|
|
data-parsley-validation-threshold="0">
|
|
|
|
<input type="hidden" id="ticket_id_url" name="ticket_id_url">
|
|
|
|
<div class="form-group">
|
|
|
|
<div id="dynamic-form-container">
|
|
<div align="right">
|
|
<a id="toggle-upload-btn" class="btn btn-info waves-effect waves-light mr-1" onclick="toggleUploadType(this)">
|
|
File Upload
|
|
</a>
|
|
<a class="btn btn-primary waves-effect waves-light" id="add_btn_for_claim_file_upload" onclick="addHTMLInput(this)">+ Add</a>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="form-group text-right m-b-0">
|
|
<button type="submit" class="btn btn-primary waves-effect waves-light mr-1"
|
|
id="g_drive_file_upload_sbt_btn">Save</button>
|
|
</div>
|
|
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<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 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-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
|
|
</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">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th class="text-center">S.No </th>
|
|
<th>Docs Name </th>
|
|
<th>File Name </th>
|
|
<th class="text-center">Sent to TPA </th>
|
|
<th>Action </th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="table_bd">
|
|
</tbody>
|
|
</table>
|
|
<div>
|
|
</div>
|
|
</div>
|
|
</div><!-- end col -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- edit modal -->
|
|
<div class="modal fade" id="edit_url_modal" tabindex="-1" role="dialog" aria-labelledby="editUrlModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog" role="document">
|
|
<form id="edit_url_form" class="parsley-examples" novalidate
|
|
data-parsley-validation-threshold="0">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Edit URL</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span>×</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<input type="hidden" id="edit_url_id" name="id">
|
|
|
|
<div class="form-group">
|
|
<label for="edit_doc_name">Document Name</label>
|
|
<input type="text" class="form-control" id="edit_doc_name" name="doc_name"
|
|
data-parsley-ticketdocname-message="Document name can only contain letters, numbers, spaces, hyphens, and underscores.">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="edit_url_link">URL</label>
|
|
<input type="text" class="form-control" id="edit_url_link" name="url"
|
|
data-parsley-ticketclaimurl-message="Enter a valid web address (e.g. https://example.com/path?x=1 or example.com).">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="submit" class="btn btn-primary">Save Changes</button>
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
$(document).ready(function(){
|
|
let ticket_id = getClaimFileListTicketId();
|
|
$('#ticket_id_url').val(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() {
|
|
var id = $('#ticket_master_id').val();
|
|
if (!id) {
|
|
id = $('#ticket_id_url').val();
|
|
}
|
|
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) {
|
|
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) {
|
|
|
|
event.preventDefault();
|
|
|
|
if (typeof window.validateTicketFormInputs === 'function' && !window.validateTicketFormInputs(this)) {
|
|
toastr.warning('Form validation failed. Please correct the highlighted fields.', 'Validation');
|
|
var $form = $(this);
|
|
var $first = $form.find('.parsley-error').first();
|
|
if (!$first.length) {
|
|
$first = $form.find('input.parsley-error, select.parsley-error, textarea.parsley-error').first();
|
|
}
|
|
if ($first.length) {
|
|
$('html, body').animate({ scrollTop: $first.offset().top - 100 }, 400);
|
|
$first.focus();
|
|
}
|
|
return;
|
|
}
|
|
|
|
var badFileExt = false;
|
|
$('#drive_file_upload_form input[type=file]').each(function () {
|
|
if (!this.files || !this.files.length) {
|
|
return;
|
|
}
|
|
if (!/\.(pdf|jpe?g|png)$/i.test(this.files[0].name)) {
|
|
badFileExt = true;
|
|
return false;
|
|
}
|
|
});
|
|
if (badFileExt) {
|
|
toastr.warning('Only PDF, JPG, JPEG, and PNG files are allowed.', 'Validation');
|
|
return;
|
|
}
|
|
|
|
if (typeof window.validateGlobalUploadPayload === 'function' && !window.validateGlobalUploadPayload(this)) {
|
|
return;
|
|
}
|
|
|
|
form_action = '<?php echo base_url() . 'ticket/upload_url' ?>';
|
|
|
|
$('.loader').fadeIn();
|
|
$('.loader-mask').fadeIn();
|
|
|
|
var formData = new FormData($('#drive_file_upload_form')[0]);
|
|
|
|
|
|
|
|
$.ajax({
|
|
data:formData,
|
|
url: form_action,
|
|
type: "POST",
|
|
dataType: 'json',
|
|
processData: false,
|
|
contentType: false,
|
|
success: function(res) {
|
|
|
|
$('.loader').fadeOut();
|
|
$('.loader-mask').delay(350).fadeOut('slow');
|
|
|
|
if(res.status == true){
|
|
toastr.success(res.message, 'Success');
|
|
window.location.reload();
|
|
}else{
|
|
toastr.error(res.message, 'Error');
|
|
}
|
|
|
|
},
|
|
error: function (xhr, status, error) {
|
|
console.log("error in submission of url data");
|
|
console.error(xhr.responseText);
|
|
console.error(status, error);
|
|
if (xhr.status === 400) {
|
|
let response = JSON.parse(xhr.responseText);
|
|
let errorMessages = "";
|
|
let seenMessages = []; // Array to store unique messages
|
|
if (response.errors) {
|
|
$.each(response.errors, function (field, message) {
|
|
if (!seenMessages.includes(message)) {
|
|
errorMessages += `• ${message}<br>`;
|
|
seenMessages.push(message); // Mark this message as "seen"
|
|
}
|
|
});
|
|
toastr.error(errorMessages, 'Validation Error', { "allowHtml": true });
|
|
} else {
|
|
toastr.warning(response.message || 'Validation failed', 'Warning');
|
|
}
|
|
} else if (xhr.status === 403) {
|
|
let response = JSON.parse(xhr.responseText);
|
|
toastr.error(response.message, 'Security Policy');
|
|
} else if (xhr.status === 500) {
|
|
toastr.error('Something went wrong . Please try again later.', 'Server Error');
|
|
} else {
|
|
toastr.error('An unexpected error occurred. Please try again later.', 'Error');
|
|
}
|
|
|
|
},
|
|
complete : function(){
|
|
console.log("ajax call is completed for submission of url data..!!");
|
|
$('.loader').fadeOut();
|
|
$('.loader-mask').delay(350).fadeOut('slow');
|
|
}
|
|
});
|
|
});
|
|
|
|
function addHTMLInput() {
|
|
const container = document.getElementById('dynamic-form-container');
|
|
const rowKey = 'u_' + Date.now() + '_' + Math.floor(Math.random() * 10000);
|
|
const docsId = 'docs_name_' + rowKey;
|
|
const urlId = 'url_name_' + rowKey;
|
|
const newRow = document.createElement('div');
|
|
newRow.className = 'form-row dynamic-form-row';
|
|
newRow.innerHTML = `
|
|
<div class="form-group col-md-5">
|
|
<label for="${docsId}">Document Name<span class="text-danger">*</span></label>
|
|
<input type="text" class="form-control" id="${docsId}" name="docs_name[]" placeholder="Enter file name" required
|
|
data-parsley-required-message="Document name is required."
|
|
data-parsley-ticketdocname-message="Document name can only contain letters, numbers, spaces, hyphens, and underscores."
|
|
value=""
|
|
>
|
|
</div>
|
|
<div class="form-group col-md-5">
|
|
<label for="${urlId}">URL<span class="text-danger">*</span></label>
|
|
<input type="text" class="form-control" id="${urlId}" name="url[]" required
|
|
data-parsley-required-message="URL is required."
|
|
data-parsley-ticketclaimurl-message="Enter a valid web address (e.g. https://example.com/path?x=1 or example.com)."
|
|
value=""
|
|
>
|
|
</div>
|
|
<div class="form-group col-md-2" style="position: relative;top: 28px;">
|
|
<a class="btn btn-danger waves-effect waves-light" onclick="removeHTMLInput(this)" style="background-color: #BD0707;">
|
|
<i class="mdi mdi-delete" ></i>
|
|
</a>
|
|
</div>
|
|
`;
|
|
container.appendChild(newRow);
|
|
if (typeof window.refreshTicketFormValidationForForm === 'function') {
|
|
window.refreshTicketFormValidationForForm('#drive_file_upload_form');
|
|
}
|
|
}
|
|
|
|
function removeHTMLInput(element) {
|
|
const container = document.getElementById('dynamic-form-container');
|
|
const rows = container.querySelectorAll('.dynamic-form-row');
|
|
|
|
if (rows.length > 1) {
|
|
const row = element.closest('.dynamic-form-row');
|
|
row.remove();
|
|
if (typeof window.refreshTicketFormValidationForForm === 'function') {
|
|
window.refreshTicketFormValidationForForm('#drive_file_upload_form');
|
|
}
|
|
}
|
|
}
|
|
|
|
function getUrlDataByTicketId(ticket_id) {
|
|
|
|
// Show loader
|
|
$('.loader').fadeIn();
|
|
$('.loader-mask').fadeIn();
|
|
|
|
$.ajax({
|
|
url: "<?= base_url('ticket/getUrlDataByTicketId')?>", // base_url must be defined in JS
|
|
type: "POST",
|
|
data: { ticket_id: ticket_id },
|
|
dataType: 'json',
|
|
success: function(response) {
|
|
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");
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.log("error in get urldata api");
|
|
console.error("AJAX Error:", error);
|
|
},
|
|
complete: function() {
|
|
// Hide loader
|
|
$('.loader').fadeOut();
|
|
$('.loader-mask').delay(350).fadeOut('slow');
|
|
console.log("Ajax is completed for get url data..!!");
|
|
if (typeof window.refreshTicketFormValidationForForm === 'function') {
|
|
window.refreshTicketFormValidationForForm('#drive_file_upload_form');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function openEditModal(id, docName, url) {
|
|
$('#edit_url_id').val(id);
|
|
$('#edit_doc_name').val(docName);
|
|
$('#edit_url_link').val(url);
|
|
$('#edit_url_modal').modal('show'); // Bootstrap modal
|
|
}
|
|
|
|
$('#edit_url_modal').on('shown.bs.modal', function () {
|
|
if (typeof window.refreshTicketFormValidationForForm === 'function') {
|
|
window.refreshTicketFormValidationForForm('#edit_url_form');
|
|
}
|
|
});
|
|
|
|
$('#edit_url_form').on('submit', function (e) {
|
|
e.preventDefault();
|
|
if (typeof window.validateTicketFormInputs === 'function' && !window.validateTicketFormInputs(this)) {
|
|
toastr.warning('Please correct the highlighted fields.', 'Validation');
|
|
var $first = $(this).find('.parsley-error').first();
|
|
if ($first.length) {
|
|
$first.focus();
|
|
}
|
|
return false;
|
|
}
|
|
return false;
|
|
});
|
|
|
|
function escapeClaimFileListAttr(s) {
|
|
return String(s == null ? '' : s)
|
|
.replace(/&/g, '&')
|
|
.replace(/"/g, '"')
|
|
.replace(/</g, '<')
|
|
.replace(/'/g, ''');
|
|
}
|
|
|
|
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 claimFileIsLocalUpload(item) {
|
|
// file_type 2 = uploaded claim doc, 4 = merged combined PDF (both stored on disk)
|
|
return item.file_type == 2 || item.file_type === '2'
|
|
|| item.file_type == 4 || item.file_type === '4';
|
|
}
|
|
|
|
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 (claimFileIsLocalUpload(item)) {
|
|
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 (claimFileIsLocalUpload(item)) {
|
|
return base_url + 'viewClaimFile/' + encodeURIComponent(item.id);
|
|
}
|
|
return String(item.url || '');
|
|
}
|
|
|
|
function claimFileDownloadOpenUrl(item, base_url) {
|
|
if (claimFileIsLocalUpload(item)) {
|
|
return base_url + 'downloadClaimFile/' + encodeURIComponent(item.id);
|
|
}
|
|
return String(item.url || '');
|
|
}
|
|
|
|
function create_url_list(data) {
|
|
$('#table_bd').empty(); // clear existing rows
|
|
|
|
let base_url = "<?php echo base_url() ?>";
|
|
|
|
if (data && data.length > 0) {
|
|
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 downloadHref = escapeClaimFileListAttr(claimFileDownloadOpenUrl(item, base_url));
|
|
const fileNameLinkHref = viewOk ? viewHref : downloadHref;
|
|
const fileNameLinkTitle = viewOk ? 'View file' : 'Download';
|
|
html += `
|
|
<tr>
|
|
<td class="text-center">${index + 1}</td>
|
|
<td>${item.doc_name}</td>
|
|
<td><a href="${fileNameLinkHref}" title="${fileNameLinkTitle}">${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="${downloadHref}" class="text-primary mr-2" title="Download" download>
|
|
<i class="mdi mdi-download"></i>
|
|
</a>
|
|
<a href="javascript:void(0);" class="delete-url"
|
|
style="bacolor:black;"
|
|
data-href="${base_url}/ticket/remove_url?id=${item.id}">
|
|
<i class="mdi mdi-delete mr-1"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#table_bd').append(html);
|
|
} 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) {
|
|
e.preventDefault();
|
|
const url = $(this).data('href');
|
|
const $row = $(this).closest('tr'); // capture the row before async execution
|
|
|
|
confirmActionSweertAlert("Do you want to delete?", "Yes, Proceed!", "No, Cancel")
|
|
.then((confirmed) => {
|
|
if (confirmed) {
|
|
$.ajax({
|
|
url: url,
|
|
type: "GET",
|
|
dataType: "json",
|
|
beforeSend: function () {
|
|
$('.loader').fadeIn();
|
|
$('.loader-mask').fadeIn();
|
|
},
|
|
success: function (response) {
|
|
if (response.status === true) {
|
|
toastr.success('Removed Successfully');
|
|
$row.remove();
|
|
} else {
|
|
toastr.error(response.message || 'Deletion failed');
|
|
}
|
|
},
|
|
error: function (xhr, status, error) {
|
|
console.log("error ");
|
|
console.error("AJAX Error:", error);
|
|
toastr.error('AJAX request failed');
|
|
},
|
|
complete: function () {
|
|
$('.loader').fadeOut();
|
|
$('.loader-mask').delay(350).fadeOut('slow');
|
|
console.log("Ajax is completed for get url data..!!");
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
function addFileUploadHtml() {
|
|
const container = document.getElementById('dynamic-form-container');
|
|
const rowKey = 'f_' + Date.now() + '_' + Math.floor(Math.random() * 10000);
|
|
const docsId = 'docs_name_' + rowKey;
|
|
const fileId = 'file_upload_' + rowKey;
|
|
const newRow = document.createElement('div');
|
|
newRow.className = 'form-row dynamic-form-row';
|
|
newRow.innerHTML = `
|
|
<div class="form-group col-md-5">
|
|
<label for="${docsId}">Document Name <span class="text-danger">*</span></label>
|
|
<input type="text" class="form-control" id="${docsId}" name="docs_name[]" placeholder="Enter file name" required
|
|
data-parsley-required-message="Document name is required."
|
|
data-parsley-ticketdocname-message="Document name can only contain letters, numbers, spaces, hyphens, and underscores.">
|
|
</div>
|
|
<div class="form-group col-md-5">
|
|
<label for="${fileId}">Choose File <span class="text-danger">*</span></label>
|
|
<input type="file" class="form-control" id="${fileId}" name="file_upload[]" accept=".pdf,.jpg,.jpeg,.png" required
|
|
data-parsley-required-message="File is required."
|
|
data-parsley-claimfileext-message="Only PDF, JPG, JPEG, and PNG files are allowed.">
|
|
<small class="text-muted"> Allowed: PDF, JPG, JPEG, PNG. </small>
|
|
</div>
|
|
<div class="form-group col-md-2" style="position: relative; top: 28px;">
|
|
<a class="btn btn-danger waves-effect waves-light" onclick="removeHTMLInput(this)" style="background-color: #BD0707;">
|
|
<i class="mdi mdi-delete"></i>
|
|
</a>
|
|
</div>
|
|
`;
|
|
container.appendChild(newRow);
|
|
if (typeof window.refreshTicketFormValidationForForm === 'function') {
|
|
window.refreshTicketFormValidationForForm('#drive_file_upload_form');
|
|
}
|
|
}
|
|
|
|
function toggleUploadType(btn) {
|
|
|
|
const $btn = $(btn);
|
|
const $addBtn = $('#add_btn_for_claim_file_upload');
|
|
console.log('addBtn', $addBtn);
|
|
const $container = $('#dynamic-form-container');
|
|
const currentType = $btn.text().trim();
|
|
console.log('currentType', currentType);
|
|
|
|
// Remove all existing dynamic rows when mode changes
|
|
$container.find('.dynamic-form-row').remove();
|
|
|
|
if (currentType === 'URL Upload') {
|
|
|
|
$btn.text('File Upload').removeClass('btn-success').addClass('btn-info');
|
|
|
|
// Change the Add button action
|
|
$addBtn.attr('onclick', 'addHTMLInput(this)');
|
|
|
|
// Handle switching to file upload mode here
|
|
console.log('Switched to File Upload mode');
|
|
|
|
// call the function
|
|
addHTMLInput();
|
|
if (typeof window.refreshTicketFormValidationForForm === 'function') {
|
|
window.refreshTicketFormValidationForForm('#drive_file_upload_form');
|
|
}
|
|
|
|
} else {
|
|
|
|
$btn.text('URL Upload').removeClass('btn-info').addClass('btn-success');
|
|
|
|
// Change the Add button action
|
|
$addBtn.attr('onclick', 'addFileUploadHtml(this)');
|
|
|
|
// Handle switching to URL upload mode here
|
|
console.log('Switched to URL Upload mode');
|
|
|
|
// call the function
|
|
addFileUploadHtml();
|
|
if (typeof window.refreshTicketFormValidationForForm === 'function') {
|
|
window.refreshTicketFormValidationForForm('#drive_file_upload_form');
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
</script>
|
|
|
|
<script>
|
|
|
|
let documentConfig = {
|
|
is_action_freeze: false,
|
|
docs: []
|
|
};
|
|
|
|
$(document).ready(function(){
|
|
|
|
let jsonDocumentConfig = <?= isset($ticket_data['required_docs']) && !empty($ticket_data['required_docs'])
|
|
? $ticket_data['required_docs']
|
|
: '{"is_action_freeze": false, "docs": [{"document_name":"","document_received":false}]}' ?>;
|
|
|
|
console.log('loadConfiguration pre', jsonDocumentConfig);
|
|
loadConfiguration(jsonDocumentConfig);
|
|
})
|
|
|
|
// Initialize the form with JSON data
|
|
function initializeForm(jsonData) {
|
|
|
|
documentConfig = jsonData;
|
|
|
|
// Set the freeze switch
|
|
const freezeSwitch = document.getElementById('action_freeze_switch');
|
|
if (freezeSwitch) {
|
|
freezeSwitch.checked = documentConfig.is_action_freeze;
|
|
}
|
|
|
|
// Render document list
|
|
renderDocumentList();
|
|
}
|
|
|
|
// Render the document input list
|
|
function renderDocumentList() {
|
|
const container = document.getElementById('document-list-container');
|
|
if (!container) return;
|
|
|
|
container.innerHTML = '';
|
|
|
|
documentConfig.docs.forEach((doc, index) => {
|
|
const docRow = createDocumentRow(doc, index);
|
|
container.appendChild(docRow);
|
|
});
|
|
|
|
if (typeof window.refreshTicketFormValidationForForm === 'function') {
|
|
window.refreshTicketFormValidationForForm('#ir_documents_form');
|
|
}
|
|
}
|
|
|
|
// Create a single document row
|
|
function createDocumentRowOld(doc, index) {
|
|
const row = document.createElement('div');
|
|
row.className = 'form-row align-items-center mb-2';
|
|
row.dataset.index = index;
|
|
|
|
row.innerHTML = `
|
|
<div class="col-md-7">
|
|
<input type="text" class="form-control"
|
|
placeholder="Document Name"
|
|
value="${doc.document_name}"
|
|
onchange="updateDocumentName(${index}, this.value)"
|
|
${documentConfig.is_action_freeze ? 'disabled' : ''}>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<span class="badge ${doc.document_received ? 'badge-success' : 'badge-danger'} text-center d-block"
|
|
style="cursor:pointer; font-size:14px; padding:13px 12px; font-weight:600; border-radius:9px;"
|
|
onclick="${documentConfig.is_action_freeze ? '' : `updateDocumentReceived(${index}, ${!doc.document_received})`}">
|
|
${doc.document_received ? 'Received' : 'Not Received'}
|
|
</span>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<button type="button" class="btn btn-sm btn-danger"
|
|
onclick="removeDocument(${index})"
|
|
${documentConfig.is_action_freeze ? 'disabled' : ''}>
|
|
<i class="mdi mdi-delete"></i> Remove
|
|
</button>
|
|
</div>
|
|
`;
|
|
|
|
return row;
|
|
}
|
|
|
|
function escapeHtmlAttr(s) {
|
|
return String(s == null ? '' : s)
|
|
.replace(/&/g, '&')
|
|
.replace(/"/g, '"')
|
|
.replace(/</g, '<')
|
|
.replace(/'/g, ''');
|
|
}
|
|
|
|
function createDocumentRow(doc, index) {
|
|
const row = document.createElement('div');
|
|
row.className = 'form-row align-items-center mb-2';
|
|
row.dataset.index = index;
|
|
|
|
const isLastRow = index === documentConfig.docs.length - 1; // 👉 Check last item
|
|
const safeName = escapeHtmlAttr(doc.document_name);
|
|
const irId = 'ir_doc_name_' + index;
|
|
const reqAttrs = documentConfig.is_action_freeze ? 'disabled' : 'required';
|
|
|
|
row.innerHTML = `
|
|
<div class="col-md-7">
|
|
<input type="text" class="form-control"
|
|
id="${irId}"
|
|
name="ir_document_name[]"
|
|
placeholder="Document Name"
|
|
value="${safeName}"
|
|
onchange="updateDocumentName(${index}, this.value)"
|
|
data-parsley-required-message="Document name is required."
|
|
data-parsley-ticketdocname-message="Document name can only contain letters, numbers, spaces, hyphens, and underscores."
|
|
${reqAttrs}>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<span class="badge ${doc.document_received ? 'badge-success' : 'badge-danger'} text-center d-block"
|
|
style="cursor:pointer; font-size:14px; padding:13px 12px; font-weight:600; border-radius:9px;"
|
|
onclick="${documentConfig.is_action_freeze ? '' : `updateDocumentReceived(${index}, ${!doc.document_received})`}">
|
|
${doc.document_received ? 'Received' : 'Not Received'}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="col-md-2 text-center">
|
|
<button type="button" class="btn btn-sm btn-danger"
|
|
onclick="removeDocument(${index})"
|
|
${documentConfig.is_action_freeze ? 'disabled' : ''}>
|
|
<i class="mdi mdi-delete"></i>
|
|
</button>
|
|
|
|
${isLastRow && !documentConfig.is_action_freeze ? `
|
|
<button type="button" class="btn btn-sm btn-primary ml-1"
|
|
onclick="addDocument()">
|
|
<i class="mdi mdi-plus"></i>
|
|
</button>` : ''}
|
|
</div>
|
|
`;
|
|
|
|
return row;
|
|
}
|
|
|
|
// Add new document
|
|
function addDocument() {
|
|
|
|
if (documentConfig.is_action_freeze) {
|
|
toastr.warning('Cannot add documents when action is frozen', 'Warning');
|
|
return;
|
|
}
|
|
|
|
documentConfig.docs.push({
|
|
document_name: '',
|
|
document_received: false
|
|
});
|
|
|
|
renderDocumentList();
|
|
}
|
|
|
|
// Remove document
|
|
function removeDocumentold(index) {
|
|
if (documentConfig.is_action_freeze) {
|
|
alert('Cannot remove documents when action is frozen');
|
|
return;
|
|
}
|
|
|
|
documentConfig.docs.splice(index, 1);
|
|
renderDocumentList();
|
|
}
|
|
|
|
function removeDocument(index) {
|
|
if (documentConfig.is_action_freeze) {
|
|
toastr.warning('Cannot remove documents when action is frozen', 'Warning');
|
|
return;
|
|
}
|
|
|
|
const doc = documentConfig.docs[index];
|
|
|
|
// ❗ If document is already received, do not remove
|
|
if (doc.document_received === true) {
|
|
toastr.warning('Cannot remove a received document', 'Warning');
|
|
return;
|
|
}
|
|
|
|
// 👉 First row cannot be removed
|
|
if (index === 0) {
|
|
documentConfig.docs[0].document_name = '';
|
|
documentConfig.docs[0].document_received = false;
|
|
renderDocumentList();
|
|
return;
|
|
}
|
|
|
|
// 👉 Other rows can be removed
|
|
documentConfig.docs.splice(index, 1);
|
|
renderDocumentList();
|
|
}
|
|
|
|
// Update document name
|
|
function updateDocumentName(index, value) {
|
|
documentConfig.docs[index].document_name = value;
|
|
}
|
|
|
|
// Update document received status
|
|
function updateDocumentReceived(index, value) {
|
|
documentConfig.docs[index].document_received = value === 'true';
|
|
}
|
|
|
|
// Toggle freeze state
|
|
function toggleActionFreeze() {
|
|
const freezeSwitch = document.getElementById('action_freeze_switch');
|
|
documentConfig.is_action_freeze = freezeSwitch.checked;
|
|
|
|
// Re-render to update disabled states
|
|
renderDocumentList();
|
|
}
|
|
|
|
function syncIrDocumentNamesFromInputs() {
|
|
documentConfig.docs.forEach(function (doc, index) {
|
|
var el = document.getElementById('ir_doc_name_' + index);
|
|
if (el && !el.disabled) {
|
|
doc.document_name = el.value;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Save configuration
|
|
function saveConfiguration() {
|
|
|
|
syncIrDocumentNamesFromInputs();
|
|
|
|
var irForm = document.getElementById('ir_documents_form');
|
|
if (irForm && typeof window.validateTicketFormInputs === 'function' && !window.validateTicketFormInputs(irForm)) {
|
|
toastr.warning('Please correct the highlighted document name fields.', 'Validation');
|
|
var $first = $(irForm).find('.parsley-error').first();
|
|
if ($first.length) {
|
|
$('html, body').animate({ scrollTop: $first.offset().top - 120 }, 400);
|
|
$first.focus();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
let ticket_id = $('#ticket_id_url').val();
|
|
let required_docs = JSON.stringify(documentConfig);
|
|
|
|
console.log('Saving configuration:', JSON.stringify(documentConfig, null, 2));
|
|
console.log('ticket_id', ticket_id);
|
|
|
|
// Data to send in the AJAX request
|
|
let requestData = {
|
|
ticket_id: ticket_id,
|
|
required_docs: required_docs
|
|
};
|
|
|
|
let url = '<?= base_url('ticket/saveIRDocsJson') ?>';
|
|
|
|
// Send AJAX request
|
|
sendAjaxRequestForGlobal(url, 'POST', requestData, function(response) {
|
|
|
|
console.log('Data fetched successfully:', response);
|
|
|
|
if (response.status) {
|
|
loadConfiguration(response.data);
|
|
toastr.success(response.message, 'Success');
|
|
} else {
|
|
toastr.warning(response.message, 'Warning');
|
|
}
|
|
|
|
}, function(xhr, status, error) {
|
|
console.error('Error fetching data:', error);
|
|
console.error(xhr.responseText);
|
|
if (xhr.status === 400) {
|
|
let response = JSON.parse(xhr.responseText);
|
|
let errorMessages = "";
|
|
let seenMessages = []; // Array to store unique messages
|
|
if (response.errors) {
|
|
$.each(response.errors, function (field, message) {
|
|
if (!seenMessages.includes(message)) {
|
|
errorMessages += `• ${message}<br>`;
|
|
seenMessages.push(message); // Mark this message as "seen"
|
|
}
|
|
});
|
|
toastr.error(errorMessages, 'Validation Error', { "allowHtml": true });
|
|
} else {
|
|
toastr.warning(response.message || 'Validation failed', 'Warning');
|
|
}
|
|
} else if (xhr.status === 403) {
|
|
let response = JSON.parse(xhr.responseText);
|
|
toastr.error(response.message, 'Security Policy');
|
|
} else if (xhr.status === 500) {
|
|
toastr.error('Something went wrong . Please try again later.', 'Server Error');
|
|
} else {
|
|
toastr.error('An unexpected error occurred. Please try again later.', 'Error');
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
// Get current configuration as JSON
|
|
function getConfiguration() {
|
|
return documentConfig;
|
|
}
|
|
|
|
// Edit mode - load existing configuration
|
|
function loadConfiguration(jsonString) {
|
|
try {
|
|
const data = typeof jsonString === 'string' ? JSON.parse(jsonString) : jsonString;
|
|
initializeForm(data);
|
|
} catch (e) {
|
|
console.error('Invalid JSON:', e);
|
|
}
|
|
}
|
|
|
|
</script>
|