This portal only for GCC Officers. Based on there roles and Group ID they can view there module`s Like PGR, QR Public Asset Feedback, Makkalai Thedi Mayor,etc...
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

898 lines
32 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head th:replace="~{fragments/modules/base/head :: head}">
  4. </head>
  5. <style>
  6. .required {
  7. color: red;
  8. }
  9. .card-box {
  10. box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px;
  11. height: 140px;
  12. }
  13. @media ( max-width : 768px) {
  14. .card-box {
  15. text-align: center;
  16. }
  17. }
  18. .custom-width1 {
  19. width: 120px; /* Adjust the width as needed */
  20. }
  21. .custom-width2 {
  22. width: 100px; /* Adjust the width as needed */
  23. }
  24. #modalBody h4 {
  25. font-weight: bold;
  26. margin-top: 15px;
  27. margin-bottom: 10px;
  28. }
  29. #modalBody p {
  30. margin: 5px 0;
  31. }
  32. #modalBody hr {
  33. margin: 15px 0;
  34. }
  35. .comment {
  36. margin-bottom: 20px;
  37. }
  38. .comment p {
  39. margin: 0;
  40. }
  41. hr {
  42. border: 1px solid #ccc;
  43. }
  44. .col-4 {
  45. font-weight: bold;
  46. text-align: right;
  47. }
  48. .col-8 {
  49. padding-left: 20px;
  50. }
  51. .comment {
  52. padding: 10px 0;
  53. }
  54. .comment .text-muted {
  55. font-size: 0.9em;
  56. color: #6c757d;
  57. }
  58. .comment hr {
  59. border-top: 1px solid #ccc;
  60. }
  61. .comment .btn-link {
  62. font-size: 0.9em;
  63. text-decoration: underline;
  64. color: #007bff;
  65. }
  66. /* Make the modal body scrollable */
  67. #detailsModal .modal-body {
  68. max-height: 70vh; /* Limit the height to 70% of the viewport */
  69. overflow-y: auto; /* Enable vertical scrolling */
  70. }
  71. </style>
  72. <body>
  73. <div class="wrapper">
  74. <!-- Header -->
  75. <header th:replace="~{fragments/modules/base/header :: header}"></header>
  76. <div class="page-wrap">
  77. <!-- Left Menu -->
  78. <div th:replace="~{fragments/modules/base/menu :: menu}"></div>
  79. <div class="main-content">
  80. <div class="container-fluid">
  81. <div class="page-header">
  82. <div class="row align-items-end">
  83. <div class="col-lg-6">
  84. <div class="page-header-title">
  85. <i class="ik ik-layers bg-blue"></i>
  86. <div class="d-inline">
  87. <h5>Agent's Followup Calls</h5>
  88. <span>1913 Followup Call List</span>
  89. </div>
  90. </div>
  91. </div>
  92. <div class="col-lg-6">
  93. <nav class="breadcrumb-container" aria-label="breadcrumb">
  94. <ol class="breadcrumb">
  95. <li class="breadcrumb-item"><a href="/gcc/index"><i
  96. class="ik ik-home"></i></a></li>
  97. <li class="breadcrumb-item" aria-current="page">1913 QAQC</li>
  98. <li class="breadcrumb-item" aria-current="page">Agents
  99. QAQC</li>
  100. <li class="breadcrumb-item active" aria-current="page">Official FollowUp Calls</li>
  101. </ol>
  102. </nav>
  103. </div>
  104. </div>
  105. </div>
  106. <div class="row mt-4">
  107. <div class="col-md-12">
  108. <div class="card">
  109. <div class="card-body">
  110. <div class="page-header-title">
  111. <h5 style="margin: 0; font-weight: bold;">Today Assigned
  112. Calls</h5>
  113. </div>
  114. <div>
  115. <div class="row mt-2">
  116. <!-- Total Calls Assigned -->
  117. <div class="col-xl-3 col-md-6 col-sm-12">
  118. <div class="card card-box p-3 text-center mt-4">
  119. <h6 class="text-facebook mb-4">
  120. <b>Total Calls Assigned</b>
  121. </h6>
  122. <h4 class="text-twitter fw-700 mt-4"
  123. th:text="${details[0]?.Total_Calls_assigned}">
  124. <!-- Display Total Calls Assigned -->
  125. </h4>
  126. </div>
  127. </div>
  128. <!-- QA&QC Calls -->
  129. <div class="col-xl-3 col-md-6 col-sm-12">
  130. <div class="card card-box p-3 text-center mt-4">
  131. <h6 class="text-facebook mb-4">
  132. <b>QA&QC Calls</b>
  133. </h6>
  134. <h4 class="text-twitter fw-700 mt-4"
  135. th:text=" ${details[0]?.Closed_Call_count}">
  136. <!-- Display Closed Calls Count -->
  137. </h4>
  138. </div>
  139. </div>
  140. <!-- In-progress Calls -->
  141. <div class="col-xl-2 col-md-6 col-sm-12">
  142. <div class="card card-box p-3 text-center mt-4 ">
  143. <h6 class="text-facebook mb-4">
  144. <b>In-progress Calls</b>
  145. </h6>
  146. <h4 class="text-twitter fw-700 mt-4"
  147. th:text="${details[0]?.Inprogress_Call_count}">
  148. <!-- Display In-progress Calls Count -->
  149. </h4>
  150. </div>
  151. </div>
  152. <!-- Follow-up Calls -->
  153. <div class="col-xl-2 col-md-6 col-sm-12" style="background-color: aqua;">
  154. <div class="card card-box p-3 text-center mt-4">
  155. <h6 class="text-facebook mb-2">
  156. <b>Official Follow-up Calls</b>
  157. </h6>
  158. <h4 class="text-twitter fw-700 mt-3"
  159. th:text="${details[0]?.Followup_Call_count}">
  160. <!-- Display Follow-up Calls Count -->
  161. </h4>
  162. </div>
  163. </div>
  164. <div class="col-xl-2 col-md-6 col-sm-12">
  165. <div class="card card-box p-3 text-center mt-4">
  166. <h6 class="text-facebook mb-2">
  167. <b>Public Follow-up Calls</b>
  168. </h6>
  169. <h4 class="text-twitter fw-700 mt-3"
  170. th:text="${details[0]?.PublicFollowup_Call_count}">
  171. <!-- Display Follow-up Calls Count -->
  172. </h4>
  173. </div>
  174. </div>
  175. </div>
  176. <div class="row mt-2">
  177. <div class="col-md-12">
  178. <div class="card-header">
  179. <h3 style="font-weight: bold; font-size: large;"><span th:text="${userId}" style="display:none;" id="userIdSpan"></span>
  180. <span th:text="${agent[0]['agent_name']}"
  181. style="font-weight: bold; font-size: large;"></span>'s
  182. Followup Calls List
  183. </h3>
  184. </div>
  185. <div class="card-block">
  186. <div class="col-md-12 ">
  187. <div class="row">
  188. <button id="primaryButton" class="btn btn-success">Non-Processed
  189. Calls</button>
  190. <button id="secondaryButton"
  191. class="btn btn-secondary btn-custom ml-3">Processed
  192. Calls</button>
  193. </div>
  194. </div>
  195. </div>
  196. <div class="card-body">
  197. <div class="table-responsive" id="primaryTable"
  198. style="display: block;">
  199. <table id="QaqcDatatable"
  200. class="table table-striped table-bordered table-hover dataTable"
  201. role="grid">
  202. <thead class="thead-dark">
  203. <tr role="row">
  204. <th class="text-center">S.No</th>
  205. <th class="text-center">ID</th>
  206. <th class="text-center">Complaint Date</th>
  207. <!-- <th class="text-center">Name</th>
  208. <th class="text-center">Phone No</th> -->
  209. <th class="text-center">Officer Name</th>
  210. <th class="text-center">Officer PhoneNo</th>
  211. <th class="text-center">Complaint Type</th>
  212. <th class="text-center custom-width2">View</th>
  213. <th class="text-center custom-width1">Actions</th>
  214. <th class="text-center">Remarks</th>
  215. <th class="text-center">Submit</th>
  216. </tr>
  217. </thead>
  218. <tbody>
  219. <!-- Thymeleaf loop for populating data -->
  220. <tr th:each="call, iterStat : ${qaqcfollowuplists}">
  221. <td th:text="${iterStat.index + 1}" class="text-center"></td>
  222. <td th:text="${call['complaint_number']}"
  223. class="text-center complaint-select"></td>
  224. <td th:text="${call['complaint_date']}"
  225. class="text-center"></td>
  226. <!-- <td th:text="${call['complaint_person_name']}"
  227. class="text-center"></td>
  228. <td th:text="${call['complaint_mobilenumber']}"
  229. class="text-center"></td> -->
  230. <td th:text="${call['official_name']}"
  231. class="text-center"></td>
  232. <td th:text="${call['official_mobilenum']}"
  233. class="text-center"></td>
  234. <td th:text="${call['complaint_type']}"
  235. class="text-center"></td>
  236. <!-- view function -->
  237. <td class="text-center">
  238. <button type="button" class="btn btn-info details-btn"
  239. style="margin-bottom: 3px"
  240. th:data-complaint-number="${call['complaint_number']}">
  241. View</button>
  242. </td>
  243. <td class="text-center"><select
  244. class="form-control form-control-sm action-select action-dropdown">
  245. <option value="" selected>Select</option>
  246. <option th:each="status : ${qaqccategorylists}"
  247. th:value="${status.call_status}"
  248. th:text="${status.call_status}"></option>
  249. </select>
  250. <div class="schedule-call d-none mt-2">
  251. <!-- <span class="schedule-text">Schedule Call</span> -->
  252. <input type="date" class="date-picker form-control"
  253. name="remainderDate">
  254. </div></td>
  255. <td class="text-center"><input type="text"
  256. class="form-control form-control-sm"
  257. placeholder="Remarks"></td>
  258. <td class="text-center">
  259. <button class="btn btn-primary btn-sm submit-btn submitid"
  260. th:data-id="${call['data_id']}"
  261. onclick="submitComplaint(this)" disabled="disabled">
  262. Submit</button>
  263. </td>
  264. </tr>
  265. </tbody>
  266. </table>
  267. </div>
  268. <div class="table-responsive" id="secondaryTable"
  269. style="display: none;">
  270. <table id="SecondaryDatatable"
  271. class="table table-striped table-bordered table-hover dataTable"
  272. role="grid">
  273. <thead class="thead-dark">
  274. <tr role="row">
  275. <th class="text-center">S.No</th>
  276. <th class="text-center">ID</th>
  277. <th class="text-center">Complaint Date</th>
  278. <th class="text-center">Officer Name</th>
  279. <th class="text-center">Officer PhoneNo</th>
  280. <th class="text-center">Complaint Type</th>
  281. <th class="text-center">View Details</th>
  282. <th class="text-center custom-width1">Actions</th>
  283. <th class="text-center">Remarks</th>
  284. </tr>
  285. </thead>
  286. <tbody>
  287. <tr th:each="call, iterStat : ${fcSubmitDetails}">
  288. <td th:text="${iterStat.index + 1}" class="text-center"></td>
  289. <td th:text="${call['complaint_number']}"
  290. class="text-center complaint-select"></td>
  291. <td th:text="${call['complaint_date']}"
  292. class="text-center"></td>
  293. <td th:text="${call['official_name']}"
  294. class="text-center"></td>
  295. <td th:text="${call['official_mobilenum']}"
  296. class="text-center"></td>
  297. <td th:text="${call['complaint_type']}"
  298. class="text-center"></td>
  299. <td class="text-center">
  300. <button type="button" class="btn btn-info"
  301. th:data-complaint-number="${call['complaint_number']}">View</button>
  302. </td>
  303. <td th:text="${call['call_status']}" class="text-center"></td>
  304. <td th:text="${call['remarks']}" class="text-center"></td>
  305. </tr>
  306. </tbody>
  307. </table>
  308. </div>
  309. </div>
  310. </div>
  311. </div>
  312. </div>
  313. </div>
  314. </div>
  315. </div>
  316. </div>
  317. </div>
  318. </div>
  319. <footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
  320. </div>
  321. </div>
  322. <!--Details button Modal -->
  323. <div class="modal fade" id="detailsModal" tabindex="-1" role="dialog"
  324. aria-labelledby="detailsModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
  325. <div class="modal-dialog modal-lg" role="document">
  326. <div class="modal-content">
  327. <div class="modal-header">
  328. <h5 class="modal-title" id="detailsModalLabel">Complaint
  329. Details</h5>
  330. <button type="button" class="close" data-dismiss="modal"
  331. aria-label="Close">
  332. <span aria-hidden="true">&times;</span>
  333. </button>
  334. </div>
  335. <div class="modal-body" id="modalBody">
  336. <!-- Details will be populated here -->
  337. </div>
  338. <div class="modal-footer">
  339. <button type="button" class="btn btn-secondary"
  340. data-dismiss="modal">Close</button>
  341. </div>
  342. </div>
  343. </div>
  344. </div>
  345. <!-- Include jQuery and Bootstrap JavaScript -->
  346. <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  347. <script
  348. src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
  349. <script th:replace="~{fragments/modules/base/script :: script}"></script>
  350. <!-- sweet alert -->
  351. <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  352. <script type="text/javascript">
  353. $(document).ready(function() {
  354. $(document).on('click', '.btn-info', function () {
  355. // Retrieve the complaint number from the data attribute
  356. var complaintNumber = $(this).data('complaint-number');
  357. // Call the viewDetails function with the complaint number
  358. viewDetails(complaintNumber);
  359. });
  360. $('#primaryButton').addClass('btn-success').removeClass('btn-secondary');
  361. $('#secondaryButton').addClass('btn-secondary').removeClass('btn-success');
  362. // Toggle functionality for Primary and Secondary buttons
  363. $('#primaryButton').click(function () {
  364. $('#primaryTable').show();
  365. $('#secondaryTable').hide();
  366. $(this).addClass('btn-success').removeClass('btn-secondary');
  367. $('#secondaryButton').addClass('btn-secondary').removeClass('btn-success');
  368. $('#QaqcDatatable').DataTable().columns.adjust().draw();
  369. });
  370. $('#secondaryButton').click(function () {
  371. $('#primaryTable').hide();
  372. $('#secondaryTable').show();
  373. $(this).addClass('btn-success').removeClass('btn-secondary');
  374. $('#primaryButton').addClass('btn-secondary').removeClass('btn-success');
  375. $('#SecondaryDatatable').DataTable().columns.adjust().draw();
  376. });
  377. var table = $('#QaqcDatatable').DataTable({
  378. dom: 'Bftip',
  379. columnDefs: [
  380. { targets: 'no-sort', orderable: false }
  381. ],
  382. lengthMenu: [
  383. [50, 100, 200, 500, -1],
  384. ['50 rows', '100 rows', '200 rows', 'Show all']
  385. ],
  386. scrollY: '50vh',
  387. fixedColumns: {
  388. left: 1,
  389. right: 1
  390. },
  391. buttons: [
  392. {
  393. extend: 'pageLength',
  394. className: 'btn btn-warning'
  395. },
  396. {
  397. title: 'Data export',
  398. extend: 'copyHtml5',
  399. text: 'Copy',
  400. className: 'btn btn-secondary',
  401. id: 'copyBtn'
  402. },
  403. {
  404. extend: 'excelHtml5',
  405. text: 'Excel',
  406. className: 'btn btn-secondary',
  407. id: 'excelBtn'
  408. },
  409. {
  410. extend: 'csvHtml5',
  411. text: 'CSV',
  412. className: 'btn btn-secondary',
  413. id: 'csvBtn'
  414. },
  415. {
  416. extend: 'pdfHtml5',
  417. text: 'PDF',
  418. className: 'btn btn-secondary',
  419. id: 'pdfBtn'
  420. }
  421. ],
  422. fixedHeader: true,
  423. autoWidth: true,
  424. responsive: true,
  425. searching: true, // Enable default search functionality
  426. select: false,
  427. processing: false
  428. });
  429. var table1 = $('#SecondaryDatatable').DataTable({
  430. dom: 'Bftip',
  431. columnDefs: [
  432. { targets: 'no-sort', orderable: false }
  433. ],
  434. lengthMenu: [
  435. [50, 100, 200, 500, -1],
  436. ['50 rows', '100 rows', '200 rows', 'Show all']
  437. ],
  438. scrollY: '50vh',
  439. fixedColumns: {
  440. left: 1,
  441. right: 1
  442. },
  443. buttons: [
  444. {
  445. extend: 'pageLength',
  446. className: 'btn btn-warning'
  447. },
  448. {
  449. title: 'Data export',
  450. extend: 'copyHtml5',
  451. text: 'Copy',
  452. className: 'btn btn-secondary',
  453. id: 'copyBtn'
  454. },
  455. {
  456. extend: 'excelHtml5',
  457. text: 'Excel',
  458. className: 'btn btn-secondary',
  459. id: 'excelBtn'
  460. },
  461. {
  462. extend: 'csvHtml5',
  463. text: 'CSV',
  464. className: 'btn btn-secondary',
  465. id: 'csvBtn'
  466. },
  467. {
  468. extend: 'pdfHtml5',
  469. text: 'PDF',
  470. className: 'btn btn-secondary',
  471. id: 'pdfBtn'
  472. }
  473. ],
  474. fixedHeader: true,
  475. autoWidth: true,
  476. responsive: true,
  477. searching: true,
  478. select: false,
  479. processing: false
  480. });
  481. // // Event listeners for changes in dropdown, remarks, and date picker
  482. $(document).on('change', '.action-dropdown', function () {
  483. const parentRow = $(this).closest('tr');
  484. const schedulerDiv = parentRow.find('.schedule-call');
  485. schedulerDiv.toggleClass('d-none', $(this).val() !== 'FOLLOWUP');
  486. validateFields(parentRow);
  487. });
  488. $(document).on('input', 'input[type="text"]', function () {
  489. const parentRow = $(this).closest('tr');
  490. validateFields(parentRow);
  491. });
  492. $(document).on('change', '.date-picker', function () {
  493. const parentRow = $(this).closest('tr');
  494. validateFields(parentRow);
  495. });
  496. // Validate function to check conditions for enabling/disabling submit button
  497. function validateFields(row) {
  498. const actionSelect = row.find('.action-select');
  499. const remarksInput = row.find('input[type="text"]');
  500. const submitButton = row.find('.submit-btn');
  501. const actionValue = actionSelect.val().trim();
  502. const remarksFilled = remarksInput.val().trim() !== "";
  503. const followUpSelected = actionValue === "FOLLOWUP";
  504. const remainderDateFilled = row.find('.date-picker').val()?.trim() !== ""; // Check if date is selected
  505. // Enable submit button based on conditions
  506. if (
  507. (followUpSelected && remainderDateFilled && remarksFilled) || (actionValue !== "FOLLOWUP" && actionValue !=="Select") // FOLLOWUP requires remainder date and remarks
  508. ) {
  509. submitButton.prop('disabled', false); // Enable submit button
  510. } else {
  511. submitButton.prop('disabled', true); // Disable submit button
  512. }
  513. }
  514. // Initial validation for all rows on page load
  515. $("#QaqcDatatable tbody tr").each(function () {
  516. const row = $(this);
  517. const submitButton = row.find('.submit-btn');
  518. submitButton.prop('disabled', true); // Ensure submit button is initially disabled
  519. validateFields(row); // Validate fields for further interaction
  520. });
  521. // Re-validate fields on input changes
  522. $("#QaqcDatatable").on('input change', '.action-select, input[type="text"], .date-picker', function () {
  523. const row = $(this).closest('tr');
  524. validateFields(row);
  525. });
  526. });
  527. function submitComplaint(button) {
  528. var userId = document.getElementById('userIdSpan').textContent;
  529. const row = button.parentNode.parentNode;
  530. // Fetch the values from the corresponding cells in the row
  531. const dataId = row.querySelector('.submit-btn').getAttribute('data-id'); // Fetch the data_id
  532. const action = row.querySelector('.action-select').value.trim(); // Fetch the action value
  533. const complaintNumber = row.querySelector('.complaint-select').innerText.trim(); // Fetch complaint number
  534. const remarks = row.querySelector('input[type="text"]').value.trim(); // Fetch the remarks value
  535. const remainderDate = row.querySelector('.date-picker')?.value.trim(); // Fetch the remainder date (if any)
  536. /* console.log(row);
  537. console.log(dataId);
  538. console.log(action);
  539. console.log(complaintNumber);
  540. console.log(remarks);
  541. console.log(remainderDate); */
  542. $('.submitid').prop('disabled', true).text('Submitting...');
  543. // Validation
  544. if (!dataId || !action || action === "Select") {
  545. Swal.fire("Error", "Action is required!", "error");
  546. $('.submitid').prop('disabled', false).text('Submit');
  547. return;
  548. }
  549. if (action === 'FOLLOWUP' && remarks === "" && (!remainderDate || remainderDate === "")) {
  550. Swal.fire("Error", "Schedule Date is required for Follow-Up!", "error");
  551. $('.submitid').prop('disabled', false).text('Submit');
  552. return;
  553. }
  554. // AJAX Request
  555. $.ajax({
  556. url: '/gcc/api/callcenterqaqc/agent/followupcalls/update',
  557. type: 'POST',
  558. data: {
  559. dataId: dataId,
  560. complaintNumber: complaintNumber,
  561. action: action,
  562. remarks: remarks,
  563. remainderDate: remainderDate,
  564. userId:userId
  565. },
  566. success: function (response) {
  567. if (response === "Success") {
  568. Swal.fire({
  569. icon: 'success',
  570. title: 'Success',
  571. text: 'Complaint updated successfully!',
  572. allowOutsideClick: false, // Disable clicking outside the modal to close it
  573. allowEscapeKey: false, // Disable escape key to close the modal
  574. allowEnterKey: false, // Disable enter key to close the modal
  575. showConfirmButton: true, // Ensure the confirm button is visible
  576. }).then((result) => {
  577. if (result.isConfirmed) {
  578. $('.submitid').prop('disabled', false).text('Submit');
  579. const table = $('#QaqcDatatable').DataTable();
  580. // Remove the row
  581. table.row($(row)).remove();
  582. // Reorder S.No column
  583. table.rows().every(function (index) {
  584. const row = this.node();
  585. $(row).find('td:first-child').text(index + 1); // Update S.No
  586. });
  587. // Redraw the table
  588. table.draw(false);
  589. }
  590. });
  591. }
  592. else if (response === "error") {
  593. $('.submitid').prop('disabled', false).text('Submit');
  594. Swal.fire("Error", "Failed to update complaint. Please try again later.", "error");
  595. }
  596. else {
  597. $('.submitid').prop('disabled', false).text('Submit');
  598. Swal.fire("Error", "Failed to update complaint. Please try again.", "error");
  599. }
  600. },
  601. error: function (xhr, status, error) {
  602. $('.submitid').prop('disabled', false).text('Submit');
  603. Swal.fire("Error", `An error occurred: ${xhr.responseText || error}`, "error");
  604. }
  605. });
  606. }
  607. //view button script
  608. function viewDetails(complaintNumber) {
  609. document.getElementById('modalBody').innerHTML = '<p style="text-align:center;">Please wait, loading data...</p>';
  610. $('#detailsModal').modal('show');
  611. // Fetch the main complaint details
  612. $.ajax({
  613. url: '/gcc/api/callcenterqaqc/agent/qaqccalls/getComplaintDetails',
  614. type: 'GET',
  615. data:{complaintNumber:complaintNumber},
  616. success: function (data) {
  617. //console.log('Complaint Data:', data);
  618. // Fetch agent response details
  619. $.ajax({
  620. url: '/gcc/api/callcenterqaqc/agent/attendedcomplaintshistory',
  621. type: 'GET',
  622. data: { complaintNumber },
  623. success: function (agentResponse) {
  624. //console.log('Agent Response:', agentResponse);
  625. // Use the logic for building complaint and agent details as HTML
  626. const detailsHtml = generateDetailsHtml(data, agentResponse);
  627. // Update modal content
  628. document.getElementById('modalBody').innerHTML = detailsHtml;
  629. },
  630. error: function () {
  631. document.getElementById('modalBody').innerHTML = '<p>Error loading agent details. Please try again later.</p>';
  632. }
  633. });
  634. },
  635. error: function () {
  636. document.getElementById('modalBody').innerHTML = '<p>Error loading complaint details. Please try again later.</p>';
  637. }
  638. });
  639. }
  640. // Function to generate complaint and agent details HTML
  641. function generateDetailsHtml(data, agentResponse) {
  642. // Helper function to format date to yyyy-mm-dd
  643. function formatDate(dateStr) {
  644. if (!dateStr) return 'N/A';
  645. const date = new Date(dateStr);
  646. return date.toISOString().split('T')[0]; // Formats to yyyy-mm-dd
  647. }
  648. // Format complaint messages
  649. let messagesHtml = '';
  650. if (data.comments && data.comments.length > 0) {
  651. data.comments.forEach((comment) => {
  652. const commentImageLink = comment.Comp_Image && comment.Comp_Image !== "No image available"
  653. ? `<a href="${comment.Comp_Image}" target="_blank" style="color: green; text-decoration: underline;">View Image</a>`
  654. : '<p style="color: red;">No image available for this comment.</p>';
  655. messagesHtml += `
  656. <div class="comment mb-4">
  657. <div class="row">
  658. <div class="col-2 text-center">
  659. <p class="text-muted">${comment.comment_date}</p>
  660. </div>
  661. <div class="col-10">
  662. <p><strong>${comment.user || 'N/A'}</strong> Says:</p>
  663. <p>${comment.message || 'No message available'}</p>
  664. <div class="user-image">${commentImageLink}</div>
  665. </div>
  666. </div>
  667. </div>
  668. `;
  669. });
  670. } else {
  671. messagesHtml = '<p>No comments available.</p>';
  672. }
  673. // Format agent responses
  674. let agentRepliedHtml = '';
  675. if (agentResponse.length > 0) {
  676. agentResponse.forEach((agentItem) => {
  677. agentRepliedHtml += `
  678. <div class="comment mb-4">
  679. <div class="row">
  680. <div class="col-2 text-center">
  681. <p class="text-muted"><strong>${formatDate(agentItem.created_date) || 'N/A'}</strong></p>
  682. </div>
  683. <div class="col-10">
  684. <p><strong>${agentItem.agent_name || 'N/A'}</strong>, Says: ${agentItem.call_status || 'N/A'}</p>
  685. <p><strong>Remarks: </strong>${agentItem.remarks || 'N/A'}</p>
  686. <p><strong>Remainder Date: </strong> ${formatDate(agentItem.remainder_date) || 'N/A'}</p>
  687. </div>
  688. </div>
  689. </div>
  690. `;
  691. });
  692. } else {
  693. agentRepliedHtml = '<p>No agent replied messages available.</p>';
  694. }
  695. // Check for user images
  696. const userImages = data.userimages && data.userimages.length > 0 ? data.userimages[0] : {};
  697. const imageLink = userImages.Comp_Image && userImages.Comp_Image !== "null" && userImages.Comp_Image !== ""
  698. ? `<a href="${userImages.Comp_Image}" target="_blank" style="color: green; text-decoration: underline;">UserImages: View Image</a>`
  699. : '<p style="color: red;">UserImages: No image available.</p>';
  700. // Combine all sections into the final HTML
  701. const detailsHtml = `
  702. <div class="row">
  703. <div class="col-md-12">
  704. <h4>Complaint Person's Details:</h4>
  705. <div class="row">
  706. <div class="col-6">
  707. <p><strong>Complaint Number:</strong> ${data.complaintid || 'N/A'}</p>
  708. </div>
  709. <div class="col-6">
  710. <p><strong>Complaint Date:</strong> ${data.complaintdate}</p>
  711. </div>
  712. </div>
  713. <div class="row">
  714. <div class="col-6">
  715. <p><strong>Complainant's Name:</strong> ${data.complainantName || 'N/A'}</p>
  716. </div>
  717. <div class="col-6">
  718. <p><strong>Phone Number:</strong> ${data.mobileNumber || 'N/A'}</p>
  719. </div>
  720. </div>
  721. <div class="row">
  722. <div class="col-6">
  723. <p><strong>Zone:</strong> ${data.Zone || 'N/A'}</p>
  724. </div>
  725. <div class="col-6">
  726. <p><strong>Division:</strong> ${data.Division || 'N/A'}</p>
  727. </div>
  728. </div>
  729. <div class="row">
  730. <div class="col-6">
  731. <p><strong>Gender:</strong> ${data.gender || 'N/A'}</p>
  732. </div>
  733. <div class="col-6">
  734. <p><strong>Complainant's Address:</strong> ${data.Street || 'N/A'}, ${data.Area || 'N/A'}, ${data.Landmark || 'N/A'}, ${data.Location || 'N/A'}</p>
  735. </div>
  736. </div>
  737. </div>
  738. </div>
  739. <hr>
  740. <h4>Complaint Details:</h4>
  741. <div class="row">
  742. <div class="col-6">
  743. <p><strong>Complaint Dept:</strong> ${data.deptname || 'N/A'}</p>
  744. </div>
  745. <div class="col-6">
  746. <p><strong>Complaint Mode:</strong> ${data.compmode || 'N/A'}</p>
  747. </div>
  748. </div>
  749. <div class="row">
  750. <div class="col-6">
  751. <p><strong>Complaint Type:</strong> ${data.complaintType || 'N/A'}</p>
  752. </div>
  753. <div class="col-6">
  754. <p><strong>Details of Complaint:</strong> ${data.description || 'N/A'}</p>
  755. </div>
  756. </div>
  757. <div class="row">
  758. <div class="col-6">
  759. <p><strong>Current Status:</strong> ${data.currentStatus || 'N/A'}</p>
  760. </div>
  761. <div class="col-6">
  762. <p><strong style="color:blue;">Official Mobile:</strong> ${data.OfficialMobile || 'N/A'}</p>
  763. </div>
  764. </div>
  765. <div class="row">
  766. <div class="col-6">
  767. <p><strong>Last Updated Date:</strong> ${data.greatestDate || 'N/A'}</p>
  768. </div>
  769. </div>
  770. <hr>
  771. <h4>Complaint Messages:</h4>
  772. ${messagesHtml}
  773. <hr>
  774. <h4>Agent Replied Messages:</h4>
  775. ${agentRepliedHtml}
  776. <hr>
  777. ${imageLink}
  778. `;
  779. return detailsHtml;
  780. }
  781. </script>
  782. </body>
  783. </html>