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.

3201 lines
179 KiB

1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
1 year ago
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
1 year ago
​
1 year ago
1 year ago
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
1 year ago
​
1 year ago
​
​
​
​
​
1 year ago
​
1 year ago
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
​
1 year ago
1 year ago
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
1 year ago
​
1 year ago
​
​
1 year ago
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
1 year ago
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
​
1 year ago
​
​
1 year ago
​
1 year ago
​
​
1 year ago
​
​
​
​
1 year ago
1 year ago
​
​
​
1 year ago
​
​
​
​
1 year ago
​
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
​
1 year ago
​
​
​
1 year ago
​
​
​
1 year ago
​
​
​
1 year ago
​
​
1 year ago
​
​
​
1 year ago
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
​
1 year ago
​
1 year ago
​
​
1 year ago
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
1 year ago
​
​
​
​
1 year ago
​
1 year ago
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
1 year ago
​
1 year ago
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
1 year ago
​
​
1 year ago
​
​
​
1 year ago
​
​
​
1 year ago
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
1 year ago
​
​
1 year ago
​
1 year ago
​
​
​
1 year ago
​
​
1 year ago
​
​
​
​
1 year ago
​
1 year ago
​
​
1 year ago
​
​
​
1 year ago
​
​
​
1 year ago
​
​
​
1 year ago
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
1 year ago
​
​
​
​
​
​
​
1 year ago
1 year ago
​
​
​
1 year ago
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
1 year ago
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
1 year ago
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
1 year ago
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
​
1 year ago
​
1 year ago
​
​
1 year ago
​
​
​
​
1 year ago
​
1 year ago
​
​
​
​
​
1 year ago
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
1 year ago
​
1 year ago
​
1 year ago
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
​
1 year ago
​
​
  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
  3. <head th:replace="~{fragments/head :: head}">
  4. </head>
  5. <!--datatables-->
  6. <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css">
  7. <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/2.4.1/css/buttons.dataTables.min.css">
  8. <style>
  9. .card-body table {
  10. width: 100%;
  11. padding: 100px;
  12. }
  13. .card-body th,
  14. td {
  15. padding: 8px;
  16. text-align: left;
  17. }
  18. .amount-cell {
  19. text-align: right;
  20. padding-right: 1rem;
  21. /* Adjust padding as needed */
  22. }
  23. .ui-datepicker-container {
  24. width: 100%;
  25. }
  26. .fixedcontainer {
  27. width: 250%;
  28. margin: 40px 0;
  29. display: none
  30. }
  31. .disabled {
  32. pointer-events: none;
  33. opacity: 1;
  34. }
  35. .ui-widget {
  36. width: 40%
  37. }
  38. .ui-datepicker {
  39. padding: 3px;
  40. border: 1px solid #ccc;
  41. border-radius: 5px;
  42. background-color: white;
  43. left: 29.1418px;
  44. }
  45. .ui-datepicker-header {
  46. background-color: #f0f0f0;
  47. border: none;
  48. border-radius: 5px 5px 0 0;
  49. }
  50. .ui-datepicker-title {
  51. font-size: 1.2em;
  52. margin: 0;
  53. padding: 10px;
  54. text-align: center;
  55. }
  56. .ui-datepicker-calendar {
  57. margin: 0;
  58. padding: 0;
  59. font-weight: bold;
  60. }
  61. .ui-datepicker-calendar th,
  62. .ui-datepicker-calendar td {
  63. padding: 5px;
  64. text-align: center;
  65. }
  66. .ui-datepicker-calendar .ui-state-default {
  67. cursor: pointer;
  68. width: 100%;
  69. height: 100%;
  70. display: flex;
  71. justify-content: center;
  72. align-items: center;
  73. }
  74. .ui-datepicker-week-end {
  75. color: black;
  76. font-weight: bold;
  77. }
  78. .ui-datepicker-calendar th span {
  79. color: black;
  80. font-weight: bold;
  81. }
  82. .highlight-greens .ui-state-default {
  83. background: green !important;
  84. color: #FFF !important;
  85. }
  86. .highlight-yellow .ui-state-default {
  87. background: yellow !important;
  88. color: #000 !important;
  89. }
  90. .highlight-violet .ui-state-default {
  91. background: #a93da9 !important;
  92. color: #000 !important;
  93. }
  94. .highlight-pink .ui-state-default {
  95. background: red !important;
  96. color: #000 !important;
  97. }
  98. .form-control[readonly] {
  99. background-color: white;
  100. }
  101. .modal {
  102. overflow-y: auto;
  103. }
  104. .stepper-wrapper {
  105. display: flex;
  106. justify-content: space-between;
  107. margin-bottom: 20px;
  108. position: relative;
  109. }
  110. .stepper-item {
  111. display: flex;
  112. flex-direction: column;
  113. position: relative;
  114. width: 100%;
  115. z-index: 1;
  116. }
  117. .stepper-item::before {
  118. content: '';
  119. position: absolute;
  120. top: 15px;
  121. left: 50%;
  122. height: 4px;
  123. background-color: #dcdcdc;
  124. /* Default grey line */
  125. z-index: -1;
  126. }
  127. .stepper-item:first-child::before {
  128. left: 50%;
  129. width: 0;
  130. }
  131. .stepper-item:last-child::before {
  132. content: none;
  133. }
  134. .stepper-item.completed:not(:last-child)::after {
  135. content: '';
  136. position: absolute;
  137. top: 15px;
  138. left: 50%;
  139. width: calc(100% - 30px);
  140. height: 4px;
  141. background-color: #28a745;
  142. z-index: -1;
  143. transform: translateX(-50%);
  144. }
  145. .step-counter {
  146. width: 30px;
  147. height: 30px;
  148. border-radius: 50%;
  149. background-color: #dcdcdc;
  150. display: flex;
  151. justify-content: center;
  152. align-items: center;
  153. font-weight: bold;
  154. color: white;
  155. }
  156. .step-name {
  157. margin-top: 10px;
  158. font-size: 11px;
  159. }
  160. .stepper-item.completed .step-counter {
  161. background-color: #28a745;
  162. }
  163. .stepper-item.completed .step-name {
  164. font-weight: bold;
  165. }
  166. .tracking-container {
  167. padding: 10px;
  168. background: #f9f9f9;
  169. border-radius: 8px;
  170. overflow: hidden;
  171. max-height: 500px;
  172. }
  173. .tracking-steps {
  174. list-style: none;
  175. padding: 0;
  176. margin: 0;
  177. position: relative;
  178. }
  179. .tracking-steps::before {
  180. content: '';
  181. position: absolute;
  182. top: 0;
  183. left: 8px;
  184. width: 4px;
  185. height: 100%;
  186. background: yellowgreen;
  187. z-index: 0;
  188. }
  189. .tracking-step {
  190. display: flex;
  191. align-items: flex-start;
  192. margin-bottom: 20px;
  193. position: relative;
  194. padding-left: 40px;
  195. text-align: center;
  196. border-bottom: 1px solid #ddd;
  197. transition: background-color 0.3s ease-in-out;
  198. background-color: #fff;
  199. /* White background for steps */
  200. border-radius: 5px;
  201. /* Optional rounded corners */
  202. box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  203. }
  204. /* Line adjustments between steps */
  205. .tracking-step::before {
  206. width: 100%;
  207. height: 5px;
  208. background: yellowgreen;
  209. /* Line color */
  210. position: absolute;
  211. top: 10px;
  212. /* Adjust position to connect icons */
  213. left: 8px;
  214. /* Aligns with step icons */
  215. margin: 0;
  216. }
  217. .tracking-step:first-child::before {
  218. background: none;
  219. /* No line before the first step */
  220. }
  221. /* Step icon styling */
  222. .step-icon {
  223. flex-shrink: 0;
  224. font-size: 1.5em;
  225. margin-right: 15px;
  226. position: absolute;
  227. left: 0;
  228. top: 0;
  229. width: 20px;
  230. height: 20px;
  231. border-radius: 50%;
  232. display: flex;
  233. justify-content: center;
  234. align-items: center;
  235. background: #ccc;
  236. /* Default icon background */
  237. border: 4px solid #ccc;
  238. /* Default border */
  239. color: #eee;
  240. font-size: 14px;
  241. line-height: 20px;
  242. z-index: 1;
  243. font-family: "Ionicons";
  244. /* Icon font */
  245. }
  246. /* Completed step icon and line color */
  247. .tracking-step.completed .step-icon {
  248. background: #56B500;
  249. /* Green for completed */
  250. border-color: #56B500;
  251. color: #fff;
  252. }
  253. .tracking-step.completed::before {
  254. background: #56B500;
  255. /* Green line for completed steps */
  256. }
  257. .tracking-step.completed {
  258. background-color: #e6ffe6;
  259. }
  260. /* Waiting step icon and line color */
  261. .tracking-step.waiting .step-icon {
  262. background: #ffeb3b;
  263. /* Yellow for waiting */
  264. border-color: #ffeb3b;
  265. }
  266. .tracking-step.waiting {
  267. background-color: #fff3cd;
  268. }
  269. /* Initiated step icon and line color */
  270. .tracking-step.initiated .step-icon {
  271. background: #03a9f4;
  272. /* Blue for initiated */
  273. border-color: #03a9f4;
  274. }
  275. .tracking-step.initiated {
  276. background-color: #cce5ff;
  277. }
  278. /* Pending step icon and line color */
  279. .tracking-step.pending .step-icon {
  280. background: #9e9e9e;
  281. /* Grey for pending */
  282. border-color: #9e9e9e;
  283. }
  284. /* Cancelled step icon and line color */
  285. .tracking-step.cancelled .step-icon {
  286. background: #dc3545 !important;
  287. /* Red for cancelled */
  288. border-color: #dc3545 !important;
  289. color: #fff !important;
  290. }
  291. .tracking-step.cancelled::before {
  292. background: #dc3545 !important;
  293. /* Red line for cancelled steps */
  294. }
  295. .tracking-step.cancelled {
  296. background-color: #fdecea;
  297. /* Light red background for cancelled steps */
  298. }
  299. /* Rejected step icon and line color */
  300. .tracking-step.rejected .step-icon {
  301. background: #ff0000;
  302. /* Dark red for rejected */
  303. border-color: #ff0000;
  304. color: #fff;
  305. }
  306. .tracking-step.rejected {
  307. background-color: #ffe6e6;
  308. }
  309. .tracking-step.rejected::before {
  310. background: #ff0000;
  311. /* Dark red line for rejected steps */
  312. }
  313. /* GCC Blocked step icon and line color */
  314. .tracking-step.gcc-blocked .step-icon {
  315. background: #ff6600;
  316. /* Orange for GCC blocked */
  317. border-color: #ff6600;
  318. color: #fff;
  319. }
  320. .tracking-step.gcc-blocked {
  321. background-color: #ffe0cc;
  322. }
  323. .tracking-step.gcc-blocked::before {
  324. background: #ff6600;
  325. /* Orange line for GCC blocked steps */
  326. }
  327. /* Step content styling */
  328. .step-content {
  329. padding: 2px 15px;
  330. background: #fff;
  331. border: 1px solid #ddd;
  332. border-radius: 5px;
  333. width: 100%;
  334. flex-grow: 1;
  335. box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  336. }
  337. .step-content h5 {
  338. margin: 0 0 5px;
  339. font-size: 16px;
  340. font-weight: bold;
  341. }
  342. .step-date {
  343. color: #666;
  344. font-size: 14px;
  345. }
  346. /* Icon color customization */
  347. .fas,
  348. .fa-solid {
  349. font-weight: 900;
  350. color: white;
  351. }
  352. #transactionmodel {
  353. max-width: 90%;
  354. /* Make modal wider */
  355. }
  356. .table-responsive {
  357. max-height: 400px;
  358. /* Adjust the table's maximum height */
  359. overflow-y: auto;
  360. /* Enable vertical scrolling if needed */
  361. }
  362. body {
  363. font-family: Arial, sans-serif;
  364. }
  365. .chat-icon {
  366. position: fixed;
  367. bottom: 20px;
  368. right: 20px;
  369. width: 60px;
  370. height: 60px;
  371. background-color: #007bff;
  372. border-radius: 50%;
  373. cursor: pointer;
  374. display: flex;
  375. align-items: center;
  376. justify-content: center;
  377. }
  378. .chat-icon img {
  379. width: 30px;
  380. height: 30px;
  381. }
  382. .chat-notification {
  383. position: absolute;
  384. top: -10px;
  385. right: -10px;
  386. background-color: red;
  387. color: white;
  388. border-radius: 50%;
  389. padding: 5px;
  390. font-size: 12px;
  391. }
  392. .chat-box {
  393. position: fixed;
  394. bottom: 90px;
  395. right: 20px;
  396. width: 300px;
  397. height: 400px;
  398. background-color: white;
  399. border: 1px solid #ccc;
  400. display: none;
  401. flex-direction: column;
  402. box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
  403. }
  404. .chat-header {
  405. background-color: #007bff;
  406. color: white;
  407. padding: 10px;
  408. display: flex;
  409. justify-content: space-between;
  410. align-items: center;
  411. }
  412. .chat-body {
  413. flex-grow: 1;
  414. padding: 10px;
  415. overflow-y: scroll;
  416. border-top: 1px solid #ccc;
  417. border-bottom: 1px solid #ccc;
  418. }
  419. .chat-footer {
  420. display: flex;
  421. padding: 10px;
  422. }
  423. .chat-footer input {
  424. flex-grow: 1;
  425. padding: 5px;
  426. margin-right: 10px;
  427. }
  428. .chat-footer button {
  429. background-color: #007bff;
  430. color: white;
  431. border: none;
  432. padding: 5px 10px;
  433. cursor: pointer;
  434. }
  435. .otp-input-box {
  436. display: flex;
  437. justify-content: center;
  438. gap: 10px;
  439. margin: 20px 0;
  440. }
  441. .otp-input-box .otp-input {
  442. width: 40px;
  443. height: 40px;
  444. text-align: center;
  445. font-size: 16px;
  446. border: 1px solid #ccc;
  447. border-radius: 5px;
  448. }
  449. </style>
  450. <body>
  451. <!-- Pre-loader start -->
  452. <div class="theme-loader">
  453. <div class="ball-scale">
  454. <div class='contain'>
  455. <div class="ring">
  456. <div class="frame"></div>
  457. </div>
  458. <div class="ring">
  459. <div class="frame"></div>
  460. </div>
  461. <div class="ring">
  462. <div class="frame"></div>
  463. </div>
  464. <div class="ring">
  465. <div class="frame"></div>
  466. </div>
  467. <div class="ring">
  468. <div class="frame"></div>
  469. </div>
  470. <div class="ring">
  471. <div class="frame"></div>
  472. </div>
  473. <div class="ring">
  474. <div class="frame"></div>
  475. </div>
  476. <div class="ring">
  477. <div class="frame"></div>
  478. </div>
  479. <div class="ring">
  480. <div class="frame"></div>
  481. </div>
  482. <div class="ring">
  483. <div class="frame"></div>
  484. </div>
  485. </div>
  486. </div>
  487. </div>
  488. <!-- Pre-loader end -->
  489. <div id="pcoded" class="pcoded">
  490. <div class="pcoded-container">
  491. <!-- Menu header start -->
  492. <nav th:replace="~{fragments/nav-user :: nav}"></nav>
  493. <!-- Menu header end -->
  494. <div class="pcoded-main-container">
  495. <nav th:replace="~{fragments/nav-usermenu :: nav}"></nav>
  496. <div class="pcoded-wrapper">
  497. <div class="pcoded-content">
  498. <div class="pcoded-inner-content">
  499. <!-- Main-body start -->
  500. <div class="main-body" style="background-color: white">
  501. <div class="page-wrapper" style="padding: 0;">
  502. <!-- Page-header start -->
  503. <div class="page-header m-t-50">
  504. </div>
  505. <div id="futureEventsContainer" class="page-body" style="display: none;"></div>
  506. <div class="card">
  507. <div class="card-header">
  508. <h5>Hall Booking Details</h5>
  509. <button type="button" class="btn btn-primary btn-square-md"
  510. th:if="${userBookingspast.size() > 0}"
  511. th:onclick="'transactionHistory(' + ${userBookingspast[0].users_user_id} + ')'">
  512. Transaction History
  513. </button>
  514. </div>
  515. <div class="card-block">
  516. <div class="table-responsive">
  517. <table
  518. class="table table-bordered table-striped table-vcenter js-dataTable-responsive"
  519. id="detailstable" style="width: 100%">
  520. <thead class="thead-light">
  521. <tr>
  522. <th class="text-center no-sort" width="10%">S.No</th>
  523. <th>Booking Id</th>
  524. <th>Booking date</th>
  525. <th>Hall Name</th>
  526. <th>Starting Date</th>
  527. <th>Ending Date</th>
  528. <th>Starting Period</th>
  529. <th>Ending Period</th>
  530. <th>Reason for booking</th>
  531. <th>Booking Status</th>
  532. <th>Payment Status</th>
  533. <th>Event Status</th>
  534. <th class="text-center no-sort" width="10%">Action</th>
  535. <th>View</th>
  536. </tr>
  537. </thead>
  538. <tbody>
  539. <tr th:each="booking, i : ${userBookingspast}"
  540. class="${userBookingspast}">
  541. <td th:text="${i.count}"></td>
  542. <td th:text="${booking.booking_id}"></td>
  543. <td th:text="${booking.booking_date}"></td>
  544. <td th:text="${booking.hall_name}"></td>
  545. <td th:text="${booking.start_date}"></td>
  546. <td th:text="${booking.end_date}"></td>
  547. <td
  548. th:text="${booking.starting_slot == 1 ? 'morning' : (booking.starting_slot == 2 ? 'evening' : '')}">
  549. </td>
  550. <td
  551. th:text="${booking.ending_slot == 1 ? 'morning' : (booking.ending_slot == 2 ? 'evening' : '')}">
  552. </td>
  553. <td th:text="${booking.reason}"></td>
  554. <td
  555. th:text="${#strings.replace(booking.booking_status, '_', ' ')}">
  556. </td>
  557. <td
  558. th:text="${booking.payment_status != null ? booking.payment_status : 'NA'}">
  559. </td>
  560. <td>
  561. <span th:if="${booking.booking_status == 'APPROVED'}">
  562. <span th:switch="${booking.event_category}">
  563. <span th:case="'Current'">Current Event</span>
  564. <span th:case="'Past'">Completed Event</span>
  565. <span th:case="'Future'">Upcoming Event</span>
  566. <span th:case="'Reschedule'">Upcoming
  567. Event</span>
  568. <span th:case="'noaction'">Govt Event</span>
  569. </span>
  570. </span>
  571. <span th:if="${booking.booking_status == 'COMPLETED'}">
  572. <span>Refund Completed Event</span>
  573. </span>
  574. <span th:if="${booking.booking_status == 'CANCELED'}">
  575. <span>User Canceled Event</span>
  576. </span>
  577. <span th:if="${booking.booking_status == 'REJECTED'}">
  578. <span>GCC Rejected Event</span>
  579. </span>
  580. <span
  581. th:if="${booking.booking_status == 'GCC_BLOCKED'}">
  582. <span>GCC Blocked Event</span>
  583. </span>
  584. <span
  585. th:if="${booking.booking_status == 'WAITING_FOR_NOC'}">
  586. <span>Waiting For NOC Document</span>
  587. </span>
  588. <span
  589. th:if="${booking.booking_status == 'WAITING_FOR_NOC_APPROVAL'}">
  590. <span>Waiting For Admin Approval</span>
  591. </span>
  592. </td>
  593. <td th:switch="${booking.event_category}">
  594. <p th:case="'Future'">
  595. <a class="view-button"
  596. th:if="${booking.booking_status == 'APPROVED'}">
  597. <span class="badge bg-danger"
  598. style="cursor: pointer;"
  599. th:onclick="cancelBooking([[${booking.booking_id}]], [[${booking.mobile_no}]], [[${booking.booking_type}]])">Cancel
  600. Booking</span>
  601. </a>
  602. </p>
  603. <p th:case="'waitingfornoc'">
  604. <a class="view-button"
  605. th:if="${booking.booking_status == 'WAITING_FOR_NOC'}">
  606. <span class="badge bg-danger"
  607. style="cursor: pointer;"
  608. data-bs-toggle="modal"
  609. data-bs-target="#uploadNocModal"
  610. th:attr="data-booking-id=${booking.booking_id}">Upload
  611. NOC</span>
  612. </a>
  613. <a class="view-button"
  614. th:if="${booking.booking_status == 'WAITING_FOR_NOC'}">
  615. <span class="badge bg-danger"
  616. style="cursor: pointer;"
  617. th:onclick="cancelBooking([[${booking.booking_id}]], [[${booking.mobile_no}]], [[${booking.booking_type}]])">Cancel
  618. Booking</span>
  619. </a>
  620. <!--<a class="reschedule-button"
  621. th:if="${booking.booking_status == 'WAITING_FOR_NOC' and booking.schedule_count < 1}">
  622. &lt;!&ndash;th:if="${booking.booking_status == 'WAITING_FOR_NOC'}">&ndash;&gt;
  623. <span class="badge bg-danger"
  624. style="cursor: pointer;"
  625. th:onclick="openRescheduleModal([[${booking.booking_id}]], [[${booking.start_date}]], [[${booking.end_date}]],[[${booking.no_of_days}]],
  626. [[${booking.hall_details_hall_id}]],[[${booking.starting_slot}]],[[${booking.ending_slot}]],[[${booking.reason}]])">Reschedule
  627. Booking</span>
  628. </a>-->
  629. </p>
  630. <p th:case="'waitingfornocapproval'">
  631. <a class="view-button"
  632. th:if="${booking.booking_status == 'WAITING_FOR_NOC_APPROVAL'}">
  633. <span class="badge bg-danger"
  634. style="cursor: pointer;"
  635. th:onclick="cancelBooking([[${booking.booking_id}]], [[${booking.mobile_no}]], [[${booking.booking_type}]])">Cancel
  636. Booking</span>
  637. </a>
  638. </p>
  639. <!--<p th:case="'noaction'">
  640. <a class="view-button">
  641. <span>&#45;&#45;No Action&#45;&#45;</span>
  642. </a>
  643. </p>-->
  644. <p th:case="'noaction'">
  645. <a class="view-button">
  646. <a class="view-button"
  647. th:if="${booking.booking_status == 'APPROVED'}">
  648. <span class="badge bg-danger"
  649. style="cursor: pointer;"
  650. th:onclick="cancelBooking([[${booking.booking_id}]], [[${booking.mobile_no}]], [[${booking.booking_type}]])">Cancel
  651. Booking</span>
  652. </a>
  653. </a>
  654. </p>
  655. <p th:case="'noaction'">
  656. <a class="view-button">
  657. <span>--No Action--</span>
  658. </a>
  659. </p>
  660. <p th:case="'Reschedule'">
  661. <a class="view-button"
  662. th:if="${booking.booking_status == 'APPROVED'}">
  663. <span class="badge bg-danger"
  664. style="cursor: pointer;"
  665. th:onclick="cancelBooking([[${booking.booking_id}]], [[${booking.mobile_no}]], [[${booking.booking_type}]])">Cancel
  666. Booking</span>
  667. </a>
  668. <a class="reschedule-button"
  669. th:if="${booking.booking_status == 'APPROVED'}">
  670. <span class="badge bg-danger"
  671. style="cursor: pointer;"
  672. th:onclick="openRescheduleModal([[${booking.booking_id}]], [[${booking.start_date}]], [[${booking.end_date}]],[[${booking.no_of_days}]],
  673. [[${booking.hall_details_hall_id}]],[[${booking.starting_slot}]],[[${booking.ending_slot}]],[[${booking.reason}]])">Reschedule
  674. Booking</span>
  675. </a>
  676. <a class="reschedule-button"
  677. th:if="${booking.booking_status == 'WAITING_FOR_NOC'}">
  678. <span class="badge bg-danger"
  679. style="cursor: pointer;"
  680. th:onclick="openRescheduleModal([[${booking.booking_id}]], [[${booking.start_date}]], [[${booking.end_date}]],[[${booking.no_of_days}]],
  681. [[${booking.hall_details_hall_id}]],[[${booking.starting_slot}]],[[${booking.ending_slot}]],[[${booking.reason}]])">Reschedule
  682. Booking</span>
  683. </a>
  684. </p>
  685. </td>
  686. <td>
  687. <a class="view-button">
  688. <span class="badge bg-primary"
  689. style="cursor: pointer;"
  690. th:onclick="showBookingDetails([[${booking.booking_id}]])">View</span>
  691. </a>
  692. <!--<a class="view-button">
  693. <span class="badge bg-primary"
  694. style="cursor: pointer;"
  695. th:onclick="trackBooking([[${booking.booking_id}]])">Track</span>
  696. </a>-->
  697. </td>
  698. </tr>
  699. </tbody>
  700. </table>
  701. </div>
  702. </div>
  703. </div>
  704. <input type="hidden" id="serverDate" th:value=${serverDate}>
  705. <div class="modal fade backdrop" id="showBookingDetails" data-backdrop="static"
  706. tabindex="-1" role="dialog" aria-labelledby="staticBackdropLabel"
  707. aria-hidden="true">
  708. <div class="modal-dialog modal-lg" role="document">
  709. <div class="modal-content" id="printableContent">
  710. <form id="regform" onsubmit="return rejectsubmit();">
  711. <div
  712. class="block block-rounded block-themed block-transparent mb-0">
  713. <div class="block-header bg-primary-dark">
  714. <h3 class="block-title" id="2mtitle">Booking
  715. Information</h3>
  716. <div class="block-options">
  717. <button type="button" class="btn-block-option"
  718. data-bs-dismiss="modal" aria-label="Close">
  719. <i class="fa fa-fw fa-times"></i>
  720. </button>
  721. </div>
  722. </div>
  723. <div class="block-content row"
  724. style="margin-right:0px;margin:0;padding:0;">
  725. <div class="col-md-12 col-lg-12 col-sm-12">
  726. <div class="card-body">
  727. <table>
  728. <tr>
  729. <th colspan="10"
  730. style="background-color: lightgrey;">
  731. User Details
  732. </th>
  733. </tr>
  734. <tr>
  735. <th
  736. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  737. User Name:
  738. </th>
  739. <td class="fw-semibold"
  740. style="padding: 0.45rem 0.45rem;"
  741. id="td_userName"></td>
  742. <th
  743. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  744. Mobile Number:
  745. </th>
  746. <td class="fw-semibold"
  747. style="padding: 0.45rem 0.45rem;"
  748. id="td_mobileNumber"></td>
  749. <th
  750. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  751. User Type:
  752. </th>
  753. <td class="fw-semibold"
  754. style="padding: 0.45rem 0.45rem;"
  755. id="td_usertype"></td>
  756. </tr>
  757. <tr>
  758. <th
  759. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  760. User Address:
  761. </th>
  762. <td colspan="5" class="fw-semibold"
  763. style="padding: 0.45rem 0.45rem;text-wrap: pretty;"
  764. id="td_useraddress"></td>
  765. </tr>
  766. <input type="hidden"
  767. class="form-control text-center"
  768. name="bookingid" id="bookingid" disabled />
  769. <tr>
  770. <th colspan="10"
  771. style="background-color: lightgrey;">
  772. Hall Details
  773. </th>
  774. </tr>
  775. <tr>
  776. <th
  777. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  778. Hall Name:
  779. </th>
  780. <td colspan="10" class="fw-semibold"
  781. style="padding: 0.45rem 0.45rem;text-wrap:pretty;"
  782. id="td_hallName"></td>
  783. </tr>
  784. <th
  785. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  786. Hall Address:
  787. </th>
  788. <td colspan="10" class="fw-semibold"
  789. style="padding: 0.45rem 0.45rem;text-wrap: pretty;"
  790. id="td_halladdress"></td>
  791. </tr>
  792. <tr>
  793. <th
  794. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  795. Caretaker Name:
  796. </th>
  797. <td colspan="2" class="fw-semibold"
  798. style="padding: 0.45rem 0.45rem;"
  799. id="td_caretakername"></td>
  800. <th
  801. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  802. Caretaker Mobile Number:
  803. </th>
  804. <td colspan="2" class="fw-semibold"
  805. style="padding: 0.45rem 0.45rem;"
  806. id="td_caretakermobileNumber"></td>
  807. </tr>
  808. <tr>
  809. <th colspan="10"
  810. style="background-color: lightgrey;">
  811. Booking
  812. Details (Booking Id:-<span
  813. id="booking_id"
  814. style="color:blue"></span>)
  815. </th>
  816. </tr>
  817. <tr>
  818. <th
  819. style="padding: 0.45rem 0.45rem;font-weight: normal">
  820. Booking Date:
  821. </th>
  822. <td colspan="2" class="fw-semibold"
  823. style="padding: 0.45rem 0.45rem;"
  824. id="td_bookingDate"></td>
  825. <th
  826. style="padding: 0.45rem 0.45rem;font-weight: normal">
  827. Deposit Amount (in Rs):
  828. </th>
  829. <td colspan="2"
  830. class="fw-semibold amount-cell"
  831. style="padding: 0.45rem 0.45rem;"
  832. id="td_depositeAmount"></td>
  833. </tr>
  834. <tr>
  835. <th
  836. style="padding: 0.45rem 0.45rem;font-weight: normal">
  837. Start Date:
  838. </th>
  839. <td colspan="2" class="fw-semibold"
  840. style="padding: 0.45rem 0.45rem;"
  841. id="td_startDate"></td>
  842. <th
  843. style="padding: 0.45rem 0.45rem;font-weight: normal">
  844. Hall Amount (in Rs):
  845. </th>
  846. <td colspan="2"
  847. class="fw-semibold amount-cell"
  848. style="padding: 0.45rem 0.45rem;"
  849. id="td_hallAmount"></td>
  850. </tr>
  851. <tr>
  852. <th
  853. style="padding: 0.45rem 0.45rem;font-weight: normal">
  854. END Date:
  855. </th>
  856. <td colspan="2" class="fw-semibold"
  857. style="padding: 0.45rem 0.45rem;"
  858. id="td_endDate"></td>
  859. <th
  860. style="padding: 0.45rem 0.45rem;font-weight: normal">
  861. GST @18% (in Rs):
  862. </th>
  863. <td colspan="2"
  864. class="fw-semibold amount-cell"
  865. style="padding: 0.45rem 0.45rem;"
  866. id="td_gst"></td>
  867. </tr>
  868. <tr>
  869. <th
  870. style="padding: 0.45rem 0.45rem;font-weight: normal">
  871. Starting Slot:
  872. </th>
  873. <td colspan="2" class="fw-semibold"
  874. style="padding: 0.45rem 0.45rem;"
  875. id="td_startingSlot"></td>
  876. <th
  877. style="padding: 0.45rem 0.45rem;font-weight: normal">
  878. Total Amount (in Rs):
  879. </th>
  880. <td colspan="2"
  881. class="fw-semibold amount-cell"
  882. style="padding: 0.45rem 0.45rem;"
  883. id="td_totalAmount"></td>
  884. </tr>
  885. <tr>
  886. <th
  887. style="padding: 0.45rem 0.45rem;font-weight: normal">
  888. Ending Slot:
  889. </th>
  890. <td colspan="2" class="fw-semibold"
  891. style="padding: 0.45rem 0.45rem;"
  892. id="td_endingSlot"></td>
  893. <!--<th style="display:none;padding: 0.45rem 0.45rem;border:none"
  894. id="rejectionreasondiv">Rejection
  895. Reason:</th>
  896. <td class="fw-semibold"
  897. style="padding: 0.45rem 0.45rem;"
  898. id="reasonforrejection"></td>-->
  899. <th
  900. style="padding: 0.45rem 0.45rem;border:none">
  901. Booking Status:
  902. </th>
  903. <td colspan="2" class="fw-semibold"
  904. style="padding: 0.45rem 0.45rem;text-wrap: pretty;"
  905. id="bookingstatus_td"></td>
  906. </tr>
  907. <tr>
  908. <th style="display:none;padding: 0.45rem 0.45rem;border:none"
  909. id="rejectionreasondiv">Rejection
  910. Reason:
  911. </th>
  912. <td class="fw-semibold"
  913. style="padding: 0.45rem 0.45rem;text-wrap: pretty;"
  914. id="reasonforrejection"></td>
  915. </tr>
  916. </table>
  917. </div>
  918. </div>
  919. <div class="row col-md-12 col-lg-12 col-sm-12"
  920. style="margin-left:6px;margin-top:-21px">
  921. <div class="documents" id="documents"></div>
  922. </div>
  923. <div class="col-md-12 col-lg-12 col-sm-12 mb-2"
  924. id="paymentsdetails"
  925. style="display:none; margin-top: -26px;">
  926. <div class="card-body">
  927. <table>
  928. <tr>
  929. <th colspan="10"
  930. style="background-color: lightgrey;">
  931. Booking Payment Details
  932. </th>
  933. </tr>
  934. <tr>
  935. <th
  936. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  937. Transaction ID:
  938. </th>
  939. <td colspan="10" class="fw-semibold"
  940. style="padding: 0.45rem 0.45rem;"
  941. id="td_transactionId"></td>
  942. </tr>
  943. <th
  944. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  945. Amount Received (in Rs):
  946. </th>
  947. <td colspan="10" class="fw-semibold"
  948. style="padding: 0.45rem 0.45rem;"
  949. id="td_payamountReceived"></td>
  950. </tr>
  951. <tr>
  952. <th
  953. style="padding: 0.45rem 0.45rem;font-weight: normal;">
  954. Transaction Status:
  955. </th>
  956. <td class="fw-semibold"
  957. style="padding: 0.45rem 0.45rem;"
  958. id="td_paymentStatus"></td>
  959. </tr>
  960. </table>
  961. </div>
  962. </div>
  963. <div class="row col-md-12 col-lg-12 col-sm-12"
  964. id="ebdetails"
  965. style="display:none;margin-left: 0px;margin-top: -49px">
  966. <div class="card-body">
  967. <table>
  968. <tr>
  969. <th colspan="4"
  970. style="background-color: lightgrey;">EB
  971. Details
  972. </th>
  973. </tr>
  974. <tr>
  975. <th
  976. style="padding: 0.45rem 0.45rem;font-weight: normal">
  977. Consumer Number:
  978. </th>
  979. <td class="fw-semibold"
  980. style="padding: 0.45rem 0.45rem;"
  981. id="td_EBNumber"></td>
  982. <th
  983. style="padding: 0.45rem 0.45rem;font-weight: normal">
  984. EB Amount Per Unit (in Rs):
  985. </th>
  986. <td class="fw-semibold"
  987. style="padding: 0.45rem 0.45rem;"
  988. id="td_ebamountperunit"></td>
  989. </tr>
  990. <tr>
  991. <th
  992. style="padding: 0.45rem 0.45rem;font-weight: normal">
  993. Start Reading:
  994. </th>
  995. <td class="fw-semibold"
  996. style="padding: 0.45rem 0.45rem;"
  997. id="td_startingReading"></td>
  998. <th
  999. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1000. Unit Consumed:
  1001. </th>
  1002. <td class="fw-semibold"
  1003. style="padding: 0.45rem 0.45rem;"
  1004. id="td_usedunit"></td>
  1005. </tr>
  1006. <tr>
  1007. <th
  1008. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1009. END Reading:
  1010. </th>
  1011. <td class="fw-semibold"
  1012. style="padding: 0.45rem 0.45rem;"
  1013. id="td_endingReading"></td>
  1014. <th
  1015. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1016. EB Amount (in Rs):
  1017. </th>
  1018. <td class="fw-semibold"
  1019. style="padding: 0.45rem 0.45rem;"
  1020. id="td_electricityamount"></td>
  1021. </tr>
  1022. </tbody>
  1023. </table>
  1024. </div>
  1025. </div>
  1026. <div class="row col-md-12 col-lg-12 col-sm-12"
  1027. id="damagelist" style="disaply:none">
  1028. <div id="damageDetails"></div>
  1029. </div>
  1030. <div class="col-md-12 col-lg-12 col-sm-12"
  1031. id="refunddetails" style="margin-top:-41px">
  1032. <div class="card-body">
  1033. <table>
  1034. <tr>
  1035. <th colspan="2"
  1036. style="background-color: lightgrey;">
  1037. Amount to be Refunded (in Rs)
  1038. </th>
  1039. </tr>
  1040. <tr>
  1041. <th
  1042. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1043. Deposit Amount:
  1044. </th>
  1045. <td class="fw-semibold amount-cell"
  1046. style="padding: 0.45rem 0.45rem;"
  1047. id="td_depositeamountforrefund">0
  1048. </td>
  1049. </tr>
  1050. <tr>
  1051. <th
  1052. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1053. EB Amount:
  1054. </th>
  1055. <td class="fw-semibold amount-cell"
  1056. style="padding: 0.45rem 0.45rem;"
  1057. id="td_ebAmount"></td>
  1058. </tr>
  1059. <tr>
  1060. <th
  1061. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1062. Damage Amount:
  1063. </th>
  1064. <td class="fw-semibold amount-cell"
  1065. style="padding: 0.45rem 0.45rem;"
  1066. id="td_damage"></td>
  1067. </tr>
  1068. <tr id="pendingcolumn">
  1069. <th id="th_settel_label"
  1070. style="padding: 0.45rem 0.45rem; background-color: #f2f2f2;font-weight: normal">
  1071. Collection Pending Amount:
  1072. </th>
  1073. <td class="fw-semibold amount-cell"
  1074. style="padding: 0.45rem 0.45rem; color: green;"
  1075. id="td_pending_amt">0
  1076. </td>
  1077. </tr>
  1078. <tr id="collectionstatuscolumn">
  1079. <th id="label"
  1080. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1081. Collection Pending Status
  1082. :
  1083. </th>
  1084. <td class="fw-semibold amount-cell"
  1085. style="padding: 0.45rem 0.45rem; color: green;"
  1086. id="td_collection_status">
  1087. </td>
  1088. </tr>
  1089. <tr>
  1090. <th
  1091. style="padding: 0.45rem 0.45rem; background-color: #f2f2f2;font-weight: normal">
  1092. Actual refundable Amount:
  1093. </th>
  1094. <td class="fw-semibold amount-cell"
  1095. style="padding: 0.45rem 0.45rem; color: green;"
  1096. id="td_settel_amt">0
  1097. </td>
  1098. </tr>
  1099. </table>
  1100. </div>
  1101. </div>
  1102. <div class="row col-md-12 col-lg-12 col-sm-12"
  1103. id="refundamountDetails"
  1104. style="display:none;margin-left: 0px;margin-top: -49px">
  1105. <div class="card-body">
  1106. <table>
  1107. <tr>
  1108. <th colspan="4"
  1109. style="background-color: lightgrey;">
  1110. Refund Details
  1111. </th>
  1112. </tr>
  1113. <tr>
  1114. <th
  1115. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1116. Booking Status:
  1117. </th>
  1118. <td class="fw-semibold"
  1119. style="padding: 0.45rem 0.45rem;"
  1120. id="td_bookingStatus"></td>
  1121. <th
  1122. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1123. Refund Status:
  1124. </th>
  1125. <td class="fw-semibold"
  1126. style="padding: 0.45rem 0.45rem;"
  1127. id="td_refundStatus"></td>
  1128. </tr>
  1129. <tr>
  1130. <th
  1131. style="padding: 0.45rem 0.45rem;font-weight: normal;text-wrap: pretty;">
  1132. Refund amount:
  1133. </th>
  1134. <td class="fw-semibold" colspan="5"
  1135. style="padding: 0.45rem 0.45rem;"
  1136. id="td_refundamount"></td>
  1137. </tr>
  1138. </tbody>
  1139. </table>
  1140. </div>
  1141. </div>
  1142. <div id="refundMessage" style="display: none;">
  1143. <h1 id="refundText"
  1144. style="font-size: 17px;margin-left: 20px;color: darkgreen;">
  1145. </h1>
  1146. </div>
  1147. <div id="rejectrefundMessage" style="display: none;">
  1148. <h1 id="rejectrefundText"
  1149. style="font-size: 17px;margin-left: 20px;color: darkgreen;">
  1150. </h1>
  1151. </div>
  1152. <div id="blockedrefundMessage" style="display: none;">
  1153. <h1 id="blockedrefundText"
  1154. style="font-size: 17px;margin-left: 20px;color: darkgreen;">
  1155. </h1>
  1156. </div>
  1157. <!--Newly added for Reschedule Details-->
  1158. <!--<div class="row col-md-12 col-lg-12 col-sm-12"
  1159. id="rescheduleDetails"
  1160. style="display:none;margin-left: 0px;margin-top: -49px">
  1161. <div class="card-body">
  1162. <table>
  1163. <tr>
  1164. <th colspan="4"
  1165. style="background-color: lightgrey;">
  1166. Reschedule Details
  1167. </th>
  1168. </tr>
  1169. <tr>
  1170. <th
  1171. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1172. Event Start Date:
  1173. </th>
  1174. <td class="fw-semibold"
  1175. style="padding: 0.45rem 0.45rem;"
  1176. id="td_res_start_date"></td>
  1177. <th
  1178. style="padding: 0.45rem 0.45rem;font-weight: normal">
  1179. Event End Date:
  1180. </th>
  1181. <td class="fw-semibold"
  1182. style="padding: 0.45rem 0.45rem;"
  1183. id="td_res_end_date"></td>
  1184. </tr>
  1185. <tr>
  1186. <th
  1187. style="padding: 0.45rem 0.45rem;font-weight: normal;text-wrap: pretty;">
  1188. Rescheduled Date:</th>
  1189. <td class="fw-semibold" colspan="5"
  1190. style="padding: 0.45rem 0.45rem;"
  1191. id="td_res_date"></td>
  1192. </tr>
  1193. </tbody>
  1194. </table>
  1195. </div>
  1196. </div>-->
  1197. </div>
  1198. </div>
  1199. <div class="block-content block-content-full text-end bg-body"
  1200. id="mbutton">
  1201. <button class="btn btn-success"
  1202. onclick="downloadAcknowledgment(event)"
  1203. style="background: #FB6340;">View
  1204. Acknowledgement
  1205. </button>
  1206. <button type="button"
  1207. style="background-color: rgb(21,69,93);color: white;"
  1208. class="btn btn-sm btn-alt-secondary"
  1209. data-bs-dismiss="modal">Close
  1210. </button>
  1211. </div>
  1212. </form>
  1213. </div>
  1214. </div>
  1215. </div>
  1216. </div>
  1217. <br>
  1218. </div>
  1219. </div>
  1220. <div class="modal fade" id="fileModal" tabindex="-1" role="dialog"
  1221. aria-labelledby="fileModalLabel" aria-hidden="true">
  1222. <div class="modal-dialog modal-lg" role="document">
  1223. <div class="modal-content">
  1224. <div class="modal-header">
  1225. <h5 class="modal-title" id="fileModalLabel">File Preview</h5>
  1226. <button type="button" class="close" data-bs-dismiss="modal" aria-label="Close"
  1227. style="border: 1px solid black; padding: 5px;
  1228. display: inline-flex; align-items: center; justify-content: center;
  1229. background-color: transparent; color: black; font-size: 20px;">
  1230. <span aria-hidden="true">&times;</span>
  1231. </button>
  1232. </div>
  1233. <div class="modal-body">
  1234. <embed id="filePreview" src="" width="100%" height="600px">
  1235. </div>
  1236. <div class="modal-footer">
  1237. <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close
  1238. </button>
  1239. </div>
  1240. </div>
  1241. </div>
  1242. </div>
  1243. </div>
  1244. <div class="modal fade" id="bookingRescheduleModal" tabindex="-1"
  1245. aria-labelledby="bookingModalLabel" aria-hidden="true">
  1246. <div class="modal-dialog modal-dialog-centered modal-lg">
  1247. <div class="modal-content">
  1248. <!-- Modal Header -->
  1249. <div class="modal-header" style="color:black">
  1250. <h5 class="modal-title" id="bookingModalLabel" style="color:black">Booking
  1251. Reschedule</h5>
  1252. <br>
  1253. <br>
  1254. <div style="margin-bottom: -59px; margin-left: -185px;">
  1255. <!-- Adding margin-top for separation -->
  1256. <p style="font-size: 14px; color: #6c757d;">Note: Only the Start Date can be
  1257. changed.</p>
  1258. </div>
  1259. <button type="button" class="btn-close" data-bs-dismiss="modal"
  1260. aria-label="Close"></button>
  1261. </div>
  1262. <!-- Modal Body -->
  1263. <div class="modal-body">
  1264. <div class="container-fluid">
  1265. <div class="row">
  1266. <!-- Datepicker and Availability Buttons Column -->
  1267. <div id="datepicker-container" class="fixedcontainer"></div>
  1268. <!-- Start Date, End Date, Number of Days Inputs Column -->
  1269. <div class="col">
  1270. <input type="hidden" class="form-control" id="bookingId"
  1271. name="bookingId" required>
  1272. <label for="startDateInput" class="form-label">Start Date:</label>
  1273. <input type="text" class="form-control" id="startDateInput"
  1274. name="startDateInput" required readonly>
  1275. <input type="hidden" class="form-control" id="startDatetext"
  1276. name="startDatetext" required>
  1277. </div>
  1278. <div class="col">
  1279. <label for="endDateInput" class="form-label">End Date:</label>
  1280. <input type="date" class="form-control" id="endDateInput"
  1281. name="endDateInput" readonly>
  1282. </div>
  1283. <div class="col">
  1284. <label for="noOfDaysInput" class="form-label">Number of Days:</label>
  1285. <input type="number" class="form-control" id="noOfDaysInput"
  1286. name="noOfDaysInput" readonly>
  1287. </div>
  1288. </div>
  1289. <div class="row">
  1290. <div class="col">
  1291. <input type="hidden" id="daysDiff">
  1292. <label for="startingSlot" class="form-label">Starting Slot:</label>
  1293. <input type="text" class="form-control" id="startingSlotText"
  1294. name="startingSlot" readonly>
  1295. <input type="hidden" class="form-control" id="startingSlot"
  1296. name="startingSlot" required>
  1297. </div>
  1298. <div class="col">
  1299. <label for="endingSlot" class="form-label">Ending Slot:</label>
  1300. <input type="text" class="form-control" id="endingSlotText"
  1301. name="endDateInput" readonly>
  1302. <input type="hidden" class="form-control" id="endingSlot"
  1303. name="endDateInput" readonly>
  1304. </div>
  1305. </div>
  1306. <div class="row" style="margin-top: 39px;">
  1307. <div class="col col-lg-2 col-sm-2 col-md-2">
  1308. <button type="button" class="btn btn-primary btn-square-md"
  1309. style="background-color:#008000;"></button>
  1310. <p style="margin-left: 14px;">Day<br>(Available)</p>
  1311. </div>
  1312. <div class="col col-lg-2 col-sm-2 col-md-2">
  1313. <button type="button" class="btn btn-primary btn-square-md"
  1314. style="background-color: #ac2bac;"></button>
  1315. <p style="margin-left: 14px;">Morning<br>(Available)</p>
  1316. </div>
  1317. <div class="col col-lg-2 col-sm-2 col-md-2">
  1318. <button type="button" class="btn btn-primary btn-square-md"
  1319. style="background-color:#FFEA00;"></button>
  1320. <p style="margin-left: 14px;">Evening<br>(Available)</p>
  1321. </div>
  1322. <div class="col col-lg-2 col-sm-2 col-md-2">
  1323. <button type="button" class="btn btn-primary btn-square-md"
  1324. style="background-color: red;"></button>
  1325. <p style="margin-left: 14px;">Not Available</p>
  1326. </div>
  1327. <div class="col col-lg-2 col-sm-2 col-md-2">
  1328. <button type="button" class="btn btn-primary btn-square-md"
  1329. style="background-color: blue;"></button>
  1330. <p style="margin-left: 14px;">GCC Blocked</p>
  1331. </div>
  1332. <!--<div class="col col-lg-2 col-sm-2 col-md-2">
  1333. <button type="button" class="btn btn-primary btn-square-md"
  1334. style="background-color: lightpink;"></button>
  1335. <p style="margin-left: 14px;">Temporary Blocked</p>
  1336. </div>-->
  1337. </div>
  1338. </div>
  1339. </div>
  1340. <!-- Modal Footer -->
  1341. <div class="modal-footer">
  1342. <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close
  1343. </button>
  1344. <button type="button" class="btn btn-primary" onclick="Reschedule()">Save
  1345. Changes
  1346. </button>
  1347. </div>
  1348. </div>
  1349. </div>
  1350. </div>
  1351. <!-- Reschedule OTP Verification Modal -->
  1352. <div class="modal fade" id="rescheduleOtpModal" tabindex="-1" role="dialog"
  1353. aria-labelledby="rescheduleOtpModalLabel" aria-hidden="true">
  1354. <div class="modal-dialog" role="document">
  1355. <div class="modal-content">
  1356. <div class="modal-header">
  1357. <h6 class="modal-title m-0" id="rescheduleOtpModalLabel">Reschedule Verification
  1358. </h6>
  1359. <button type="button" class="btn-close" data-bs-dismiss="modal"
  1360. aria-label="Close"></button>
  1361. </div>
  1362. <div class="modal-body">
  1363. <div class="row">
  1364. <div class="mb-3 text-center">
  1365. <img src="media/images/mobileotp.png" width="50%" alt="Mobileotp">
  1366. </div>
  1367. <div class="mb-0 text-center">
  1368. <h4>OTP Verification</h4>
  1369. <p class="text-mute">Enter the OTP sent to <b class="text-info"
  1370. id="rescheduleMobileTxt"></b></p>
  1371. <p class="text-danger" id="rescheduleOtpError"></p>
  1372. </div>
  1373. <div class="mb-3 text-center">
  1374. <div class="otp-input-box">
  1375. <input type="text" maxlength="1" class="otp-input" id="rescheduleOtp1"
  1376. required />
  1377. <input type="text" maxlength="1" class="otp-input" id="rescheduleOtp2"
  1378. required />
  1379. <input type="text" maxlength="1" class="otp-input" id="rescheduleOtp3"
  1380. required />
  1381. <input type="text" maxlength="1" class="otp-input" id="rescheduleOtp4"
  1382. required />
  1383. <input type="text" maxlength="1" class="otp-input" id="rescheduleOtp5"
  1384. required />
  1385. </div>
  1386. </div>
  1387. <div class="mb-3 text-center">
  1388. <div id="rescheduleResendContainer">
  1389. <p class="mb-0">Didn't receive OTP?</p>
  1390. <p class="mb-0 text-info" id="rescheduleResendLink">Please wait..<span
  1391. id="rescheduleCountdown">60</span>s</p>
  1392. </div>
  1393. </div>
  1394. </div>
  1395. </div>
  1396. <div class="modal-footer">
  1397. <button type="button" class="btn btn-secondary btn-sm"
  1398. data-bs-dismiss="modal">Close</button>
  1399. <button type="button" class="btn btn-primary btn-sm"
  1400. onclick="verifyRescheduleOtp()">Verify OTP</button>
  1401. </div>
  1402. </div>
  1403. </div>
  1404. </div>
  1405. <!-- Tracking Log Modal -->
  1406. <!-- Tracking Modal -->
  1407. <div class="modal fade" id="trackingModal" tabindex="-1" aria-labelledby="trackingModalLabel"
  1408. aria-hidden="true">
  1409. <div class="modal-dialog modal-lg">
  1410. <div class="modal-content">
  1411. <div class="modal-header">
  1412. <h4 class="modal-title">Booking Tracking</h4>
  1413. <button type="button" class="btn-close" data-bs-dismiss="modal"
  1414. aria-label="Close"></button>
  1415. </div>
  1416. <div class="modal-body">
  1417. <div class="tracking-container">
  1418. <ul id="trackingList" class="tracking-steps list-unstyled">
  1419. <!-- Steps will be dynamically appended here -->
  1420. </ul>
  1421. </div>
  1422. </div>
  1423. </div>
  1424. </div>
  1425. </div>
  1426. <!-- Modal -->
  1427. <div class="modal fade" id="uploadNocModal" tabindex="-1" aria-labelledby="uploadNocModalLabel"
  1428. aria-hidden="true">
  1429. <div class="modal-dialog">
  1430. <div class="modal-content">
  1431. <div class="modal-header">
  1432. <h5 class="modal-title" id="uploadNocModalLabel">Upload NOC</h5>
  1433. <button type="button" class="btn-close" data-bs-dismiss="modal"
  1434. aria-label="Close"></button>
  1435. </div>
  1436. <div class="modal-body">
  1437. <div class="mb-3">
  1438. <label for="nocFile" class="form-label">Select NOC File</label>
  1439. <input type="file" class="form-control nocfile" id="nocFile" name="nocFile"
  1440. required>
  1441. <input type="hidden" id="bookingssId" name="bookingssId">
  1442. </div>
  1443. </div>
  1444. <div class="modal-footer">
  1445. <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close
  1446. </button>
  1447. <button type="button" class="btn btn-primary" id="submitNocButton">Submit</button>
  1448. </div>
  1449. </div>
  1450. </div>
  1451. </div>
  1452. <!-- Modal -->
  1453. <div class="modal fade" id="transactionHistoryModal" tabindex="-1"
  1454. aria-labelledby="transactionHistoryModalLabel" aria-hidden="true">
  1455. <div class="modal-dialog modal-lg" id="transactionmodel"> <!-- modal-lg makes it larger -->
  1456. <div class="modal-content">
  1457. <div class="modal-header">
  1458. <h5 class="modal-title" id="transactionHistoryModalLabel">Transaction History</h5>
  1459. <button type="button" class="btn-close" data-bs-dismiss="modal"
  1460. aria-label="Close"></button>
  1461. </div>
  1462. <div class="modal-body">
  1463. <!-- Scrollable Table -->
  1464. <div class="table-responsive"> <!-- Make the table scrollable if too large -->
  1465. <table class="table table-bordered" id="transactionTable">
  1466. <thead>
  1467. <tr>
  1468. <th>S.NO</th>
  1469. <th>Booking ID</th>
  1470. <th>Amount</th>
  1471. <th>Date</th>
  1472. <th>Transaction ID</th>
  1473. <th>Status</th>
  1474. </tr>
  1475. </thead>
  1476. <tbody>
  1477. <!-- Data will be populated dynamically here -->
  1478. </tbody>
  1479. </table>
  1480. </div>
  1481. <div class="table-responsive" id="refunddetails" style="display: none;">
  1482. <h2>Refund Details</h2>
  1483. <table class="table table-bordered" id="refunddetailsTable">
  1484. <thead>
  1485. <tr>
  1486. <th>S.NO</th>
  1487. <th>Booking ID</th>
  1488. <th>Amount</th>
  1489. <th>Date</th>
  1490. <th>Transaction ID</th>
  1491. <th>Refund Amount</th>
  1492. </tr>
  1493. </thead>
  1494. <tbody>
  1495. <!-- Data will be populated dynamically here -->
  1496. </tbody>
  1497. </table>
  1498. </div>
  1499. </div>
  1500. <div class="modal-footer">
  1501. <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close
  1502. </button>
  1503. </div>
  1504. </div>
  1505. </div>
  1506. </div>
  1507. <footer th:replace="~{fragments/footer :: footer}"></footer>
  1508. </div>
  1509. </div>
  1510. </div>
  1511. <!--otp form-->
  1512. <div th:replace="~{fragments/loginreg :: div}"></div>
  1513. <!--otp form-->
  1514. <script src="js/html2pdf.bundle.min.js"></script>
  1515. <script th:replace="~{fragments/script :: script}"></script>
  1516. <script th:replace="~{fragments/logRegiOtpScript :: script}"></script>
  1517. <script type="text/javascript" src="https://www.paynimo.com/paynimocheckout/server/lib/checkout.js"></script>
  1518. <script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
  1519. <script src="https://cdn.datatables.net/buttons/2.4.1/js/dataTables.buttons.min.js"></script>
  1520. <script src="https://cdn.datatables.net/buttons/2.4.1/js/buttons.html5.min.js"></script>
  1521. <script type="text/javascript">
  1522. // Reschedule variables
  1523. var rescheduleBookingId = null;
  1524. var rescheduleStartDate = null;
  1525. var rescheduleEndDate = null;
  1526. var rescheduleMobileNumber = null;
  1527. var rescheduleHallId = null;
  1528. var rescheduleStartingSlot = null;
  1529. var rescheduleEndingSlot = null;
  1530. var rescheduleReason = null;
  1531. $(document).ready(function () {
  1532. $('#detailstable').DataTable({
  1533. responsive: true,
  1534. pageLength: 10,
  1535. ordering: true,
  1536. columnDefs: [{
  1537. targets: 'no-sort',
  1538. orderable: false
  1539. }],
  1540. dom: 'Bfrtip',
  1541. buttons: [
  1542. {
  1543. extend: 'excelHtml5',
  1544. text: 'Export to Excel',
  1545. className: 'btn btn-primary'
  1546. }
  1547. ]
  1548. });
  1549. });
  1550. $(document).ready(function () {
  1551. $('#submitNocButton').on('click', function (e) {
  1552. e.preventDefault();
  1553. // Get the form data
  1554. var formData = new FormData();
  1555. var fileInput = $('#nocFile')[0].files[0]; // Get the selected file
  1556. var bookingssId = $('#bookingssId').val(); // Get the bookingId
  1557. // Check if a file is selected
  1558. if (!fileInput) {
  1559. Swal.fire({
  1560. icon: 'warning',
  1561. title: 'No File Selected',
  1562. text: 'Please select a file to upload.',
  1563. });
  1564. return;
  1565. }
  1566. // Append file and bookingId to formData
  1567. formData.append('nocFile', fileInput);
  1568. formData.append('bookingssId', bookingssId);
  1569. // Perform Ajax request
  1570. $.ajax({
  1571. url: '/communityhall/user/api/uploaddocs', // API endpoint
  1572. type: 'POST',
  1573. data: formData,
  1574. contentType: false,
  1575. processData: false,
  1576. success: function (response) {
  1577. // Show success message and refresh the page
  1578. Swal.fire({
  1579. icon: 'success',
  1580. title: 'Success',
  1581. text: 'NOC uploaded successfully!',
  1582. }).then(() => {
  1583. $('#uploadNocModal').modal('hide'); // Close the modal
  1584. location.reload(); // Refresh the page
  1585. });
  1586. },
  1587. error: function (xhr, status, error) {
  1588. // Show error message
  1589. Swal.fire({
  1590. icon: 'error',
  1591. title: 'Upload Failed',
  1592. text: 'Failed to upload NOC: ' + error,
  1593. });
  1594. }
  1595. });
  1596. });
  1597. // Populate bookingId when opening the modal
  1598. $('#uploadNocModal').on('show.bs.modal', function (event) {
  1599. var button = $(event.relatedTarget); // Button that triggered the modal
  1600. var bookingId = button.data('booking-id'); // Extract bookingId from the button
  1601. $('#bookingssId').val(bookingId); // Set the bookingId in the hidden input field
  1602. });
  1603. });
  1604. // Function to track booking
  1605. function trackBooking(bookingId) {
  1606. $.ajax({
  1607. url: '/communityhall/user/api/trackBooking',
  1608. method: 'GET',
  1609. data: { bookingId: bookingId }, // Send booking ID to the server
  1610. success: function (data) {
  1611. // console.log("Received tracking data:", data);
  1612. // Clear the list initially before appending steps
  1613. $('#trackingList').empty();
  1614. if (Array.isArray(data) && data.length > 0) {
  1615. // Show the modal first
  1616. $('#trackingModal').modal('show');
  1617. // Create a Set to track seen statuses
  1618. const seenStatuses = new Set();
  1619. // Append steps one by one
  1620. data.forEach((event) => {
  1621. // Append each step if it hasn't been seen before
  1622. if (!seenStatuses.has(event.status)) {
  1623. seenStatuses.add(event.status); // Add status to Set
  1624. appendStep(event); // Call to append the event step
  1625. }
  1626. });
  1627. } else {
  1628. // Show a message when no tracking events are available
  1629. $('#trackingList').append('<li class="no-events">No tracking events available.</li>');
  1630. }
  1631. },
  1632. error: function (xhr, status, error) {
  1633. console.error("Failed to fetch booking details:", status, error);
  1634. alert('Failed to fetch booking details. Please try again later.');
  1635. }
  1636. });
  1637. }
  1638. function appendStep(event) {
  1639. const formattedDate = moment(event.dateTime).isValid()
  1640. ? moment(event.dateTime).format('MMM DD, YYYY, h:mm A') // Format date using Moment.js
  1641. : 'Invalid date';
  1642. const statusClass = getStatusClass(event.status); // Get CSS class for the status
  1643. const statusIcon = getStatusIcon(event.status); // Get icon for the status
  1644. // Create and append a step element for each event
  1645. const stepElement = `
  1646. <li class="tracking-step ${statusClass}">
  1647. <div class="step-icon">
  1648. <i class="fas ${statusIcon}"></i> <!-- Add the icon -->
  1649. </div>
  1650. <div class="step-content">
  1651. <h5>${event.description || 'No Description Available'}</h5> <!-- Event description -->
  1652. <p class="step-date">${formattedDate}</p> <!-- Formatted date -->
  1653. </div>
  1654. </li>
  1655. `;
  1656. // Append the element to the list
  1657. $('#trackingList').append(stepElement);
  1658. }
  1659. function getStatusClass(status) {
  1660. switch (status) {
  1661. case 'PAYMENT_SUCCESS':
  1662. case 'APPROVED':
  1663. case 'EVENT_COMPLETED':
  1664. case 'COMPLETED':
  1665. return 'completed'; // Returns 'completed' class for these statuses
  1666. case 'SETTLEMENT_RAISING':
  1667. return 'waiting';
  1668. case 'CANCELED':
  1669. return 'cancelled';
  1670. case 'REJECTED':
  1671. return 'rejected';
  1672. case 'GCC_BLOCKED':
  1673. return 'gcc-blocked';
  1674. default:
  1675. return 'pending'; // Default class if status is unknown
  1676. }
  1677. }
  1678. function getStatusIcon(status) {
  1679. switch (status) {
  1680. case 'PAYMENT_SUCCESS':
  1681. return 'fa-check-circle'; // Icon for payment success
  1682. case 'APPROVED':
  1683. return 'fa-thumbs-up';
  1684. case 'EVENT_COMPLETED':
  1685. return 'fa-calendar-check';
  1686. case 'CANCELED':
  1687. return 'fa-ban';
  1688. case 'REJECTED':
  1689. return 'fa-times-circle';
  1690. case 'GCC_BLOCKED':
  1691. return 'fa-lock';
  1692. default:
  1693. return 'fa-clock'; // Default icon for pending steps
  1694. }
  1695. }
  1696. function showFutureEvents() {
  1697. document.getElementById('futureEventsContainer').style.display = 'block';
  1698. }
  1699. function downloadAcknowledgment(event) {
  1700. event.preventDefault();
  1701. var bookingId = document.getElementById("booking_id").innerHTML;
  1702. // Redirect to the acknowledgment URL in the same tab
  1703. window.location.href = '/communityhall/user/acknowledgement?bookingId=' + encodeURIComponent(bookingId);
  1704. }
  1705. function getTimeSlot(slotValue) {
  1706. var timeSlot;
  1707. var trimmedSlotValue = String(slotValue).trim(); // Convert to string and then trim
  1708. if (trimmedSlotValue === '1') {
  1709. timeSlot = 'Morning';
  1710. } else if (trimmedSlotValue === '2') {
  1711. timeSlot = 'Evening';
  1712. } else {
  1713. timeSlot = 'Unknown';
  1714. }
  1715. return timeSlot;
  1716. }
  1717. function showBookingDetails(bookingId) {
  1718. $.ajax({
  1719. url: '/communityhall/user/api/viewAllBookingDetails',
  1720. method: 'GET',
  1721. data: { bookingId: bookingId },
  1722. success: function (response) {
  1723. document.getElementById("td_userName").innerHTML = response.users.name;
  1724. document.getElementById("td_mobileNumber").innerHTML = response.users.mobileNo;
  1725. document.getElementById("td_usertype").innerHTML = response.users.usertype;
  1726. var userDetails = response.users;
  1727. var userDetailsString =
  1728. userDetails.doorNo + ", " +
  1729. userDetails.street + ", " +
  1730. userDetails.area + ", " +
  1731. userDetails.location + " ,Chennai- " +
  1732. userDetails.pinCode;
  1733. document.getElementById("td_useraddress").innerHTML = userDetailsString;
  1734. document.getElementById("td_hallName").innerHTML = response.hallDetails.hallName;
  1735. var hallDetails = response.hallDetails;
  1736. var hallDetailsString =
  1737. hallDetails.doorNo + ", " +
  1738. hallDetails.street + ", " +
  1739. hallDetails.area + ", " +
  1740. hallDetails.city + "- " +
  1741. hallDetails.pinCode;
  1742. document.getElementById("td_halladdress").innerHTML = hallDetailsString;
  1743. document.getElementById("td_caretakername").innerHTML = response.hallDetails.hallInchargeName;
  1744. document.getElementById("td_caretakermobileNumber").innerHTML = response.hallDetails.hallInchargeMobno;
  1745. document.getElementById("td_bookingDate").innerHTML = response.bookingDate;
  1746. document.getElementById("td_depositeAmount").innerHTML = parseFloat(response.depositAmount).toFixed(2);
  1747. document.getElementById("td_hallAmount").innerHTML = parseFloat(response.hallAmount).toFixed(2);
  1748. // Calculate GST and total amount
  1749. var gstAmount = (parseFloat(response.hallAmount) * (response.hallDetails.gst / 100)).toFixed(2);
  1750. var totalAmount = parseFloat(response.amountReceived).toFixed(2);
  1751. document.getElementById("td_gst").innerHTML = gstAmount;
  1752. document.getElementById("td_totalAmount").innerHTML = totalAmount;
  1753. document.getElementById("td_startDate").innerHTML = response.startDate;
  1754. document.getElementById("td_endDate").innerHTML = response.endDate;
  1755. document.getElementById("booking_id").innerHTML = response.bookingId;
  1756. function getTimeSlot(slotValue) {
  1757. var timeSlot;
  1758. var trimmedSlotValue = String(slotValue).trim(); // Convert to string and then trim
  1759. if (trimmedSlotValue === '1') {
  1760. timeSlot = 'Morning';
  1761. } else if (trimmedSlotValue === '2') {
  1762. timeSlot = 'Evening';
  1763. } else {
  1764. timeSlot = 'Unknown';
  1765. }
  1766. return timeSlot;
  1767. }
  1768. document.getElementById("td_startingSlot").innerHTML = getTimeSlot(response.startingSlot);
  1769. document.getElementById("td_endingSlot").innerHTML = getTimeSlot(response.endingSlot);
  1770. document.getElementById("bookingstatus_td").innerHTML = response.bookingStatus;
  1771. console.log("before comments user view history...");
  1772. console.log("Comments..." + response.comments);
  1773. if (response.bookingStatus === 'REJECTED' && response.comments) {
  1774. document.getElementById("rejectionreasondiv").style.display = "block";
  1775. const rejectionCell = document.getElementById("reasonforrejection");
  1776. rejectionCell.innerHTML = response.comments;
  1777. } else {
  1778. document.getElementById("rejectionreasondiv").style.display = "none";
  1779. document.getElementById("reasonforrejection").style.display = "none";
  1780. }
  1781. showReasonDocuments(response);
  1782. if (response.payments) {
  1783. document.getElementById("paymentsdetails").style.display = "block";
  1784. document.getElementById("td_transactionId").innerHTML = response.payments.transactionId;
  1785. document.getElementById("td_payamountReceived").innerHTML = response.payments.amountReceived;
  1786. document.getElementById("td_paymentStatus").innerHTML = response.payments.paymentStatus;
  1787. } else {
  1788. document.getElementById("paymentsdetails").style.display = "none";
  1789. }
  1790. if (response.ebDetails) {
  1791. document.getElementById("ebdetails").style.display = "block";
  1792. document.getElementById("td_EBNumber").innerHTML = response.hallDetails.ebNumber;
  1793. document.getElementById("td_startingReading").innerHTML = response.ebDetails.startingReading;
  1794. document.getElementById("td_endingReading").innerHTML = response.ebDetails.endingReading;
  1795. document.getElementById("td_usedunit").innerHTML = response.ebDetails.usedUnit;
  1796. document.getElementById("td_ebamountperunit").innerHTML = parseFloat(response.hallDetails.ebCostPerUnit).toFixed(2);
  1797. document.getElementById("td_electricityamount").innerHTML = parseFloat(response.ebDetails.ebAmount).toFixed(2);
  1798. } else {
  1799. document.getElementById("ebdetails").style.display = "none";
  1800. }
  1801. if (response.damageList && response.damageList.length > 0) {
  1802. document.getElementById("damagelist").style.display = "block";
  1803. } else {
  1804. document.getElementById("damagelist").style.display = "none";
  1805. }
  1806. if (response.settlement) {
  1807. document.getElementById("refunddetails").style.display = "block";
  1808. document.getElementById("td_depositeamountforrefund").innerHTML = parseFloat(response.depositAmount).toFixed(2);
  1809. document.getElementById("td_electricityamount").innerHTML = parseFloat(response.ebDetails.ebAmount).toFixed(2);
  1810. document.getElementById("td_ebAmount").innerHTML = parseFloat(response.ebDetails.ebAmount).toFixed(2);
  1811. document.getElementById("td_damage").innerHTML = parseFloat(response.settlement.damageAmount).toFixed(2);
  1812. var eb_amt = parseFloat(response.ebDetails.ebAmount).toFixed(2);
  1813. var deposit_amt = parseFloat(response.depositAmount).toFixed(2);
  1814. var tem_total = (deposit_amt - eb_amt).toFixed(2);
  1815. $("#td_settel_amt").html(tem_total);
  1816. } else {
  1817. document.getElementById("refunddetails").style.display = "none";
  1818. }
  1819. showDamageDetails(response);
  1820. if (response.bookingStatus === 'CANCELED' && ['WAITING', 'APPROVED', 'INITIATED'].includes(response.refundStatus)) {
  1821. document.getElementById("td_refundamount").innerHTML = `Your booking has been cancelled. Deposit amount of ₹ ${parseFloat(response.depositAmount).toFixed(2)} will be refund 3 to 15 Days`;
  1822. document.getElementById("refundamountDetails").style.display = "block";
  1823. document.getElementById("td_bookingStatus").innerHTML = response.bookingStatus;
  1824. document.getElementById("td_refundStatus").innerHTML = response.refundStatus;
  1825. } else if (response.bookingStatus === 'CANCELED' && response.refundStatus === 'COMPLETED') {
  1826. document.getElementById("td_refundamount").innerHTML = `Deposit amount of ₹ ${parseFloat(response.depositAmount).toFixed(2)} refunded successfully`;
  1827. document.getElementById("refundamountDetails").style.display = "block";
  1828. document.getElementById("td_bookingStatus").innerHTML = response.bookingStatus;
  1829. document.getElementById("td_refundStatus").innerHTML = response.refundStatus;
  1830. } else if (response.bookingStatus === 'REJECTED' && ['WAITING', 'APPROVED', 'INITIATED'].includes(response.refundStatus) && response.amountReceived == 0) {
  1831. document.getElementById("refundamountDetails").style.display = "none";
  1832. } else if (response.bookingStatus === 'REJECTED' && ['WAITING', 'APPROVED', 'INITIATED'].includes(response.refundStatus)) {
  1833. document.getElementById("td_refundamount").innerHTML = `Your booking has been Rejected by GCC. Full amount of ₹ ${parseFloat(response.amountReceived).toFixed(2)} will be refunded shortly`;
  1834. document.getElementById("refundamountDetails").style.display = "block";
  1835. document.getElementById("td_bookingStatus").innerHTML = response.bookingStatus;
  1836. document.getElementById("td_refundStatus").innerHTML = response.refundStatus;
  1837. } else if (response.bookingStatus === 'REJECTED' && response.refundStatus === 'COMPLETED') {
  1838. document.getElementById("td_refundamount").innerHTML = `Full amount of ₹${parseFloat(response.amountReceived).toFixed(2)} refunded successfully`;
  1839. document.getElementById("refundamountDetails").style.display = "block";
  1840. document.getElementById("td_bookingStatus").innerHTML = response.bookingStatus;
  1841. document.getElementById("td_refundStatus").innerHTML = response.refundStatus;
  1842. } else if (response.bookingStatus === 'REJECTED' && response.refundStatus === 'NA') {
  1843. document.getElementById("td_refundamount").innerHTML = `Your Booking has been rejected by GCC`;
  1844. document.getElementById("refundamountDetails").style.display = "block";
  1845. document.getElementById("td_bookingStatus").innerHTML = response.bookingStatus;
  1846. document.getElementById("td_refundStatus").innerHTML = response.refundStatus;
  1847. } else if (response.bookingStatus === 'GCC_BLOCKED' && ['WAITING', 'APPROVED', 'INITIATED'].includes(response.refundStatus)) {
  1848. document.getElementById("td_refundamount").innerHTML = `Your booking has been Blocked by GCC. Full amount of ₹ ${parseFloat(response.amountReceived).toFixed(2)} will be refunded shortly`;
  1849. document.getElementById("refundamountDetails").style.display = "block";
  1850. document.getElementById("td_bookingStatus").innerHTML = response.bookingStatus;
  1851. document.getElementById("td_refundStatus").innerHTML = response.refundStatus;
  1852. } else if (response.bookingStatus === 'GCC_BLOCKED' && response.refundStatus === 'COMPLETED') {
  1853. document.getElementById("td_refundamount").innerHTML = `Full amount of ₹${parseFloat(response.amountReceived).toFixed(2)} refunded successfully`;
  1854. document.getElementById("refundamountDetails").style.display = "block";
  1855. document.getElementById("td_bookingStatus").innerHTML = response.bookingStatus;
  1856. document.getElementById("td_refundStatus").innerHTML = response.refundStatus;
  1857. } /*else if(response.scheduleCount === 1){
  1858. document.getElementById("rescheduleDetails").style.display = "block";
  1859. document.getElementById("td_res_start_date").innerHTML = response.startDate;
  1860. document.getElementById("td_res_end_date").innerHTML = response.endDate;
  1861. document.getElementById("td_res_date").innerHTML = response.updatedDate;
  1862. }*/ else {
  1863. document.getElementById("refundamountDetails").style.display = "none";
  1864. }
  1865. // Show the modal
  1866. $('#showBookingDetails').modal('show');
  1867. },
  1868. error: function () {
  1869. console.error("An error occurred while fetching booking details.");
  1870. }
  1871. });
  1872. }
  1873. function showDamageDetails(data) {
  1874. var damageFieldContainer = $('#damageDetails');
  1875. damageFieldContainer.empty();
  1876. // Create a div for table responsiveness
  1877. var tableResponsiveDiv = $('<div>').addClass('table-responsive').css({
  1878. 'margin-top': '-19px',
  1879. 'margin-left': '19px'
  1880. });
  1881. ;
  1882. // Create table with similar classes and styles to the modal table
  1883. var table = $('<table>').addClass('table table-bordered table-striped').css({
  1884. 'width': '97%',
  1885. 'border-color': 'black',
  1886. 'border-top-color': 'white',
  1887. 'width': ' 730px'
  1888. });
  1889. var thead = $('<thead>').addClass('thead-light');
  1890. var tbody = $('<tbody>');
  1891. // Create Damage Details header row
  1892. var headerRow = $('<tr>').appendTo(thead);
  1893. $('<th>').attr('colspan', '6').text('Damage Details (if any)').css({
  1894. 'padding': '0.45rem 0.45rem',
  1895. 'background-color': 'lightgrey',
  1896. 'font-weight': 'bold',
  1897. 'color': 'black',
  1898. }).appendTo(headerRow);
  1899. // Create table header row
  1900. var columnHeadersRow = $('<tr>').css('background-color', 'white').appendTo(thead);
  1901. $('<th>').text('S.No').css('padding', '0.45rem 0.45rem').appendTo(columnHeadersRow);
  1902. $('<th>').text('Asset Name').css('padding', '0.45rem 0.45rem').appendTo(columnHeadersRow);
  1903. $('<th>').text('Damage Img').css('padding', '0.45rem 0.45rem').appendTo(columnHeadersRow);
  1904. $('<th>').text('Cost').css('padding', '0.45rem 0.45rem').appendTo(columnHeadersRow);
  1905. $('<th>').text('Qty').css('padding', '0.45rem 0.45rem').appendTo(columnHeadersRow);
  1906. $('<th>').text('Amount').css('padding', '0.45rem 0.45rem').appendTo(columnHeadersRow);
  1907. var totalAmount = 0;
  1908. $.each(data.damageList, function (index, detail) {
  1909. var row = $('<tr>').appendTo(tbody);
  1910. $('<td>').text(index + 1).css('padding', '0.45rem 0.45rem').appendTo(row);
  1911. $('<td>').text(detail.assetName).css('padding', '0.45rem 0.45rem').appendTo(row);
  1912. var viewLink = $('<a>').attr('href', 'javascript:void(0)').text('View').on('click', function () {
  1913. showDamageImage(detail.damageImageUrl);
  1914. });
  1915. var assetamt = (detail.assetAmount / detail.quantity).toFixed(2);
  1916. $('<td>').css('padding', '0.45rem 0.45rem').append(viewLink).appendTo(row);
  1917. $('<td>').text(assetamt).css('padding', '0.45rem 0.45rem').appendTo(row);
  1918. $('<td>').text(detail.quantity).css('padding', '0.45rem 0.45rem').appendTo(row);
  1919. var amount = detail.assetAmount;
  1920. totalAmount += amount;
  1921. $('<td>').text(amount.toFixed(2)).css('padding', '0.45rem 0.45rem').appendTo(row);
  1922. $("#td_dam_amt").html(totalAmount.toFixed(2));
  1923. });
  1924. // Add row for total amount
  1925. var totalRow = $('<tr>').appendTo(tbody);
  1926. $('<td>').attr('colspan', '5').text('Total Amount').css('padding', '0.45rem 0.45rem; font-weight: bold; background-color: #f2f2f2').appendTo(totalRow);
  1927. $('<td>').text(totalAmount.toFixed(2)).css('padding', '0.45rem 0.45rem').appendTo(totalRow);
  1928. // Append the table elements to the container div
  1929. table.append(thead, tbody);
  1930. tableResponsiveDiv.append(table);
  1931. damageFieldContainer.append(tableResponsiveDiv);
  1932. var temp_total = parseFloat($("#td_settel_amt").html());
  1933. var settleAmount = temp_total - totalAmount;
  1934. if (settleAmount < 0) {
  1935. var pendingstatus = data.settlement.collectionStatus
  1936. $("#td_settel_amt").html(0.00);
  1937. $("#pendingcolumn").show();
  1938. $("#collectionstatuscolumn").show();
  1939. $('#td_collection_status').html(pendingstatus);
  1940. $("#td_pending_amt").html(Math.abs(settleAmount).toFixed(2));
  1941. $("#td_pending_amt").css("color", "red");
  1942. } else {
  1943. $("#td_settel_amt").html(settleAmount.toFixed(2));
  1944. $("#pendingcolumn").hide();
  1945. $("#collectionstatuscolumn").hide();
  1946. $("#td_settel_amt").css("color", "green"); // Set color to green for positive amounts
  1947. }
  1948. }
  1949. function showDamageImage(damageImageUrl) {
  1950. document.getElementById('filePreview').src = damageImageUrl;
  1951. $('#fileModal').modal('show');
  1952. }
  1953. function showchallonimage(challanImgLink) {
  1954. document.getElementById('filePreview').src = challanImgLink;
  1955. $('#fileModal').modal('show');
  1956. }
  1957. function showReasonDocuments(list) {
  1958. $.ajax({
  1959. type: "GET",
  1960. url: '/communityhall/api/officer/getReasonByName',
  1961. data: {
  1962. 'reasonName': list.reason
  1963. },
  1964. success: function (x) {
  1965. showReasonWithDocument(x, list);
  1966. }
  1967. });
  1968. }
  1969. // Display booking documents
  1970. function showReasonWithDocument(reasonData, list) {
  1971. var reasonDocumentData = reasonData.reasonDocumentMasterList;
  1972. var bookingDocumentsList = list.bookingDocumentsList;
  1973. const reasonFieldsContainer = $('#documents');
  1974. reasonFieldsContainer.empty();
  1975. // Create a responsive table container
  1976. var tableResponsiveDiv = $('<div>').addClass('table-responsive').css({
  1977. 'width': '729px',
  1978. 'border': '1px solid black'
  1979. });
  1980. // Create the table with Bootstrap classes and custom styles
  1981. var table = $('<table>').addClass('table table-bordered table-striped table-vcenter js-dataTable-responsive').css({
  1982. 'width': '100%',
  1983. 'height': 'auto',
  1984. 'border': '1px solid black'
  1985. });
  1986. // Create the table header (thead)
  1987. var thead = $('<thead>').appendTo(table);
  1988. var headerRow = $('<tr>').appendTo(thead);
  1989. $('<th>').attr('colspan', '3').text('Document Details').css({
  1990. 'color': 'black',
  1991. 'background-color': 'lightgrey',
  1992. 'padding': '0.45rem 0.45rem'
  1993. }).appendTo(headerRow);
  1994. // Create header row for columns
  1995. var columnHeadersRow = $('<tr>').appendTo(thead);
  1996. $('<th>').text('S.No').appendTo(columnHeadersRow);
  1997. $('<th>').text('Required Info').appendTo(columnHeadersRow);
  1998. $('<th>').text('Required Documents').appendTo(columnHeadersRow);
  1999. // Create the table body (tbody)
  2000. var tbody = $('<tbody>').appendTo(table);
  2001. // Iterate through the documents list and populate rows
  2002. for (var i = 0; i < bookingDocumentsList.length; i++) {
  2003. (function (index) {
  2004. var row = $('<tr>').appendTo(tbody);
  2005. $('<td>').text(index + 1).appendTo(row);
  2006. // Determine the text content for the second cell
  2007. var name = bookingDocumentsList[index].name ? bookingDocumentsList[index].name : ''; // Empty string if name is null or undefined
  2008. var fieldText = reasonDocumentData[index].fieldName;
  2009. var fullText = name ? fieldText + ': ' + name : fieldText; // Include colon only if name is not empty
  2010. $('<td>').text(fullText).appendTo(row);
  2011. // Create a link to view document image
  2012. var viewLink = $('<a>').attr('href', 'javascript:void(0)').text(reasonDocumentData[index].docFieldName).on('click', function () {
  2013. showDocumentImage(bookingDocumentsList[index].bookingDocUrl);
  2014. });
  2015. $('<td>').append(viewLink).appendTo(row);
  2016. })(i);
  2017. }
  2018. // Append table to the responsive container
  2019. tableResponsiveDiv.append(table);
  2020. // Append table to the container in the DOM
  2021. reasonFieldsContainer.append(tableResponsiveDiv);
  2022. }
  2023. function showDocumentImage(fileURL) {
  2024. openFileModal(fileURL);
  2025. }
  2026. // Event delegation for dynamically added elements
  2027. $(document).on('click', '.view-document', function () {
  2028. const fileURL = $(this).data('url');
  2029. openFileModal(fileURL);
  2030. });
  2031. function openFileModal(fileURL) {
  2032. $('#filePreview').attr('src', fileURL);
  2033. $('#fileModal').modal('show');
  2034. }
  2035. // For OTP input box
  2036. $('.otp-input').on('keyup', function (e) {
  2037. var $this = $(this);
  2038. if ($this.val().length === 1) {
  2039. $this.next('.otp-input').focus();
  2040. }
  2041. if ($this.val().length === 0) {
  2042. $this.prev('.otp-input').focus();
  2043. }
  2044. });
  2045. function cancelBooking(bookingId, mobileNo, bookingType) {
  2046. var mobileNum = mobileNo;
  2047. var bookingId = bookingId;
  2048. // Check if the booking type is OFFLINE
  2049. if (bookingType === "OFFLINE") {
  2050. Swal.fire({
  2051. title: 'Cancellation Not Available',
  2052. text: 'Cancellation is not available for offline bookings.',
  2053. icon: 'error'
  2054. });
  2055. } else {
  2056. Swal.fire({
  2057. title: 'Are you sure?',
  2058. text: 'Once canceled, this action can\'t be undo. Only the deposit Amount will be refunded within 3 to 15 days.',
  2059. icon: 'warning',
  2060. showCancelButton: true,
  2061. confirmButtonColor: '#3085d6',
  2062. cancelButtonColor: '#d33',
  2063. confirmButtonText: 'Yes, cancel it!',
  2064. cancelButtonText: 'Close',
  2065. }).then((result) => {
  2066. if (result.isConfirmed) {
  2067. // If user confirms, show OTP form
  2068. mobileNumberForCancel = mobileNum;
  2069. cancelBookingId = bookingId;
  2070. cancelBookingLogin = true;
  2071. sendOTP(mobileNum);
  2072. }
  2073. });
  2074. }
  2075. }
  2076. function resetRescheduleOTPSection() {
  2077. // Hide OTP section
  2078. var otpSection = document.getElementById("otpSection");
  2079. if (otpSection) {
  2080. otpSection.style.display = "none";
  2081. }
  2082. // Show reschedule button and hide verify button
  2083. var rescheduleBtn = document.getElementById("rescheduleBtn");
  2084. var verifyOtpBtn = document.getElementById("verifyOtpBtn");
  2085. if (rescheduleBtn) {
  2086. rescheduleBtn.style.display = "inline-block";
  2087. }
  2088. if (verifyOtpBtn) {
  2089. verifyOtpBtn.style.display = "none";
  2090. }
  2091. // Clear OTP input fields
  2092. for (let i = 1; i <= 6; i++) {
  2093. var otpField = document.getElementById("otp" + i);
  2094. if (otpField) {
  2095. otpField.value = "";
  2096. }
  2097. }
  2098. // Reset variables
  2099. rescheduleBookingId = null;
  2100. rescheduleStartDate = null;
  2101. rescheduleEndDate = null;
  2102. rescheduleMobileNumber = null;
  2103. rescheduleHallId = null;
  2104. rescheduleStartingSlot = null;
  2105. rescheduleEndingSlot = null;
  2106. rescheduleReason = null;
  2107. }
  2108. function openRescheduleModal(bookingId, startDate, endDate, noOfDays, hallId, startingSlot, endingSlot, reason) {
  2109. // Function to map slot values to their text representation
  2110. function getSlotText(slot) {
  2111. return slot === 1 ? 'Morning' : 'Evening';
  2112. }
  2113. // Populate modal inputs
  2114. const start = new Date(startDate);
  2115. const end = new Date(endDate);
  2116. const timeDiff = end - start;
  2117. // Convert time difference from milliseconds to days
  2118. const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)) + 1;
  2119. // Set values for inputs
  2120. document.getElementById("bookingId").value = bookingId;
  2121. document.getElementById("startDateInput").value = startDate;
  2122. document.getElementById("endDateInput").value = endDate;
  2123. document.getElementById("noOfDaysInput").value = noOfDays;
  2124. document.getElementById("startingSlot").value = startingSlot;
  2125. document.getElementById("endingSlot").value = endingSlot;
  2126. document.getElementById("daysDiff").value = daysDiff;
  2127. // Display slot text in the modal
  2128. document.getElementById("startDatetext").value = startDate;
  2129. document.getElementById("startingSlotText").value = getSlotText(startingSlot);
  2130. document.getElementById("endingSlotText").value = getSlotText(endingSlot);
  2131. // Store booking details for OTP verification
  2132. rescheduleBookingId = bookingId;
  2133. rescheduleStartDate = startDate;
  2134. rescheduleEndDate = endDate;
  2135. rescheduleHallId = hallId;
  2136. rescheduleStartingSlot = startingSlot;
  2137. rescheduleEndingSlot = endingSlot;
  2138. rescheduleReason = reason;
  2139. // Optionally, fetch and update calendar or availability based on hallId
  2140. getBookingCalendar(hallId, reason);
  2141. // Show the date change modal
  2142. $('#bookingRescheduleModal').modal('show');
  2143. }
  2144. function getBookingCalendar(hall_id, reason) {
  2145. // Make an AJAX call to fetch booking data
  2146. $.ajax({
  2147. type: 'GET',
  2148. url: '/communityhall/user/api/getPastData',
  2149. data: {
  2150. hall_id: hall_id
  2151. },
  2152. success: function (response) {
  2153. window.bookingResponse = {};
  2154. if (response && Array.isArray(response)) {
  2155. $("#startDateInput").datepicker("destroy");
  2156. for (var i = 0; i < response.length; i++) {
  2157. var dateString = datepickerFormat(response[i].bdate);
  2158. window.bookingResponse[dateString] = [response[i].morningSlot, response[i].eveningSlot];
  2159. }
  2160. initializeDatepickerWithColors(hall_id, reason);
  2161. if (response.length == 0) {
  2162. initializeDatepickerWithColors(hall_id, reason);
  2163. }
  2164. } else {
  2165. console.error('Invalid or empty response data.');
  2166. }
  2167. },
  2168. error: function (xhr, status, error) {
  2169. console.error('Error fetching hall details:', error);
  2170. }
  2171. });
  2172. }
  2173. function initializeDatepickerWithColors(hallId, reason) { // Confirm hallId is passed here
  2174. $("#datepicker-container").datepicker("destroy");
  2175. const serverDate = new Date($("#serverDate").val() + "T00:00:00")
  2176. // console.log(" view history Date:", serverDate);
  2177. const maxDate = new Date(serverDate);
  2178. maxDate.setMonth(maxDate.getMonth() + 6);
  2179. // console.log("View History: "+maxDate);
  2180. $("#startDateInput,#datepicker-container").datepicker({
  2181. dateFormat: "yy-mm-dd",
  2182. minDate: serverDate,
  2183. maxDate: maxDate,
  2184. beforeShowDay: function (eDate) {
  2185. const dateString = $.datepicker.formatDate("yy-mm-dd", eDate);
  2186. const bookingStatus = window.bookingResponse[dateString] || {};
  2187. // const currentDate = new Date();
  2188. serverDate.setHours(0, 0, 0, 0); // Normalize current date to midnight
  2189. eDate.setHours(0, 0, 0, 0); // Normalize selected date to midnight
  2190. // Logic for other dates
  2191. if (eDate < serverDate) {
  2192. return [false, "highlight-disabled", "Slot not Available"];
  2193. }
  2194. const isToday = eDate.getTime() === serverDate.getTime();
  2195. const currentHour = new Date().getHours();
  2196. const isBefore6AM = currentHour < 6;
  2197. const isAfter2PM = currentHour >= 14;
  2198. // Block 3-day logic for specific event types
  2199. // const today = new Date();
  2200. const blockedDate = new Date(serverDate);
  2201. blockedDate.setDate(serverDate.getDate() + 2);
  2202. const isThreeDayBlock = ["Commercial", "State Govt Event", "Central Govt Event"].includes(reason);
  2203. if (eDate <= blockedDate && isThreeDayBlock) {
  2204. return [false, "highlight-disabled", "Blocked due to event type"];
  2205. }
  2206. // Logic for currentdate
  2207. if (isToday) {
  2208. if (isBefore6AM) {
  2209. // Before 6 AM: Allow full-day booking or adjust based on booking status
  2210. return handleBookingStatus(bookingStatus, "Full Day Available");
  2211. } else if (isAfter2PM) {
  2212. // After 2 PM: Block all bookings
  2213. return handleAfter2PM(bookingStatus);
  2214. } else {
  2215. // Between 6 AM and 2 PM: Check status and disable morning slots
  2216. return handleMorningSlots(bookingStatus);
  2217. }
  2218. }
  2219. return handleBookingStatus(bookingStatus, "Slot Available");
  2220. },
  2221. });
  2222. $("#startDateInput").on("change", function () {
  2223. var selectedDate = $(this).val();
  2224. var noOfDays = document.getElementById('noOfDaysInput').value;
  2225. var startingSlot = document.getElementById("startingSlot").value;
  2226. var endingSlot = document.getElementById("endingSlot").value;
  2227. var noofdays = document.getElementById("noOfDaysInput").value;
  2228. updateEndDate(selectedDate, noofdays, startingSlot, endingSlot);
  2229. });
  2230. }
  2231. function handleBookingStatus(bookingStatus, defaultMessage) {
  2232. if (bookingStatus[2]) {
  2233. return [true, "highlight-blue disabled", "GCC Blocked"];
  2234. } /*else if (bookingStatus[3]) {
  2235. return [true, "highlight-lightpink disabled", "Temporary Blocked"];
  2236. }*/ else if (bookingStatus[0] && bookingStatus[1]) {
  2237. return [true, "highlight-pink disabled", "Slot Occupied"];
  2238. } else if (bookingStatus[0] && !bookingStatus[1]) {
  2239. return [true, "highlight-yellow", "Evening Slot Available"];
  2240. } else if (!bookingStatus[0] && bookingStatus[1]) {
  2241. return [true, "highlight-violet", "Only Morning Slot Available"];
  2242. }
  2243. return [true, "highlight-greens", defaultMessage];
  2244. }
  2245. // Helper function: Handles logic after 2 PM
  2246. function handleAfter2PM(bookingStatus) {
  2247. if (bookingStatus[2]) {
  2248. return [true, "highlight-blue disabled", "GCC Blocked"];
  2249. } else if (bookingStatus[0] || bookingStatus[1]) {
  2250. return [true, "highlight-pink disabled", "Slot Occupied"];
  2251. }
  2252. return [false, "highlight-disabled", "Not Allowed to Book"];
  2253. }
  2254. // Helper function: Handles morning slots between 6 AM and 2 PM
  2255. function handleMorningSlots(bookingStatus) {
  2256. if (bookingStatus[2]) {
  2257. return [true, "highlight-blue disabled", "GCC Blocked"];
  2258. } else if (bookingStatus[0] && bookingStatus[1]) {
  2259. return [true, "highlight-pink disabled", "Slot Occupied"];
  2260. } else if (bookingStatus[0] && !bookingStatus[1]) {
  2261. return [true, "highlight-yellow", "Evening Slot Available"];
  2262. } else if (!bookingStatus[0] && bookingStatus[1]) {
  2263. return [false, "highlight-disabled", "Slot Occupied"];
  2264. }
  2265. return [true, "highlight-yellow", "Evening Slot Available"];
  2266. Swal.fire({
  2267. title: 'Morning Slot Not Available',
  2268. text: 'The Morning slot is not available for the selected date range.',
  2269. icon: 'warning',
  2270. confirmButtonText: 'OK'
  2271. });
  2272. document.getElementById('endDateInput').value = "";
  2273. }
  2274. function updateEndDate(startDate, noofdays, startingSlot, endingSlot) {
  2275. if (startDate && noofdays !== undefined) {
  2276. var start = new Date(startDate);
  2277. var startFormatted = start.toISOString().split('T')[0];
  2278. var bookingStatus = window.bookingResponse[startFormatted] || [false, false];
  2279. var morningAvailable = !bookingStatus[0]; // false means available
  2280. var eveningAvailable = !bookingStatus[1]; // false means available
  2281. var endDate;
  2282. var isValid = true; // Flag to determine if all slots are available
  2283. // Convert noofdays to a number for accurate calculations
  2284. noofdays = parseFloat(noofdays);
  2285. // Handle slot availability and combinations
  2286. if (startingSlot === "2" && endingSlot === "2") { // Evening to Evening
  2287. //console.log("Handling Evening to Evening slot.");
  2288. if (noofdays === 0.5) {
  2289. if (eveningAvailable) {
  2290. endDate = new Date(start);
  2291. endDate.setDate(start.getDate() + Math.ceil(noofdays) - 1);
  2292. endDate = endDate.toISOString().split('T')[0];
  2293. document.getElementById('endDateInput').value = endDate;
  2294. //console.log("End Date (Evening to Evening):", endDate);
  2295. } else {
  2296. Swal.fire({
  2297. title: 'Evening Slot Not Available',
  2298. text: 'The evening slot is not available for the selected date range.',
  2299. icon: 'warning',
  2300. confirmButtonText: 'OK'
  2301. });
  2302. document.getElementById('endDateInput').value = "";
  2303. //console.log("Evening slot not available for", noofdays, "days.");
  2304. }
  2305. } else if (noofdays === 1.5) {
  2306. // Special handling for 2 days
  2307. let endDateCandidate = new Date(start);
  2308. endDateCandidate.setDate(start.getDate() + 1);
  2309. let endDateFormattedCandidate = endDateCandidate.toISOString().split('T')[0];
  2310. let endDateStatusCandidate = window.bookingResponse[endDateFormattedCandidate] || [false, false];
  2311. let morningAvailableOnEndDate = !endDateStatusCandidate[0]; // false means available
  2312. let eveningAvailableOnEndDate = !endDateStatusCandidate[1]; // false means available
  2313. if (eveningAvailable && morningAvailableOnEndDate && eveningAvailableOnEndDate) {
  2314. endDate = endDateCandidate.toISOString().split('T')[0];
  2315. document.getElementById('endDateInput').value = endDate;
  2316. //console.log("End Date (Morning to Evening with 2 days):", endDate);
  2317. } else {
  2318. Swal.fire({
  2319. title: 'Slot Not Available',
  2320. text: 'The Morning slots are not available for the selected date range.',
  2321. icon: 'warning',
  2322. confirmButtonText: 'OK'
  2323. });
  2324. document.getElementById('endDateInput').value = "";
  2325. //console.log("Morning or Evening slot not available for 2 days.");
  2326. }
  2327. } else {
  2328. //console.log("Unsupported duration for Evening to Evening slot.");
  2329. Swal.fire({
  2330. title: 'Invalid Selection',
  2331. text: 'The selected duration for the evening slot is not supported.',
  2332. icon: 'error',
  2333. confirmButtonText: 'OK'
  2334. });
  2335. document.getElementById('endDateInput').value = "";
  2336. }
  2337. } else if (startingSlot === "1" && endingSlot === "1") { // Morning to Morning
  2338. //console.log("Handling Morning to Morning slot.");
  2339. if (noofdays === 0.5) {
  2340. if (morningAvailable) {
  2341. endDate = new Date(start);
  2342. endDate.setDate(start.getDate() + Math.ceil(noofdays) - 1);
  2343. endDate = endDate.toISOString().split('T')[0];
  2344. document.getElementById('endDateInput').value = endDate;
  2345. //console.log("End Date (morning to morning):", endDate);
  2346. } else {
  2347. Swal.fire({
  2348. title: 'Morning Slot Not Available',
  2349. text: 'The Morning slot is not available for the selected date range.',
  2350. icon: 'warning',
  2351. confirmButtonText: 'OK'
  2352. });
  2353. document.getElementById('endDateInput').value = "";
  2354. //console.log("Evening slot not available for", noofdays, "days.");
  2355. }
  2356. } else if (noofdays === 1.5) {
  2357. // Special handling for 2 days
  2358. let endDateCandidate = new Date(start);
  2359. endDateCandidate.setDate(start.getDate() + 1);
  2360. let endDateFormattedCandidate = endDateCandidate.toISOString().split('T')[0];
  2361. let endDateStatusCandidate = window.bookingResponse[endDateFormattedCandidate] || [false, false];
  2362. let morningAvailableOnEndDate = !endDateStatusCandidate[0]; // false means available
  2363. let eveningAvailableOnEndDate = !endDateStatusCandidate[1]; // false means available
  2364. if (morningAvailable && eveningAvailable && morningAvailableOnEndDate) {
  2365. endDate = endDateCandidate.toISOString().split('T')[0];
  2366. document.getElementById('endDateInput').value = endDate;
  2367. //console.log("End Date (Morning to Evening with 2 days):", endDate);
  2368. } else {
  2369. Swal.fire({
  2370. title: 'Slot Not Available',
  2371. text: 'The evening slots are not available for the selected date range.',
  2372. icon: 'warning',
  2373. confirmButtonText: 'OK'
  2374. });
  2375. document.getElementById('endDateInput').value = "";
  2376. //console.log("Morning or Evening slot not available for 2 days.");
  2377. }
  2378. } else {
  2379. //console.log("Unsupported duration for Morning to Morning slot.");
  2380. Swal.fire({
  2381. title: 'Invalid Selection',
  2382. text: 'The selected duration for the morning slot is not supported.',
  2383. icon: 'error',
  2384. confirmButtonText: 'OK'
  2385. });
  2386. document.getElementById('endDateInput').value = "";
  2387. }
  2388. } else if (startingSlot === "1" && endingSlot === "2") { // Morning to Evening
  2389. //console.log("Handling Morning to Evening slot.");
  2390. if (noofdays === 1) {
  2391. if (morningAvailable && eveningAvailable) {
  2392. endDate = new Date(start);
  2393. endDate.setDate(start.getDate() + Math.ceil(noofdays) - 1);
  2394. endDate = endDate.toISOString().split('T')[0];
  2395. document.getElementById('endDateInput').value = endDate;
  2396. //console.log("End Date (Morning to Evening):", endDate);
  2397. } else {
  2398. Swal.fire({
  2399. title: ' Slot Not Available',
  2400. text: 'The Selected slot is not available for the selected date range.',
  2401. icon: 'warning',
  2402. confirmButtonText: 'OK'
  2403. });
  2404. document.getElementById('endDateInput').value = "";
  2405. //console.log("Evening slot not available for", noofdays, "days.");
  2406. }
  2407. } else if (noofdays === 2) {
  2408. // Special handling for 2 days
  2409. let endDateCandidate = new Date(start);
  2410. endDateCandidate.setDate(start.getDate() + 1);
  2411. let endDateFormattedCandidate = endDateCandidate.toISOString().split('T')[0];
  2412. let endDateStatusCandidate = window.bookingResponse[endDateFormattedCandidate] || [false, false];
  2413. let morningAvailableOnEndDate = !endDateStatusCandidate[0]; // false means available
  2414. let eveningAvailableOnEndDate = !endDateStatusCandidate[1]; // false means available
  2415. if (morningAvailable && eveningAvailable && morningAvailableOnEndDate && eveningAvailableOnEndDate) {
  2416. endDate = endDateCandidate.toISOString().split('T')[0];
  2417. document.getElementById('endDateInput').value = endDate;
  2418. //console.log("End Date (Morning to Evening with 2 days):", endDate);
  2419. } else {
  2420. Swal.fire({
  2421. title: 'Slot Not Available',
  2422. text: 'The morning and/or evening slots are not available for the selected date range.',
  2423. icon: 'warning',
  2424. confirmButtonText: 'OK'
  2425. });
  2426. document.getElementById('endDateInput').value = "";
  2427. //console.log("Morning or Evening slot not available for 2 days.");
  2428. }
  2429. } else {
  2430. //console.log("Unsupported duration for Morning to Evening slot.");
  2431. Swal.fire({
  2432. title: 'Invalid Selection',
  2433. text: 'The selected duration for the morning to evening slot is not supported.',
  2434. icon: 'error',
  2435. confirmButtonText: 'OK'
  2436. });
  2437. document.getElementById('endDateInput').value = "";
  2438. }
  2439. } else if (startingSlot === "2" && endingSlot === "1") { // Evening to Morning
  2440. //console.log("Handling Evening to Morning slot.");
  2441. if (noofdays === 1) {
  2442. if (eveningAvailable) { // Check if evening slot is available
  2443. let nextDay = new Date(start);
  2444. nextDay.setDate(start.getDate() + 1);
  2445. let nextDayFormatted = nextDay.toISOString().split('T')[0];
  2446. let nextDayStatus = window.bookingResponse[nextDayFormatted] || [false, false];
  2447. let nextDayMorningAvailable = !nextDayStatus[0]; // false means available
  2448. if (nextDayMorningAvailable) {
  2449. endDate = nextDay.toISOString().split('T')[0];
  2450. document.getElementById('endDateInput').value = endDate;
  2451. //console.log("End Date (Evening to Morning):", endDate);
  2452. } else {
  2453. Swal.fire({
  2454. title: 'Morning Slot Not Available',
  2455. text: 'The morning slot is not available for the next day.',
  2456. icon: 'warning',
  2457. confirmButtonText: 'OK'
  2458. });
  2459. document.getElementById('endDateInput').value = "";
  2460. //console.log("Morning slot not available for the next day.");
  2461. }
  2462. } else {
  2463. Swal.fire({
  2464. title: 'Evening Slot Not Available',
  2465. text: 'The evening slot is not available for the selected date.',
  2466. icon: 'warning',
  2467. confirmButtonText: 'OK'
  2468. });
  2469. document.getElementById('endDateInput').value = "";
  2470. //console.log("Evening slot not available for", startDate);
  2471. }
  2472. } else {
  2473. //console.log("Unsupported duration for Evening to Morning slot.");
  2474. Swal.fire({
  2475. title: 'Invalid Selection',
  2476. text: 'The selected duration for the evening to morning slot is not supported.',
  2477. icon: 'error',
  2478. confirmButtonText: 'OK'
  2479. });
  2480. document.getElementById('endDateInput').value = "";
  2481. }
  2482. } else {
  2483. //console.log("Unsupported slot combination or duration.");
  2484. Swal.fire({
  2485. title: 'Invalid Slot Combination',
  2486. text: 'The selected slot combination or duration is not supported.',
  2487. icon: 'error',
  2488. confirmButtonText: 'OK'
  2489. });
  2490. document.getElementById('endDateInput').value = "";
  2491. }
  2492. } else {
  2493. //console.log("Start Date or Number of Days not provided.");
  2494. Swal.fire({
  2495. title: 'Invalid Input',
  2496. text: 'Please provide a valid start date and number of days.',
  2497. icon: 'error',
  2498. confirmButtonText: 'OK'
  2499. });
  2500. document.getElementById('endDateInput').value = "";
  2501. }
  2502. }
  2503. function datepickerFormat(dateString) {
  2504. var dateObject = new Date(dateString);
  2505. var year = dateObject.getFullYear();
  2506. var month = (dateObject.getMonth() + 1).toString().padStart(2, "0");
  2507. var day = dateObject.getDate().toString().padStart(2, "0");
  2508. return `${year}-${month}-${day}`;
  2509. }
  2510. function printTables() {
  2511. // Get the printable content
  2512. var printableContent = document.getElementById('printableContent').innerHTML;
  2513. // Open a print window
  2514. var printWindow = window.open('', '', 'height=400,width=600');
  2515. // Write the printable content to the print window
  2516. printWindow.document.write('<html><head><title>Print</title></head><body>' + printableContent + '</body></html>');
  2517. // Close the print window after printing
  2518. printWindow.document.close();
  2519. printWindow.print();
  2520. printWindow.close();
  2521. }
  2522. function Reschedule() {
  2523. // Get mobile number and show OTP modal for verification
  2524. $.ajax({
  2525. type: "GET",
  2526. url: '/communityhall/user/api/viewAllBookingDetails',
  2527. data: { bookingId: rescheduleBookingId },
  2528. success: function (response) {
  2529. rescheduleMobileNumber = response.users.mobileNo;
  2530. // Show mobile number in OTP modal
  2531. document.getElementById("rescheduleMobileTxt").textContent = rescheduleMobileNumber;
  2532. // Clear any previous OTP errors
  2533. document.getElementById("rescheduleOtpError").textContent = "";
  2534. // Clear OTP inputs
  2535. for (let i = 1; i <= 5; i++) {
  2536. document.getElementById("rescheduleOtp" + i).value = "";
  2537. }
  2538. // Close date change modal and show OTP modal
  2539. $('#bookingRescheduleModal').modal('hide');
  2540. $('#rescheduleOtpModal').modal('show');
  2541. // Send OTP immediately
  2542. sendRescheduleOTP(rescheduleMobileNumber);
  2543. },
  2544. error: function () {
  2545. Swal.fire({
  2546. icon: 'error',
  2547. title: 'Error',
  2548. text: 'Failed to get booking details. Please try again.',
  2549. showConfirmButton: true
  2550. });
  2551. }
  2552. });
  2553. }
  2554. function sendRescheduleOTP(mobileNumber) {
  2555. $.ajax({
  2556. type: "GET",
  2557. url: "/communityhall/user/api/sendOTP",
  2558. data: {
  2559. mobileNo: mobileNumber,
  2560. purpose: "reschedule"
  2561. },
  2562. success: function (response) {
  2563. // Start countdown timer
  2564. startRescheduleCountdown();
  2565. },
  2566. error: function () {
  2567. Swal.fire({
  2568. icon: 'error',
  2569. title: 'Error',
  2570. text: 'Failed to send OTP. Please try again.',
  2571. showConfirmButton: true
  2572. });
  2573. }
  2574. });
  2575. }
  2576. function startRescheduleCountdown() {
  2577. var resendTimeout;
  2578. var resendLink = $("#rescheduleResendLink");
  2579. $("#rescheduleResendLink").html('Please wait..<span id="rescheduleCountdown">60</span>s');
  2580. var countdown = $("#rescheduleCountdown");
  2581. function startCountdown() {
  2582. var timeleft = 60;
  2583. countdown.text(timeleft);
  2584. resendTimeout = setInterval(function () {
  2585. timeleft--;
  2586. countdown.text(timeleft);
  2587. if (timeleft <= 0) {
  2588. clearInterval(resendTimeout);
  2589. $("#rescheduleResendLink").html('<a href="#" id="rescheduleResendLink" class="text-info" onclick="return sendRescheduleOTP(' + rescheduleMobileNumber + ');">Resend OTP</a>');
  2590. }
  2591. }, 1000);
  2592. }
  2593. startCountdown();
  2594. }
  2595. function resendRescheduleOTP() {
  2596. if (rescheduleMobileNumber) {
  2597. sendRescheduleOTP(rescheduleMobileNumber);
  2598. }
  2599. }
  2600. function verifyRescheduleOtp() {
  2601. // Get all the input fields with class `otp-input`
  2602. var otpInputs = $('.otp-input');
  2603. // Get the OTP value as a string
  2604. var otpValue = '';
  2605. otpInputs.each(function () {
  2606. otpValue += $(this).val();
  2607. });
  2608. if (otpValue.length !== 5) {
  2609. document.getElementById("rescheduleOtpError").textContent = "Please enter complete OTP";
  2610. return false;
  2611. }
  2612. // Verify OTP
  2613. $.ajax({
  2614. type: "GET",
  2615. url: "/communityhall/user/api/verifyofficialOTP",
  2616. data: {
  2617. otp: otpValue
  2618. },
  2619. dataType: 'text',
  2620. success: function (response) {
  2621. if (response.trim() === "Success") {
  2622. // OTP verified successfully, close OTP modal and proceed with reschedule
  2623. $('#rescheduleOtpModal').modal('hide');
  2624. validateDatesAndReschedule();
  2625. } else {
  2626. document.getElementById("rescheduleOtpError").textContent = "OTP is Incorrect!!!";
  2627. // Clear OTP inputs
  2628. for (let i = 1; i <= 5; i++) {
  2629. document.getElementById("rescheduleOtp" + i).value = "";
  2630. }
  2631. }
  2632. },
  2633. error: function () {
  2634. document.getElementById("rescheduleOtpError").textContent = "Error verifying OTP. Please try again.";
  2635. }
  2636. });
  2637. return false;
  2638. }
  2639. function proceedWithReschedule() {
  2640. // Debug: Log the data being sent
  2641. console.log('Reschedule data:', {
  2642. bookingId: rescheduleBookingId,
  2643. startDate: rescheduleStartDate,
  2644. endDate: rescheduleEndDate
  2645. });
  2646. $.ajax({
  2647. type: "POST",
  2648. url: "/communityhall/user/api/reschedule-dates",
  2649. data: {
  2650. bookingId: rescheduleBookingId,
  2651. startDate: rescheduleStartDate,
  2652. endDate: rescheduleEndDate
  2653. },
  2654. success: function (response) {
  2655. Swal.fire({
  2656. icon: 'success',
  2657. title: 'Success',
  2658. text: 'Booking rescheduled successfully!',
  2659. showConfirmButton: true
  2660. }).then((result) => {
  2661. if (result.isConfirmed) {
  2662. // Close modal and reload page
  2663. $('#bookingRescheduleModal').modal('hide');
  2664. location.reload();
  2665. }
  2666. });
  2667. },
  2668. error: function (xhr, status, error) {
  2669. console.error('Reschedule API Error:', {
  2670. status: xhr.status,
  2671. statusText: xhr.statusText,
  2672. responseText: xhr.responseText,
  2673. error: error
  2674. });
  2675. let errorMessage = 'Failed to reschedule booking. Please try again.';
  2676. if (xhr.responseText) {
  2677. try {
  2678. const errorData = JSON.parse(xhr.responseText);
  2679. errorMessage = errorData.message || errorData.error || errorMessage;
  2680. } catch (e) {
  2681. errorMessage = xhr.responseText || errorMessage;
  2682. }
  2683. }
  2684. Swal.fire({
  2685. icon: 'error',
  2686. title: 'Error',
  2687. text: errorMessage,
  2688. showConfirmButton: true
  2689. });
  2690. }
  2691. });
  2692. }
  2693. function validateDatesAndReschedule() {
  2694. // Retrieve values from modal inputs
  2695. var startDate = document.getElementById("startDateInput").value;
  2696. var endDate = document.getElementById("endDateInput").value;
  2697. var originalStartDate = document.getElementById("startDatetext").value;
  2698. // Debug: Log the retrieved dates
  2699. console.log('Retrieved dates:', {
  2700. startDate: startDate,
  2701. endDate: endDate,
  2702. originalStartDate: originalStartDate
  2703. });
  2704. // Check if the rescheduled start date is the same as the original booked start date
  2705. if (startDate === originalStartDate) {
  2706. Swal.fire({
  2707. icon: 'warning',
  2708. title: 'Warning',
  2709. text: 'Your Rescheduled Start Date is the same as Your booking Start Date. Please change the date.',
  2710. showConfirmButton: true
  2711. });
  2712. return;
  2713. }
  2714. if (!endDate) {
  2715. Swal.fire({
  2716. icon: 'error',
  2717. title: 'Error',
  2718. text: 'End Date is Empty! Please check your Start Date',
  2719. showConfirmButton: true
  2720. });
  2721. return;
  2722. }
  2723. // Store the validated dates
  2724. rescheduleStartDate = startDate;
  2725. rescheduleEndDate = endDate;
  2726. // Debug: Log the final dates being sent
  2727. console.log('Final reschedule dates:', {
  2728. startDate: rescheduleStartDate,
  2729. endDate: rescheduleEndDate,
  2730. bookingId: rescheduleBookingId
  2731. });
  2732. // Proceed with reschedule
  2733. proceedWithReschedule();
  2734. }
  2735. $(document).ready(function () {
  2736. // DataTables buttons configuration
  2737. var buttons = [
  2738. {
  2739. extend: 'pageLength',
  2740. className: 'btn btn-primary'
  2741. }
  2742. ];
  2743. $('#simpletable').DataTable({
  2744. dom: 'Bftip',
  2745. columnDefs: [
  2746. { targets: 'no-sort', orderable: false }
  2747. ],
  2748. lengthMenu: [
  2749. [5, 10, 20, 50, -1],
  2750. ['5 rows', '10 rows', '20 rows', '50 rows', 'Show all']
  2751. ],
  2752. scrollY: '50vh',
  2753. fixedColumns: {
  2754. left: 1,
  2755. right: 1
  2756. },
  2757. buttons: [buttons],
  2758. responsive: true,
  2759. searching: true, // Enable search
  2760. select: false,
  2761. processing: false,
  2762. });
  2763. $('#searchInput').on('keyup', function () {
  2764. dataTable.search(this.value).draw();
  2765. });
  2766. });
  2767. $(document).on('change', '.nocfile', function () {
  2768. validateFile(this);
  2769. });
  2770. function transactionHistory(userId) {
  2771. $.ajax({
  2772. type: "GET",
  2773. url: '/communityhall/user/api/getTransactionDetails',
  2774. data: { 'userId': userId },
  2775. success: function (data) {
  2776. // console.log("Full response:", data);
  2777. // console.log("Refund Details:", data.refundDetails);
  2778. const transactions = data.transactions || [];
  2779. const refundDetails = data.refundDetails || [];
  2780. populateTransactionTable(transactions);
  2781. populateRefundDetailsTable(refundDetails);
  2782. $('#transactionHistoryModal').modal('show'); // Show the modal
  2783. },
  2784. error: function (error) {
  2785. console.error("Error fetching transaction details", error);
  2786. }
  2787. });
  2788. }
  2789. function populateTransactionTable(transactions) {
  2790. const tableBody = $('#transactionTable tbody');
  2791. tableBody.empty(); // Clear any existing rows
  2792. transactions.forEach((transaction, index) => {
  2793. const paymentStatus = (transaction.statusCode === "0300" && transaction.response?.includes("success"))
  2794. ? "Success"
  2795. : "Payment Failed";
  2796. const row = `
  2797. <tr>
  2798. <td>${index + 1}</td>
  2799. <td>${transaction.bookingId}</td>
  2800. <td>${transaction.amount || '-'}</td>
  2801. <td>${transaction.date || '-'}</td>
  2802. <td>${transaction.txansactionId || '-'}</td>
  2803. <td>${paymentStatus}</td>
  2804. </tr>
  2805. `;
  2806. tableBody.append(row); // Append the row to the table body
  2807. });
  2808. }
  2809. function populateRefundDetailsTable(refundDetails) {
  2810. const refundTable = $('#refunddetails');
  2811. const tableBody = $('#refunddetailsTable tbody');
  2812. tableBody.empty(); // Clear any existing rows
  2813. if (refundDetails.length > 0) {
  2814. refundTable.show(); // Show the refund details table
  2815. refundDetails.forEach((refund, index) => {
  2816. const row = `
  2817. <tr>
  2818. <td>${index + 1}</td>
  2819. <td>${refund.bookingId}</td>
  2820. <td>${refund.amount}</td>
  2821. <td>${refund.date}</td>
  2822. <td>${refund.txansactionId}</td>
  2823. <td>${refund.refundAmount}</td>
  2824. </tr>
  2825. `;
  2826. tableBody.append(row);
  2827. });
  2828. } else {
  2829. refundTable.hide(); // Hide the refund details table
  2830. }
  2831. }
  2832. // Toggle Chat Box
  2833. function toggleChat() {
  2834. const chatBox = document.getElementById('chat-box');
  2835. chatBox.style.display = (chatBox.style.display === 'block') ? 'none' : 'block';
  2836. }
  2837. // Send Message
  2838. function sendMessage() {
  2839. const userInput = document.getElementById('userInput');
  2840. const message = userInput.value.trim();
  2841. if (message) {
  2842. // Create message element
  2843. const chatBody = document.getElementById('chat-body');
  2844. const userMessage = document.createElement('div');
  2845. userMessage.className = 'user-message';
  2846. userMessage.textContent = message;
  2847. chatBody.appendChild(userMessage);
  2848. chatBody.scrollTop = chatBody.scrollHeight; // Auto-scroll to bottom
  2849. // Send message to the server (Spring Boot API)
  2850. fetch('/communityhall/admin/api/send', {
  2851. method: 'POST',
  2852. headers: {
  2853. 'Content-Type': 'application/json',
  2854. },
  2855. body: JSON.stringify({ message }),
  2856. })
  2857. .then(response => response.json())
  2858. .then(data => {
  2859. // Add response message to chat
  2860. const responseMessage = document.createElement('div');
  2861. responseMessage.className = 'bot-message';
  2862. responseMessage.textContent = data.response;
  2863. chatBody.appendChild(responseMessage);
  2864. chatBody.scrollTop = chatBody.scrollHeight;
  2865. });
  2866. userInput.value = ''; // Clear input field
  2867. }
  2868. }
  2869. // OTP input navigation for reschedule modal
  2870. $('.otp-input').on('keyup', function (e) {
  2871. var $this = $(this);
  2872. if ($this.val().length === 1) {
  2873. $this.next('.otp-input').focus();
  2874. }
  2875. if ($this.val().length === 0) {
  2876. $this.prev('.otp-input').focus();
  2877. }
  2878. });
  2879. // Clear OTP inputs when OTP modal is shown
  2880. $('#rescheduleOtpModal').on('shown.bs.modal', function () {
  2881. $('.otp-input').val('');
  2882. $('#rescheduleOtpError').text('');
  2883. });
  2884. </script>
  2885. </div>
  2886. </div>
  2887. </div>
  2888. </body>
  2889. </html>