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.

905 lines
40 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!DOCTYPE html>
  2. <html lang="en" dir="">
  3. <html xmlns:th="http://www.thymeleaf.org">
  4. <head th:replace="~{fragments/modules/base/head :: head}"></head>
  5. <style>
  6. .required{
  7. color: red;
  8. }
  9. /* Mobile screens - targeting devices with a max width of 767px */
  10. @media (max-width: 767px)
  11. {
  12. #qaqcRequestForm label{
  13. margin-top: 10px;
  14. }
  15. }
  16. .card-box {
  17. box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px;
  18. }
  19. .bg-grey-inline-text {
  20. padding:2px 2px;
  21. background-color: #e6e6e6;
  22. border-radius: 4px;
  23. }
  24. </style>
  25. <body>
  26. <!--[if lt IE 8]>
  27. <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
  28. <![endif]-->
  29. <div class="wrapper">
  30. <!-- header top menu Start -->
  31. <header th:replace="~{fragments/modules/base/header :: header}"></header>
  32. <!-- header top menu end -->
  33. <div class="page-wrap">
  34. <!--=============== Left Menu side Start ================-->
  35. <div th:replace="~{fragments/modules/base/menu :: menu}"></div>
  36. <!--=============== Left side End ================-->
  37. <div class="main-content">
  38. <div class="container-fluid">
  39. <div class="page-header mb-2">
  40. <div class="row align-items-end">
  41. <div class="col-lg-8">
  42. <div class="page-header-title">
  43. <i class="far fa-calendar-plus bg-blue"></i>
  44. <div class="d-inline">
  45. <h5>Assign Agents</h5>
  46. <span>Assign Agents for Task</span>
  47. </div>
  48. </div>
  49. </div>
  50. <div class="col-lg-4">
  51. <nav class="breadcrumb-container" aria-label="breadcrumb">
  52. <ol class="breadcrumb">
  53. <li class="breadcrumb-item"><a href="/gcc/index"><i
  54. class="ik ik-home"></i></a></li>
  55. <li class="breadcrumb-item" aria-current="page">1913 QAQC</li>
  56. <li class="breadcrumb-item" aria-current="page">Admin QAQC</li>
  57. <li class="breadcrumb-item active" aria-current="page">Assign Agents</li>
  58. </ol>
  59. </nav>
  60. </div>
  61. </div>
  62. </div>
  63. <div class="row mt-4">
  64. <div class="col-sm-4 mb-2">
  65. <label for="displaystartDate" class="form-label"
  66. style="font-size: medium; margin-bottom: 0px; font-weight: bold;">From
  67. Date:</label> <input type="date" id="displaystartDate"
  68. class="form-control" >
  69. </div>
  70. <div class="col-sm-4 mb-2">
  71. <label for="displayendDate" class="form-label"
  72. style="font-size: medium; margin-bottom: 0px; font-weight: bold;">To
  73. Date:</label> <input type="date" id="displayendDate"
  74. class="form-control">
  75. </div>
  76. </div>
  77. <div class="row mt-3">
  78. <div class="col-xl-3 col-md-4 col-sm-12">
  79. <div class="card card-box" id="closedCard" style="display: none;">
  80. <p class="text-facebook mb-20 text-center mt-4" id="displayClosename"><b></b></p>
  81. <h2 class="text-twitter fw-700 ml-5 text-center" id="displayClosedcount"></h2>
  82. </div>
  83. <div class="card card-box" id="reopenedCard" style="display: none;">
  84. <p class="text-facebook mb-20 text-center mt-4" id="displayReopenname"><b></b></p>
  85. <h3 class="text-twitter fw-700 ml-5 text-center" id="displayReopenedcount"></h3>
  86. </div>
  87. <div class="card card-box" id="inProgressCard" style="display: none;">
  88. <p class="text-facebook mb-20 text-center mt-4" id="displayInProgressname"><b></b></p>
  89. <h3 class="text-twitter fw-700 ml-5 text-center" id="displayInProgresscount"></h3>
  90. </div>
  91. <div class="card card-box" id="redressedCard" style="display: none;">
  92. <p class="text-facebook mb-20 text-center mt-4" id="displayRedressedname"><b></b></p>
  93. <h3 class="text-twitter fw-700 ml-5 text-center" id="displayRedressedcount"></h3>
  94. </div>
  95. <div class="card card-box" id="followupCard1" style="display: none;">
  96. <p class="text-facebook mb-20 text-center mt-4" id="displayFollowupname1"><b></b></p>
  97. <h3 class="text-twitter fw-700 ml-5 text-center" id="displayfollowupcount1"></h3>
  98. </div>
  99. <div class="card card-box" id="followupCard2" style="display: none;">
  100. <p class="text-facebook mb-20 text-center mt-4" id="displayFollowupname2"><b></b></p>
  101. <h3 class="text-twitter fw-700 ml-5 text-center" id="displayfollowupcount2"></h3>
  102. </div>
  103. </div>
  104. </div>
  105. <div class="row">
  106. <div class="col-12">
  107. <div class="card">
  108. <div class="card-block">
  109. <label>Task Description If any</label>
  110. <textarea rows="1" cols="5" style="width: 100%;height:50px;" placeholder="Enter description"></textarea>
  111. </div>
  112. </div>
  113. </div>
  114. </div>
  115. <div class="row">
  116. <div class="col-12">
  117. <div class="card">
  118. <div class="card-block">
  119. <div class="row">
  120. <div class=" col-lg-4 col-md-5 col-sm-12">
  121. <label style="font-size: medium;font-weight: bold;">Click this Button to Clear the Pending Calls...</label>
  122. </div>
  123. <div class="col-lg-8 col-md-7 col-sm-12">
  124. <button id="clearButton" class="btn btn-danger">Clear</button>
  125. </div>
  126. </div>
  127. </div>
  128. </div>
  129. </div>
  130. </div>
  131. <div class="row">
  132. <div class="col-12">
  133. <div class="card">
  134. <div class="card-header">
  135. <h3><b>Available Agent List</b></h3>
  136. </div>
  137. <div class="card-body">
  138. <div class="d-flex justify-content-end mb-2">
  139. <button class="btn btn-light mr-4" disabled style="color: blue;border-color: blue;"><i class="ik ik-user-plus f-16" style="color: blue;"></i>Productivity Count:<span class="ml-4" id="productivitycount" style="color: blue;"></span></button>
  140. <button class="btn btn-primary" disabled><i class="ik ik-user-plus f-16"></i>Total Available agents:<span class="ml-4" id="availableagentcount"></span></button>
  141. </div>
  142. <table id="AgentDatatable" class="table table-striped table-bordered table-hover dataTable" role="grid" >
  143. <thead class="thead-dark">
  144. <tr role="row">
  145. <th class="text-center">
  146. <input type="checkbox" id="selectAll" />
  147. <label for="selectAll">Select All</label>
  148. </th>
  149. <th class="text-center" width="1%">S.No</th>
  150. <th class="text-center">AGENT ID</th>
  151. <th class="text-center">NAME</th>
  152. <th class="text-center">CAMPAIGN PENDING CALLS</th>
  153. <th class="text-center">ALREADY ASSIGNED CALLS</th>
  154. <th class="text-center">CALLS ASSIGNED</th>
  155. <th class="text-center">TOTAL CALLS</th>
  156. <th class="text-center">ACTION</th>
  157. </tr>
  158. </thead>
  159. <tbody style="text-align:center;">
  160. </tbody>
  161. <!-- Transfer Modal -->
  162. <div id="transferModal" class="modal" tabindex="-1" role="dialog">
  163. <div class="modal-dialog" role="document">
  164. <div class="modal-content">
  165. <div class="modal-header">
  166. <h5 class="modal-title">Transfer Calls</h5>
  167. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  168. <span aria-hidden="true">&times;</span>
  169. </button>
  170. </div>
  171. <div class="modal-body">
  172. <!-- Editable Calls Assigned Count -->
  173. <div class="form-group">
  174. <label for="callsAssignedInput">Calls Assigned Count</label>
  175. <input type="number" id="callsAssignedInput" class="form-control" min="1" placeholder="Enter Calls Count">
  176. </div>
  177. <!-- Transfer To Dropdown -->
  178. <div class="form-group">
  179. <label for="transferToDropdown">Transfer To</label>
  180. <select id="transferToDropdown" class="form-control">
  181. <!-- Options populated dynamically -->
  182. </select>
  183. </div>
  184. </div>
  185. <div class="modal-footer">
  186. <button type="button" id="transferButton" class="btn btn-primary">Transfer</button>
  187. <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
  188. </div>
  189. </div>
  190. </div>
  191. </div>
  192. </table>
  193. <div class="text-center">
  194. <button class="btn btn-primary" id="assignBtn">Click to Assign</button>
  195. </div>
  196. <div>
  197. <button class="btn btn-secondary" id="backBtn">Back</button>
  198. </div>
  199. </div>
  200. </div>
  201. </div>
  202. </div>
  203. </div>
  204. </div>
  205. <div id="pageLoader" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
  206. <div style="position: relative; top: 50%; transform: translateY(-50%);">
  207. <div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
  208. <span class="sr-only">Loading...</span>
  209. </div>
  210. <!-- Add the 'Please wait' text below the spinner -->
  211. <p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
  212. </div>
  213. </div>
  214. <footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
  215. </div>
  216. </div>
  217. <div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
  218. <script th:replace="~{fragments/modules/base/script :: script}"></script>
  219. <script src="node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min.js"></script>
  220. <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  221. <script type="text/javascript">
  222. $(document).ready(function () {
  223. const redirected = sessionStorage.getItem('redirected'); // Check if redirected flag is set
  224. const cardType = sessionStorage.getItem('cardType'); // Get the card type
  225. //console.log("Redirected flag:", redirected);
  226. //console.log("Card Type:", cardType);
  227. if (redirected === 'true') {
  228. // Fetch data from sessionStorage
  229. const closeName = sessionStorage.getItem("closename");
  230. const closedCount = sessionStorage.getItem("closedcount");
  231. const reopenName = sessionStorage.getItem("reopenname");
  232. const reopenedCount = sessionStorage.getItem("reopenedcount");
  233. const inProgressName = sessionStorage.getItem("inProgressName");
  234. const inProgressCount = sessionStorage.getItem("inProgressCount");
  235. const redressedName = sessionStorage.getItem("redressedName");
  236. const redressedCount = sessionStorage.getItem("redressedCount");
  237. const startDate = sessionStorage.getItem("startDate");
  238. const endDate = sessionStorage.getItem("endDate");
  239. const followupName1=sessionStorage.getItem("followupname1");
  240. const followupCount1=sessionStorage.getItem("followupcount1");
  241. const followupName2=sessionStorage.getItem("followupname2");
  242. const followupCount2=sessionStorage.getItem("followupcount2");
  243. const group=sessionStorage.getItem("group");
  244. const type=sessionStorage.getItem("type");
  245. const mode=sessionStorage.getItem("mode");
  246. const zone=sessionStorage.getItem("zone");
  247. /* console.log("CloseName:", closeName);
  248. console.log("ClosedCount:", closedCount);
  249. console.log("ReopenName:", reopenName);
  250. console.log("ReopenedCount:", reopenedCount);
  251. console.log("InProgressName:", inProgressName);
  252. console.log("InProgressCount:", inProgressCount);
  253. console.log("RedressedName:", redressedName);
  254. console.log("RedressedCount:", redressedCount);
  255. console.log("StartDate:", startDate);
  256. console.log("EndDate:", endDate);
  257. console.log("followupName:", followupName);
  258. console.log("followupCount:", followupCount);
  259. console.log("group:",group);
  260. console.log("type",type);
  261. console.log("mode",mode);
  262. console.log("zone",zone); */
  263. /* console.log("ofollowupName:", followupName1);
  264. console.log("ofollowupCount:", followupCount1);
  265. console.log("pfollowupName:", followupName2);
  266. console.log("pfollowupCount:", followupCount2); */
  267. let cardName = '';
  268. let cardCount = '';
  269. // Set the relevant data based on cardType
  270. if (cardType === 'Closed') {
  271. cardName = closeName;
  272. cardCount = closedCount;
  273. $("#displayClosename").text(closeName); // Display Closed
  274. $("#displayClosedcount").text(closedCount);
  275. // Hide others
  276. $("#reopenedCard, #inProgressCard, #redressedCard","#followupCard1","#followupCard2").hide();
  277. $("#closedCard").show(); // Show the Closed card
  278. } else if (cardType === 'Reopened') {
  279. cardName = reopenName;
  280. cardCount = reopenedCount;
  281. $("#displayReopenname").text(reopenName); // Display Reopened
  282. $("#displayReopenedcount").text(reopenedCount);
  283. // Hide others
  284. $("#closedCard, #inProgressCard, #redressedCard","#followupCard1","#followupCard2").hide();
  285. $("#reopenedCard").show(); // Show the Reopened card
  286. } else if (cardType === 'In Progress') {
  287. cardName = inProgressName;
  288. cardCount = inProgressCount;
  289. $("#displayInProgressname").text(inProgressName); // Display In Progress
  290. $("#displayInProgresscount").text(inProgressCount);
  291. // Hide others
  292. $("#closedCard, #reopenedCard, #redressedCard","#followupCard1","#followupCard2").hide();
  293. $("#inProgressCard").show(); // Show the In Progress card
  294. } else if (cardType === 'Redressed') {
  295. cardName = redressedName;
  296. cardCount = redressedCount;
  297. $("#displayRedressedname").text(redressedName); // Display Redressed
  298. $("#displayRedressedcount").text(redressedCount);
  299. // Hide others
  300. $("#closedCard, #reopenedCard, #inProgressCard","#followupCard1","#followupCard2").hide();
  301. $("#redressedCard").show(); // Show the Redressed card
  302. }
  303. else if (cardType === 'Followup1') {
  304. cardName = followupName1;
  305. cardCount = followupCount1;
  306. $("#displayFollowupname1").text(followupName1); // Display Redressed
  307. $("#displayfollowupcount1").text(followupCount1);
  308. // Hide others
  309. $("#closedCard, #reopenedCard, #inProgressCard","#followupCard2").hide();
  310. $("#followupCard1").show(); // Show the Redressed card
  311. }
  312. else if (cardType === 'Followup2') {
  313. cardName = followupName2;
  314. cardCount = followupCount2;
  315. $("#displayFollowupname2").text(followupName2); // Display Redressed
  316. $("#displayfollowupcount2").text(followupCount2);
  317. // Hide others
  318. $("#closedCard, #reopenedCard, #inProgressCard","#followupCard1").hide();
  319. $("#followupCard2").show(); // Show the Redressed card
  320. }
  321. // Fill in date values
  322. $("#displaystartDate").val(startDate);
  323. $("#displayendDate").val(endDate);
  324. // Disable the start and end date inputs
  325. $("#displaystartDate, #displayendDate").prop("disabled", true);
  326. // Call the getStart function
  327. getStart(cardName, cardCount, startDate, endDate);
  328. $('#assignBtn').click(function (event) {
  329. event.preventDefault();
  330. if (!isCleared) {
  331. // Trigger Clear button flow
  332. Swal.fire({
  333. allowOutsideClick: false, // Disable clicking outside the modal to close it
  334. allowEscapeKey: false, // Disable escape key to close the modal
  335. allowEnterKey: false, // Disable enter key to close the modal
  336. title: 'Clear pending calls before assigning?',
  337. icon: 'info',
  338. showCancelButton: true,
  339. showDenyButton: true, // Show the Deny button
  340. confirmButtonColor: 'green',
  341. cancelButtonColor: 'orange',
  342. denyButtonColor: 'grey',
  343. confirmButtonText: 'Yes, clear it!', // Confirm button text
  344. cancelButtonText: 'No, assign without clearing', // Cancel button text
  345. denyButtonText: 'Exit' // Deny button text
  346. }).then((result) => {
  347. if (result.isConfirmed) {
  348. // Trigger Clear logic
  349. $('#clearButton').click();
  350. // Wait until Clear logic completes
  351. const interval = setInterval(() => {
  352. if (isCleared) {
  353. clearInterval(interval); // Stop checking
  354. assignLogic(); // Proceed to Assign logic
  355. }
  356. }, 500); // Check every 500ms
  357. }
  358. else if (result.isDenied) {
  359. // Do nothing on cancel (Cancel button clicked)
  360. Swal.fire('Cancelled', 'No action performed.', 'info');
  361. }
  362. else {
  363. // Proceed directly to Assign logic
  364. assignLogic();
  365. }
  366. });
  367. } else {
  368. // Proceed with Assign logic directly if Clear is already done
  369. assignLogic();
  370. }
  371. });
  372. function assignLogic() {
  373. // Fetch the values from the fields
  374. const startDate = $('#displaystartDate').val();
  375. const endDate = $('#displayendDate').val();
  376. const description = $('textarea').val().trim() || "N/A"; // Default to "N/A" if empty
  377. /* console.log("startDate",startDate);
  378. console.log("endDate",endDate); */
  379. // Validate inputs if necessary
  380. if (!startDate || !endDate || !cardName || !cardCount) {
  381. Swal.fire({
  382. icon: 'error',
  383. title: 'Error',
  384. text: 'All fields must be filled!',
  385. });
  386. return;
  387. }
  388. const allAgents = [];
  389. const table = $('#AgentDatatable').DataTable();
  390. //Loop through all rows in the DataTable
  391. table.rows().every(function (rowIdx, tableLoop, rowLoop) {
  392. const row = $(this.node()); // Get the DOM row
  393. const checkbox = row.find('.select-agent');
  394. const agentId = row.find('td:nth-child(3)').text().trim();
  395. const callsPerAgent = row.find('td:nth-child(7)').text().trim();
  396. // Add agent to allAgents with default callsPerAgent = 0
  397. allAgents.push({ agentId: agentId, callsPerAgent: 0 });
  398. // If checkbox is checked, update callsPerAgent
  399. if (checkbox.is(':checked')) {
  400. const agent = allAgents.find(a => a.agentId === agentId);
  401. if (agent) {
  402. agent.callsPerAgent = callsPerAgent;
  403. }
  404. }
  405. });
  406. // Remove agents with callsPerAgent still set to 0
  407. const filteredAgents = allAgents.filter(agent => agent.callsPerAgent > 0);
  408. // Check if no agents were selected
  409. if (filteredAgents.length === 0) {
  410. Swal.fire({
  411. icon: 'error',
  412. title: 'Error',
  413. text: 'Please select at least one agent or assign calls!',
  414. });
  415. return;
  416. }
  417. //console.log('Filtered agents:', filteredAgents);
  418. // Prepare the data object to send in the AJAX request
  419. const data = {
  420. startDate: startDate,
  421. endDate: endDate,
  422. closeName: cardName,
  423. closedCount: cardCount,
  424. description: description,
  425. group:group,
  426. type:type,
  427. mode:mode,
  428. zone:zone,
  429. agents:filteredAgents // Send only agents with callsPerAgent > 0
  430. };
  431. //console.log('Data to send:', data);
  432. // Show the loader
  433. $('#pageLoader').show();
  434. // Send the AJAX request
  435. $.ajax({
  436. type: "POST",
  437. url: "/gcc/api/callcenterqaqc/agentassign/taskassign", // Replace with your API endpoint
  438. data: JSON.stringify(data),
  439. contentType: "application/json",
  440. success: function (response) {
  441. // Hide the loader
  442. $('#pageLoader').hide();
  443. // Show a success message using Swal
  444. Swal.fire({
  445. icon: 'success',
  446. title: 'Success',
  447. allowOutsideClick: false, // Disable clicking outside the modal to close it
  448. allowEscapeKey: false, // Disable escape key to close the modal
  449. allowEnterKey: false, // Disable enter key to close the modal
  450. showConfirmButton: true, // Ensure the confirm button is visible
  451. text: response.message || 'Data transferred successfully!',
  452. }).then((result) => {
  453. if (result.isConfirmed) {
  454. window.location.href = `/gcc/callcenterqaqc/qaqctasklist`;
  455. }
  456. });
  457. },
  458. error: function (error) {
  459. $('#pageLoader').hide();
  460. // Show an error message using Swal
  461. Swal.fire({
  462. allowOutsideClick: false, // Disable clicking outside the modal to close it
  463. allowEscapeKey: false, // Disable escape key to close the modal
  464. allowEnterKey: false, // Disable enter key to close the modal
  465. showConfirmButton: true, // Ensure the confirm button is visible
  466. icon: 'error',
  467. title: 'Error',
  468. text: error.responseJSON?.message,
  469. }).then((result) => {
  470. if (result.isConfirmed) {
  471. window.location.href = `/gcc/callcenterqaqc/admin/qaqcgrievancedashboard`;
  472. }
  473. });
  474. }
  475. });
  476. }
  477. // Clear the redirected flag after use
  478. sessionStorage.removeItem('redirected');
  479. } else {
  480. // Clear sessionStorage and notify the user
  481. sessionStorage.clear();
  482. // Show Swal alert and redirect on OK button
  483. Swal.fire({
  484. allowOutsideClick: false, // Disable clicking outside the modal to close it
  485. allowEscapeKey: false, // Disable escape key to close the modal
  486. allowEnterKey: false, // Disable enter key to close the modal
  487. showConfirmButton: true, // Ensure the confirm button is visible
  488. icon: 'error',
  489. title: 'Access Denied',
  490. text: 'Please navigate from the Dashboard Page.',
  491. confirmButtonText: 'OK',
  492. }).then((result) => {
  493. if (result.isConfirmed) {
  494. // Redirect to the desired page
  495. window.location.href = `/gcc/callcenterqaqc/admin/qaqcgrievancedashboard`;
  496. }
  497. }); }
  498. // Optional: You can still allow toggling of cards if needed:
  499. $('.card-box').on('click', function () {
  500. // Hide all the card-box elements
  501. $('.card-box').hide();
  502. // Get the id of the clicked card-box and show it
  503. const cardId = $(this).attr('id');
  504. $('#' + cardId).show();
  505. });
  506. function getStart(closeName,closedCount,startDate,endDate)
  507. {
  508. // Show the loader
  509. $('#pageLoader').show();
  510. $.ajax({
  511. url: '/gcc/api/callcenterqaqc/agentassign/getavailableagents?totalDataCount='+closedCount,
  512. type: 'GET',
  513. dataType: 'json',
  514. success: function(response) {
  515. // Hide the loader
  516. $('#pageLoader').hide();
  517. if (response.status === 'success') {
  518. populateDataTable(response);
  519. $("#productivitycount").text(response.productivity_count);
  520. $("#availableagentcount").text(response.agent_available_count);
  521. } if (response.status === 'error') {
  522. $('#pageLoader').hide();
  523. Swal.fire({
  524. icon: 'error',
  525. title: 'Error',
  526. text: response.message || "Error fetching Agents.",
  527. confirmButtonText: 'OK',
  528. }).then((result) => {
  529. if (result.isConfirmed) {
  530. // Reload the same page
  531. window.location.href = `/gcc/callcenterqaqc/admin/qaqcgrievancedashboard`;
  532. }
  533. });
  534. }
  535. },
  536. error: function(xhr, status, error) {
  537. $('#pageLoader').hide();
  538. console.error('Error fetching assigned agents:', error);
  539. }
  540. });
  541. }
  542. function populateDataTable(data) {
  543. // Clear existing rows
  544. var table = $('#AgentDatatable').DataTable();
  545. table.clear();
  546. // Populate table
  547. data.available_agents.forEach((agent, index) => {
  548. table.row.add([
  549. `<input type="checkbox" class="select-agent" value="${agent.agent_id}" checked />`,
  550. index + 1,
  551. agent.agent_id,
  552. agent.agent_name,
  553. agent.campaignPendingCount,
  554. agent.todayCount1,
  555. agent.calls_per_agent,
  556. agent.totalCallsCount,
  557. `<button class="btn btn-warning btn-sm edit-agent" data-id="${agent.agent_id}"><i class="ik ik-edit"></i></button>`
  558. ]);
  559. });
  560. // Redraw table to reflect new data
  561. table.draw();
  562. }
  563. let selectedAgentId; // Store the agent being edited
  564. // Handle "Edit" button click
  565. $(document).on('click', '.edit-agent', function () {
  566. const row = $(this).closest('tr'); // Get the parent row of the clicked button
  567. selectedAgentId = row.find('td:nth-child(3)').text().trim(); // Get the Agent ID
  568. const callsAssigned = row.find('td:nth-child(7)').text().trim(); // Get Calls Assigned Count
  569. // Populate the Calls Assigned input field
  570. $('#callsAssignedInput').val(callsAssigned);
  571. // Populate the Transfer To dropdown
  572. const dropdown = $('#transferToDropdown');
  573. dropdown.empty(); // Clear previous options
  574. $('#AgentDatatable tbody tr').each(function () {
  575. const agentId = $(this).find('td:nth-child(3)').text().trim();
  576. const agentName = $(this).find('td:nth-child(4)').text().trim();
  577. // Exclude the currently selected agent from the dropdown
  578. if (agentId !== selectedAgentId) {
  579. dropdown.append(`<option value="${agentId}">${agentName}</option>`);
  580. }
  581. });
  582. // Show the modal
  583. $('#transferModal').modal('show');
  584. });
  585. // Handle "Transfer" button click
  586. $('#transferButton').click(function () {
  587. const transferCount = parseInt($('#callsAssignedInput').val(), 10);
  588. const transferToAgentId = $('#transferToDropdown').val();
  589. if (!transferCount || transferCount <= 0) {
  590. alert('Please enter a valid calls count!');
  591. return;
  592. }
  593. if (!transferToAgentId) {
  594. alert('Please select an agent to transfer the calls!');
  595. return;
  596. }
  597. let deductionSuccess = false; // Flag for successful deduction from the current agent
  598. let additionSuccess = false; // Flag for successful addition to the receiving agent
  599. const productivityCount = parseInt($('#productivitycount').text().trim(), 10); // Fetch dynamic productivity count from the button
  600. // Validate and update the table
  601. $('#AgentDatatable tbody tr').each(function () {
  602. const agentId = $(this).find('td:nth-child(3)').text().trim();
  603. const callsAssignedCell = $(this).find('td:nth-child(7)'); // Calls Assigned column
  604. // Validate deduction from the current agent
  605. if (agentId === selectedAgentId) {
  606. const currentCount = parseInt(callsAssignedCell.text().trim(), 10);
  607. if (currentCount >= transferCount) {
  608. deductionSuccess = true;
  609. } else {
  610. alert('Transfer not allowed! Transferring more calls than assigned.');
  611. return false; // Stop the operation
  612. }
  613. }
  614. // Validate addition to the receiving agent
  615. if (agentId === transferToAgentId) {
  616. const currentCount = parseInt(callsAssignedCell.text().trim(), 10);
  617. const newCount = currentCount + transferCount;
  618. if (newCount <= productivityCount) {
  619. additionSuccess = true;
  620. } else {
  621. alert(`Transfer not allowed! Transferring ${transferCount} calls will exceed the productivity count of ${productivityCount} for agent ID: ${transferToAgentId}.`);
  622. return false; // Stop the operation
  623. }
  624. }
  625. });
  626. // If both validations pass, proceed to update the table
  627. if (deductionSuccess && additionSuccess) {
  628. $('#AgentDatatable tbody tr').each(function () {
  629. const agentId = $(this).find('td:nth-child(3)').text().trim();
  630. const callsAssignedCell = $(this).find('td:nth-child(7)'); // Calls Assigned column
  631. const totalCallsCell = $(this).find('td:nth-child(8)'); // TOTAL CALLS column
  632. // Deduct calls from the current agent
  633. if (agentId === selectedAgentId) {
  634. const currentCount = parseInt(callsAssignedCell.text().trim(), 10);
  635. callsAssignedCell.text(currentCount - transferCount);
  636. // Update TOTAL CALLS for the current agent
  637. const currentTotalCalls = parseInt(totalCallsCell.text().trim(), 10);
  638. totalCallsCell.text(currentTotalCalls - transferCount);
  639. }
  640. // Add calls to the receiving agent
  641. if (agentId === transferToAgentId) {
  642. const currentCount = parseInt(callsAssignedCell.text().trim(), 10);
  643. callsAssignedCell.text(currentCount + transferCount);
  644. // Update TOTAL CALLS for the receiving agent
  645. const currentTotalCalls = parseInt(totalCallsCell.text().trim(), 10);
  646. totalCallsCell.text(currentTotalCalls + transferCount);
  647. }
  648. });
  649. // Dynamically update the total calls across all agents
  650. let totalCalls = 0;
  651. $('#AgentDatatable tbody tr').each(function () {
  652. const totalCallsCell = $(this).find('td:nth-child(8)'); // TOTAL CALLS column
  653. totalCalls += parseInt(totalCallsCell.text().trim(), 10);
  654. });
  655. $('#totalCallsCount').text(totalCalls); // Update total calls count across all agents
  656. // Close the modal
  657. $('#transferModal').modal('hide');
  658. }
  659. });
  660. // Initialize DataTable
  661. var table = $('#AgentDatatable').DataTable({
  662. dom: 'Bftip',
  663. columnDefs: [
  664. { targets: 'no-sort', orderable: false }
  665. ],
  666. lengthMenu: [
  667. [50, 100, 200, 500, -1],
  668. ['50 rows', '100 rows', '200 rows', 'Show all']
  669. ],
  670. scrollY: '50vh',
  671. fixedColumns: {
  672. left: 1,
  673. right: 1
  674. },
  675. buttons: [
  676. {
  677. extend: 'pageLength',
  678. className: 'btn btn-warning'
  679. },
  680. {
  681. title: 'Data export',
  682. extend: 'copyHtml5',
  683. text: 'Copy',
  684. className: 'btn btn-secondary',
  685. id: 'copyBtn'
  686. },
  687. {
  688. extend: 'excelHtml5',
  689. text: 'Excel',
  690. className: 'btn btn-secondary',
  691. id: 'excelBtn'
  692. },
  693. {
  694. extend: 'csvHtml5',
  695. text: 'CSV',
  696. className: 'btn btn-secondary',
  697. id: 'csvBtn'
  698. },
  699. {
  700. extend: 'pdfHtml5',
  701. text: 'PDF',
  702. className: 'btn btn-secondary',
  703. id: 'pdfBtn'
  704. }
  705. ],
  706. fixedHeader: true,
  707. autoWidth: true,
  708. responsive: true,
  709. searching: false,
  710. select: false,
  711. processing: false
  712. });
  713. });
  714. $(document).ready(function () {
  715. // "Select All" checkbox functionality
  716. $('#selectAll').on('change', function () {
  717. const isChecked = $(this).is(':checked');
  718. $('.select-agent').prop('checked', isChecked); // Check/uncheck all checkboxes
  719. });
  720. // Ensure "Select All" is checked/unchecked based on individual checkboxes
  721. $(document).on('change', '.select-agent', function () {
  722. const allChecked = $('.select-agent:checked').length === $('.select-agent').length;
  723. $('#selectAll').prop('checked', allChecked); // Check "Select All" only if all checkboxes are selected
  724. });
  725. });
  726. </script>
  727. <script type="text/javascript">
  728. $(document).ready(function () {
  729. $('#backBtn').click(function (event) {
  730. window.location.href = `/gcc/callcenterqaqc/admin/qaqcgrievancedashboard`;
  731. });
  732. });
  733. </script>
  734. <script>
  735. // Global flag to track if Clear logic has been executed
  736. let isCleared = false;
  737. document.getElementById('clearButton').addEventListener('click', function () {
  738. Swal.fire({
  739. title: 'Are you sure to clear calls?',
  740. icon: 'warning',
  741. allowOutsideClick: false, // Disable clicking outside the modal to close it
  742. allowEscapeKey: false, // Disable escape key to close the modal
  743. allowEnterKey: false, // Disable enter key to close the modal
  744. showCancelButton: true,
  745. confirmButtonColor: '#d33',
  746. cancelButtonColor: '#3085d6',
  747. confirmButtonText: 'Yes, clear it!',
  748. cancelButtonText: 'No, cancel'
  749. }).then((result) => {
  750. if (result.isConfirmed) {
  751. // Logic to clear calls can be added here
  752. $.ajax({
  753. url: '/gcc/api/callcenterqaqc/agentassign/deleteRecords',
  754. type: 'GET',
  755. contentType: 'application/json',
  756. success: function (response) {
  757. //console.log("response",response);
  758. if (response==="success") {
  759. Swal.fire(
  760. 'Cleared!',
  761. 'The calls have been cleared.',
  762. 'success'
  763. );
  764. isCleared = true; // Mark as cleared
  765. }
  766. else {
  767. Swal.fire("Info", "No Records to clear,You can Assign", "info");
  768. isCleared = true; // Mark as cleared
  769. }
  770. },
  771. error: function (xhr, status, error) {
  772. Swal.fire("Error", `An error occurred: ${xhr.responseText || error}`, "error");
  773. }
  774. });
  775. } else {
  776. Swal.fire(
  777. 'Cancelled',
  778. 'Your data is safe,If you wish you can Assign :)',
  779. 'info'
  780. );
  781. isCleared = true;
  782. }
  783. });
  784. });
  785. </script>
  786. </body>
  787. </html>