nhance/app/Views/thz_list.php

987 lines
40 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
helper('datatable_view');
$thz_header_labels = [
'Ticket ID', 'Name', 'Policy Number', 'Ticket Type', 'Subject', 'Status', 'Assign To', 'Created At', 'Updated At',
];
$thz_col_count = count($thz_header_labels);
$thz_col_max_len = array_fill(0, $thz_col_count, 0);
for ($i = 0; $i < $thz_col_count; $i++) {
$thz_col_max_len[$i] = mb_strlen($thz_header_labels[$i]);
}
$ticket_data = $ticket_data ?? [];
foreach ($ticket_data as $row) {
$thz_col_max_len[0] = max($thz_col_max_len[0], mb_strlen((string) ($row['thz_id'] ?? '')));
$namePlain = (string) ($row['name'] ?? '');
if (! empty($row['empcode'])) {
$namePlain .= ' (' . $row['empcode'] . ')';
}
if (! empty($row['mobile'])) {
$namePlain .= ' ' . $row['mobile'];
}
$thz_col_max_len[1] = max($thz_col_max_len[1], mb_strlen($namePlain));
$pol = (! empty($row['policy_no']) && strtolower((string) $row['policy_no']) !== 'null') ? (string) $row['policy_no'] : 'N/A';
$thz_col_max_len[2] = max($thz_col_max_len[2], mb_strlen($pol));
$tt = $row['ticket_type'] ? (string) $row['ticket_type'] : 'N/A';
$thz_col_max_len[3] = max($thz_col_max_len[3], mb_strlen($tt));
$subject = $row['subject'] ? (string) $row['subject'] : 'N/A';
$subDisp = (strlen($subject) > 18) ? substr($subject, 0, 18) . '...' : $subject;
$thz_col_max_len[4] = max($thz_col_max_len[4], mb_strlen($subDisp));
$st = $row['status'] ? (string) $row['status'] : 'N/A';
$thz_col_max_len[5] = max($thz_col_max_len[5], mb_strlen($st));
$as = $row['assignee_name'] ? (string) $row['assignee_name'] : 'N/A';
$thz_col_max_len[6] = max($thz_col_max_len[6], mb_strlen($as));
$cr = '';
if (! empty($row['created_at'])) {
$cr = date('j M Y', strtotime((string) $row['created_at'])) . ' ' . date('h:i A', strtotime((string) $row['created_at']));
}
$thz_col_max_len[7] = max($thz_col_max_len[7], mb_strlen($cr));
$ur = '';
if (! empty($row['updated_at'])) {
$ur = date('j M Y', strtotime((string) $row['updated_at'])) . ' ' . date('h:i A', strtotime((string) $row['updated_at']));
}
$thz_col_max_len[8] = max($thz_col_max_len[8], mb_strlen($ur));
}
$thz_col_min_px = [72, 160, 120, 100, 120, 88, 120, 140, 140];
$thz_col_max_px = [120, 360, 280, 220, 400, 160, 280, 220, 220];
$thz_col_width_px = nhance_dt_column_widths_px($thz_header_labels, $thz_col_max_len, $thz_col_min_px, $thz_col_max_px);
?>
<style>
.table th,
.table td {
padding: 8px;
}
table.dataTable tbody td {
padding: 4px 4px !important;
}
.col-12 {
max-width: 98% !important;
}
.dataTables_filter {
position: absolute;
}
.column-header {
margin-right: 10px;
}
.btn {
font-size: 0.9rem;
padding: 0.5rem 1rem;
}
</style>
<style>
.text-custom-grey{
font-size: 0.85em;
color: #6c757d !important;
}
/* don't erase it. keep it safe
beccause = dataTables_length and dataTables_paginate need in same line thats why i tried in css ...
.dataTables_info,
.dataTables_length,
.dataTables_paginate {
display: flex;
align-items: center;
} */
.dataTables_length label {
height: 21px !important;
}
</style>
<style>
<?php for ($i = 0; $i < $thz_col_count; $i++) : ?>
#thz-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#thz-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $thz_col_width_px[$i] ?>px;
width: <?= (int) $thz_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#thz-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $thz_col_width_px[$i] ?>px;
max-width: <?= (int) $thz_col_width_px[$i] ?>px;
min-width: <?= (int) $thz_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#thz-table tbody td:nth-child(1),
#thz-table tbody td:nth-child(2),
#thz-table tbody td:nth-child(3),
#thz-table tbody td:nth-child(4),
#thz-table tbody td:nth-child(5),
#thz-table tbody td:nth-child(6),
#thz-table tbody td:nth-child(7),
#thz-table tbody td:nth-child(8),
#thz-table tbody td:nth-child(9) {
overflow: hidden;
text-overflow: ellipsis;
}
#thz-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#thz-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="row" id="ticket_list">
<div class="col-12">
<div class="card">
<div class="card-body">
<div>
<div class="table-responsive">
<table data-custom-table-css="table" class="table mb-0 nowrap w-100 table-centered" cellspacing="0" id="thz-table">
<thead class="bg-light">
<tr>
<th><div class="column-header">Ticket ID&nbsp;</div></th>
<th class="text-left"><div class="column-header">Name &nbsp;</div></th>
<th><div class="column-header">Policy Number &nbsp;</div></th>
<th><div class="column-header">Ticket Type &nbsp;</div></th>
<th><div class="column-header">Subject &nbsp;</div></th>
<th><div class="column-header">Status &nbsp;</div></th>
<th class="text-left"><div class="column-header">Assign To &nbsp;</div></th>
<th><div class="column-header">Created At &nbsp;</div></th>
<th><div class="column-header">Updated At &nbsp;</div></th>
</tr>
</thead>
<tbody class="app-table-body">
<?php if(isset($ticket_data)) { ?>
<?php foreach($ticket_data as $index => $row){ ?>
<tr data-id="<?= $row['thz_id']; ?>" style="cursor: pointer;">
<td><?php echo $row['thz_id']; ?></td>
<td class="text-left"><?php echo $row['name']; ?>
<span class="text-custom-grey"><?php if (!empty($row['empcode'])): echo '('.$row['empcode'].')'; endif; ?></span><br>
<span class="text-custom-grey"><?php if (!empty($row['mobile'])): echo $row['mobile']; endif; ?></span>
</td>
<td class="text-center"><?php echo (!empty($row['policy_no']) && strtolower($row['policy_no']) !== 'null')
? $row['policy_no']
: 'N/A'; ?>
</td>
<td class="text-center"><?php echo $row['ticket_type'] ? $row['ticket_type'] : 'N/A'; ?></td>
<td class="text-center wrap" title="<?php echo htmlspecialchars($row['subject']); ?>">
<?php
$subject = $row['subject'] ? $row['subject'] : 'N/A';
echo (strlen($subject) > 18)
? htmlspecialchars(substr($subject, 0, 18)) . "..."
: htmlspecialchars($subject);
?>
</td>
<td class="text-center"><?php echo $row['status'] ? $row['status'] : 'N/A' ; ?></td>
<td class="text-left"><?php echo $row['assignee_name'] ? $row['assignee_name'] : 'N/A'; ?></td>
<td class="text-left">
<?php if (!empty($row['created_at'])):
$cd = date("j/m/Y", strtotime($row['created_at']));
$ct = date("h:i A", strtotime($row['created_at']));
echo $cd . "<br><span class='time'> " . $ct . "</span>";
endif;
?>
</td>
<td class="text-left">
<?php if (!empty($row['updated_at'])):
$ud = date("j/m/Y", strtotime($row['updated_at']));
$ut = date("h:i A", strtotime($row['updated_at']));
echo $ud . "<br><span class='time'> " . $ut . "</span>";
endif;
?>
</td>
</tr>
<?php } ?>
<?php } else { ?>
<tr>
<td colspan="9" class="text-center">No data available</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div><!-- end col -->
</div>
<div class="modal fade " id="ticketModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl" style="margin:5px auto!important;">
<div class="modal-content">
<form class="parsley-examples" id="ticketForm">
<!-- <div class="modal-header">
<h4 class="modal-title" id="modalLabel">New Ticket</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div> -->
<div class="modal-header flex-column">
<!-- first row -->
<div class="d-flex w-100 justify-content-between align-items-center">
<h4 class="modal-title mb-0" id="modalLabel" style="font-size:27px !important">New Ticket</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<!-- second row -->
<div class="form-row mt-3 w-100 ">
<div class="form-group col-md-6 ">
<label for="client_id">Client</label>
<select class="form-control app-field-grey font-color-black" id="client_id" name="client_id">
<option value="">Select Client</option>
<?php if(isset($client_list)) { ?>
<?php foreach ($client_list as $c) { ?>
<option value="<?= $c->id ?>"><?= $c->client_name ?> (<?= $c->short_name ?>) </option>
<?php } ?>
<?php } ?>
</select>
</div>
<div class="form-group col-md-5 ">
<label for="mobile">Mobile<span class="text-danger">*</span></label>
<input type="tel" class="form-control app-field-grey" id="mobile" placeholder="Enter Mobile Number"
name="mobile"
required pattern="[0-9]{10}" maxlength="10" inputmode="numeric"
oninput="this.value=this.value.replace(/[^0-9]/g,'');"
title="Please enter a valid 10-digit mobile number">
<small class="text-danger d-block mt-1 field-error" id="mobile_error"></small>
</div>
<div class="form-group col-md-1" style="padding:32.5px 0 0 18px;">
<button type="button" class="btn-custom app-btn-primary " style="padding: 0 10px !important; border-radius:13px;" onclick="getAutoFetchDetails()"><i class="mdi mdi-cached " style="font-size:24px;"></i></button>
</div>
</div>
</div>
<div class="modal-body" style="padding: 12px 15px 0px 15px !important;">
<div class="form-row">
<input type="hidden" id="thz_id" name="thz_id">
<input type="hidden" id="return_type" name="return_type">
<input type="hidden" id="branch_id" name="branch_id">
<input type="hidden" id="policy_id" name="policy_id">
<input type="hidden" id="created_by" name="created_by" value="<?= get_session_userid(); ?>">
<div class="form-group col-md-4 ">
<label for="name">Name<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter Name" required>
<small class="text-danger d-block mt-1 field-error" id="name_error"></small>
</div>
<div class="form-group col-md-4 ">
<label for="email">Email Id<span class="text-danger">*</span></label>
<input type="email" class="form-control" id="email"
name="email" placeholder="Enter Email"
required
title="Please enter a valid email address">
<small class="text-danger d-block mt-1 field-error" id="email_error"></small>
</div>
<div class="form-group col-md-4 ">
<label for="empcode">Employee code</label>
<input type="text" class="form-control" id="empcode" name="empcode" placeholder="Enter Employee code">
<small class="text-danger d-block mt-1 field-error" id="empcode_error"></small>
</div>
<div class="form-group col-md-4 ">
<label for="ticket_type">Ticket Type<span class="text-danger">*</span></label>
<select class="form-control" id="ticket_type" name="ticket_type" required onchange="hideandshowpolicy()">
<option value="">Select Ticket Type</option>
<!-- <option value="Sales" selected >Sales</option> -->
<!-- <option value="Service">Service</option> -->
<!-- <option value="0">+ Add New</option> -->
<?php if (!empty($ticket_type)): ?>
<?php foreach ($ticket_type as $t): ?>
<option value="<?= esc($t['name']) ?>"
<?= (strtolower($t['name']) === "sales") ? 'selected' : '' ?>>
<?= esc($t['name']) ?>
</option>
<?php endforeach; ?>
<?php endif; ?>
</select>
<small class="text-danger d-block mt-1 field-error" id="ticket_type_error"></small>
</div>
<div class="form-group col-md-4 " id="policy_container">
<label for="policy_no">Policy Number</label>
<select class="form-control" id="policy_no" name="policy_no" onchange="changevalue()">
<option value="" selected data-id="">Select Policy</option>
</select>
</div>
<!-- <div class="form-group col-md-6">
<label for="status">Status</label>
<select class="form-control" id="status" name="status">
<option value="">Select Status</option>
<option value="Open">Open</option>
<option value="In Progress">In Progress</option>
<option value="Resolved">Resolved</option>
<option value="Closed">Closed</option>
</select>
</div> -->
<!-- // enga 5-"head" and 1-"admin" assign pannvaga dropdown-data la varakudhathu. but dropdown display aganum
// 2,3,4 dropdown data'va varannum but dropdown hide pannanum -->
<?php if (in_array(get_role_id(), [1,2,5])): ?>
<div class="form-group col-md-4">
<label for="assign_to">Assign To</label>
<select class="form-control" id="assign_to" name="assign_to">
<option value="">Select Assign To</option>
<?php if (!empty($assignee)): ?>
<?php foreach ($assignee as $a): ?>
<option value="<?= esc($a['id']) ?>">
<?= esc($a['emp_code']) ?> - <?= esc($a['first_name']) ?> <?= esc($a['last_name']) ?>
</option>
<?php endforeach; ?>
<?php endif; ?>
</select>
<small class="text-danger d-block mt-1 field-error" id="assign_to_error"></small>
</div>
<?php else: ?>
<input type="hidden" id="hide_assign_to" name="assign_to" value="<?= esc(get_session_userid()); ?>">
<?php endif; ?>
<!-- <div class="form-group col-md-12 ">
<label for="subject">Subject<span class="text-danger">*</span></label>
<small id="subjectCounter" class="form-text text-muted text-right">0/150</small>
</div> -->
<div class="form-group col-md-12 ">
<div class="d-flex justify-content-between">
<label for="subject" class="mb-1">Subject <span class="text-danger">*</span></label>
<small id="subjectCounter" class="form-text text-muted">0/150</small>
</div>
<input type="text" class="form-control" id="subject" name="subject" placeholder="Enter Subject" required maxlength="150">
<small class="text-danger d-block mt-1 field-error" id="subject_error"></small>
</div>
<div class="form-group col-md-12 ">
<div class="d-flex justify-content-between">
<label for="message">Message<span class="text-danger">*</span></label>
<small id="messageCounter" class="form-text text-muted text-end text-right">0/1500</small>
</div>
<!-- <input type="text" class="form-control" id="message" name="message" placeholder="Enter Message"> -->
<textarea class="form-control" id="message" name="message" placeholder="Enter Message" rows="3" required maxlength="1500"></textarea>
<small class="text-danger d-block mt-1 field-error" id="message_error"></small>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn app-btn-primary mr-2 " onclick="resetTicket()">Reset</button>
<button type="submit" class="btn app-btn-secondary " onclick="submitTicket(event)">Save</button>
</div>
</form>
</div>
</div>
</div>
<div class="modal fade " id="AssignModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="assignModalLabel">Ticket</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<div class="form-row">
<input type="hidden" id="hidden_thz_id" name="hidden_thz_id">
<div class="form-group col-md-12">
<label for="modal_assignee">Assign To<span class="text-danger">*</span></label>
<select class="form-control" id="modal_assignee" name="modal_assignee" required>
<option value="">Select Assign To</option>
<?php if(isset($assignee)) { ?>
<?php foreach ($assignee as $a) { ?>
<option value="<?= $a['id']?>"><?= $a['emp_code'] ?> - <?= $a['first_name'] ?> <?= $a['last_name'] ?></option>
<?php } ?>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn-custom app-btn-secondary " onclick="updateAssignTo()">Save</button>
</div>
</div>
</div>
</div>
<script>
// Datatable document ready
$(document).ready(function() {
var ticketsTable = $('#thz-table');
if (ticketsTable.length) {
nhanceListDataTableBeforeInit();
var nhThzTable = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right
"<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]],
buttons: [
{
text: '<i class="mdi mdi-plus" ></i><span class=" btn-custom"> Add </span>',
className: 'btn app-btn-primary mr-2',
action: function(e, dt, node, config) {
openTicket();
}
},
{
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: 'Tickets',
},
{
extend: 'excel',
text: '<i class="mdi mdi-file-excel " ></i><span class=" btn-custom"> EXCEL </span>',
exportOptions: {
orthogonal: 'sort'
},
className: 'app-btn-primary ',
title: 'Tickets',
sheetName: 'Tickets',
}
]
}
],
language: {
search: `
<div class="datatable-search-wrapper" style="position:relative; display:inline-block;">
_INPUT_
<i class="mdi mdi-magnify datatable-search-icon"
style="position:absolute; right:10px; top:50%; transform:translateY(-50%); color:#666;"></i>
<i class="mdi mdi-close-circle datatable-clear-icon"
style="position:absolute; right:10px; top:50%; transform:translateY(-50%); color:#666; display:none;"></i>
</div>`,
searchPlaceholder: "Search",
emptyTable: '<div class="text-center text-muted">No Data found</div>'
},
paging: true,
pageLength: 10,
order: [[0, 'desc']],
columnDefs: [
<?php for ($i = 0; $i < $thz_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $thz_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhThzTable);
} else {
console.error("Table not found.");
}
$(document).on('click', '.datatable-clear-icon', function () {
const input = $(this).closest('.datatable-search-wrapper').find('input');
input.val('').trigger('input');
$('#thz-table').DataTable().search('').draw();
});
});
function openTicket(){
var form = document.getElementById('ticketForm');
form.reset();
$("#client_id").select2();
$("#ticket_type").select2();
clearAllFieldErrors();
document.getElementById('thz_id').value = '';
document.getElementById('modalLabel').innerText = "New Ticket";
document.getElementById('return_type').innerText = "Web";
var myModal = new bootstrap.Modal(document.getElementById('ticketModal'));
myModal.show();
}
function resetTicket(){
var form = document.getElementById('ticketForm');
form.reset();
$("#client_id").select2();
$("#ticket_type").select2();
clearAllFieldErrors();
}
function showFieldError(fieldId, message) {
var field = document.getElementById(fieldId);
var error = document.getElementById(fieldId + "_error");
if (!field || !error) return;
error.textContent = message || "";
if (message) {
field.classList.add("is-invalid");
} else {
field.classList.remove("is-invalid");
}
}
function clearAllFieldErrors() {
document.querySelectorAll(".field-error").forEach(function (el) {
el.textContent = "";
});
["mobile", "name", "email", "empcode", "ticket_type", "assign_to", "subject", "message"].forEach(function (id) {
var field = document.getElementById(id);
if (field) field.classList.remove("is-invalid");
});
}
function validateMobile(value) {
if (!value) return "Mobile number is required";
if (!/^[0-9]{10}$/.test(value)) return "Mobile number must be exactly 10 digits";
return "";
}
function validateName(value) {
if (!value) return "Name is required";
if (value.length < 3) return "Name must be at least 3 characters";
if (value.length > 100) return "Name must be at most 100 characters";
if (!/^[A-Za-z ]+$/.test(value)) return "Name can contain only letters and spaces";
return "";
}
function validateEmail(value) {
if (!value) return "Email address is required.";
if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value)) {
return "Please enter a valid email format (e.g., name@domain.com).";
}
return "";
}
function validateEmpcode(value) {
if (!value) return "";
if (value.length > 50) return "Employee code is too long";
if (!/^[A-Za-z0-9 ~!#\$%\^&\*\(\)_\+\-\=\{\}\[\]\|:;\"'<>,\.\/\?`]+$/.test(value)) {
return "Employee code contains invalid characters.";
}
return "";
}
function validateTicketType(value) {
if (!value) return "Ticket Type is required";
return "";
}
function validateAssignTo(value) {
if (!value) return "";
if (!/^\d+$/.test(value)) return "Invalid assignee selected";
return "";
}
function validateSubject(value) {
if (!value) return "Subject is required.";
if (value.length < 3) return "Subject must be at least 3 characters long.";
if (value.length > 150) return "Subject cannot exceed 150 characters";
if (!/^[a-zA-Z0-9 .,\-_()&\/\?]+$/.test(value)) {
return "Subject contains invalid characters (Avoid quotes and special symbols).";
}
return "";
}
function validateMessage(value) {
if (!value) return "Message is required";
if (value.length < 10) return "Message must be at least 10 characters";
if (value.length > 1500) return "Message cannot exceed 1500 characters";
return "";
}
function validateField(fieldId) {
var field = document.getElementById(fieldId);
if (!field) return true;
var value = (field.value || "").trim();
var error = "";
switch (fieldId) {
case "mobile": error = validateMobile(value); break;
case "name": error = validateName(value); break;
case "email": error = validateEmail(value); break;
case "empcode": error = validateEmpcode(value); break;
case "ticket_type": error = validateTicketType(value); break;
case "assign_to": error = validateAssignTo(value); break;
case "subject": error = validateSubject(value); break;
case "message": error = validateMessage(value); break;
}
showFieldError(fieldId, error);
return !error;
}
function validateTicketForm() {
var fields = ["mobile", "name", "email", "empcode", "ticket_type", "subject", "message"];
if (document.getElementById("assign_to")) {
fields.push("assign_to");
}
var firstInvalid = null;
var isValid = true;
fields.forEach(function (fieldId) {
var ok = validateField(fieldId);
if (!ok && !firstInvalid) firstInvalid = document.getElementById(fieldId);
if (!ok) isValid = false;
});
if (!isValid && firstInvalid) firstInvalid.focus();
return isValid;
}
function submitTicket(event) {
event.preventDefault();
var form = document.getElementById('ticketForm');
if (!validateTicketForm()) {
toastr.warning('Please correct highlighted fields.', 'Warning');
return;
}
var form = document.getElementById("ticketForm"); // your form ID
var formData = new FormData(form);
var btn = event.target;
btn.disabled = true;
btn.innerText = "Saving...";
$.ajax({
url: "<?= base_url('ticketSave') ?>",
type: "POST",
data: formData,
processData: false,
contentType: false,
dataType: 'json',
success: function(response) {
if (response.status === "success") {
toastr.success(response.message, 'Success');
$('#ticketModal').modal('hide');
form.reset();
window.location.href = "<?= base_url('ticketList?return_type=web') ?>";
} else {
toastr.error(response.message, 'Error');
}
},
error: function(xhr) {
console.error(xhr.responseText);
if (xhr.status === 400) {
let response = JSON.parse(xhr.responseText);
clearAllFieldErrors();
let errorMessages = "";
let seenMessages = []; // Array to store unique messages
if (response.errors) {
$.each(response.errors, function (field, message) {
showFieldError(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() {
btn.disabled = false;
btn.innerText = "Save";
}
});
}
</script>
<script>
function getAutoFetchDetails() {
var client_id = document.getElementById('client_id').value.trim();
var mobile = document.getElementById('mobile').value.trim();
// reset fields
document.getElementById('name').value = "";
document.getElementById('email').value = "";
document.getElementById('empcode').value = "";
document.getElementById('branch_id').value = "";
document.getElementById('policy_id').value = "";
// reset select dropdown
var policySelect = document.getElementById('policy_no');
policySelect.innerHTML = '<option value="" data-id="">Select Policy</option>';
if (client_id === "") {
toastr.warning('Please Select Client.', 'Warning');
return;
}
if (mobile === "") {
toastr.warning('Please Enter a mobile number.', 'Warning');
return;
}
var mobilePattern = /^[0-9]{10}$/;
if (!mobilePattern.test(mobile)) {
toastr.warning('Please enter a valid 10-digit mobile number.', 'Warning');
document.getElementById('mobile').focus();
return;
}
$.ajax({
url: "<?= base_url('ticketAutoFetchDetails') ?>",
type: "POST",
data: { client_id: client_id, mobile: mobile },
dataType: 'json',
success: function(response) {
if (response.status === "success") {
let client = response.data.client_details[0];
let policies = response.data.policy_details;
document.getElementById('name').value = client.name || "";
document.getElementById('email').value = client.email_corporate || "";
document.getElementById('empcode').value = client.emp_code || "";
document.getElementById('branch_id').value = client.branch_id || "";
if (policies && policies.length > 0) {
policies.forEach(function(p) {
let opt = document.createElement("option");
opt.value = p.policy_no;
opt.text = p.policy_no;
opt.setAttribute("data-id", p.id);
policySelect.appendChild(opt);
});
// If you want to auto-select the first real policy instead of "Select Policy"
policySelect.value = policies[0].policy_no;
document.getElementById('policy_no').value = policies[0].policy_no || "";
document.getElementById('policy_id').value = policies[0].id;
}
} else {
toastr.warning(response.message || "No details found.", 'Warning');
}
},
error: function(xhr) {
toastr.error("Something went wrong!", 'Error');
console.error(xhr.responseText);
}
});
}
</script>
<script>
function changevalue() {
var select = document.getElementById('policy_no');
var selectedOption = select.options[select.selectedIndex];
var policyId = selectedOption.getAttribute("data-id");
document.getElementById('policy_id').value = policyId || "";
}
// function hideandshowpolicy() {
// var select = document.getElementById('ticket_type').value;
// var policyContainer = document.getElementById('policy_container');
// if (select === 'Service') {
// policyContainer.style.display = "block"; // show
// } else {
// policyContainer.style.display = "none"; // hide
// document.getElementById('policy_no').value = "";
// document.getElementById('policy_id').value = "";
// }
// }
function hideandshowpolicy() {
var select = document.getElementById('ticket_type');
var value = select.value;
var policyContainer = document.getElementById('policy_container');
if (value === "0") {
let newType = prompt("Enter new ticket type:");
if (newType && newType.trim() !== "") {
var formData = new FormData(form);
$.ajax({
url: "<?= base_url('ticketType') ?>",
type: "POST",
data: formData,
processData: false,
contentType: false,
dataType: 'json',
success: function(response) {
if (response.status === "success") {
let option = new Option(newType, newType);
let addNewOption = select.querySelector('option[value="0"]');
select.insertBefore(option, addNewOption);
select.value = newType;
value = newType;
console.log(response.message);
} else { console.log(response.message); value = ""; }
},
error: function(xhr) { console.log("Error: " + xhr.statusText); value = ""; }
});
} else {
select.value = "";
value = "";
}
}
if (value === 'Service') {
policyContainer.style.display = "block";
} else {
policyContainer.style.display = "none";
document.getElementById('policy_no').value = "";
document.getElementById('policy_id').value = "";
}
}
</script>
<script>
function updateAssignTo(){
console.log('function called then call the api then refresh the updateAssignTo');
}
</script>
<!-------------------------------------------------------------------------------------------------->
<script>
$(document).ready(function() {
$('[data-toggle="tooltip"]').tooltip();
// Initialize select2
$("#client_id").select2();
$("#ticket_type").select2();
$("#status").select2();
$("#assign_to").select2();
$("#policy_no").select2();
$("#modal_assignee").select2();
hideandshowpolicy();
const subjectInput = document.getElementById("subject");
const subjectCounter = document.getElementById("subjectCounter");
subjectInput.addEventListener("input", function () {
const subjectLength = subjectInput.value.length;
subjectCounter.textContent = `${subjectLength}/150`;
if (subjectLength > 150) {
subjectInput.classList.add('is-invalid');
} else {
subjectInput.classList.remove('is-invalid');
}
validateField("subject");
});
const messageInput = document.getElementById("message");
const messageCounter = document.getElementById("messageCounter");
messageInput.addEventListener("input", function () {
const messageLength = messageInput.value.length;
messageCounter.textContent = `${messageLength}/1500`;
if (messageLength > 1500) {
messageInput.classList.add('is-invalid');
} else {
messageInput.classList.remove('is-invalid');
}
validateField("message");
});
[
{ id: "mobile", event: "input" },
{ id: "name", event: "input" },
{ id: "email", event: "input" },
{ id: "empcode", event: "input" },
{ id: "ticket_type", event: "change" },
{ id: "assign_to", event: "change" }
].forEach(function (cfg) {
var el = document.getElementById(cfg.id);
if (el) {
el.addEventListener(cfg.event, function () {
validateField(cfg.id);
});
}
});
});
function viewTicket(ticket_id){
// $('.loader').fadeIn();
// $('.loader-mask').fadeIn();
let url = '<?= base_url('ticketConversationList?return_type=web&thz_id='); ?>' + ticket_id;
window.location.href = url;
}
function removeticket(input, ticket_id) {
confirmActionSweertAlert("Do you want to delete this ticket?", "Yes, Proceed!", "No, Cancel").then((confirmed) => {
if (confirmed) {
let url = '<?= base_url('ticket/remove') ?>';
// Include `pt_id` in the AJAX request if necessary
let requestData = { ticket_id: ticket_id };
sendAjaxRequestForGlobal(url, 'GET', requestData, function(response) {
console.log('Data fetched successfully:', response);
if (response.status === true) {
toastr.success(response.message, 'Success');
window.location.reload();
} else {
toastr.warning(response.message, 'Warning');
}
}, function(xhr, status, error) {
console.error('Error fetching data:', error);
console.error(xhr.responseText);
});
}
});
}
$(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) {
const id = $(this).data('id');
console.log('Ticket ID', id)
viewTicket(id);
}
});
</script>