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.

968 lines
39 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">Public 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" >
  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" style="background-color: aqua;">
  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">Public Name</th>
  208. <th class="text-center">Public PhoneNo</th>
  209. <th class="text-center">Complaint Type</th>
  210. <th class="text-center custom-width2">View</th>
  211. <th class="text-center custom-width1">Actions</th>
  212. <th class="text-center">Remarks</th>
  213. <th class="text-center">Submit</th>
  214. </tr>
  215. </thead>
  216. <tbody>
  217. <!-- Thymeleaf loop for populating data -->
  218. <tr th:each="call, iterStat : ${qaqcfollowuplists}">
  219. <td th:text="${iterStat.index + 1}" class="text-center"></td>
  220. <td th:text="${call['complaint_number']}"
  221. class="text-center complaint-select"></td>
  222. <td th:text="${call['complaint_date']}"
  223. class="text-center"></td>
  224. <td th:text="${call['complaint_person_name']}"
  225. class="text-center"></td>
  226. <td th:text="${call['complaint_mobilenumber']}"
  227. class="text-center"></td>
  228. <!-- <td th:text="${call['official_name']}"
  229. class="text-center"></td>
  230. <td th:text="${call['official_mobilenum']}"
  231. class="text-center"></td> -->
  232. <td th:text="${call['complaint_type']}"
  233. class="text-center"></td>
  234. <!-- view function -->
  235. <td class="text-center">
  236. <button type="button" class="btn btn-info details-btn"
  237. style="margin-bottom: 3px"
  238. th:data-complaint-number="${call['complaint_number']}">
  239. View</button>
  240. </td>
  241. <td class="text-center"><select
  242. class="form-control form-control-sm action-select action-dropdown">
  243. <option value="" selected>Select</option>
  244. <option th:each="status : ${qaqccategorylists}"
  245. th:value="${status.call_status}"
  246. th:text="${status.call_status}"></option>
  247. </select>
  248. <div class="schedule-call d-none mt-2">
  249. <!-- <span class="schedule-text">Schedule Call</span> -->
  250. <input type="date" class="date-picker form-control"
  251. name="remainderDate">
  252. </div></td>
  253. <td class="text-center"><input type="text"
  254. class="form-control form-control-sm"
  255. placeholder="Remarks"></td>
  256. <td class="text-center">
  257. <button class="btn btn-primary btn-sm submit-btn submitid"
  258. th:data-id="${call['data_id']}"
  259. th:complaint-select="${call['complaint_number']}"
  260. th:data-name="${call['complaint_person_name']}"
  261. th:data-number="${call['complaint_mobilenumber']}"
  262. th:data-complaint-type="${call['complaint_type']}"
  263. onclick="submitComplaint(this)" disabled="disabled">
  264. Submit</button>
  265. </td>
  266. </tr>
  267. </tbody>
  268. </table>
  269. </div>
  270. <div class="table-responsive" id="secondaryTable"
  271. style="display: none;">
  272. <table id="SecondaryDatatable"
  273. class="table table-striped table-bordered table-hover dataTable"
  274. role="grid">
  275. <thead class="thead-dark">
  276. <tr role="row">
  277. <th class="text-center">S.No</th>
  278. <th class="text-center">ID</th>
  279. <th class="text-center">Complaint Date</th>
  280. <th class="text-center">Public Name</th>
  281. <th class="text-center">Public PhoneNo</th>
  282. <th class="text-center">Complaint Type</th>
  283. <th class="text-center">View Details</th>
  284. <th class="text-center custom-width1">Actions</th>
  285. <th class="text-center">Remarks</th>
  286. </tr>
  287. </thead>
  288. <tbody>
  289. <tr th:each="call, iterStat : ${fcSubmitDetails}">
  290. <td th:text="${iterStat.index + 1}" class="text-center"></td>
  291. <td th:text="${call['complaint_number']}"
  292. class="text-center complaint-select"></td>
  293. <td th:text="${call['complaint_date']}"
  294. class="text-center"></td>
  295. <td th:text="${call['complaint_person_name']}"
  296. class="text-center"></td>
  297. <td th:text="${call['complaint_mobilenumber']}"
  298. class="text-center"></td>
  299. <td th:text="${call['complaint_type']}"
  300. class="text-center"></td>
  301. <td class="text-center">
  302. <button type="button" class="btn btn-info"
  303. th:data-complaint-number="${call['complaint_number']}">View</button>
  304. </td>
  305. <td th:text="${call['call_status']}" class="text-center"></td>
  306. <td th:text="${call['remarks']}" class="text-center"></td>
  307. </tr>
  308. </tbody>
  309. </table>
  310. </div>
  311. </div>
  312. </div>
  313. </div>
  314. </div>
  315. </div>
  316. </div>
  317. </div>
  318. </div>
  319. </div>
  320. </div>
  321. <footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
  322. </div>
  323. </div>
  324. <!--Details button Modal -->
  325. <div class="modal fade" id="detailsModal" tabindex="-1" role="dialog"
  326. aria-labelledby="detailsModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
  327. <div class="modal-dialog modal-lg" role="document">
  328. <div class="modal-content">
  329. <div class="modal-header">
  330. <h5 class="modal-title" id="detailsModalLabel">Complaint
  331. Details</h5>
  332. <button type="button" class="close" data-dismiss="modal"
  333. aria-label="Close">
  334. <span aria-hidden="true">&times;</span>
  335. </button>
  336. </div>
  337. <div class="modal-body" id="modalBody">
  338. <!-- Details will be populated here -->
  339. </div>
  340. <div class="modal-footer">
  341. <button type="button" class="btn btn-secondary"
  342. data-dismiss="modal">Close</button>
  343. </div>
  344. </div>
  345. </div>
  346. </div>
  347. <!-- Include jQuery and Bootstrap JavaScript -->
  348. <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  349. <script
  350. src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
  351. <script th:replace="~{fragments/modules/base/script :: script}"></script>
  352. <!-- sweet alert -->
  353. <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  354. <script type="text/javascript">
  355. $(document).ready(function() {
  356. $(document).on('click', '.btn-info', function () {
  357. // Retrieve the complaint number from the data attribute
  358. var complaintNumber = $(this).data('complaint-number');
  359. // Call the viewDetails function with the complaint number
  360. viewDetails(complaintNumber);
  361. });
  362. $('#primaryButton').addClass('btn-success').removeClass('btn-secondary');
  363. $('#secondaryButton').addClass('btn-secondary').removeClass('btn-success');
  364. // Toggle functionality for Primary and Secondary buttons
  365. $('#primaryButton').click(function () {
  366. $('#primaryTable').show();
  367. $('#secondaryTable').hide();
  368. $(this).addClass('btn-success').removeClass('btn-secondary');
  369. $('#secondaryButton').addClass('btn-secondary').removeClass('btn-success');
  370. $('#QaqcDatatable').DataTable().columns.adjust().draw();
  371. });
  372. $('#secondaryButton').click(function () {
  373. $('#primaryTable').hide();
  374. $('#secondaryTable').show();
  375. $(this).addClass('btn-success').removeClass('btn-secondary');
  376. $('#primaryButton').addClass('btn-secondary').removeClass('btn-success');
  377. $('#SecondaryDatatable').DataTable().columns.adjust().draw();
  378. });
  379. var table = $('#QaqcDatatable').DataTable({
  380. dom: 'Bftip',
  381. columnDefs: [
  382. { targets: 'no-sort', orderable: false }
  383. ],
  384. lengthMenu: [
  385. [50, 100, 200, 500, -1],
  386. ['50 rows', '100 rows', '200 rows', 'Show all']
  387. ],
  388. scrollY: '50vh',
  389. fixedColumns: {
  390. left: 1,
  391. right: 1
  392. },
  393. buttons: [
  394. {
  395. extend: 'pageLength',
  396. className: 'btn btn-warning'
  397. },
  398. {
  399. title: 'Data export',
  400. extend: 'copyHtml5',
  401. text: 'Copy',
  402. className: 'btn btn-secondary',
  403. id: 'copyBtn'
  404. },
  405. {
  406. extend: 'excelHtml5',
  407. text: 'Excel',
  408. className: 'btn btn-secondary',
  409. id: 'excelBtn'
  410. },
  411. {
  412. extend: 'csvHtml5',
  413. text: 'CSV',
  414. className: 'btn btn-secondary',
  415. id: 'csvBtn'
  416. },
  417. {
  418. extend: 'pdfHtml5',
  419. text: 'PDF',
  420. className: 'btn btn-secondary',
  421. id: 'pdfBtn'
  422. }
  423. ],
  424. fixedHeader: true,
  425. autoWidth: true,
  426. responsive: true,
  427. searching: true, // Enable default search functionality
  428. select: false,
  429. processing: false
  430. });
  431. var table1 = $('#SecondaryDatatable').DataTable({
  432. dom: 'Bftip',
  433. columnDefs: [
  434. { targets: 'no-sort', orderable: false }
  435. ],
  436. lengthMenu: [
  437. [50, 100, 200, 500, -1],
  438. ['50 rows', '100 rows', '200 rows', 'Show all']
  439. ],
  440. scrollY: '50vh',
  441. fixedColumns: {
  442. left: 1,
  443. right: 1
  444. },
  445. buttons: [
  446. {
  447. extend: 'pageLength',
  448. className: 'btn btn-warning'
  449. },
  450. {
  451. title: 'Data export',
  452. extend: 'copyHtml5',
  453. text: 'Copy',
  454. className: 'btn btn-secondary',
  455. id: 'copyBtn'
  456. },
  457. {
  458. extend: 'excelHtml5',
  459. text: 'Excel',
  460. className: 'btn btn-secondary',
  461. id: 'excelBtn'
  462. },
  463. {
  464. extend: 'csvHtml5',
  465. text: 'CSV',
  466. className: 'btn btn-secondary',
  467. id: 'csvBtn'
  468. },
  469. {
  470. extend: 'pdfHtml5',
  471. text: 'PDF',
  472. className: 'btn btn-secondary',
  473. id: 'pdfBtn'
  474. }
  475. ],
  476. fixedHeader: true,
  477. autoWidth: true,
  478. responsive: true,
  479. searching: true,
  480. select: false,
  481. processing: false
  482. });
  483. // // Event listeners for changes in dropdown, remarks, and date picker
  484. $(document).on('change', '.action-dropdown', function () {
  485. const parentRow = $(this).closest('tr');
  486. const schedulerDiv = parentRow.find('.schedule-call');
  487. schedulerDiv.toggleClass('d-none', $(this).val() !== 'FOLLOWUP');
  488. validateFields(parentRow);
  489. });
  490. $(document).on('input', 'input[type="text"]', function () {
  491. const parentRow = $(this).closest('tr');
  492. validateFields(parentRow);
  493. });
  494. $(document).on('change', '.date-picker', function () {
  495. const parentRow = $(this).closest('tr');
  496. validateFields(parentRow);
  497. });
  498. // Validate function to check conditions for enabling/disabling submit button
  499. function validateFields(row) {
  500. const actionSelect = row.find('.action-select');
  501. const remarksInput = row.find('input[type="text"]');
  502. const submitButton = row.find('.submit-btn');
  503. const actionValue = actionSelect.val().trim();
  504. const remarksFilled = remarksInput.val().trim() !== "";
  505. const followUpSelected = actionValue === "FOLLOWUP";
  506. const remainderDateFilled = row.find('.date-picker').val()?.trim() !== ""; // Check if date is selected
  507. // Enable submit button based on conditions
  508. if (
  509. (followUpSelected && remainderDateFilled && remarksFilled) || (actionValue !== "FOLLOWUP" && actionValue !=="Select") // FOLLOWUP requires remainder date and remarks
  510. ) {
  511. submitButton.prop('disabled', false); // Enable submit button
  512. } else {
  513. submitButton.prop('disabled', true); // Disable submit button
  514. }
  515. }
  516. // Initial validation for all rows on page load
  517. $("#QaqcDatatable tbody tr").each(function () {
  518. const row = $(this);
  519. const submitButton = row.find('.submit-btn');
  520. submitButton.prop('disabled', true); // Ensure submit button is initially disabled
  521. validateFields(row); // Validate fields for further interaction
  522. });
  523. // Re-validate fields on input changes
  524. $("#QaqcDatatable").on('input change', '.action-select, input[type="text"], .date-picker', function () {
  525. const row = $(this).closest('tr');
  526. validateFields(row);
  527. });
  528. });
  529. function submitComplaint(button) {
  530. var userId = document.getElementById('userIdSpan').textContent;
  531. const row = button.parentNode.parentNode;
  532. // Fetch the values from the corresponding cells in the row
  533. const dataId = row.querySelector('.submit-btn').getAttribute('data-id'); // Fetch the data_id
  534. const action = row.querySelector('.action-select').value.trim(); // Fetch the action value
  535. const complaintNumber = row.querySelector('.complaint-select').innerText.trim(); // Fetch complaint number
  536. const remarks = row.querySelector('input[type="text"]').value.trim(); // Fetch the remarks value
  537. const remainderDate = row.querySelector('.date-picker')?.value.trim(); // Fetch the remainder date (if any)
  538. /* console.log(row);
  539. console.log(dataId);
  540. console.log(action);
  541. console.log(complaintNumber);
  542. console.log(remarks);
  543. console.log(remainderDate); */
  544. $('.submitid').prop('disabled', true).text('Submitting...');
  545. const name = button.getAttribute('data-name')?.trim() || "N/A";
  546. const cellnumber = button.getAttribute('data-number');
  547. const complaintTypeName = button.getAttribute('data-complaint-type');
  548. // Validation
  549. if (!dataId || !action || action === "Select") {
  550. Swal.fire("Error", "Action is required!", "error");
  551. $('.submitid').prop('disabled', false).text('Submit');
  552. return;
  553. }
  554. if (action !== 'COMPLETED' && remarks === "") {
  555. Swal.fire("Error", "Fill Remarks", "error");
  556. $('.submitid').prop('disabled', false).text('Submit');
  557. return;
  558. }
  559. if (action === 'FOLLOWUP' && remarks === "" && (!remainderDate || remainderDate === "")) {
  560. Swal.fire("Error", "Schedule Date is required for Follow-Up!", "error");
  561. $('.submitid').prop('disabled', false).text('Submit');
  562. return;
  563. }
  564. // AJAX Request
  565. $.ajax({
  566. url: '/gcc/api/callcenterqaqc/agent/publicfollowupcalls/update',
  567. type: 'POST',
  568. data: {
  569. dataId: dataId,
  570. complaintNumber: complaintNumber,
  571. action: action,
  572. remarks: remarks,
  573. remainderDate: remainderDate,
  574. userId:userId
  575. },
  576. success: function (response) {
  577. if (response === "Success") {
  578. //Validate cellnumber
  579. if (!isNaN(cellnumber) || !cellnumber.trim() === "") {
  580. //console.log("valid phone number");
  581. $('.submitid').prop('disabled', false).text('Submit');
  582. // Trigger WhatsApp message functions based on action
  583. if (action === "UNATTENDED") {
  584. //sendWhatsAppMessageUnattended(name, complaintNumber, cellnumber, complaintTypeName);
  585. } else if (action === "REOPEN") {
  586. //sendWhatsAppMessageReopened(name, complaintNumber, cellnumber, complaintTypeName);
  587. }
  588. }
  589. else{
  590. console.log("not valid phone number,So message not sent");
  591. }
  592. Swal.fire({
  593. icon: 'success',
  594. title: 'Success',
  595. text: 'Complaint updated successfully!',
  596. allowOutsideClick: false, // Disable clicking outside the modal to close it
  597. allowEscapeKey: false, // Disable escape key to close the modal
  598. allowEnterKey: false, // Disable enter key to close the modal
  599. showConfirmButton: true, // Ensure the confirm button is visible
  600. }).then((result) => {
  601. if (result.isConfirmed) {
  602. $('.submitid').prop('disabled', false).text('Submit');
  603. const table = $('#QaqcDatatable').DataTable();
  604. // Remove the row
  605. table.row($(row)).remove();
  606. // Reorder S.No column
  607. table.rows().every(function (index) {
  608. const row = this.node();
  609. $(row).find('td:first-child').text(index + 1); // Update S.No
  610. });
  611. // Redraw the table
  612. table.draw(false);
  613. }
  614. });
  615. }
  616. else if (response === "error") {
  617. $('.submitid').prop('disabled', false).text('Submit');
  618. Swal.fire("Error", "Failed to update complaint. Please try again later.", "error");
  619. }
  620. else {
  621. $('.submitid').prop('disabled', false).text('Submit');
  622. Swal.fire("Error", "Failed to update complaint. Please try again.", "error");
  623. }
  624. },
  625. error: function (xhr, status, error) {
  626. $('.submitid').prop('disabled', false).text('Submit');
  627. Swal.fire("Error", `An error occurred: ${xhr.responseText || error}`, "error");
  628. }
  629. });
  630. }
  631. //view button script
  632. function viewDetails(complaintNumber) {
  633. document.getElementById('modalBody').innerHTML = '<p style="text-align:center;">Please wait, loading data...</p>';
  634. $('#detailsModal').modal('show');
  635. // Fetch the main complaint details
  636. $.ajax({
  637. url: '/gcc/api/callcenterqaqc/agent/qaqccalls/getComplaintDetails',
  638. type: 'GET',
  639. data:{complaintNumber:complaintNumber},
  640. success: function (data) {
  641. //console.log('Complaint Data:', data);
  642. // Fetch agent response details
  643. $.ajax({
  644. url: '/gcc/api/callcenterqaqc/agent/attendedcomplaintshistory',
  645. type: 'GET',
  646. data: { complaintNumber },
  647. success: function (agentResponse) {
  648. //console.log('Agent Response:', agentResponse);
  649. // Use the logic for building complaint and agent details as HTML
  650. const detailsHtml = generateDetailsHtml(data, agentResponse);
  651. // Update modal content
  652. document.getElementById('modalBody').innerHTML = detailsHtml;
  653. },
  654. error: function () {
  655. document.getElementById('modalBody').innerHTML = '<p>Error loading agent details. Please try again later.</p>';
  656. }
  657. });
  658. },
  659. error: function () {
  660. document.getElementById('modalBody').innerHTML = '<p>Error loading complaint details. Please try again later.</p>';
  661. }
  662. });
  663. }
  664. // Function to generate complaint and agent details HTML
  665. function generateDetailsHtml(data, agentResponse) {
  666. // Helper function to format date to yyyy-mm-dd
  667. function formatDate(dateStr) {
  668. if (!dateStr) return 'N/A';
  669. const date = new Date(dateStr);
  670. return date.toISOString().split('T')[0]; // Formats to yyyy-mm-dd
  671. }
  672. // Format complaint messages
  673. let messagesHtml = '';
  674. if (data.comments && data.comments.length > 0) {
  675. data.comments.forEach((comment) => {
  676. const commentImageLink = comment.Comp_Image && comment.Comp_Image !== "No image available"
  677. ? `<a href="${comment.Comp_Image}" target="_blank" style="color: green; text-decoration: underline;">View Image</a>`
  678. : '<p style="color: red;">No image available for this comment.</p>';
  679. messagesHtml += `
  680. <div class="comment mb-4">
  681. <div class="row">
  682. <div class="col-2 text-center">
  683. <p class="text-muted">${comment.comment_date}</p>
  684. </div>
  685. <div class="col-10">
  686. <p><strong>${comment.user || 'N/A'}</strong> Says:</p>
  687. <p>${comment.message || 'No message available'}</p>
  688. <div class="user-image">${commentImageLink}</div>
  689. </div>
  690. </div>
  691. </div>
  692. `;
  693. });
  694. } else {
  695. messagesHtml = '<p>No comments available.</p>';
  696. }
  697. // Format agent responses
  698. let agentRepliedHtml = '';
  699. if (agentResponse.length > 0) {
  700. agentResponse.forEach((agentItem) => {
  701. agentRepliedHtml += `
  702. <div class="comment mb-4">
  703. <div class="row">
  704. <div class="col-2 text-center">
  705. <p class="text-muted"><strong>${formatDate(agentItem.created_date) || 'N/A'}</strong></p>
  706. </div>
  707. <div class="col-10">
  708. <p><strong>${agentItem.agent_name || 'N/A'}</strong>, Says: ${agentItem.call_status || 'N/A'}</p>
  709. <p><strong>Remarks: </strong>${agentItem.remarks || 'N/A'}</p>
  710. <p><strong>Remainder Date: </strong> ${formatDate(agentItem.remainder_date) || 'N/A'}</p>
  711. </div>
  712. </div>
  713. </div>
  714. `;
  715. });
  716. } else {
  717. agentRepliedHtml = '<p>No agent replied messages available.</p>';
  718. }
  719. // Check for user images
  720. const userImages = data.userimages && data.userimages.length > 0 ? data.userimages[0] : {};
  721. const imageLink = userImages.Comp_Image && userImages.Comp_Image !== "null" && userImages.Comp_Image !== ""
  722. ? `<a href="${userImages.Comp_Image}" target="_blank" style="color: green; text-decoration: underline;">UserImages: View Image</a>`
  723. : '<p style="color: red;">UserImages: No image available.</p>';
  724. // Combine all sections into the final HTML
  725. const detailsHtml = `
  726. <div class="row">
  727. <div class="col-md-12">
  728. <h4>Complaint Person's Details:</h4>
  729. <div class="row">
  730. <div class="col-6">
  731. <p><strong>Complaint Number:</strong> ${data.complaintid || 'N/A'}</p>
  732. </div>
  733. <div class="col-6">
  734. <p><strong>Complaint Date:</strong> ${data.complaintdate}</p>
  735. </div>
  736. </div>
  737. <div class="row">
  738. <div class="col-6">
  739. <p><strong>Complainant's Name:</strong> ${data.complainantName || 'N/A'}</p>
  740. </div>
  741. <div class="col-6">
  742. <p><strong>Phone Number:</strong> ${data.mobileNumber || 'N/A'}</p>
  743. </div>
  744. </div>
  745. <div class="row">
  746. <div class="col-6">
  747. <p><strong>Zone:</strong> ${data.Zone || 'N/A'}</p>
  748. </div>
  749. <div class="col-6">
  750. <p><strong>Division:</strong> ${data.Division || 'N/A'}</p>
  751. </div>
  752. </div>
  753. <div class="row">
  754. <div class="col-6">
  755. <p><strong>Gender:</strong> ${data.gender || 'N/A'}</p>
  756. </div>
  757. <div class="col-6">
  758. <p><strong>Complainant's Address:</strong> ${data.Street || 'N/A'}, ${data.Area || 'N/A'}, ${data.Landmark || 'N/A'}, ${data.Location || 'N/A'}</p>
  759. </div>
  760. </div>
  761. </div>
  762. </div>
  763. <hr>
  764. <h4>Complaint Details:</h4>
  765. <div class="row">
  766. <div class="col-6">
  767. <p><strong>Complaint Dept:</strong> ${data.deptname || 'N/A'}</p>
  768. </div>
  769. <div class="col-6">
  770. <p><strong>Complaint Mode:</strong> ${data.compmode || 'N/A'}</p>
  771. </div>
  772. </div>
  773. <div class="row">
  774. <div class="col-6">
  775. <p><strong>Complaint Type:</strong> ${data.complaintType || 'N/A'}</p>
  776. </div>
  777. <div class="col-6">
  778. <p><strong>Details of Complaint:</strong> ${data.description || 'N/A'}</p>
  779. </div>
  780. </div>
  781. <div class="row">
  782. <div class="col-6">
  783. <p><strong>Current Status:</strong> ${data.currentStatus || 'N/A'}</p>
  784. </div>
  785. <div class="col-6">
  786. <p><strong style="color:blue;">Official Mobile:</strong> ${data.OfficialMobile || 'N/A'}</p>
  787. </div>
  788. </div>
  789. <div class="row">
  790. <div class="col-6">
  791. <p><strong>Last Updated Date:</strong> ${data.greatestDate || 'N/A'}</p>
  792. </div>
  793. </div>
  794. <hr>
  795. <h4>Complaint Messages:</h4>
  796. ${messagesHtml}
  797. <hr>
  798. <h4>Agent Replied Messages:</h4>
  799. ${agentRepliedHtml}
  800. <hr>
  801. ${imageLink}
  802. `;
  803. return detailsHtml;
  804. }
  805. //whatsapp message function for REOPENED
  806. function sendWhatsAppMessageReopened(name,complaintNumber,cellnumber,complaintTypeName) {
  807. //console.log('whatsapp CustomerMobile:', cellnumber);
  808. //console.log('name:',name);
  809. //console.log('id:',complaintNumber);
  810. //console.log('complainttype',complaintTypeName)
  811. let viewstatus = "pgr" ;
  812. // Send the WhatsApp message pending
  813. let msgUrl = `https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=${encodeURIComponent(cellnumber)}&v=1.1&format=json&msg_type=IMAGE&method=SENDMEDIAMESSAGE&caption=Dear+Mr%2FMs+${encodeURIComponent(name)}%2C%0A%0AYour+complaint+regarding+${encodeURIComponent(complaintTypeName)}+with+complaint+number+%2A${encodeURIComponent(complaintNumber)}%2A+has+been+reopened+based+on+your+feedback.%0AThe+relevant+department+is+working+to+resolve+the+issue%2C+and+updates+will+be+provided+on+the+progress.%0A%0AClick+the+button+below+to+view+your+complaint+status%F0%9F%91%87&media_url=https%3A%2F%2Ferp.chennaicorporation.gov.in%2Fpgr%2Fimages%2Fpgr_whatsapp_banner.jpg&isTemplate=true&footer=-Greater+Chennai+Corporation&buttonUrlParam=${encodeURIComponent(viewstatus)}`
  814. let tamilmsgUrl = `https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=${encodeURIComponent(cellnumber)}&v=1.1&format=json&msg_type=IMAGE&method=SENDMEDIAMESSAGE&caption=%E0%AE%85%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%BE%E0%AE%B0%E0%AF%8D%E0%AE%A8%E0%AF%8D%E0%AE%A4+%E0%AE%A4%E0%AE%BF%E0%AE%B0%E0%AF%81%2F%E0%AE%A4%E0%AE%BF%E0%AE%B0%E0%AF%81%E0%AE%AE%E0%AE%A4%E0%AE%BF+${encodeURIComponent(name)}%2C%0A%0A%E0%AE%89%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%2A${encodeURIComponent(complaintNumber)}%2A%2C+${encodeURIComponent(complaintTypeName)}+%E0%AE%A4%E0%AF%8A%E0%AE%9F%E0%AE%B0%E0%AF%8D%E0%AE%AA%E0%AE%BE%E0%AE%A9+%E0%AE%95%E0%AE%B0%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%95%E0%AE%B3%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%85%E0%AE%9F%E0%AE%BF%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%88%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AF%8D%2C+%E0%AE%AA%E0%AF%81%E0%AE%95%E0%AE%BE%E0%AE%B0%E0%AF%8D+%E0%AE%AE%E0%AF%80%E0%AE%A3%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%BF%E0%AE%B1%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AE%A4%E0%AF%81.%0A%E0%AE%9A%E0%AE%AE%E0%AF%8D%E0%AE%AA%E0%AE%A8%E0%AF%8D%E0%AE%A4%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%8D%E0%AE%9F+%E0%AE%A4%E0%AF%81%E0%AE%B1%E0%AF%88+%E0%AE%85%E0%AE%A4%E0%AE%BF%E0%AE%95%E0%AE%BE%E0%AE%B0%E0%AE%BF%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%87%E0%AE%A8%E0%AF%8D%E0%AE%A4+%E0%AE%AA%E0%AE%BF%E0%AE%B0%E0%AE%9A%E0%AF%8D%E0%AE%9A%E0%AE%BF%E0%AE%A9%E0%AF%88%E0%AE%AF%E0%AF%88+%E0%AE%A4%E0%AF%80%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AF%8D%E0%AE%95+%E0%AE%AA%E0%AE%A3%E0%AE%BF%E0%AE%AF%E0%AE%BE%E0%AE%B1%E0%AF%8D%E0%AE%B1%E0%AE%BF+%E0%AE%B5%E0%AE%B0%E0%AF%81%E0%AE%95%E0%AE%BF%E0%AE%A9%E0%AF%8D%E0%AE%B1%E0%AE%A9%E0%AE%B0%E0%AF%8D.%0A%E0%AE%AA%E0%AF%81%E0%AE%95%E0%AE%BE%E0%AE%B0%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%A4%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AF%8B%E0%AE%A4%E0%AF%88%E0%AE%AF+%E0%AE%A8%E0%AE%BF%E0%AE%B2%E0%AF%88+%E0%AE%95%E0%AF%81%E0%AE%B1%E0%AE%BF%E0%AE%A4%E0%AF%8D%E0%AE%A4+%E0%AE%A4%E0%AE%95%E0%AE%B5%E0%AE%B2%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%B5%E0%AE%BF%E0%AE%B0%E0%AF%88%E0%AE%B5%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%AE%E0%AF%87%E0%AE%B2%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%B5%E0%AE%B4%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%AE%E0%AF%8D.%0A%0A%E0%AE%89%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%AA%E0%AF%81%E0%AE%95%E0%AE%BE%E0%AE%B0%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%A8%E0%AE%BF%E0%AE%B2%E0%AF%88%E0%AE%AF%E0%AF%88%E0%AE%AA%E0%AF%8D+%E0%AE%AA%E0%AE%BE%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AF%8D%E0%AE%95+%E0%AE%95%E0%AF%80%E0%AE%B4%E0%AF%87+%E0%AE%89%E0%AE%B3%E0%AF%8D%E0%AE%B3+%E0%AE%AA%E0%AF%8A%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BE%E0%AE%A9%E0%AF%88%E0%AE%95%E0%AF%8D+%E0%AE%95%E0%AE%BF%E0%AE%B3%E0%AE%BF%E0%AE%95%E0%AF%8D+%E0%AE%9A%E0%AF%86%E0%AE%AF%E0%AF%8D%E0%AE%AF%E0%AE%B5%E0%AF%81%E0%AE%AE%E0%AF%8D%F0%9F%91%87&media_url=https%3A%2F%2Ferp.chennaicorporation.gov.in%2Fpgr%2Fimages%2Fpgr_whatsapp_banner.jpg&isTemplate=true&footer=-%E0%AE%AA%E0%AF%86%E0%AE%B0%E0%AF%81%E0%AE%A8%E0%AE%95%E0%AE%B0+%E0%AE%9A%E0%AF%86%E0%AE%A9%E0%AF%8D%E0%AE%A9%E0%AF%88+%E0%AE%AE%E0%AE%BE%E0%AE%A8%E0%AE%95%E0%AE%B0%E0%AE%BE%E0%AE%9F%E0%AF%8D%E0%AE%9A%E0%AE%BF.&buttonUrlParam=${encodeURIComponent(viewstatus)}`
  815. $.ajax({
  816. url: '/gcc/qaqc/api/whatsapp/send-whatsapp-message', // Replace with your service path
  817. type: 'POST',
  818. data: { msgUrl: msgUrl,
  819. tamilmsgUrl: tamilmsgUrl},
  820. success: function(response) {
  821. //console.log('WhatsApp message sent successfully', response);
  822. console.log('success');
  823. //alert('WhatsApp message sent!');
  824. },
  825. error: function(xhr, status, error) {
  826. console.error('Error sending WhatsApp message:', error);
  827. //alert('Failed to send WhatsApp message.');
  828. Swal.fire({
  829. title: 'Error!',
  830. text: 'Message Not sent!',
  831. icon: 'error',
  832. timer: 2000,
  833. showConfirmButton: false
  834. })
  835. }
  836. });
  837. }
  838. </script>
  839. </body>
  840. </html>