1$(function () { 2 // initSidebar(); 3 initSearchWidget(); 4 initPWA(); 5 6 $(document).ajaxError(function (event, jqxhr, settings, thrownError) { 7 jqxhr.status === 401 && logout(); // Unauthorized 8 settings.dataType === 'json' && settings.success({ status: 0, errorDesc: thrownError || 'An Unknown Error Occurred' }); 9 }); 10 11 window.onerror = function (message, source, lineno, colno, error) { 12 $.post('user/log-client-err', { 13 error: error.stack, 14 pathname: location.pathname 15 }); 16 }; 17 18 $('.previous-day').on('click', function (e) { 19 trackEvent('Previous Day', 'click', 'Previous Day'); 20 }); 21 $('.next-day').on('click', function (e) { 22 trackEvent('Next Day', 'click', 'Next Day'); 23 }); 24 $('.swap-icon').on('click', function (e) { 25 trackEvent('Station Swap', 'click', 'Station Swapping'); 26 }); 27 28 29 $('.payment-slider').slick({ 30 arrows: false, 31 autoplay: true, 32 dots: true, 33 autoplaySpeed: 3000, 34 speed: 3000, 35 cssEase: 'linear', 36 slidesToShow: 1, 37 slidesToScroll: 1, 38 responsive: [ 39 { 40 breakpoint: 1024, 41 settings: { 42 slidesToShow: 1, 43 slidesToScroll: 1 44 } 45 } 46 ] 47 }); 48}); 49 50let isLoadingBusMap = false; 51let connectingSelected = false; 52 53var connDetails = new Array(); 54var triggerConnEle = $(); 55 56var tripStageCode = new Array(); 57var tripDate = new Array(); 58var fromStation = new Array(); 59var toStation = new Array(); 60var fromStationName = new Array(); 61var toStationName = new Array(); 62 63var busmapp = new Array(); 64var previousTrip = null; 65 66var discountCoupon = []; 67 68var currencySymbol = ''; 69 70var regConnTrip = initOrResetRegConnTrip(); 71function initOrResetRegConnTrip() { 72 return { 73 "PREVIOUS_M_TRIP": null, 74 "CURRENT_M_TRIP": null, 75 "TRIP_SET": new Set(), 76 "AVAILABLE_SEAT": 0, 77 "PASSENGER_COUNT": 0, 78 "SEAT_COUNT": 0, 79 "CURRENT_SEQ": 0, 80 "PREVIOUS_SEQ": 0, 81 "SEQ_COMPLETED": -1, 82 "SEQ_STATUS": "BOARDING", // [BOARDING , CONNECTING ,DROPPING] 83 "TOTAL_SEQ": 1, 84 "SEQUENCE_TRIP_CODE": new Array(), 85 "SEQUENCE_TRIP_NAME": new Array(), 86 "SEQUENCE_TRIP_F_T_D_AMOUNT": new Map(), 87 "TRIP_FARE": new Array(), 88 /** 89 * @description use to auto filling passenger detail except SEQ_STATUS BOARDING 90 */ 91 "PASSENGER_DETAILS": { 92 "NAME": new Array(), 93 "AGE": new Array(), 94 "GENDER": new Array(), 95 }, 96 /** 97 * @template 98 * common for ticket booking at trips(mapped to connecting trips) 99 * @field 100 * common fields : emailaddress, phonebooking, freeservice, phone ,additionalAttributes , etc...(relevant like those) 101 * orderDetails : detail for booking ticket in a trip 102 * additionalAttributes : extra details for booking ticket 103 * @var orderDetails - It holds array of sampleTripDetail, 104 * which has to be done at final process before ajax/api request for blocking 105 */ 106 "TKT_BLK_BOOK_DETAILS": { 107 'emailaddress': "", 108 'phonebooking': 0, 109 'freeservice': 0, 110 'phone': "", 111 /** 112 * @description holds array of sampleTripDetail 113 */ 114 'orderDetails': new Array(), 115 /** 116 * @requires TRIP_CONNECT - required connecting service code - master code 117 * @description except TRIP_CONNECT remaining fields are optional/based on booking process 118 * @field ALTERNATE_MOBILE, INCLUSIVE_GST, GST_IN, GST_TRADE_NAME, GST_EMAIL , etc... 119 */ 120 'additionalAttributes': { 121 "TRIP_CONNECT": '' 122 } 123 124 }, 125 }; 126} 127 128 129/** 130 * @template - for ticket detail format 131 */ 132var sampleTicketDetail = { 133 'name': '', 134 'age': 0, 135 'gender': '', 136 'fare': 0, 137 'seatname': '', 138 'code': '' 139}; 140/** 141 * @template - for COMMON_DETAILS.orderDetails array element 142 * @field 143 * tripCode ,travelDate - code and date of trip mapped to connecting trip 144 * journeyType - CN (connection type there is not OW and RT in this) 145 * fromStation, boardingPoint, toStation, droppingPoint - trip's respective station and its point 146 * ticketDetails - contains array of sampleTicketDetail obj 147*/ 148var sampleTripDetail = { 149 'tripCode': '', 150 'travelDate': '', 151 'journeyType': 'CN',// for Connection type 152 'fromStation': '', 153 'fromStationName': '', 154 'boardingPoint': '', 155 'boardingPointName': '', 156 'toStation': '', 157 'toStationName': '', 158 'droppingPoint': '', 159 'droppingPointName': '', 160 'bus': {}, 161 'ticketDetails': new Array(), 162}; 163 164var sampleBusDetails = { 165 'busName': '', 166 'busDisplayName': '', 167 'busType': '', 168 'fromStationTime': '', 169 'toStationTime': '', 170 'schedule': { 171 'code': '', 172 'name': '', 173 'serviceNumber': '', 174 'displayName': '', 175 } 176 177}; 178 179function isObjectEmpty(obj) { 180 return Object.keys(obj).length === 0; 181} 182 183(function ($) { 184 _alert = function (node, settings) { 185 return node.finish() 186 .off('detach') 187 .html('<div class="alert alert-' + settings.type + ' alert-dismissible fade show" role="alert">\n\ 188 <button aria-label="Close" class="close" data-dismiss="alert" type="button">\n\ 189 <span aria-hidden="true"> x</span>\n\ 190 </button>\n\ 191 <strong>' + settings.title + '</strong> ' + settings.message + 192 '</div>') 193 .delay(settings.delay) 194 .queue(function () { 195 $(this).children('.alert').last().alert('close'); 196 }) 197 .children('.alert').last().on('close.bs.alert', function () { 198 $(this).trigger('detach'); 199 }); 200 }; 201 202 $.fn.danger = function (options) { 203 var settings = $.extend({ 204 type: 'danger', 205 title: '<i class="fa fa-exclamation-triangle fa-lg" aria-hidden="true"></i>', 206 message: 'Please fillout the necessary fields.', 207 delay: 5000 208 }, (typeof options === 'string') ? { message: options } : options); 209 210 return _alert(this, settings); 211 }; 212 213 $.fn.timeExceed = function (options) { 214 var settings = $.extend({ 215 type: 'danger', 216 title: '<i class="fa fa-exclamation-triangle fa-lg" aria-hidden="true"></i>', 217 message: 'OTP limit exceeded. Kindly use an alternate number.', 218 delay: 5000 219 }, (typeof options === 'string') ? { message: options } : options); 220 221 return _alert(this, settings); 222 }; 223 224 $.fn.success = function (options) { 225 var settings = $.extend({ 226 type: 'success', 227 title: '<i class="fa fa-check fa-lg" aria-hidden="true"></i>', 228 message: 'Your request has been completed Successfully.', 229 delay: 3000 230 }, (typeof options === 'string') ? { message: options } : options); 231 232 return _alert(this, settings); 233 }; 234 235 $.fn.emailmobile = function (options) { 236 var settings = $.extend({ 237 type: 'danger', 238 title: '<i class="fa fa-exclamation-triangle fa-lg" aria-hidden="true"></i>', 239 message: 'Invalid Email / Mobile number.', 240 delay: 5000 241 }, (typeof options === 'string') ? { message: options } : options); 242 243 return _alert(this, settings); 244 }; 245 246 $.fn.invalidTicket = function (options) { 247 var settings = $.extend({ 248 type: 'danger', 249 title: '<i class="fa fa-exclamation-triangle fa-lg" aria-hidden="true"></i>', 250 message: 'Invalid Access', 251 delay: 5000 252 }, (typeof options === 'string') ? { message: options } : options); 253 254 return _alert(this, settings); 255 }; 256}(jQuery)); 257 258(function ($) { 259 $.cookie = function (key, value, milliseconds, path = '/') { 260 if (!value) { 261 var keyValue = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)'); 262 return keyValue ? keyValue[2] : null; 263 } 264 var expires = new Date(); 265 expires.setTime(expires.getTime() + milliseconds); 266 document.cookie = key + '=' + value + ';expires=' + expires.toUTCString() + '; path=' + path; 267 }; 268}(jQuery)); 269 270(function ($) { 271 if (location.pathname !== '/') return; 272 273 $.ajax({ 274 type: 'POST', 275 url: 'banners', 276 dataType: 'json', 277 success: function (result) { 278 if (result.status != 1 || (result.data.length == 0 && result.announcement.length == 0)) return; 279 280 let banners = []; 281 let bannersAnnounce = []; 282 283 if (Array.isArray(result.data)) { 284 banners = result.data.map(url => ({ src: url })); 285 } 286 287 if (Array.isArray(result.announcement)) { 288 bannersAnnounce = result.announcement.map(item => ({ 289 src: item.url, 290 caption: `<a class="fancybox-caption" href="${item.redirectUrl}" data-redirect-url="${item.redirectUrl}" target="_blank"></a>` 291 })); 292 } 293 294 let bannerData = [...bannersAnnounce, ...banners]; 295 296 Fancybox.show(bannerData, { 297 Thumbs: false, 298 Toolbar: false, 299 300 Image: { 301 zoom: false, 302 click: false, 303 wheel: 'slide' 304 }, 305 }); 306 setTimeout(() => { 307 document.addEventListener('click', (event) => { 308 if (event.target.closest('.carousel__button.is-close')) { 309 return; 310 } 311 312 if (event.target.closest('.fancybox__content')) { 313 handleRedirect(); 314 } 315 }); 316 317 function handleRedirect() { 318 const selectedSlide = document.querySelector('.fancybox__slide.is-selected'); 319 if (selectedSlide) { 320 let redirectUrl = selectedSlide.querySelector('a.fancybox-caption')?.getAttribute('data-redirect-url'); 321 322 if (!redirectUrl) return; 323 324 if (!/^https?:\/\//i.test(redirectUrl)) { 325 redirectUrl = 'https://' + redirectUrl; 326 } 327 328 if (isValidURL(redirectUrl)) { 329 window.open(redirectUrl, '_blank'); 330 } 331 } 332 } 333 334 function isValidURL(url) { 335 try { 336 new URL(url); 337 return true; 338 } catch (_) { 339 return false;
340 } 341 } 342 343 }, 1000); 344 } 345 }); 346}(jQuery)); 347 348var totalTripCount = 0; 349var totalAvailableSeatCount = 0; 350 351Selectize.define('search_on_focus', function () { 352 var self = this; 353 354 self.on('dropdown_open', function () { 355 self.clear(true); 356 }); 357 358 self.on('blur', function () { 359 if (self.getValue() == '') { 360 self.setValue(self.lastValidValue, true); 361 } 362 }); 363 364 self.on('item_add', function (value) { 365 if (self.lastValidValue != value) { 366 self.lastValidValue = value; 367 } 368 }); 369}); 370 371const validate = { 372 isEmail: function (email) { 373 let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 374 return re.test(email); 375 }, 376 isMobile: function (mobile) { 377 let re = /^[6-9]\d{9}$/; 378 return re.test(mobile); 379 }, 380 isGSTIN: function (GSTIN) { 381 let re = /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/; 382 return re.test(GSTIN); 383 } 384}; 385 386function cleanString(string = '') { 387 return string.replace(/[^a-zA-Z0-9-]/g, '').toLowerCase(); 388} 389 390function percentageOf(percent, total) { 391 return (percent / 100) * total; 392} 393 394function logout() { 395 location.href = 'user/logout'; 396} 397 398function initSidebar() { 399 var slideout = new Slideout({ 400 panel: document.getElementById('panel'), 401 menu: document.getElementById('menu'), 402 padding: 256, 403 tolerance: 70, 404 easing: 'cubic-bezier(.32,2,.55,.27)' 405 }); 406 407 $('.toggle-button').on('click', function () { 408 slideout.toggle(); s 409 }); 410} 411 412var renderFromStations; 413var renderToStations; 414var fromselectize 415var toselectize 416 417function initSearchWidget() { 418 if (!$('#search-form').length) { 419 return; 420 } 421 $('#search-form').on('submit', initSearch); 422 423 const SELECTIZEOPTIONS = { 424 valueField: 'code', 425 labelField: 'name', 426 searchField: ['name'], 427 sortField: ['name'], 428 closeAfterSelect: true, 429 copyClassesToDropdown: false, 430 optgroups: [ 431 { label: 'TOP STATIONS', value: 'TOP' }, 432 { label: 'ALL STATIONS', value: 'ALL' } 433 ], 434 plugins: ['search_on_focus'] 435 }; 436 437 var $fromselect = $('#search-from-station').selectize(SELECTIZEOPTIONS); 438 var $toselect = $('#search-to-station').selectize(SELECTIZEOPTIONS); 439 440 fromselectize = $fromselect.prop('selectize'); 441 toselectize = $toselect.prop('selectize'); 442 443 fromselectize.settings.placeholder = 'Select From City'; 444 toselectize.settings.placeholder = 'Select To City'; 445 fromselectize.updatePlaceholder(); 446 toselectize.updatePlaceholder(); 447 448 const DATEPICKEROPTIONS = { 449 format: 'D, d M', 450 startDate: '0d', 451 endDate: '+90d', 452 weekStart: 1, 453 daysOfWeekHighlighted: '0,6', 454 maxViewMode: 'days', 455 autoclose: true, 456 todayHighlight: true, 457 templates: { 458 leftArrow: '<i class="fas fa-chevron-left"></i>', 459 rightArrow: '<i class="fas fa-chevron-right"></i>' 460 } 461 }; 462 463 var $onwardpicker = $('#search-onward-date').datepicker(DATEPICKEROPTIONS); 464 var $returnpicker = $('#search-return-date').datepicker(DATEPICKEROPTIONS); 465 466 $onwardpicker 467 .datepicker('setDate', moment().toDate()) 468 .on('changeDate', function (e) { 469 $returnpicker.datepicker('setDate', null); 470 $returnpicker.datepicker('setStartDate', moment(e.date).toDate()); 471 }); 472 473 $('[data-datebtn]').on('click', function () { 474 var days = $(this).data('datebtn'); 475 $onwardpicker.datepicker('setDate', moment().add(days, 'days').toDate()); 476 initSearch(); 477 }); 478 479 $onwardpicker.attr('placeholder', 'Journey Date').prop('autocomplete', 'off'); 480 $returnpicker.attr('placeholder', 'Return Date').prop('autocomplete', 'off'); 481 482 var routes = $('#routes-data:hidden').data('value'); 483 484 var mapStationsOptions = function (routeList, optgroup) { 485 var stationList = []; 486 487 $.each(routeList || [], function (i, station) { 488 station.optgroup = optgroup; 489 stationList.push(station) 490 }); 491 492 return stationList; 493 }; 494 495 renderFromStations = function () { 496 toselectize.setValue(''); 497 498 fromselectize.clearOptions(); 499 fromselectize.addOption(mapStationsOptions(routes.topRoute, 'TOP')); 500 fromselectize.addOption(mapStationsOptions(routes.route, 'ALL')); 501 }; 502 503 renderToStations = function () { 504 var fromStationCode = fromselectize.getValue(); 505 var toStationCode = toselectize.getValue(); 506 var route = routes.route[fromStationCode]; 507 508 toselectize.setValue('', true); 509 toselectize.clearOptions(); 510 if (!route) return; 511 512 var topRoutes = routes.route[fromStationCode].topRoutesList; 513 var toRoutes = routes.route[fromStationCode].toRoutesList; 514 515 toselectize.addOption(mapStationsOptions(topRoutes, 'TOP')); 516 toselectize.addOption(mapStationsOptions(toRoutes, 'ALL')); 517 toselectize.setValue((topRoutes[toStationCode] || toRoutes[toStationCode] || { code: '' }).code, true); 518 }; 519 520 renderFromStations(); 521 renderToStations(); 522 523 $fromselect.on('change', function () { 524 toselectize.focus(); 525 renderToStations(); 526 }); 527 528 $toselect.on('change', function () { 529 $onwardpicker.focus(); 530 }); 531 532 var $swapbtn = $('#search-swap-icon'); 533 $swapbtn.find('a').addBack().attr('tabindex', '-1'); 534 535 $swapbtn.on('click', function () { 536 var fromStationCode = fromselectize.getValue(); 537 var toStationCode = toselectize.getValue(); 538 539 // clear search 540 if (!toStationCode || !fromStationCode) { 541 fromselectize.setValue('', true); 542 toselectize.setValue('', true); 543 return; 544 } 545 546 var emptyObj = { code: '' }; 547 548 // set from station 549 var toRouteObj = routes.route[toStationCode] || emptyObj; 550 fromselectize.setValue(toRouteObj.code, true); 551 renderToStations(); 552 553 // set to station 554 var fromRouteObj = toRouteObj.toRoutesList[fromStationCode] || toRouteObj.topRoutesList[fromStationCode] || emptyObj; 555 toselectize.setValue(fromRouteObj.code, true); 556 }); 557 558 // apply recent search 559 var recentSearch = $('#recent-search-data:hidden').data('value'); 560 561 if (recentSearch) { 562 let [fromStationCode, toStationCode, onwardDate] = recentSearch || []; 563 564 fromselectize.setValue(fromStationCode, true); 565 renderToStations(); 566 toselectize.setValue(toStationCode, true); 567 $onwardpicker.datepicker('setDate', moment(onwardDate, 'YYYY-MM-DD').toDate()); 568 } 569 570 // fill only in SRP 571 var returnDate = $returnpicker.data('date'); 572 if (returnDate) { 573 $returnpicker.datepicker('setDate', moment(returnDate, 'YYYY-MM-DD').toDate()); 574 } 575
576 $(document).ready(function () { 577 $('a[data-toggle="modal"][data-target="#otp-login"]').on('click', function () { 578 genCaptcha(); 579 }); 580 }); 581} 582document.addEventListener('wheel', function (e) { 583 if (e.target.closest('.selectize-dropdown') || e.target.closest('.selectize-input')) { 584 e.stopPropagation(); 585 } 586}, { 587 passive: false 588}); 589function filterStations() { 590 var value = event.target.value || ''; 591 value = value.trim().toLowerCase(); 592 $('#stations-list .station').toggleClass('d-none', value !== ''); 593 $('#stations-list .station[data-station*="' + value + '"]').removeClass('d-none'); 594} 595 596function initSearch() { 597 event && event.preventDefault(); 598 599 var query = {}; 600 query.fromStationCode = $('#search-from-station').val(); 601 query.fromStationName = $('#search-from-station :selected').text(); 602 query.toStationCode = $('#search-to-station').val(); 603 query.toStationName = $('#search-to-station :selected').text(); 604 605 if (!query.fromStationCode) { 606 fromselectize.focus(); 607 // renderFromStations(); 608 return false; 609 } 610 611 if (!query.toStationCode) { 612 toselectize.focus(); 613 // renderToStations(); 614 return false; 615 } 616 617 var $onwardpicker = $('#search-onward-date'); 618 var onwardDate = moment($onwardpicker.datepicker('getDate')); 619 query.onwardDate = onwardDate.format('YYYY-MM-DD'); 620 if (!onwardDate.isValid()) { 621 query.onwardDate = moment().format('YYYY-MM-DD'); 622 $onwardpicker.datepicker('setDate', moment().toDate()); 623 } 624 625 var $returnpicker = $('#search-return-date'); 626 var returnDate = moment($returnpicker.datepicker('getDate')) 627 if (returnDate.isValid()) { 628 query.returnDate = returnDate.format('YYYY-MM-DD'); 629 } 630 631 $('#search-btn') 632 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Searching...') 633 .prop('disabled', true); 634 635 location.href = buildSearchUrl(query); 636} 637 638function buildSearchUrl(params) { 639 let fromStationName = encodeURIComponent(cleanString(params.fromStationName)); 640 let toStationName = encodeURIComponent(cleanString(params.toStationName)); 641 642 let query = {} 643 query.fromStationCode = params.fromStationCode; 644 query.toStationCode = params.toStationCode; 645 query.onwardDate = params.onwardDate; 646 647 if (params.returnDate) query.returnDate = params.returnDate; 648 if (params.searchType) query.searchType = params.searchType; 649 if (params.reschedule) query.reschedule = params.reschedule; 650 651 return 'search/' + fromStationName + '-to-' + toStationName + '?' + $.param(query); 652} 653 654function initTripSearch(data) { 655 // $('#trip-list-container').html('<div class="p-5 text-center">Loading...</div>'); 656 $('.loading').removeClass('d-none'); 657 data.tripCode = null; 658 $.ajax({ 659 type: 'POST', 660 url: 'search/search-list', 661 data: data, 662 dataType: 'json', 663 success: function (result) { 664 var $tripContents = $('#trip-list-conn-container'); 665 var $tripContent = $('#trip-list-container'); 666 forLoadingHtml(); 667 let tottrip = 0 668 669 if (result.data == '' || result.data == null) { 670 $('#trip-list-container').danger({ 671 message: 'Sorry! data not found', 672 delay: 100000 673 }); 674 } else if (result.data.conn || result.data.reg) { 675 isConnecting = true; 676 listViewConnMaster(data, result.data.conn, $tripContents); 677 connDetails = result.data.conn; 678 tottrip = result.data.conn ? result.data.conn.length : 0; 679 680 681 if (result.data.reg) { 682 isConnecting = false; 683 renderTripList(result.data.reg); 684 tottrip += result.data.reg[0].tripLength; 685 } 686 687 $('.conn-total-trip-count-div').removeClass('d-none'); 688 $('.conn-total-trip-count').html('<img src="assets/images/search/buscount.svg" alt="Bus Icon"> Showing ' + tottrip + ' Trips on this routes'); 689 690 } else { 691 $('#trip-list-container').danger({ 692 message: result.errorDesc, 693 delay: 100000 694 }); 695 } 696 } 697 }); 698} 699 700function groupPunctualityByDate(punctualityList, fromStationCode, toStationCode) { 701 var grouped = {}; 702 703 $.each(punctualityList, function (i, item) { 704 if (!item.tripDate) { 705 return; 706 } 707 708 if (!grouped[item.tripDate]) { 709 grouped[item.tripDate] = { departure: null, arrival: null, records: [] }; 710 } 711 712 grouped[item.tripDate].records.push(item); 713 }); 714 715 $.each(grouped, function (date, data) { 716 $.each(data.records, function (i, item) { 717 if (fromStationCode && item.stationCode === fromStationCode) { 718 data.departure = item; 719 } 720 if (toStationCode && item.stationCode === toStationCode) { 721 data.arrival = item; 722 } 723 }); 724 725 if (!data.departure || !data.arrival) { 726 var uniqueStations = []; 727 $.each(data.records, function (i, item) { 728 var exists = uniqueStations.some(function (s) { 729 return s.stationCode === item.stationCode; 730 }); 731 if (!exists) { 732 uniqueStations.push(item); 733 } 734 }); 735 736 if (!data.departure && uniqueStations.length) { 737 data.departure = uniqueStations[0]; 738 } 739 if (!data.arrival && uniqueStations.length > 1) { 740 data.arrival = uniqueStations[uniqueStations.length - 1]; 741 } 742 } 743 }); 744 745 return grouped; 746} 747 748function formatPunctualityDelay(minutes) { 749 // calculate the actual no of hours 750 /* if (minutes >= 60) { 751 return Math.floor(minutes / 60) + 'hr Delay'; 752 }*/ 753 // static hour seat if delay is more than 60 minutes 754 if (minutes > 60) { 755 return '1 hr Delay'; 756 } 757 return minutes + 'm Delay'; 758} 759 760function renderPunctualityStatus(item) { 761 if (!item) { 762 return '<span class="punctuality-na">-</span>'; 763 } 764 765 if (item.onTime == 1 || item.delayMinutes == 0) { 766 return '<i class="fas fa-check punctuality-check"></i>'; 767 } 768 769 var delayClass = item.delayMinutes >= 60 ? 'punctuality-delay-red' : 'punctuality-delay-orange'; 770 return '<span class="' + delayClass + '">' + formatPunctualityDelay(item.delayMinutes) + '</span>'; 771} 772 773function renderPunctuality(punctualityList, tripDate, fromStationCode, toStationCode) { 774 if (!punctualityList || !punctualityList.length) { 775 return ''; 776 } 777
778 var total = punctualityList.length; 779 var onTimeCount = 0; 780 $.each(punctualityList, function (i, item) { 781 if (item.onTime == 1) { 782 onTimeCount++; 783 } 784 }); 785 786 var percentage = Math.round((onTimeCount / total) * 100); 787 var colorClass = 'punctuality-red'; 788 if (percentage >= 81) { 789 colorClass = 'punctuality-green'; 790 } else if (percentage >= 60) { 791 colorClass = 'punctuality-orange'; 792 } 793 794 var grouped = groupPunctualityByDate(punctualityList, fromStationCode, toStationCode); 795 var sortedDates = Object.keys(grouped).sort(function (a, b) { 796 return moment(a).valueOf() - moment(b).valueOf(); 797 }); 798 799 if (sortedDates.length > 7) { 800 sortedDates = sortedDates.slice(-7); 801 } 802 803 var dotsHtml = ''; 804 var popoverRows = ''; 805 806 $.each(sortedDates, function (i, dateKey) { 807 var dayData = grouped[dateKey]; 808 var dayOnTime = true; 809 810 $.each(dayData.records, function (j, item) { 811 if (item.onTime != 1) { 812 dayOnTime = false; 813 } 814 }); 815 816 var dotClass = dayOnTime ? 'punctuality-dot-on' : 'punctuality-dot-delay'; 817 dotsHtml += '<span class="punctuality-dot ' + dotClass + '"></span>'; 818 819 popoverRows += '<tr>' + 820 '<td class="punctuality-date">' + moment(dateKey).format('ddd, DD - MMM') + '</td>' + 821 '<td class="punctuality-status">' + renderPunctualityStatus(dayData.departure) + '</td>' + 822 '<td class="punctuality-status">' + renderPunctualityStatus(dayData.arrival) + '</td>' + 823 '</tr>'; 824 }); 825 826 var popoverHtml = '<div class="punctuality-popover">' + 827 '<table class="punctuality-popover-table">' + 828 '<thead><tr>' + 829 '<th>Last 7 Days Reliability</th>' + 830 '<th>Departure Time</th>' + 831 '<th>Arrival Time</th>' + 832 '</tr></thead>' + 833 '<tbody>' + popoverRows + '</tbody>' + 834 '</table>' + 835 '</div>'; 836 837 return '<div class="trip-punctuality-wrap">' + 838 '<span class="trip-punctuality-badge ' + colorClass + '">' + percentage + '% On - Time</span>' + 839 '<div class="trip-punctuality-dots-wrap">' + 840 '<span class="trip-punctuality-dots">' + dotsHtml + '</span>' + 841 popoverHtml + 842 '</div>' + 843 '</div>'; 844} 845 846function renderTripList(trips = []) { 847 var $tripcont = $('#trip-list-container'); 848 var template = $('#template-trip-list').html(); 849 var onwardsTag = ' <small>Starts From</small>'; 850 var perSeat = 'Per Seat from'; 851 852 var filterData = {}; 853 filterData.boardingPointsMap = new Map(); 854 filterData.droppingPointsMap = new Map(); 855 filterData.busOperatorsMap = new Map(); 856 filterData.amenitiesMap = new Map(); 857 858 // var namespaceProfile = {}; 859 // var currencyFormat = ''; 860 861 totalTripCount = 0; 862 $.each(trips, function (i, tripss) { 863 864 // namespaceProfile = tripss.namespaceProfile; 865 totalTripCount = tripss.triplist.length; 866 867 // if (namespaceProfile && namespaceProfile.currencyCode == 'NPR') { 868 // currencyFormat = 'NRs.'; 869 // } else { 870 // currencyFormat = '<i class="fas fa-sm fa-rupee-sign"></i> '; 871 // } 872 873 $.each(tripss.triplist, function (i, trip) { 874 totalAvailableSeatCount += trip.computed.availableSeatCount; 875 if (trip.tripStatus.code !== 'TPO') { 876 return; 877 } 878 879 // filter data mapping 880 $.each(trip.fromStation.stationPoint || [], function (k, bp) { 881 filterData.boardingPointsMap.set(bp.code, bp); 882 }); 883 884 $.each(trip.toStation.stationPoint || [], function (k, dp) { 885 filterData.droppingPointsMap.set(dp.code, dp); 886 }); 887 888 $.each(trip.amenities || [], function (k, am) { 889 filterData.amenitiesMap.set(am.code, am); 890 }); 891 892 if (trip.operator) { 893 filterData.busOperatorsMap.set(trip.operator.code, trip.operator); 894 } 895 896 var $tpl = $(template); 897 898 // stage fare 899 var stageFares = []; 900 var discountFares = []; 901 var fareWithAvailableSeats = []; 902 $.each(trip.stageFare || [], function (i, stage) { 903 if (stage.availableSeatCount > 0) { 904 stageFares.push(stage.fare); 905 fareWithAvailableSeats.push(stage.fare); 906 } else { 907 stageFares.push(stage.fare); 908 } // un cammand for fare issue 22/11/24 909 discountFares.push(stage.discountFare || 0); 910 }); 911 var minFareSource = fareWithAvailableSeats.length > 0 ? fareWithAvailableSeats : stageFares; 912 913 var minFare = Math.min.apply(null, minFareSource); 914 var minDiscountFare = Math.min.apply(null, discountFares); 915 916 var offer = Math.round(minDiscountFare / minFare * 100); 917 918 // amenities 919 var amenities = []; 920 $.each(trip.amenities || [], function (i, amenity) { 921 amenities.push('<span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span>'); 922 }); 923 924 // via routes 925 var viaStations = []; 926 var viaStationslide = []; 927 $.each(trip.viaStations || [], function (i, via) { 928 viaStations.push(via.name); 929 if (via.name.length > 15) { 930 let viaroutecutstring = via.name.substring(0, 15) + '...'; 931 viaStationslide.push(viaroutecutstring); 932 } else { 933 viaStationslide.push(via.name); 934 } 935 }); 936 937 // badges 938 var badges = [];
939 if (new String(trip.bus.categoryCode).split('|').includes('CC01')) { 940 badges.push('<span class="badge badge-primary" title="Air Conditioned Bus">AC</span>'); 941 } 942 943 // templating 944 $tpl.attr('id', 'trip-' + trip.tripCode); 945 $tpl.find('.trip-bustype').html(trip.schedule.displayName.length > 15 ? trip.schedule.displayName : trip.bus.busType); 946 $tpl.find('.trip-badges').html(badges.join('')); 947 948 $tpl.find('.trip-offer-amount').html(minDiscountFare) 949 $tpl.find('.trip-offer-ribbon').toggleClass('d-none', !minDiscountFare); 950 951 $tpl.find('.trip-offer').toggleClass('d-none', !minDiscountFare); 952 $tpl.find('.hl-off-percent').html(offer + '%'); 953 954 offerNumber = getofferDesignNumber(); 955 956 if (offerNumber == 1) { 957 $tpl.find('.trip-offer').addClass('offer-1'); 958 $tpl.find('.offer-icon').html('<img src="assets/images/search/offer-symbol-1.svg" alt="Rating User icon" class="">'); 959 if (minDiscountFare > 0) 960 $tpl.find('.fare-margin').removeClass('fare-margin'); 961 } else if (offerNumber == 2) { 962 $tpl.find('.trip-offer').addClass('offer-2'); 963 $tpl.find('.offer-icon').html('<img src="assets/images/search/offer-symbol-2.svg" alt="Rating User icon" class="">'); 964 $tpl.find('.hl-off-percent').addClass('offer-colour'); 965 if (minDiscountFare > 0) 966 $tpl.find('.fare-margin').removeClass('fare-margin'); 967 } else if (offerNumber == 3) { 968 $tpl.find('.trip-offer').addClass('offer-3'); 969 $tpl.find('.offer-icon').html('<img src="assets/images/search/offer-symbol-2.svg" alt="Rating User icon" class="">'); 970 $tpl.find('.hl-off-percent').addClass('offer-colour'); 971 if (minDiscountFare > 0) 972 $tpl.find('.fare-margin').removeClass('fare-margin'); 973 } 974 975 currencySymbol = trip.currencySymbol; 976 977 $tpl.find('.trip-fare').html(trip.currencySymbol + (minFare - minDiscountFare)); 978 $tpl.find('.trip-onwards').html(stageFares.length > 1 && onwardsTag); 979 $tpl.find('.trip-perseat-from').html(stageFares.length > 1 && perSeat); 980 $tpl.find('.trip-fare-original').html(trip.currencySymbol + minFare).toggleClass('d-none', !minDiscountFare); 981 $tpl.find('.trip-starttime').html(moment(trip.fromStation.dateTime).format('hh:mm A')); 982 $tpl.find('.trip-endtime').html(moment(trip.toStation.dateTime).format('hh:mm A')); 983 $tpl.find('.trip-startdate').html(moment(trip.fromStation.dateTime).format('DD MMM')); 984 $tpl.find('.trip-enddate').html(moment(trip.toStation.dateTime).format('DD MMM')); 985 $tpl.find('.trip-startday').html(moment(trip.fromStation.dateTime).format('ddd')); 986 $tpl.find('.trip-endday').html(moment(trip.toStation.dateTime).format('ddd')); 987 $tpl.find('.trip-duration').html(trip.travelTime + ' hrs'); 988 $tpl.find('.trip-seatsavail').attr('title', 'Total ' + trip.bus.totalSeatCount + ' Seats').html(trip.computed.availableSeatCount); 989 $tpl.find('.trip-via').html(viaStations.join(', ')); 990 $tpl.find('.trip-amenities').html(amenities.join('')); 991 $tpl.find('.trip-reststop-count').html(trip.travelStopCount); 992 $tpl.find('[data-triptab="RESTSTOPS"]').toggleClass('d-none', !trip.travelStopCount); 993 $tpl.find('.rest-stop').toggleClass('d-none', !trip.travelStopCount); 994 995 if (amenities.length == 0) { 996 $tpl.find('[data-triptab="AMENITIES"]').addClass('d-none') 997 } 998 999 if (trip.computed.availableSeatCount === 0) { 1000 $tpl.find('.trip-seatsavail').parent().hide(); 1001 $tpl.find('.trip-viewbusmap').html('Sold Out').removeClass('btn-primary').addClass('btn-danger').css({ 'padding': '4px 15px' }); 1002 $tpl.find('.trip-viewbusmap, .tripinfo-container').addClass('no-map'); 1003 } else { 1004 $tpl.find('.trip-viewbusmap').html(trip.computed.availableSeatCount + ' Seats') 1005 } 1006 1007 $tpl.find('.COPYtooltip').attr('id', 'COPYtooltip-' + trip.tripCode); 1008 1009 $.each(trip.fromStation.stationPoint || [], function (k, bp) { 1010 $tpl.find('.trip-fromstationpoint').html(bp.name); 1011 return false; 1012 }); 1013 1014 $.each((trip.toStation.stationPoint || []).reverse(), function (k, dp) { 1015 $tpl.find('.trip-tostationpoint').html(dp.name); 1016 return false; 1017 }); 1018 1019 //bus image profile 1020 if (trip.busImageDetails && trip.busImageDetails.PROFILE && trip.busImageDetails.PROFILE.length > 0) { 1021 const imageUrl = trip.busImageDetails.PROFILE[0].imageUrlSlugs; 1022 $tpl.find('.bus-profile').css('background-image', 'url(' + imageUrl + ')'); 1023 } else { 1024 $tpl.find('.bus-profile').addClass('d-none'); 1025 } 1026 1027 $tpl.find('[data-triptab="BUSPHOTOS"]').toggleClass('d-none', !trip.busImageDetails.GALLERY); 1028 $tpl.find('.bus-gallery').toggleClass('d-none', !trip.busImageDetails.GALLERY); 1029 1030 var currentStationIndex = 0; 1031 var $viaRoutesContainer = $tpl.find('.all-via-routes'); 1032 $viaRoutesContainer.html('<span class="">' + viaStationslide[currentStationIndex] + '</span>'); 1033 $viaRoutesContainer.addClass('show'); 1034 setInterval(function () { 1035 if (currentStationIndex >= viaStationslide.length) { 1036 currentStationIndex = 0; 1037 } 1038 $viaRoutesContainer.removeClass('show'); 1039 $viaRoutesContainer.html('<span class="">' + viaStationslide[currentStationIndex] + '</span>'); 1040 setTimeout(function () { 1041 $viaRoutesContainer.addClass('show'); 1042 }, 100); 1043 currentStationIndex++; 1044 }, 3000); 1045 1046 1047 //journey status 1048 var currentDate = new Date(); // current date 1049 var year = currentDate.getFullYear();
1050 var month = ('0' + (currentDate.getMonth() + 1)).slice(-2); 1051 var day = ('0' + currentDate.getDate()).slice(-2); 1052 1053 var hours = ('0' + currentDate.getHours()).slice(-2); 1054 var minutes = ('0' + currentDate.getMinutes()).slice(-2); 1055 var seconds = ('0' + currentDate.getSeconds()).slice(-2); 1056 1057 var formattedDate = year + '-' + month + '-' + day; // date only 1058 var formattedDateTime = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds; // date time 1059 var formattedDateTimeObj = new Date(formattedDateTime); // current date time 1060 1061 // from station 1062 var fromDateTime = Object.values(trip.fromStation.stationPoint)[0]; 1063 if (fromDateTime && fromDateTime.dateTime) { 1064 var fromDateTimeObj = new Date(fromDateTime.dateTime); // from station point date time 1065 } 1066 1067 var timeDifference = formattedDateTimeObj - fromDateTimeObj; 1068 var timeDifferenceInSeconds = Math.floor(timeDifference / 1000); 1069 var timeDifferenceInMinutes = Math.floor(timeDifferenceInSeconds / 60); 1070 1071 var absoluteTimeDifferenceInMinutes = Math.abs(timeDifferenceInMinutes); // minutes 1072 var absoluteTimeDifference = Math.abs(timeDifference); // hours 1073 1074 var timeDifferenceHours = Math.round(absoluteTimeDifference / (1000 * 60 * 60)); 1075 1076 // to station 1077 var toStationPoint = Object.values(trip.toStation.stationPoint); 1078 var toDateTime = toStationPoint[toStationPoint.length - 1]; 1079 1080 if (toStationPoint.length > 0 && toStationPoint && toDateTime.dateTime) { 1081 var toDateTimeObj = new Date(toDateTime.dateTime); // to station point date time 1082 } 1083 1084 var formattedTravelDate = new Date(trip.travelDate); 1085 var formatTravelDate = formattedTravelDate.toISOString().split('T')[0]; // travel date 1086 1087 if (formattedDateTimeObj > fromDateTimeObj) { 1088 if (trip.tripStatus.code == "TCA" || (trip.tripStatus.code == "TPC" && trip.bookedSeatCount == 0)) { 1089 $tpl.find('#bus-status').removeClass('d-none').addClass('mt-35'); 1090 } else { 1091 $tpl.find('#bus-status').removeClass('d-none').addClass('in-journey').html('In Journey'); 1092 } 1093 } else if (timeDifferenceHours == 0) { 1094 if (trip.tripStatus.code == "TCA" || (trip.tripStatus.code == "TPC" && trip.bookedSeatCount == 0)) { 1095 $tpl.find('#bus-status').removeClass('d-none').addClass('mt-35'); 1096 } else { 1097 $tpl.find('#bus-status').removeClass('d-none').addClass('hg-g').html('Depart in ' + absoluteTimeDifferenceInMinutes + ' Mins'); 1098 } 1099 } else if (formattedDateTimeObj < fromDateTimeObj) { 1100 if (trip.tripStatus.code == "TCA" || (trip.tripStatus.code == "TPC" && trip.bookedSeatCount == 0)) { 1101 $tpl.find('#bus-status').removeClass('d-none').addClass('mt-35'); 1102 } else { 1103 $tpl.find('#bus-status').removeClass('d-none').addClass('hg-g').html('Depart in ' + timeDifferenceHours + ' Hrs'); 1104 } 1105 } 1106 1107 if (formatTravelDate == formattedDate) { 1108 $tpl.find('#bus-status').removeClass('d-none'); 1109 } else { 1110 $tpl.find('#bus-status').addClass('d-none'); 1111 } 1112 1113 // comingFrom-station 1114 var fromStationFirstBoarding = Object.values(trip.fromStation.stationPoint)[0]; 1115 1116 if (fromStationFirstBoarding.name.length > 13) { 1117 let stationName = fromStationFirstBoarding.name.substring(0, 13) + '...'; 1118 if (formattedDateTimeObj > fromDateTimeObj) { 1119 $tpl.find('.comingFrom-station').html('Coming from ' + stationName); 1120 } else { 1121 $tpl.find('.comingFrom-station').html('Starting from ' + stationName); 1122 } 1123 } else { 1124 if (formattedDateTimeObj > fromDateTimeObj) { 1125 $tpl.find('.comingFrom-station').html('Coming from ' + fromStationFirstBoarding.name); 1126 } else { 1127 $tpl.find('.comingFrom-station').html('Starting from ' + fromStationFirstBoarding.name); 1128 } 1129 } 1130 1131 if (trip.tripInfo.registrationNumber != '') { 1132 $tpl.find('.vehicle-number').removeClass('d-none'); 1133 $tpl.find('.veh-register-no').html(trip.tripInfo.registrationNumber); 1134 } 1135 1136 1137 if (trip.singleSeats != 0) { 1138 $tpl.find('.single-seat-details').removeClass('d-none'); 1139 $tpl.find('.single-seat').html(trip.singleSeats + ' Single'); 1140 } 1141 1142 if (trip.windowSeats != 0) { 1143 $tpl.find('.window-seat-details').removeClass('d-none'); 1144 $tpl.find('.window-seat').html(trip.windowSeats + ' Window'); 1145 } 1146 1147 if (trip.femaleBookedSeats != 0) { 1148 $tpl.find('.female-seat-details').removeClass('d-none'); 1149 $tpl.find('.female-seat').html(trip.femaleBookedSeats + ' Female'); 1150 } 1151 1152 1153 $tpl.find('.boardingpoint-count').html(trip.fromStation.stationPoint.length); 1154 $tpl.find('.droppingpoint-count').html(trip.toStation.stationPoint.length); 1155 1156 if (isPM(trip.fromStation.dateTime)) { 1157 $tpl.find('.travelTime').html('<img class="mr_2" src="assets/images/search/night-time.svg" width="17px" height= "17px">' + trip.travelTime + ' hrs'); 1158 } else { 1159 $tpl.find('.travelTime').html('<img class="mr_2" src="assets/images/search/day-time.svg" width="17px" height= "17px">' + trip.travelTime + ' hrs'); 1160 } 1161 1162 var punctualityHtml = renderPunctuality(trip.punctualityList, trip.travelDate, trip.fromStation.code, trip.toStation.code); 1163 $tpl.find('.trip-punctuality').html(punctualityHtml).toggleClass('d-none', !punctualityHtml); 1164 1165 // lower 1166 var lower = renderBusSeatsV4({ 1167 layer: 1, 1168 matrix: trip.lmatrix, 1169 seatStatus: trip.seatStatus 1170 }); 1171 1172 $tpl.find('.mini-lower-layer-seats').html(lower); 1173 1174 // upper 1175 if (trip.umatrix) { 1176 var upper = renderBusSeatsV4({ 1177 layer: 2, 1178 matrix: trip.umatrix, 1179 seatStatus: trip.seatStatus 1180 }); 1181 1182 $tpl.find('.mini-upper-layer-seats').html(upper); 1183 $tpl.find('.mini-upper-layer, .mini-layer-name').removeClass('d-none'); 1184 } 1185 1186 // busmap 1187 // $tpl.find('.trip-viewbusmap').on('click', function (e) {
1188 // if (isLoadingBusMap) return; 1189 1190 // if (!$(e.target).is('.boardingpoint-count, .droppingpoint-count')) { 1191 // !$(this).hasClass('no-map') && initBusMap(trip); 1192 // } else { 1193 // renderTripTab('STATIONPOINTS', trip); 1194 // } 1195 // }); 1196 1197 // var scrollInProgress = false; 1198 $tpl.find('.tripinfo-container').on('click', function (e) { 1199 1200 $('#trip-' + trip.tripCode).find('.trip-tabs-content').removeClass('busgallery-background'); 1201 1202 var tripElement = $('#trip-' + trip.tripCode); 1203 if (tripElement.length && !$(this).hasClass('no-map') && 1204 !$(e.target).is('.share-link') && 1205 !$(e.target).closest('.trip-punctuality-wrap').length && 1206 !$(e.target).is('.boardingpoint-count') && 1207 !$(e.target).is('.droppingpoint-count') && 1208 !$(e.target).hasClass('rest-stop') && 1209 !$(e.target).hasClass('via-routes') && 1210 !$(e.target).hasClass('bus-gallery') && 1211 !$(e.target).hasClass('bus-profile')) { 1212 1213 $('html, body').animate({ 1214 scrollTop: tripElement.offset().top - 60 1215 }, 1000, 'swing', function () { 1216 tripElement.find('.trip-tab-content').slideToggle(300); 1217 $('.trip-tab-content').not(tripElement.find('.trip-tab-content')).slideUp(300); 1218 }); 1219 } 1220 1221 if (isLoadingBusMap) return; 1222 if ($(e.target).closest('.trip-tabs').length > 0) { 1223 return; 1224 } 1225 1226 if ($(e.target).is('.share-link')) { 1227 generateSharingLink(trip); 1228 trackEvent('Share Trip', 'click', 'Share Link'); 1229 return; 1230 } 1231 1232 if ($(e.target).closest('.trip-punctuality-wrap').length) { 1233 return; 1234 } 1235 1236 if ($(e.target).is('.boardingpoint-count, .droppingpoint-count')) { 1237 renderTripTab('STATIONPOINTS', trip); 1238 trackEvent('Trip Info', 'click', 'STATIONPOINTS'); 1239 return; 1240 } 1241 1242 if ($(e.target).hasClass('rest-stop')) { 1243 renderTripTab('RESTSTOPS', trip); 1244 trackEvent('Trip Info', 'click', 'RESTSTOPS'); 1245 return; 1246 } 1247 1248 if ($(e.target).hasClass('bus-gallery') || $(e.target).hasClass('bus-profile')) { 1249 $('#trip-' + trip.tripCode).find('.trip-tabs-content').addClass('busgallery-background'); 1250 renderTripTab('BUSPHOTOS', trip); 1251 trackEvent('Trip Info', 'click', 'BUSPHOTOS'); 1252 return; 1253 } 1254 1255 if ($(e.target).hasClass('via-routes')) { 1256 renderTripTab('VIAROUTES', trip); 1257 trackEvent('Trip Info', 'click', 'VIAROUTES'); 1258 return; 1259 } 1260 1261 if (!$(this).hasClass('no-map')) { 1262 $(this).find('.trip-viewbusmap').html('Hide seats'); 1263 initBusMap(trip, 'reg'); 1264 } 1265 }); 1266 1267 // tabs 1268 $tpl.find('[data-triptab]').on('click', function (e) { 1269 var tab = $(e.target).data('triptab'); 1270 renderTripTab(tab, trip); 1271 trackEvent('Trip Info', 'click', tab); 1272 }); 1273 1274 // ordering 1275 $tpl 1276 .attr('data-departure', moment(trip.fromStation.dateTime).valueOf()) 1277 .attr('data-availability', trip.availableSeatCount) 1278 .attr('data-fare', minFare); 1279 1280 // tooltips 1281 $tpl.find('[data-toggle="tooltip"]').tooltip({ 1282 container: $tripcont, 1283 html: true, 1284 placement: 'top', 1285 boundary: 'viewport', 1286 }); 1287 1288 // append 1289 $tripcont.append($tpl); 1290 }); 1291 }); 1292 1293 // trip seat card 1294 // $('#trip-seats-card').toggleClass('d-none'); 1295 $('.total-trip-count').html('<img src="assets/images/search/buscount.svg" alt="Bus Icon"> Showing ' + trips.length + ' Buses on this route'); 1296 $('.total-seat-count').html('<b>' + totalAvailableSeatCount + '</b> Seats Available'); 1297 1298 $('#trip-empty-container').toggleClass('d-none', !!trips.length); 1299 $('#trip-list-filter').toggleClass('invisible', trips.length < 2); 1300 1301 // sort trip list 1302 sortTripList(); 1303 1304 // filter trip list 1305 renderTripFilter(filterData, trips); 1306 openSharedTrip(); 1307} 1308 1309function renderTripTab(tab, trip) { 1310 // if (isConnecting) { 1311 // var $tabcont = $('#cmTrip-' + trip.tripCode).find('.info-cont'); 1312 // // } else { 1313 var $tabcont = $('#trip-' + trip.tripCode).find('.trip-tabs-content'); 1314 // } 1315 1316 1317 if ($tabcont.find('[data-tabcontent=' + tab + ']').length) { 1318 resetTripList(trip); 1319 return; 1320 } 1321 resetTripList(trip); 1322 1323 $('#trip-' + trip.tripCode).find('[data-triptab=' + tab + ']').addClass('font-weight-bold'); 1324 $tabcont.html('<div class="text-center">Loading...</div>'); 1325 1326 switch (tab) { 1327 case 'AMENITIES': 1328 var $amenities = $('<div/>').addClass('row').attr('data-tabcontent', tab); 1329 $.each(trip.amenities || [], function (i, amenity) { 1330 $amenities.append('<div class="col-6 py-2"><span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span> <span>' + amenity.name + '</span></div>'); 1331 }); 1332 $tabcont.html($amenities); 1333 break; 1334 1335 case 'RESCHEDULE': 1336 var $rescheduleInstructions = $('<div/>').addClass('reschedule-list'); 1337 $rescheduleInstructions.append('<b>Reschedule Instructions:</b>'); 1338 $rescheduleInstructions.append('<ul class="pL-15">' + 1339 '<li>Rescheduling will be subject to availability of seats.</li>' + 1340 '<li>Rescheduled (both new & old) tickets not allowed cancel or reschedule further.</li>' + 1341 '<li>Reschedule fee and fare difference (If new ticket amount is higher than old ticket) should be paid by customer.</li>' + 1342 '<li>No amount will be refunded, if the new ticket you book is of lower amount than the previous booking.</li>' + 1343 '<li>Upon successful transaction, you will receive new ticket and same passenger(s) should travel with new ticket.</li>' + 1344 '<li>Ticket once transferred cannot transferred or cancelled again. ( Applicable for Both Postpone or Prepone )</li>' + 1345 '</ul>'); 1346 $tabcont.html($rescheduleInstructions); 1347 break; 1348 1349 case 'STATIONPOINTS': 1350 var template = $('#template-station-point').html(); 1351 var $stationpoints = $('<div/>').addClass('row').addClass('m-0').attr('data-tabcontent', tab); 1352 1353 var $frompoints = $('<div/>').addClass('col-md-6'); 1354 $frompoints.append('<h6>Boarding Points</h6>'); 1355 1356 var lastdate = {}; 1357 $.each(trip.fromStation.stationPoint || [], function (i, station) { 1358 var $sp = $(template); 1359 var date = moment(station.dateTime).format('ddd, DD MMM') 1360 if (!lastdate[date]) { 1361 lastdate[date] = date; 1362 $frompoints.append('<div class="bpdp-bg p-1 px-3">' + date + '</div>'); 1363 } 1364 $sp.find('.sp-time').html(moment(station.dateTime).format('hh:mm A')); 1365 $sp.find('.sp-name').html(station.name); 1366 $.each(station.amenities || [], function (i, amenity) { 1367 $sp.find('.sp-amenities').append('<span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span>'); 1368 }); 1369 $sp.appendTo($frompoints); 1370 }); 1371 1372 var $topoints = $('<div/>').addClass('col-md-6 border-left'); 1373 $topoints.append('<h6>Dropping Points</h6>'); 1374 1375 var lastdate = {}; 1376 var toStationPoints = trip.toStation.stationPoint || []; 1377 1378 toStationPoints.sort(function (a, b) { 1379 return moment(a.dateTime).unix() - moment(b.dateTime).unix(); 1380 }); 1381 1382 $.each(toStationPoints, function (i, station) { 1383 var $sp = $(template); 1384 var date = moment(station.dateTime).format('ddd, DD MMM') 1385 if (!lastdate[date]) { 1386 lastdate[date] = date; 1387 $topoints.append('<div class="bpdp-bg p-1 px-3">' + date + '</div>'); 1388 } 1389 $sp.find('.sp-time').html(moment(station.dateTime).format('hh:mm A')); 1390 $sp.find('.sp-name').html(station.name); 1391 $.each(station.amenities || [], function (i, amenity) { 1392 $sp.find('.sp-amenities').append('<span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span>'); 1393 }); 1394 $sp.appendTo($topoints); 1395 }); 1396 1397 $stationpoints.append($frompoints).append($topoints); 1398 $tabcont.html($stationpoints); 1399 1400 $tabcont.find('[data-toggle="tooltip"]').tooltip({ 1401 container: $tabcont, 1402 html: true, 1403 placement: 'top', 1404 boundary: 'viewport', 1405 }); 1406 break; 1407 1408 case 'CANCELTERMS': 1409 var data = {}; 1410 data.tripCode = trip.tripCode; 1411 data.fromStationCode = trip.fromStation.code;
1412 data.toStationCode = trip.toStation.code; 1413 data.travelDate = trip.travelDate; 1414 1415 $.ajax({ 1416 type: 'POST', 1417 url: 'search/cancellation-terms', 1418 data: data, 1419 dataType: 'json', 1420 success: function (result) { 1421 if (result.status == 1) { 1422 var template = $('#template-cancellation-policy').html(); 1423 var $terms = $('<div/>').attr('data-tabcontent', tab).append(template); 1424 var $tbody = $terms.find('tbody'); 1425 $.each(result.data.policyList || [], function (i, policy) { 1426 var $tr = $('<tr/>'); 1427 $('<td/>').html(policy.term).appendTo($tr); 1428 $('<td/>').html(policy.deductionAmountTxt + ' (' + policy.chargesTxt + ')').appendTo($tr); 1429 $('<td/>').html(policy.refundAmountTxt).appendTo($tr); 1430 $tr.appendTo($tbody); 1431 }); 1432 $tabcont.html($terms); 1433 } else { 1434 $tabcont.danger({ message: result.errorDesc, delay: 10e6 }); 1435 } 1436 } 1437 }); 1438 break; 1439 1440 case 'RESTSTOPS': 1441 var data = {}; 1442 data.tripCode = trip.tripCode; 1443 data.fromStationCode = trip.fromStation.code; 1444 data.toStationCode = trip.toStation.code; 1445 $.ajax({ 1446 type: 'POST', 1447 url: 'search/rest-stops', 1448 data: data, 1449 dataType: 'json', 1450 success: function (result) { 1451 if (result.status == 1) { 1452 var template = $('#template-rest-stops').html(); 1453 var $reststops = $('<div/>').addClass('row m-0').attr('data-tabcontent', tab); 1454 $.each(result.data || [], function (i, stop) { 1455 var $reststop = $(template); 1456 $reststop.find('.time').text(moment(stop.travelStopTime).format('hh:mm A')); 1457 $reststop.find('.name').text(stop.name); 1458 $reststop.find('.location').attr('href', 'https://maps.google.com?q=' + encodeURIComponent(stop.latitude + ',' + stop.longitude)); 1459 $reststop.find('.duration').text(stop.minutes); 1460 $reststop.find('.restroom').text(stop.restRoom); 1461 1462 var $remarks = $.trim(stop.remarks).split('\n').filter(Boolean).map(r => $('<div />').text(r)); 1463 $reststop.find('.remarks').html($remarks); 1464 $reststop.find('.remarks-panel').toggleClass('d-none', $remarks.length == 0); 1465 1466 $.each(stop.amenities || [], function (i, amenity) { 1467 $reststop.find('.amenities').append('<div class="badge badge-secondary font-weight-normal mr-1">' + amenity + '</div>'); 1468 }); 1469 1470 $reststops.append($reststop); 1471 }); 1472 $tabcont.html('<h6 class="rest-stopH">Rest Stops</h6>'); 1473 $tabcont.append($reststops); 1474 } 1475 else { 1476 $tabcont.danger({ message: result.errorDesc, delay: 10e6 }); 1477 } 1478 } 1479 }); 1480 break; 1481 1482 case 'VIAROUTES': 1483 var data = {}; 1484 data.tripCode = trip.tripCode; 1485 $.ajax({ 1486 type: 'POST', 1487 url: 'search/stage-details', 1488 data: data, 1489 dataType: 'json', 1490 success: function (result) { 1491 if (result.status == 1) { 1492 var $viastation = $('<div/>').addClass('row').addClass('m-0').attr('data-tabcontent', tab); 1493 1494 var $stations = $('<div/>').addClass('col-md-6 via-panel'); 1495 $stations.append('<h6>Via Stations</h6>'); 1496 1497 var lastdate = {}; 1498 $.each(result.data || [], function (i, station) { 1499 var date = moment(station.fromStation.dateTime).format('ddd, DD MMM') 1500 if (!lastdate[date]) { 1501 lastdate[date] = date; 1502 $stations.append('<div class="bpdp-bg p-1 px-3">' + date + '</div>'); 1503 } 1504 $stations.append('<div class="row bpdp-icon"><div class="col"><b>' + moment(station.fromStation.dateTime).format('hh:mm A') + '</b> - ' + station.fromStation.name + '</div></div>'); 1505 }); 1506 1507 var $map = $('<div/>').addClass('col-md-6'); 1508 $map.append('<div id="via-map"></div>'); 1509 1510 $viastation.append($stations).append($map); 1511 $tabcont.html($viastation); 1512 1513 initViaRouteMap(result.data); 1514 } else { 1515 $tabcont.danger({ message: result.errorDesc, delay: 10e6 }); 1516 } 1517 } 1518 }); 1519 break; 1520 1521 case 'BUSPHOTOS': 1522 const images = trip.busImageDetails.GALLERY ?? []; 1523 const $slider = $('<div/>').attr('data-tabcontent', tab).addClass('image-slider'); 1524 1525 images.forEach((image) => { 1526 const imgElement = `<div class="slick-slide"> 1527 <img class="bus-image-new" src="${image.imageUrlSlug}
1527" alt="Bus Image" 1528 onerror="this.style.display='none';" /> 1529 </div>`; 1530 $slider.append(imgElement); 1531 }); 1532 $tabcont.html($slider).hide().slideDown(300); 1533 $slider.before('<div class="sslick-arrow slick-prev"><i class="fa fa-chevron-left"></i></div>'); 1534 $slider.after('<div class="sslick-arrow slick-next"><i class="fa fa-chevron-right"></i></div>'); 1535 initImageSlider($slider); 1536 1537 break; 1538 default: 1539 break; 1540 } 1541} 1542 1543function renderTripFilter(filterData, trips) { 1544 var template = $('#template-custom-checkbox').html(); 1545 1546 var $bplist = $('#filter-bp-list'); 1547 filterData.boardingPointsMap.forEach(function (bp) { 1548 var $cb = $(template); 1549 $cb.attr('data-name', bp.name.toLowerCase()); 1550 $cb.find('input').attr('id', 'bp-cb-' + bp.code).attr('value', bp.code).addClass('filter-bp-cb'); 1551 $cb.find('label').attr('for', 'bp-cb-' + bp.code).html(bp.name); 1552 1553 $bplist.append($cb); 1554 }); 1555 $bplist.closest('.filter-section').find('.badge-count').html(filterData.boardingPointsMap.size); 1556 1557 var $dplist = $('#filter-dp-list'); 1558 filterData.droppingPointsMap.forEach(function (dp) { 1559 var $cb = $(template); 1560 $cb.attr('data-name', dp.name.toLowerCase()); 1561 $cb.find('input').attr('id', 'dp-cb-' + dp.code).attr('value', dp.code).addClass('filter-dp-cb'); 1562 $cb.find('label').attr('for', 'dp-cb-' + dp.code).html(dp.name); 1563 1564 $dplist.append($cb); 1565 }); 1566 $dplist.closest('.filter-section').find('.badge-count').html(filterData.droppingPointsMap.size); 1567 1568 var $bolist = $('#filter-bo-list'); 1569 filterData.busOperatorsMap.forEach(function (bo) { 1570 var $cb = $(template); 1571 $cb.attr('data-name', bo.name.toLowerCase()); 1572 $cb.find('input').attr('id', 'bo-cb-' + bo.code).attr('value', bo.code).addClass('filter-bo-cb'); 1573 $cb.find('label').attr('for', 'bo-cb-' + bo.code).html(bo.name); 1574 1575 $bolist.append($cb); 1576 }); 1577 $bolist.closest('.filter-section').toggleClass('d-none', filterData.busOperatorsMap.size < 2) 1578 .find('.badge-count').html(filterData.busOperatorsMap.size); 1579 1580 var $amlist = $('#filter-am-list'); 1581 filterData.amenitiesMap.forEach(function (am) { 1582 var $cb = $(template); 1583 $cb.attr('data-name', am.name.toLowerCase()); 1584 $cb.find('input').attr('id', 'am-cb-' + am.code).attr('value', am.code).addClass('filter-am-cb'); 1585 $cb.find('label').attr('for', 'am-cb-' + am.code).html(am.name); 1586 1587 $amlist.append($cb); 1588 }); 1589 $amlist.closest('.filter-section').toggleClass('d-none', filterData.amenitiesMap.size < 2) 1590 .find('.badge-count').html(filterData.amenitiesMap.size); 1591 1592 // Events 1593 $('#trip-filter-panel').on('change', function (e) { 1594 applyTripListFilter(trips); 1595 }); 1596 1597 const TRIPFILTER_HASH = '#tripfilter'; 1598 $('#trip-filter-modal').on('show.bs.modal', function () { 1599 location.hash = TRIPFILTER_HASH; 1600 }).on('hide.bs.modal', function () { 1601 location.hash === TRIPFILTER_HASH && history.back(); 1602 }); 1603 $(window).on('hashchange', function () { 1604 switch (location.hash) { 1605 case TRIPFILTER_HASH: 1606 showFilterTripList(); 1607 break; 1608 default: 1609 hideFilterTripList(); 1610 } 1611 }); 1612 1613 $('#trip-filter-panel .filter-search').on('input', function (e) { 1614 var value = e.target.value || ''; 1615 value = value.trim().toLowerCase(); 1616 1617 var $list = $(e.target).closest('.filter-section').find('.filter-cb-list'); 1618 $list.find('.custom-checkbox').toggleClass('d-none', value !== ''); 1619 $list.find('[data-name*="' + value + '"]').removeClass('d-none'); 1620 }); 1621} 1622 1623function showFilterTripList() { 1624 resetTripList(); 1625 $('#trip-filter-modal').modal('show'); 1626} 1627 1628function hideFilterTripList() { 1629 $('#trip-filter-modal').modal('hide'); 1630} 1631 1632function resetTripListFilter() { 1633 $('.trip-filter-toggle .active').removeClass('active'); 1634 $('#trip-filter-panel :checkbox').prop('checked', false); 1635 $('.trip-infos.d-none').removeClass('d-none'); 1636 $('#trip-empty-container').html('').removeClass('p-3'); 1637 $('#trip-filter-modal').modal('hide'); 1638} 1639 1640function applyTripListFilter(trips = []) { 1641 var filterCount = $('#trip-filter-panel :checkbox:checked').length; 1642 1643 var $allTrips = $('.trip-infos'); 1644 if (!filterCount) { 1645 $allTrips.removeClass('d-none'); 1646 $('#trip-empty-container').toggleClass('d-none', !!$allTrips.filter(':visible').length); 1647 $('#trip-filter-modal').modal('hide'); 1648 return; 1649 } 1650 $allTrips.addClass('d-none'); 1651 1652 const DAYSERVICE = $('.departure-time-cb[value="DAY"]').is(':checked'); 1653 const NIGHTSERVICE = $('.departure-time-cb[value="NIGHT"]').is(':checked'); 1654 const EVENINGSERVICE = $('.departure-time-cb[value="EVEDAYAFTERFIVE"]').is(':checked'); 1655 const LATESERVICE = $('.departure-time-cb[value="TENAFTERNIGHT"]').is(':checked'); 1656 1657 const BUSCLIMATELIST = $('.bus-type-cb[data-category="CLIMATE"]:checked').map((k, v) => v.value).get(); 1658 const BUSCLIMATEREGEX = new RegExp(BUSCLIMATELIST.join('|')); 1659 1660 const BUSTYPELIST = $('.bus-type-cb[data-category="SEATTYPE"]:checked').map((k, v) => v.value).get();
1661 const BUSTYPEREGEX = new RegExp(BUSTYPELIST.join('|')); 1662 1663 const BOARDINGLIST = $('.filter-bp-cb:checked').map((k, v) => v.value).get(); 1664 const DROPPINGLIST = $('.filter-dp-cb:checked').map((k, v) => v.value).get(); 1665 const OPERATORLIST = $('.filter-bo-cb:checked').map((k, v) => v.value).get(); 1666 const AMENITYLIST = $('.filter-am-cb:checked').map((k, v) => v.value).get(); 1667 1668 1669 $.each(trips, function (i, trip) { 1670 $.each(trip.triplist, function (i, tripss) { 1671 1672 const $trip = $('#trip-' + tripss.tripCode); 1673 1674 const DAYSTART = moment(tripss.travelDate + ' 06:00:00'); 1675 const NIGHTSTART = moment(tripss.travelDate + ' 18:00:00'); 1676 const EVENINGSTART = moment(tripss.travelDate + ' 17:00:00'); 1677 const LATESTART = moment(tripss.travelDate + ' 22:00:00'); 1678 const STARTTIME = moment(tripss.fromStation.dateTime); 1679 1680 if (DAYSERVICE && NIGHTSERVICE && EVENINGSERVICE && LATESERVICE) { 1681 } else { 1682 if (DAYSERVICE) { 1683 trackEvent('Trip Filter', 'click', 'DAYSERVICE'); 1684 // Before 10 AM (up to 10 AM) 1685 const DAYEND = moment(tripss.travelDate + ' 10:00:00'); 1686 if (!STARTTIME.isBefore(DAYEND)) { 1687 return; 1688 } 1689 } 1690 1691 if (NIGHTSERVICE) { 1692 trackEvent('Trip Filter', 'click', 'NIGHTSERVICE'); 1693 // 10 AM to 5 PM 1694 const NIGHTEND = moment(tripss.travelDate + ' 17:00:00'); 1695 if (!STARTTIME.isBetween(NIGHTSTART, NIGHTEND)) { 1696 return; 1697 } 1698 } 1699 1700 if (EVENINGSERVICE) { 1701 trackEvent('Trip Filter', 'click', 'EVENINGSERVICE'); 1702 // 5 PM to 10 PM 1703 const EVENINGEND = moment(tripss.travelDate + ' 22:00:00'); 1704 if (!STARTTIME.isBetween(EVENINGSTART, EVENINGEND)) { 1705 return; 1706 } 1707 } 1708 1709 if (LATESERVICE) { 1710 trackEvent('Trip Filter', 'click', 'LATESERVICE'); 1711 // After 10 PM 1712 if (!STARTTIME.isAfter(LATESTART)) { 1713 return; 1714 } 1715 } 1716 } 1717 1718 if ((BUSCLIMATELIST.length && !BUSCLIMATEREGEX.test(tripss.bus.categoryCode)) || 1719 (BUSTYPELIST.length && !BUSTYPEREGEX.test(tripss.bus.categoryCode))) { 1720 trackEvent('Bus Type', 'click', 'Bus Type Filter'); 1721 return; 1722 } 1723 if (BOARDINGLIST.length) { 1724 1725 trackEvent('Trip Filter', 'click', 'BOARDING'); 1726 $.each(tripss.fromStation.stationPoint || [], function (k, sp) { 1727 if (BOARDINGLIST.includes(sp.code)) { 1728 $trip.removeClass('d-none'); 1729 return false; 1730 } 1731 }); 1732 } 1733 if (DROPPINGLIST.length) { 1734 trackEvent('Trip Filter', 'click', 'DROPPING'); 1735 $.each(tripss.toStation.stationPoint || [], function (k, sp) { 1736 if (DROPPINGLIST.includes(sp.code)) { 1737 $trip.removeClass('d-none'); 1738 return false; 1739 } 1740 }); 1741 } 1742 if (OPERATORLIST.length) { 1743 trackEvent('Trip Filter', 'click', 'OPERATOR'); 1744 if (tripss.operator && OPERATORLIST.includes(tripss.operator.code)) { 1745 $trip.removeClass('d-none'); 1746 } 1747 } 1748 if (AMENITYLIST.length) { 1749 trackEvent('Trip Filter', 'click', 'AMENITY'); 1750 $.each(tripss.amenities || [], function (k, am) { 1751 if (AMENITYLIST.includes(am.code)) { 1752 $trip.removeClass('d-none'); 1753 return false; 1754 } 1755 }); 1756 } 1757 1758 $trip.removeClass('d-none'); 1759 }); 1760 }); 1761 1762 $('#trip-empty-container').toggleClass('d-none', !!$allTrips.filter(':visible').length); 1763 1764 $('#trip-filter-modal').modal('hide'); 1765} 1766 1767function sortTripList(orderby = 'departure', ordertype = 'asc') { 1768 var $tripcont = $('#trip-list-container'); 1769 1770 var $tripinfo = $tripcont.find('.trip-infos').sort(function (a, b) { 1771 return $(b).data(orderby) < $(a).data(orderby) ? 1 : -1; 1772 }); 1773 1774 if (ordertype == 'desc') { 1775 $tripinfo = $tripinfo.get().reverse(); 1776 } 1777 1778 $tripcont.append($tripinfo); 1779 1780 $('#trip-list-header').on('click', function (e) { 1781 trackEvent('Trip Sorting', 'click', orderby); 1782 }); 1783 1784 $('#trip-list-header').toggleClass('d-none', $tripinfo.length < 2); 1785} 1786 1787// Returns availableSeatCount regardless of whether the trip object uses the 1788// regular shape (`trip.computed.availableSeatCount`) or the connecting-trip 1789// shape (`trip.availableSeatCount`). 1790function getTripAvailableSeatCount(trip) { 1791 if (!trip) return 0; 1792 if (trip.computed && typeof trip.computed.availableSeatCount !== 'undefined') {
1793 return trip.computed.availableSeatCount; 1794 } 1795 if (typeof trip.availableSeatCount !== 'undefined') { 1796 return trip.availableSeatCount; 1797 } 1798 return 0; 1799} 1800 1801function initBusMap(trip, type) { 1802 var $busmapcont = $('#trip-' + trip.tripCode).find('.trip-tabs-content'); 1803 1804 var $tripinfo = $('#trip-' + trip.tripCode).find('.tripinfo-container'); 1805 1806 $('.tripinfo-container').find('.minibusfilter').removeClass('minibusfilter'); 1807 1808 if ($busmapcont.find('.busmap-container').length) { 1809 $tripinfo.find('.trip-viewbusmap').html(getTripAvailableSeatCount(trip) + ' Seats'); 1810 resetTripList(trip); 1811 return; 1812 } 1813 isLoadingBusMap = true; 1814 resetTripList(trip); 1815 1816 var data = {}; 1817 data.tripCode = trip.tripCode; 1818 data.fromStationCode = trip.fromStation.code; 1819 data.toStationCode = trip.toStation.code; 1820 data.travelDate = trip.travelDate; 1821 1822 $busmapcont.html('<div class="text-center">Loading...</div>'); 1823 1824 if (type == 'conn') { // in case of connecting need to pass master schedule code 1825 data.isConnecting = isConnecting; 1826 data.connScheduleCode = $busmapcont.closest('.c-m-trip-infos').attr('data-schedule-code-master'); 1827 } 1828 1829 $.ajax({ 1830 type: 'POST', 1831 url: 'search/busmap', 1832 data: data, 1833 dataType: 'json', 1834 success: function (result) { 1835 if (result.status == 1) { 1836 1837 type == 'conn' ? renderBusMapConn(result.data, isConnecting = true) : renderBusMap(result.data); 1838 isLoadingBusMap = false; 1839 connectingSelected = false; 1840 1841 busmapp = result.data; 1842 var res = result.data 1843 var terms = ''; 1844 1845 var servicenotes = ''; 1846 if (res.terms && res.terms['service_notes']) { 1847 servicenotes += '<h6>Service Notes</h6><ul style="font-size: 12px;line-height: 17px;">'; 1848 $.each(res.terms['service_notes'], function (k, val) { 1849 servicenotes += '<li>' + val.name + '</li>' 1850 }); 1851 servicenotes += '</ul>' 1852 } 1853 1854 $('#schedule-service-terms').html(servicenotes); 1855 1856 if (res.terms && res.terms['travel_policy']) { 1857 terms += '<ul class="travel-policy">' 1858 $.each(res.terms['travel_policy'], function (k, val) { 1859 terms += '<li>' + val.name + '</li>' 1860 }); 1861 terms += '</ul>'; 1862 } 1863 1864 $('#schedule-travel-terms').html(terms); 1865 1866 if (res.terms && !(res.terms.length > 0)) { 1867 $('.travel-info-card').addClass('d-none'); 1868 } 1869 1870 $('#trip-' + trip.tripCode).find('#minibusmap').addClass('minibusfilter'); 1871 previousTrip = trip; 1872 } else { 1873 $busmapcont.danger(result.errorDesc); 1874 isLoadingBusMap = false; 1875 } 1876 } 1877 }); 1878} 1879 1880function resetTripList(trip) { 1881 $('.trip-tabs-content').empty(); 1882 $('.trip-tabs [data-triptab].font-weight-bold').removeClass('font-weight-bold'); 1883 $('#selected-seat-footer').addClass('d-none'); 1884 $('#trip-' + trip.tripCode).find('#minibusmap').removeClass('minibusfilter'); 1885 if (previousTrip) { 1886 $('#trip-' + previousTrip.tripCode).find('.tripinfo-container').find('.trip-viewbusmap').html(getTripAvailableSeatCount(previousTrip) + ' Seats'); 1887 previousTrip = null; 1888 } 1889} 1890 1891function renderBusMap(busmap) { 1892 var template = $('#template-busmap-cont').html(); 1893 var $tpl = $(template); 1894 1895 // lower 1896 var lower = renderBusSeats({ 1897 layer: 1, 1898 matrix: busmap.lmatrix, 1899 seatStatus: busmap.seatStatus 1900 }); 1901 1902 $tpl.find('.lower-layer-seats').html(lower); 1903 1904 // upper 1905 if (busmap.umatrix) { 1906 var upper = renderBusSeats({ 1907 layer: 2, 1908 matrix: busmap.umatrix, 1909 seatStatus: busmap.seatStatus 1910 }); 1911
1912 $tpl.find('.upper-layer-seats').html(upper); 1913 $tpl.find('.upper-layer, .layer-name').removeClass('d-none'); 1914 } 1915 1916 1917 var uniqueFares = {}; 1918 $.each(busmap.seatStatus, function (i, seat) { 1919 if ($.inArray(seat.status.code, ['BO', 'BL', 'AO', 'BL', 'TBL', 'QS', 'PBL']) == -1) { 1920 uniqueFares[seat.fare] = (uniqueFares[seat.fare] || 0) + 1; 1921 } 1922 }); 1923 1924 if (Object.keys(uniqueFares).length > 1) { 1925 $tpl.find('#seat-layout-fare-filter').removeClass('d-none'); 1926 $.each(uniqueFares, function (fare, count) { 1927 $tpl.find('#seat-layout-fare-filter').append('<label class="btn btn-outline-secondary button-all btn-sm fare-labels">' + 1928 '<input type="radio" name="fare-filter" value="' + fare + '" autocomplete="off"><span class="fare-tabs">'+ currencySymbol + '<b>' + fare + '</b> <small>(' + count + ')</small> </span>' + 1929 '</label>'); 1930 }); 1931 } 1932 1933 // append 1934 $('#trip-' + busmap.busmap.tripCode).find('.trip-tabs-content').html($tpl); 1935 1936 var $busmap = $('#trip-' + busmap.busmap.tripCode).find('.busmap-layers'); 1937 1938 // select event 1939 $busmap.on('click', '.seat-select-visibility', function () { 1940 if ($(this).hasClass('seat-disabled')) { 1941 return; 1942 } 1943 1944 const searchInfo = getSearchInfo(); 1945 var $selected = $busmap.find('.seat-selected'); 1946 1947 if (searchInfo.reschedule > 0 && $selected.length >= searchInfo.reschedule) { 1948 $(this).removeClass('seat-selected'); 1949 $(this).removeClass('seater-selected'); 1950 $(this).removeClass('sleeper-selected'); 1951 return; 1952 } 1953 1954 if ($(this).hasClass('SLEEPER')) { 1955 $(this).toggleClass('seat-selected'); 1956 $(this).toggleClass('sleeper-selected'); 1957 } 1958 1959 if ($(this).hasClass('SEATER')) { 1960 $(this).toggleClass('seat-selected'); 1961 $(this).toggleClass('seater-selected'); 1962 } 1963 1964 $selected = $busmap.find('.seat-selected'); 1965 1966 if ($selected.length == 0) { 1967 zeroSeat(); 1968 } else if ($selected.length < 6) { 1969 // $('#selected-seat-panel').removeClass('d-none'); 1970 // $('#schedule-travel-terms').addClass('d-none'); 1971 } 1972 // $('#selected-seat-panel, #schedule-travel-terms').toggleClass('d-none', $selected.length == 0); 1973 1974 if ($selected.length > 0) { 1975 $("#booking-card").removeClass("d-none"); 1976 $(".select-info-card").addClass("d-none"); 1977 } 1978 1979 // validation 1980 if ($selected.length > 6) { 1981 $(this).removeClass('seat-selected'); 1982 $(this).removeClass('seater-selected'); 1983 $(this).removeClass('sleeper-selected'); 1984 alert('Maximum no.of seats allowed is 6'); 1985 return false; 1986 } 1987 1988 calculateSeatFare(busmap); 1989 }); 1990 1991 $('#seat-layout-fare-filter input[name="fare-filter"]').on('change', function () { 1992 $busmap.find('.seat-disabled').removeClass('seat-disabled'); 1993 $busmap.find('.seat-selected').removeClass('seat-selected'); 1994 $busmap.find('.seater-selected').removeClass('seater-selected'); 1995 $busmap.find('.sleeper-selected').removeClass('sleeper-selected'); 1996 1997 var fareFilter = this.value; 1998 if (fareFilter == 'ALL') { 1999 return; 2000 } 2001 $busmap.find('.seat-select-visibility:not([data-fare="' + fareFilter + '"])').toggleClass('seat-disabled', this.checked) 2002 }); 2003 2004 var spTemplate = $('#template-stationpoint-list').html(); 2005 2006 var spItems = function (item, escape) { 2007 var $tpl = $('<b/>'); 2008 $('<span/>').html(moment(escape(item.dateTime)).format('hh:mm A')).appendTo($tpl); 2009 $('<span class="ml-4"/>').html(escape(item.name)).appendTo($tpl); 2010 2011 return $tpl; 2012 } 2013 2014 var spOptions = function (item, escape) { 2015 var $tpl = $(spTemplate); 2016 $tpl.find('.sp-name').html(escape(item.name)); 2017 $tpl.find('.sp-date').html(moment(escape(item.dateTime)).format('ddd DD MMM')); 2018 $tpl.find('.sp-time').html(moment(escape(item.dateTime)).format('hh:mm A')); 2019 $tpl.find('.sp-landmark').html(escape(item.landmark)); 2020 $.each(item.amenities || [], function (i, amenity) { 2021 $tpl.find('.sp-amenities').append('<span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span>'); 2022 }); 2023 2024 return $tpl; 2025 } 2026 2027 $('#boarding-point-list').selectize({ 2028 placeholder: 'Select Boarding Point', 2029 valueField: 'code', 2030 labelField: 'name', 2031 searchField: ['name', 'landmark'], 2032 options: busmap.busmap.fromStation.stationPoint || [], 2033 render: { 2034 item: spItems, 2035 option: spOptions, 2036 }, 2037 onChange: function (value) { 2038 let station = this.options[value]; 2039 if (!station) return; 2040 let address = Array.from(new Set([station.name, station.address, station.landmark].filter(
2040Boolean))).join(', '); 2041 $('#boarding-point-address').html('<div class="bg-light p-2">' + address + '</div>'); 2042 2043 calculateSeatFare(busmap); 2044 2045 var droppingSelectize = $('#dropping-point-list').data('selectize'); 2046 droppingSelectize.focus(); 2047 } 2048 }); 2049 2050 $('#dropping-point-list').selectize({ 2051 placeholder: 'Select Dropping Point', 2052 valueField: 'code', 2053 labelField: 'name', 2054 searchField: ['name', 'landmark'], 2055 options: busmap.busmap.toStation.stationPoint || [], 2056 render: { 2057 item: spItems, 2058 option: spOptions, 2059 }, 2060 onChange: function (value) { 2061 let station = this.options[value]; 2062 if (!station) return; 2063 let address = Array.from(new Set([station.name, station.address, station.landmark].filter(Boolean))).join(', '); 2064 $('#dropping-point-address').html('<div class="bg-light p-2">' + address + '</div>'); 2065 2066 calculateSeatFare(busmap); 2067 } 2068 }); 2069 2070 $('.boarding-point-title').on('click', function () { 2071 boardingTab(); 2072 }); 2073 2074 $('.dropping-point-title').on('click', function () { 2075 droppingTab(); 2076 }); 2077 2078 $.each(busmap.busmap.fromStation.stationPoint, function (i, seat) { 2079 const radioButton = $("<input>", { 2080 type: "radio", 2081 id: `boarding-point-${i}`, 2082 name: "boarding-point", 2083 value: seat.code, 2084 }); 2085 2086 // name 2087 const boardingName = $("<div class='boarding-name'>"); 2088 boardingName.text(seat.name); 2089 2090 const dateTime = new Date(seat.dateTime.replace(' ', 'T')); 2091 const formattedBpTime = dateTime.toLocaleString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); 2092 2093 // time 2094 const boardingTime = $("<div class='boarding-time'>"); 2095 boardingTime.text(formattedBpTime); 2096 2097 // address 2098 const addressDiv = $("<div class='row m-0'>"); 2099 const address = $("<div class='bpaddress'>"); 2100 const addresscontent = Array.from(new Set([seat.name, seat.address, seat.landmark].filter(Boolean))).join(', '); 2101 address.text(addresscontent); 2102 addressDiv.append(address); 2103 2104 const boardingSelDiv = $("<div class='boarding-card'>"); 2105 boardingSelDiv.append(radioButton, boardingName, boardingTime, addressDiv); 2106 2107 const boardingAddressCard = $("<div class='boarding-address-card'>"); 2108 boardingAddressCard.append(addressDiv); 2109 2110 const amenityDiv = $("<div class='row m-0 bpamenity'>"); 2111 const amneity_card = $("<div class='boarding-amenity'>"); 2112 2113 const boardingAmenityCard = $("<div class='boarding-amenity-card'>"); 2114 $.each(seat.amenities || [], function (i, amenity) { 2115 amneity_card.append('<div class="boarding-amenity-inner"><span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span> <span class="amenity-name">' + amenity.name + '</span></div>'); 2116 }); 2117 amenityDiv.append(amneity_card); 2118 2119 if (seat.amenities.length > 0) 2120 boardingAmenityCard.append(amenityDiv); 2121 2122 const boardingInner = $("<div class='boarding-inner'>"); 2123 boardingInner.append(boardingSelDiv, boardingAddressCard, boardingAmenityCard); 2124 $('.boarding-point-list-inner').append(boardingInner); 2125 }); 2126 2127 $(".boarding-inner").on("click", function () { 2128 const radioButton = $(this).find("input[type='radio'][name='boarding-point']"); 2129 radioButton.prop("checked", true).addClass('checked'); 2130 2131 calculateSeatFare(busmap); 2132 2133 selectedBP = $(this).find("input[type='radio'][name='boarding-point']").val(); 2134 2135 $.each(busmap.busmap.fromStation.stationPoint, function (i, val) { 2136 if (val.code == selectedBP) { 2137 2138 const dateTime = new Date(val.dateTime.replace(' ', 'T')); 2139 const formattedBpTime = dateTime.toLocaleString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); 2140 2141 $('.boarding-point-name').html(val.name); 2142 $('.boarding-point-time').html(formattedBpTime); 2143 $('.boarding-address-details').html(Array.from(new Set([val.name, val.address, val.landmark].filter(Boolean))).join(', ')); 2144 } 2145 }); 2146 2147 droppingChange(); 2148 }); 2149 2150 $.each(busmap.busmap.toStation.stationPoint, function (i, seat) { 2151 const radioButton = $("<input>", { 2152 type: "radio", 2153 id: `dropping-point-${i}`, 2154 name: "dropping-point", 2155 value: seat.code, 2156 }); 2157 2158 // name 2159 const droppingName = $("<div class='dropping-name'>"); 2160 droppingName.text(seat.name); 2161 2162 const dateTime = new Date(seat.dateTime.replace(' ', 'T'));
2163 const formattedDpTime = dateTime.toLocaleString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); 2164 2165 // time 2166 const droppingTime = $("<div class='dropping-time'>"); 2167 droppingTime.text(formattedDpTime); 2168 2169 // address 2170 const dpaddressDiv = $("<div class='row m-0'>"); 2171 const dpaddress = $("<div class='bpaddress'>"); 2172 const dpaddresscontent = Array.from(new Set([seat.name, seat.address, seat.landmark].filter(Boolean))).join(', '); 2173 dpaddress.text(dpaddresscontent); 2174 dpaddressDiv.append(dpaddress); 2175 2176 const droppingSelDiv = $("<div class='dropping-card'>"); 2177 droppingSelDiv.append(radioButton, droppingName, droppingTime, dpaddressDiv); 2178 2179 const droppingAddressCard = $("<div class='dropping-address-card'>"); 2180 droppingAddressCard.append(dpaddressDiv); 2181 2182 2183 const dpamenityDiv = $("<div class='row m-0 dpamenity'>"); 2184 const dpamneity_card = $("<div class='dropping-amenity'>"); 2185 2186 const droppingAmenityCard = $("<div class='dropping-amenity-card'>"); 2187 $.each(seat.amenities || [], function (i, amenity) { 2188 dpamneity_card.append('<div class="dropping-amenity-inner"><span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span> <span class="amenity-name">' + amenity.name + '</span></div>'); 2189 }); 2190 dpamenityDiv.append(dpamneity_card); 2191 2192 if (seat.amenities.length > 0) 2193 droppingAmenityCard.append(dpamenityDiv); 2194 2195 // $(".dropping-inner").append(droppingSelDiv, droppingAddressCard, droppingAmenityCard); 2196 2197 const droppingInner = $("<div class='dropping-inner'>"); 2198 droppingInner.append(droppingSelDiv, droppingAddressCard, droppingAmenityCard); 2199 $('.dropping-point-list-inner').append(droppingInner); 2200 }); 2201 2202 $(".dropping-inner").on("click", function () { 2203 const radioButton = $(this).find("input[type='radio'][name='dropping-point']"); 2204 radioButton.prop("checked", true).addClass('checked'); 2205 calculateSeatFare(busmap); 2206 2207 selectedDP = $(this).find("input[type='radio'][name='dropping-point']").val(); 2208 2209 $.each(busmap.busmap.toStation.stationPoint, function (i, val) { 2210 if (val.code == selectedDP) { 2211 2212 const dateTime = new Date(val.dateTime.replace(' ', 'T')); 2213 const formattedDpTime = dateTime.toLocaleString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); 2214 2215 $('.dropping-point-name').html(val.name); 2216 $('.dropping-point-time').html(formattedDpTime); 2217 $('.dropping-address-details').html(Array.from(new Set([val.name, val.address, val.landmark].filter(Boolean))).join(', ')); 2218 } 2219 }); 2220 2221 boardingDroppingSelected(); 2222 2223 }); 2224 2225 var onclickNext = function () { 2226 const SEARCHINFO = getSearchInfo(); 2227 const BOOKINGDATA = getBookingData(busmap); 2228 2229 if (!$('input[name="boarding-point"]:checked').val() || !$('input[name="dropping-point"]:checked').val()) { 2230 // alert('Please select Boarding and Dropping points'); 2231 2232 $('.bpdpSelecting').addClass('inValid-shadow'); 2233 2234 setTimeout(function () { 2235 $('.bpdpSelecting').removeClass('inValid-shadow'); 2236 }, 2000); 2237 2238 return; 2239 } 2240 2241 if (SEARCHINFO.reschedule > 0 && BOOKINGDATA.seatDetails.length != SEARCHINFO.reschedule) { 2242 alert(SEARCHINFO.reschedule + ' seats need to be selected'); 2243 return; 2244 } 2245 2246 $('#selected-seat-next') 2247 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Please Wait...') 2248 .attr('disabled', true); 2249 2250 2251 if (SEARCHINFO.returnDate != '' && SEARCHINFO.searchType != 2) { // return trip 2252 var onwardData = BOOKINGDATA; 2253 2254 sessionStorage.setItem('BOOKINGDATA', JSON.stringify({ onwardData })); 2255 2256 var query = {}; 2257 query.fromStationCode = onwardData.toStation.code; 2258 query.fromStationName = encodeURIComponent(cleanString(onwardData.toStation.name)); 2259 query.toStationCode = onwardData.fromStation.code; 2260 query.toStationName = encodeURIComponent(cleanString(onwardData.fromStation.name)); 2261 query.onwardDate = SEARCHINFO.onwardDate; 2262 query.returnDate = SEARCHINFO.returnDate; 2263 query.searchType = 2; 2264 2265 location.href = buildSearchUrl(query); 2266 } else { // onward trip 2267 var bookingData = sessionStorage.getItem('BOOKINGDATA'); 2268 bookingData = JSON.parse(bookingData) || {}; 2269 if (SEARCHINFO.searchType == 2) { 2270 bookingData.returnData = BOOKINGDATA; 2271 } else { 2272 bookingData.onwardData = BOOKINGDATA; 2273 } 2274 sessionStorage.setItem('BOOKINGDATA', JSON.stringify(bookingData)); 2275 let reschedule = SEARCHINFO.reschedule > 0; 2276 gotoPassengerDetails(reschedule); 2277 } 2278 }; 2279 2280 2281 $('.boarding-point-change').on('click', function () { 2282 showBoardingDropping('board'); 2283 }); 2284 $('.dropping-point-change').on('click', function () { 2285 showBoardingDropping('drop'); 2286 }); 2287 2288 $('#selected-seat-next').off('click').on('click', onclickNext); 2289} 2290 2291function renderBusMapConn(busmap, isConnecting) { 2292 var template = $('#template-busmap-cont').html(); 2293 var $tpl = $(template); 2294 2295 tripStageCode = busmap.busmap.tripCode; 2296 tripDate = busmap.busmap.fromStation.dateTime; 2297 fromStation = busmap.busmap.fromStation.code;
2298 toStation = busmap.busmap.toStation.code; 2299 fromStationName = busmap.busmap.fromStation.name; 2300 toStationName = busmap.busmap.toStation.name; 2301 // lower 2302 var lower = renderBusSeats({ 2303 layer: 1, 2304 matrix: busmap.lmatrix, 2305 seatStatus: busmap.seatStatus 2306 }); 2307 2308 $tpl.find('.lower-layer-seats').html(lower); 2309 2310 // upper 2311 if (busmap.umatrix) { 2312 var upper = renderBusSeats({ 2313 layer: 2, 2314 matrix: busmap.umatrix, 2315 seatStatus: busmap.seatStatus 2316 }); 2317 2318 $tpl.find('.upper-layer-seats').html(upper); 2319 $tpl.find('.upper-layer, .layer-name').removeClass('d-none'); 2320 } 2321 2322 2323 var uniqueFares = {}; 2324 $.each(busmap.seatStatus, function (i, seat) { 2325 if ($.inArray(seat.status.code, ['BO', 'BL', 'AO', 'BL', 'TBL', 'QS', 'PBL']) == -1) { 2326 uniqueFares[seat.fare] = (uniqueFares[seat.fare] || 0) + 1; 2327 } 2328 }); 2329 2330 if (Object.keys(uniqueFares).length > 1) { 2331 $tpl.find('#seat-layout-fare-filter').removeClass('d-none'); 2332 $.each(uniqueFares, function (fare, count) { 2333 $tpl.find('#seat-layout-fare-filter').append('<label class="btn btn-outline-secondary button-all btn-sm fare-labels">' + 2334 '<input type="radio" name="fare-filter" value="' + fare + '" autocomplete="off"><span class="fare-tabs">'+ currencySymbol + '<b>' + fare + '</b> <small>(' + count + ')</small> </span>' + 2335 '</label>'); 2336 }); 2337 } 2338 2339 // append 2340 $('#trip-' + busmap.busmap.tripCode).find('.trip-tabs-content').html($tpl); 2341 2342 var $busmap = $('#trip-' + busmap.busmap.tripCode).find('.busmap-layers'); 2343 2344 $('.bpdpHeight').addClass('d-none'); 2345 $(".connecting-content").removeClass("d-none"); 2346 $('#selected-seat-next').html('next'); 2347 2348 // select event 2349 $busmap.on('click', '.seat-select-visibility', function () { 2350 2351 if ($(this).hasClass('seat-disabled')) { 2352 return; 2353 } 2354 2355 if (connectingSelected) { 2356 return; 2357 } 2358 2359 const searchInfo = getSearchInfo(); 2360 var $selected = $busmap.find('.seat-selected'); 2361 2362 if (regConnTrip.SEQ_STATUS !== 'BOARDING' && regConnTrip.CURRENT_SEQ !== 0 && regConnTrip.CURRENT_M_TRIP == null) { 2363 if (regConnTrip.SEAT_COUNT >= $selected.length) { 2364 alert("You cannot select more than " + regConnTrip.PASSENGER_COUNT + " seats."); 2365 $(this).removeClass('seat-selected'); 2366 $(this).removeClass('seater-selected'); 2367 $(this).removeClass('sleeper-selected'); 2368 return; 2369 } 2370 } 2371 2372 if (searchInfo.reschedule > 0 && $selected.length >= searchInfo.reschedule) { 2373 $(this).removeClass('seat-selected'); 2374 $(this).removeClass('seater-selected'); 2375 $(this).removeClass('sleeper-selected'); 2376 return; 2377 } 2378 2379 2380 if (regConnTrip.SEAT_COUNT > 0 && $selected.length >= regConnTrip.SEAT_COUNT) { 2381 // forseatSelectZero(); 2382 $(this).removeClass('seat-selected'); 2383 $(this).removeClass('seater-selected'); 2384 $(this).removeClass('sleeper-selected'); 2385 return; 2386 } 2387 2388 2389 if ($(this).hasClass('SLEEPER')) { 2390 $(this).toggleClass('seat-selected'); 2391 $(this).toggleClass('sleeper-selected'); 2392 } 2393 2394 if ($(this).hasClass('SEATER')) { 2395 $(this).toggleClass('seat-selected'); 2396 $(this).toggleClass('seater-selected'); 2397 } 2398 2399 if (isConnecting) { 2400 const $busMapCnt = $('#trip-' + busmap.busmap.tripCode).find('.trip-conn-tabs-content'); 2401 2402 //based on the sequence of connecting trip flow work 2403 // info-cont 2404 const $seqLi = $('#trip-' + busmap.busmap.tripCode).closest('.info-cont').find('.conn-stations').find(`input[name^="station_"][data-tripSequence="${regConnTrip.CURRENT_SEQ}"]`).closest('.closestdiv') 2405 $busMapCnt.find('.boarding-point-divider').addClass('d-none'); // for befor click the seat 2406 $busMapCnt.find('.dropping-point-list-card').addClass('d-none'); 2407 $busMapCnt.find('.dropping-point-title').addClass('d-none'); 2408 $busMapCnt.find(".connecting-content").removeClass("d-none"); 2409 $busMapCnt.find('#conn-from-station-name').val($seqLi.attr('data-from-station-name')); 2410 $busMapCnt.find('#conn-to-station-name').val($seqLi.attr('data-to-station-name')); 2411 2412 2413 // hided uncomanit 2414 // $busMapCnt.find('#remarks').closest('.clear_fix_both').addClass('d-none'); 2415 // $busMapCnt.find('table.table').addClass('d-none'); 2416 2417 switch (regConnTrip.SEQ_STATUS) { 2418 case 'BOARDING': 2419 // $busMapCnt.find('.pno-seg').removeClass('col-sm-4').addClass('col-sm-6'); 2420 // $busMapCnt.find('.bp-seg').removeClass('col-sm-4').addClass('col-sm-6'); 2421 // $busMapCnt.find('.station-area-filter').removeClass('hide'); 2422 // $busMapCnt.find('.alt-mobileno-lbl').removeClass('hide'); 2423 // $busMapCnt.find('#alt-mobileno').removeClass('hide'); 2424 $busMapCnt.find('#conn-dropping-point').val($seqLi.attr('data-dp-point')); 2425 $busMapCnt.find('#conn-dropping-point-name').val($seqLi.attr('data-dp-point-name')); 2426 // $busMapCnt.find('.connecting-content').addClass('d-none'); 2427 $busMapCnt.find('.bpdpHeight').removeClass('d-none'); 2428 $busMapCnt.find('.bpdpHeight').css('height', ' 450px'); 2429 2430 $busMapCnt.find('#from-state-name').val(busmap.busmap.fromStation.state.name); 2431 $busMapCnt.find('#from-state').val(busmap.busmap.fromStation.state.code); 2432 $busMapCnt.find('#from-city-name').val(busmap.busmap.fromStation.name); 2433 $busMapCnt.find('#from-city').val(busmap.busmap.fromStation.code); 2434 2435 2436 $("#booking-card").removeClass("d-none"); 2437 $(".select-info-card").addClass("d-none"); 2438 $(".bpdpHeight").removeClass("d-none"); 2439 $(".connecting-content").addClass("d-none"); 2440 2441 break; 2442 case 'CONNECTING': 2443 $busMapCnt.find('#conn-bording-point').val($seqLi.attr('data-bp-point')); 2444 $busMapCnt.find('#conn-bording-point-name').val($seqLi.attr('data-bp-point-name')); 2445 $busMapCnt.find('#conn-dropping-point').val($seqLi.attr('data-dp-point')); 2446 $busMapCnt.find('#conn-dropping-point-name').val($seqLi.attr('data-dp-point-name')); 2447 // $busMapCnt.find('.bpdpHeight').css('height', ' 350px'); 2448 $busMapCnt.find('.connecting-content').removeClass('d-none'); 2449 $busMapCnt.find('.bpdpHeight').addClass('d-none'); 2450 $(".select-info-card").addClass("d-none"); 2451 $("#booking-card").removeClass("d-none"); 2452 // $busMapCnt.find('.num-bp-dp-cnt').addClass('hide'); 2453 2454 break; 2455 case 'DROPPING': 2456 $busMapCnt.find('#conn-bording-point').val($seqLi.attr('data-bp-point')); 2457 $busMapCnt.find('#conn-bording-point-name').val($seqLi.attr('data-bp-point-name')); 2458 // $busMapCnt.find('.pno-seg').addClass('hide'); 2459 $busMapCnt.find('.boarding-point-list-card, .boarding-point-title').addClass('d-none'); 2460 $busMapCnt.find('.dropping-point-list-card').removeClass('d-none');// hide for except last sequence 2461 $busMapCnt.find('.dropping-point-title').removeClass('d-none');// hide for except last sequence 2462 $busMapCnt.find('.dropping-point-title').addClass('boardingdroppingbold'); 2463 $busMapCnt.find('.dropping-design').removeClass('d-none'); 2464 $busMapCnt.find('.bpdpHeight').removeClass('d-none'); 2465 $busMapCnt.find('.bpdpHeight').css('height', ' 450px'); 2466 $("#booking-card").removeClass("d-none"); 2467 $(".select-info-card").addClass("d-none"); 2468 $(".bpdpHeight").removeClass("d-none"); 2469 $(".connecting-content").addClass("d-none"); 2470 break; 2471 } 2472 2473 } 2474 $selected = $busmap.find('.seat-selected'); 2475 2476 if ($selected.length == 0) { 2477 zeroSeat(); 2478 } else if ($selected.length < 6) { 2479 // $('#selected-seat-panel').removeClass('d-none'); 2480 // $('#schedule-travel-terms').addClass('d-none'); 2481 } 2482 // $('#selected-seat-panel, #schedule-travel-terms').toggleClass('d-none', $selected.length == 0); 2483 2484 // if ($selected.length > 0) { 2485 // $("#booking-card").removeClass("d-none"); 2486 // $(".select-info-card").addClass("d-none"); 2487 // $(".bpdpHeight").removeClass("d-none"); 2488 // $(".connecting-content").addClass("d-none"); 2489 // } 2490 2491 2492 // validation 2493 if ($selected.length > 6) { 2494 $(this).removeClass('seat-selected'); 2495 $(this).removeClass('seater-selected'); 2496 $(this).removeClass('sleeper-selected'); 2497 alert('Maximum no.of seats allowed is 6'); 2498 return false;
2499 } 2500 2501 calculateSeatFare(busmap); 2502 2503 }); 2504 2505 $('#seat-layout-fare-filter input[name="fare-filter"]').on('change', function () { 2506 $busmap.find('.seat-disabled').removeClass('seat-disabled'); 2507 $busmap.find('.seat-selected').removeClass('seat-selected'); 2508 $busmap.find('.seater-selected').removeClass('seater-selected'); 2509 $busmap.find('.sleeper-selected').removeClass('sleeper-selected'); 2510 2511 var fareFilter = this.value; 2512 if (fareFilter == 'ALL') { 2513 return; 2514 } 2515 $busmap.find('.seat-select-visibility:not([data-fare="' + fareFilter + '"])').toggleClass('seat-disabled', this.checked) 2516 }); 2517 2518 var spTemplate = $('#template-stationpoint-list').html(); 2519 2520 var spItems = function (item, escape) { 2521 var $tpl = $('<b/>'); 2522 $('<span/>').html(moment(escape(item.dateTime)).format('hh:mm A')).appendTo($tpl); 2523 $('<span class="ml-4"/>').html(escape(item.name)).appendTo($tpl); 2524 2525 return $tpl; 2526 } 2527 2528 var spOptions = function (item, escape) { 2529 var $tpl = $(spTemplate); 2530 $tpl.find('.sp-name').html(escape(item.name)); 2531 $tpl.find('.sp-date').html(moment(escape(item.dateTime)).format('ddd DD MMM')); 2532 $tpl.find('.sp-time').html(moment(escape(item.dateTime)).format('hh:mm A')); 2533 $tpl.find('.sp-landmark').html(escape(item.landmark)); 2534 $.each(item.amenities || [], function (i, amenity) { 2535 $tpl.find('.sp-amenities').append('<span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span>'); 2536 }); 2537 2538 return $tpl; 2539 } 2540 2541 $('#boarding-point-list').selectize({ 2542 placeholder: 'Select Boarding Point', 2543 valueField: 'code', 2544 labelField: 'name', 2545 searchField: ['name', 'landmark'], 2546 options: busmap.busmap.fromStation.stationPoint || [], 2547 render: { 2548 item: spItems, 2549 option: spOptions, 2550 }, 2551 onChange: function (value) { 2552 let station = this.options[value]; 2553 if (!station) return; 2554 let address = Array.from(new Set([station.name, station.address, station.landmark].filter(Boolean))).join(', '); 2555 $('#boarding-point-address').html('<div class="bg-light p-2">' + address + '</div>'); 2556 2557 calculateSeatFare(busmap); 2558 2559 var droppingSelectize = $('#dropping-point-list').data('selectize'); 2560 droppingSelectize.focus(); 2561 } 2562 }); 2563 2564 $('#dropping-point-list').selectize({ 2565 placeholder: 'Select Dropping Point', 2566 valueField: 'code', 2567 labelField: 'name', 2568 searchField: ['name', 'landmark'], 2569 options: busmap.busmap.toStation.stationPoint || [], 2570 render: { 2571 item: spItems, 2572 option: spOptions, 2573 }, 2574 onChange: function (value) { 2575 let station = this.options[value]; 2576 if (!station) return; 2577 let address = Array.from(new Set([station.name, station.address, station.landmark].filter(Boolean))).join(', '); 2578 $('#dropping-point-address').html('<div class="bg-light p-2">' + address + '</div>'); 2579 2580 calculateSeatFare(busmap); 2581 } 2582 }); 2583 2584 $('.boarding-point-title').on('click', function () { 2585 boardingTab(); 2586 }); 2587 2588 $('.dropping-point-title').on('click', function () { 2589 droppingTab(); 2590 }); 2591 2592 $.each(busmap.busmap.fromStation.stationPoint, function (i, seat) { 2593 const radioButton = $("<input>", { 2594 type: "radio", 2595 id: `boarding-point-${i}`, 2596 name: "boarding-point", 2597 value: seat.code, 2598 }); 2599 2600 // name 2601 const boardingName = $("<div class='boarding-name'>"); 2602 boardingName.text(seat.name); 2603 2604 const dateTime = new Date(seat.dateTime.replace(' ', 'T')); 2605 const formattedBpTime = dateTime.toLocaleString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); 2606 2607 // time 2608 const boardingTime = $("<div class='boarding-time'>"); 2609 boardingTime.text(formattedBpTime); 2610 2611 // address 2612 const addressDiv = $("<div class='row m-0'>"); 2613 const address = $("<div class='bpaddress'>"); 2614 const addresscontent = Array.from(new Set([seat.name, seat.address, seat.landmark].filter(Boolean))).join(', '); 2615 address.text(addresscontent); 2616 addressDiv.append(address); 2617 2618 const boardingSelDiv = $("<div class='boarding-card'>"); 2619 boardingSelDiv.append(radioButton, boardingName, boardingTime, addressDiv); 2620 2621 const boardingAddressCard = $("<div class='boarding-address-card'>"); 2622 boardingAddressCard.append(addressDiv); 2623 2624 const amenityDiv = $("<div class='row m-0 bpamenity'>"); 2625 const amneity_card = $("<div class='boarding-amenity'>"); 2626 2627 const boardingAmenityCard = $("<div class='boarding-amenity-card'>"); 2628 $.each(seat.amenities || [], function (i, amenity) { 2629 amneity_card.append('<div class="boarding-amenity-inner"><span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span> <span class="amenity-name">' + amenity.name + '</span></div>'); 2630 }); 2631 amenityDiv.append(amneity_card); 2632 2633 if (seat.amenities.length > 0) 2634 boardingAmenityCard.append(amenityDiv); 2635 2636 const boardingInner = $("<div class='boarding-inner'>"); 2637 boardingInner.append(boardingSelDiv, boardingAddressCard, boardingAmenityCard); 2638 $('.boarding-point-list-inner').append(boardingInner); 2639 }); 2640 2641 $(".boarding-inner").on("click", function () { 2642 const radioButton = $(this).find("input[type='radio'][name='boarding-point']"); 2643 radioButton.prop("checked", true).addClass('checked'); 2644 2645 calculateSeatFare(busmap); 2646 2647 selectedBP = $(this).find("input[type='radio'][name='boarding-point']").val(); 2648 2649 $.each(busmap.busmap.fromStation.stationPoint, function (i, val) { 2650 if (val.code == selectedBP) { 2651 2652 const dateTime = new Date(val.dateTime.replace(' ', 'T'));
2653 const formattedBpTime = dateTime.toLocaleString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); 2654 2655 $('.boarding-point-name').html(val.name); 2656 $('.boarding-point-time').html(formattedBpTime); 2657 $('.boarding-address-details').html(Array.from(new Set([val.name, val.address, val.landmark].filter(Boolean))).join(', ')); 2658 } 2659 }); 2660 2661 // droppingChange(); 2662 }); 2663 2664 $.each(busmap.busmap.toStation.stationPoint, function (i, seat) { 2665 const radioButton = $("<input>", { 2666 type: "radio", 2667 id: `dropping-point-${i}`, 2668 name: "dropping-point", 2669 value: seat.code, 2670 }); 2671 2672 // name 2673 const droppingName = $("<div class='dropping-name'>"); 2674 droppingName.text(seat.name); 2675 2676 const dateTime = new Date(seat.dateTime.replace(' ', 'T')); 2677 const formattedDpTime = dateTime.toLocaleString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); 2678 2679 // time 2680 const droppingTime = $("<div class='dropping-time'>"); 2681 droppingTime.text(formattedDpTime); 2682 2683 // address 2684 const dpaddressDiv = $("<div class='row m-0'>"); 2685 const dpaddress = $("<div class='bpaddress'>"); 2686 const dpaddresscontent = Array.from(new Set([seat.name, seat.address, seat.landmark].filter(Boolean))).join(', '); 2687 dpaddress.text(dpaddresscontent); 2688 dpaddressDiv.append(dpaddress); 2689 2690 const droppingSelDiv = $("<div class='dropping-card'>"); 2691 droppingSelDiv.append(radioButton, droppingName, droppingTime, dpaddressDiv); 2692 2693 const droppingAddressCard = $("<div class='dropping-address-card'>"); 2694 droppingAddressCard.append(dpaddressDiv); 2695 2696 2697 const dpamenityDiv = $("<div class='row m-0 dpamenity'>"); 2698 const dpamneity_card = $("<div class='dropping-amenity'>"); 2699 2700 const droppingAmenityCard = $("<div class='dropping-amenity-card'>"); 2701 $.each(seat.amenities || [], function (i, amenity) { 2702 dpamneity_card.append('<div class="dropping-amenity-inner"><span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span> <span class="amenity-name">' + amenity.name + '</span></div>'); 2703 }); 2704 dpamenityDiv.append(dpamneity_card); 2705 2706 if (seat.amenities.length > 0) 2707 droppingAmenityCard.append(dpamenityDiv); 2708 2709 // $(".dropping-inner").append(droppingSelDiv, droppingAddressCard, droppingAmenityCard); 2710 2711 const droppingInner = $("<div class='dropping-inner'>"); 2712 droppingInner.append(droppingSelDiv, droppingAddressCard, droppingAmenityCard); 2713 $('.dropping-point-list-inner').append(droppingInner); 2714 }); 2715 2716 $(".dropping-inner").on("click", function () { 2717 const radioButton = $(this).find("input[type='radio'][name='dropping-point']"); 2718 radioButton.prop("checked", true).addClass('checked'); 2719 calculateSeatFare(busmap); 2720 2721 selectedDP = $(this).find("input[type='radio'][name='dropping-point']").val(); 2722 2723 $.each(busmap.busmap.toStation.stationPoint, function (i, val) { 2724 if (val.code == selectedDP) { 2725 2726 const dateTime = new Date(val.dateTime.replace(' ', 'T')); 2727 const formattedDpTime = dateTime.toLocaleString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); 2728 2729 $('.dropping-point-name').html(val.name); 2730 $('.dropping-point-time').html(formattedDpTime); 2731 $('.dropping-address-details').html(Array.from(new Set([val.name, val.address, val.landmark].filter(Boolean))).join(', ')); 2732 } 2733 }); 2734 2735 boardingDroppingSelected(); 2736 2737 }); 2738 2739 var onclickNext = function () { 2740 const SEARCHINFO = getSearchInfo(); 2741 const BOOKINGDATA = getConnBookingData(busmap); 2742 2743 if (!$('input[name="boarding-point"]:checked').val() || !$('input[name="dropping-point"]:checked').val()) { 2744 // alert('Please select Boarding and Dropping points'); 2745 2746 $('.bpdpSelecting').addClass('inValid-shadow'); 2747 2748 setTimeout(function () { 2749 $('.bpdpSelecting').removeClass('inValid-shadow'); 2750 }, 2000); 2751 2752 return; 2753 } 2754 2755 if (SEARCHINFO.reschedule > 0 && BOOKINGDATA.seatDetails.length != SEARCHINFO.reschedule) { 2756 alert(SEARCHINFO.reschedule + ' seats need to be selected'); 2757 return; 2758 } 2759 2760 $('#selected-seat-next') 2761 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Please Wait...') 2762 .attr('disabled', true); 2763 2764 2765 if (SEARCHINFO.returnDate != '' && SEARCHINFO.searchType != 2) { // return trip 2766 var onwardData = BOOKINGDATA; 2767 2768 sessionStorage.setItem('BOOKINGDATA', JSON.stringify({ onwardData })); 2769 2770 var query = {}; 2771 query.fromStationCode = onwardData.toStation.code;
2772 query.fromStationName = encodeURIComponent(cleanString(onwardData.toStation.name)); 2773 query.toStationCode = onwardData.fromStation.code; 2774 query.toStationName = encodeURIComponent(cleanString(onwardData.fromStation.name)); 2775 query.onwardDate = SEARCHINFO.onwardDate; 2776 query.returnDate = SEARCHINFO.returnDate; 2777 query.searchType = 2; 2778 2779 location.href = buildSearchUrl(query); 2780 } else { // onward trip 2781 var bookingData = sessionStorage.getItem('BOOKINGDATA'); 2782 bookingData = JSON.parse(bookingData) || {}; 2783 if (SEARCHINFO.searchType == 2) { 2784 bookingData.returnData = BOOKINGDATA; 2785 } else { 2786 bookingData.onwardData = BOOKINGDATA; 2787 } 2788 sessionStorage.setItem('BOOKINGDATA', JSON.stringify(bookingData)); 2789 let reschedule = SEARCHINFO.reschedule > 0; 2790 gotoPassengerDetails(reschedule); 2791 } 2792 }; 2793 2794 $('.boarding-point-change').on('click', function () { 2795 showBoardingDropping('board'); 2796 }); 2797 $('.dropping-point-change').on('click', function () { 2798 showBoardingDropping('drop'); 2799 }); 2800 initConnBook(busmap); 2801 // $('#selected-seat-next').off('click').on('click', initConnBook()); 2802} 2803 2804function initConnBook(busmap) { 2805 var $busmap = $('#trip-' + busmap.busmap.tripCode); 2806 $busmap.find('#selected-seat-next').on('click', function () { 2807 2808 let tripDetails = {}; 2809 let noErr = true; 2810 var connetSchedule = ''; 2811 2812 switch (regConnTrip.SEQ_STATUS) { 2813 case 'BOARDING': 2814 noErr = boardingValidation(); 2815 if (!noErr) { 2816 return; 2817 } 2818 2819 connetSchedule = getConnCommonDetails(); 2820 getConnCommonDetails(); 2821 tripDetails = getTripDetails(); 2822 break; 2823 case 'CONNECTING': 2824 noErr = connectingPtErrValidator(); 2825 if (!noErr) { 2826 return; 2827 } 2828 2829 tripDetails = getTripDetails(); 2830 break; 2831 case 'DROPPING': 2832 noErr = droppingValidation(); 2833 if (!noErr) { 2834 return; 2835 } 2836 tripDetails = getTripDetails(); 2837 break; 2838 } 2839 connectingContinue(tripDetails, $busmap, connetSchedule); 2840 }) 2841 2842 function getConnCommonDetails() { 2843 // regConnTrip.TKT_BLK_BOOK_DETAILS.emailaddress = session_email; 2844 // regConnTrip.TKT_BLK_BOOK_DETAILS.phone = $busmap.find('#mobileno').val(); 2845 // regConnTrip.TKT_BLK_BOOK_DETAILS.phonebooking = $busmap.find('input[name="phoneBooking"]').is(":checked") == true ? 1 : 0; 2846 // regConnTrip.TKT_BLK_BOOK_DETAILS.freeservice = $busmap.find('input[name="chkfreeservice"]').is(":checked") == true ? 1 : 0; 2847 regConnTrip.TKT_BLK_BOOK_DETAILS.additionalAttributes.TRIP_CONNECT = $busmap.closest('.c-m-trip-infos').attr('data-schedule-code-master'); 2848 } 2849 2850 function getTripDetails() { 2851 let tripDetails = { ...sampleTripDetail }; 2852 2853 tripDetails.tripCode = tripStageCode; 2854 tripDetails.travelDate = tripDate; 2855 tripDetails.fromStation = fromStation; 2856 tripDetails.toStation = toStation; 2857 tripDetails.fromStationName = fromStationName; 2858 tripDetails.toStationName = toStationName; 2859 // tripDetails.fromStationName = $busmap.find('#conn-from-station-name').val(); 2860 // tripDetails.toStationName = $busmap.find('#conn-to-station-name').val(); 2861 var $selected = $busmap.find('.seat-selected'); // seat count 2862 2863 2864 switch (regConnTrip.SEQ_STATUS) { 2865 case 'BOARDING': 2866 tripDetails.boardingPoint = $busmap.find('input[name="boarding-point"]:checked').val(); 2867 tripDetails.boardingPointName = $busmap.find('input[name="boarding-point"]:checked').closest('.boarding-card').find('.boarding-name').text(); 2868 // tripDetails.boardingPointName = $busmap.find('#conn-bording-point-name').val(); 2869 tripDetails.droppingPoint = $busmap.find('#conn-dropping-point').val(); 2870 tripDetails.droppingPointName = $busmap.find('#conn-dropping-point-name').val(); 2871 2872 tripDetails.city = $busmap.find('#from-city-name').val(); 2873 tripDetails.cityCode = $busmap.find('#from-city').val(); 2874 tripDetails.state = $busmap.find('#from-state-name').val(); 2875 tripDetails.stateCode = $busmap.find('#from-state').val(); 2876 2877 // set only once 2878 // regConnTrip.PASSENGER_DETAILS.NAME = $busmap.find('input[name="name"]').serializeArray(); 2879 // regConnTrip.PASSENGER_DETAILS.AGE = $busmap.find('input[name="age"]').serializeArray(); 2880 // regConnTrip.PASSENGER_DETAILS.GENDER = $busmap.find('.gen').seri
2880alizeObject(); 2881 regConnTrip.PASSENGER_COUNT = $selected.length; 2882 // set only once 2883 break; 2884 case 'CONNECTING': 2885 // tripDetails.boardingPoint = $busmap.find('#conn-bording-point').val(); 2886 tripDetails.boardingPoint = $busmap.find('#conn-bording-point').val(); 2887 tripDetails.boardingPointName = $busmap.find('#conn-bording-point-name').val(); 2888 // tripDetails.boardingPointName = $busmap.find('#conn-bording-point-name').val(); 2889 tripDetails.droppingPoint = $busmap.find('#conn-dropping-point').val(); 2890 tripDetails.droppingPointName = $busmap.find('#conn-dropping-point-name').val(); 2891 break; 2892 case 'DROPPING': 2893 tripDetails.boardingPoint = $busmap.find('#conn-bording-point').val(); 2894 tripDetails.boardingPointName = $busmap.find('#conn-bording-point-name').val(); 2895 // tripDetails.droppingPoint = $busmap.find('#dropping-point').val(); 2896 // tripDetails.droppingPointName = $busmap.find('#conn-dropping-point-name').val(); 2897 tripDetails.droppingPoint = $busmap.find('input[name="dropping-point"]:checked').val(); 2898 tripDetails.droppingPointName = $busmap.find('input[name="dropping-point"]:checked').closest('.dropping-card').find('.dropping-name').text(); 2899 break; 2900 } 2901 2902 tripDetails.ticketDetails = getTicketDetails(); 2903 tripDetails.bus = getBusDetails(); 2904 2905 return tripDetails; 2906 } 2907 2908 function getTicketDetails() { 2909 let tripTotFare = 0; 2910 let seats = []; 2911 $('#trip-' + busmap.busmap.tripCode).find('.busmap-layers .seat-selected').each(function (i, seat) { 2912 var $seat = $(seat); 2913 2914 var seatCode = $seat.data('code'); 2915 var seatDetail = busmap.seatDetails[seatCode]; 2916 seatDetail.seatCode = seatCode; 2917 seats.push(seatDetail); 2918 }); 2919 2920 if (regConnTrip.CURRENT_SEQ == 0) { 2921 regConnTrip.SEAT_COUNT = seats.length; 2922 } 2923 2924 // $('.seats-' + id).each(function () { 2925 // let seat = { ...sampleTicketDetail }; 2926 // const seatElement = $(this); 2927 2928 // seat.name = $.trim(seatElement.find('input[name="name"]').val()); 2929 // seat.age = $.trim(seatElement.find('input[name="age"]').val()); 2930 // seat.gender = seatElement.find('.gen:checked').val(); 2931 // seat.fare = parseFloat(seatElement.attr('data-fare')); 2932 // // seat.discount = seatElement.attr('data-discount');// not added in SAMPLE_TICKET_DETAIL 2933 // seat.seatname = seatElement.attr('data-name'); 2934 // seat.code = seatElement.attr('data-code'); 2935 2936 // // proof check 2937 // const prooftype = $.trim(seatElement.find('select[name="proof-type"]').val()); 2938 // const proofcode = $.trim(seatElement.find('input[name="proof-code"]').val()); 2939 2940 // if (prooftype && proofcode) { 2941 // // seat.idProof = `${prooftype} - ${proofcode}`; //not added in SAMPLE_TICKET_DETAIL 2942 // } 2943 2944 // tripTotFare += seat.fare; 2945 // seats.push(seat); 2946 // }); 2947 2948 // regConnTrip.TRIP_FARE.splice(regConnTrip.CURRENT_SEQ, 0, tripTotFare);// set trip total fare with respective sequence 2949 return seats; 2950 } 2951 2952 function getBusDetails() { 2953 const _bus = busmap.busmap; 2954 2955 // let busDetail = { ...sampleBusDetails }; 2956 let busDetail = JSON.parse(JSON.stringify(sampleBusDetails)); 2957 2958 busDetail.busName = _bus.bus.name; 2959 busDetail.busDisplayName = _bus.bus.displayName; 2960 busDetail.busType = _bus.bus.busType; 2961 busDetail.fromStationTime = _bus.fromStation.dateTime; 2962 busDetail.toStationTime = _bus.toStation.dateTime; 2963 busDetail.schedule.code = _bus.schedule.code; 2964 busDetail.schedule.name = _bus.schedule.name; 2965 busDetail.schedule.serviceNumber = _bus.schedule.serviceNumber; 2966 busDetail.schedule.displayName = _bus.schedule.displayName; 2967 2968 return busDetail; 2969 } 2970 2971 function boardingValidation() { 2972 let boardingVal = $('input[name="boarding-point"]:checked').val(); 2973 if (boardingVal == undefined || boardingVal == '') { 2974 $('.bpdpSelecting').addClass('inValid-shadow'); 2975 2976 setTimeout(function () { 2977 $('.bpdpSelecting').removeClass('inValid-shadow'); 2978 }, 2000); 2979 2980 return false; 2981 } else { 2982 return true; 2983 } 2984 } 2985 2986 function droppingValidation() { 2987 if (!isPassengerCountMatchwithBoardingCount()) return false; 2988 2989 let droppingVal = $('input[name="dropping-point"]:checked').val(); 2990 if (droppingVal == undefined || droppingVal == '') { 2991 $('.bpdpSelecting').addClass('inValid-shadow'); 2992 2993 setTimeout(function () { 2994 $('.bpdpSelecting').removeClass('inValid-shadow'); 2995 }, 2000); 2996 2997 return false;
2998 } else { 2999 return true; 3000 } 3001 } 3002 3003 3004 function isPassengerCountMatchwithBoardingCount() { 3005 let count = $('#trip-' + busmap.busmap.tripCode).find('.seat-selected').length; 3006 if (count < regConnTrip.PASSENGER_COUNT) { 3007 alert("You cannot select less than " + regConnTrip.SEAT_COUNT + " seats."); 3008 return false; 3009 } 3010 return true; 3011 } 3012 3013 function connectingPtErrValidator() { 3014 if (!isPassengerCountMatchwithBoardingCount()) return false; 3015 return true; 3016 } 3017 3018} 3019 3020function connectingContinue(tripDetails, busmap, connetSchedule) { 3021 3022 const $busmap = busmap; 3023 const $masterTrip = $busmap.closest('.c-m-trip-infos'); 3024 3025 // Initialize if no current trip is set 3026 if (regConnTrip.CURRENT_M_TRIP === null) { 3027 regConnTrip.CURRENT_M_TRIP = $masterTrip.attr('data-trip-code'); 3028 regConnTrip.PREVIOUS_M_TRIP = regConnTrip.CURRENT_M_TRIP; 3029 regConnTrip.SEQUENCE_TRIP_NAME = $masterTrip.attr('data-conn-t-stations').split(',') 3030 regConnTrip.AVAILABLE_SEAT = Number($masterTrip.attr('data-available-seat-count'));// type case to number 3031 regConnTrip.TOTAL_SEQ = ($masterTrip.attr('data-total-sequence') - 1);//to match with index number 3032 } else { 3033 regConnTrip.CURRENT_M_TRIP = $masterTrip.attr('data-trip-code'); 3034 } 3035 3036 // If the trip is being changed 3037 if (regConnTrip.CURRENT_M_TRIP !== regConnTrip.PREVIOUS_M_TRIP) { 3038 if (confirm("Are you sure you want to change Trip?")) { 3039 regConnTrip = initOrResetRegConnTrip(); // Reset the trip 3040 return; // Stop execution 3041 } 3042 } 3043 3044 // validate trip is added or not 3045 function isTripRoutDefined(tripDetails) { 3046 let isDefined = false; 3047 3048 const trip = regConnTrip.TKT_BLK_BOOK_DETAILS.orderDetails.filter(o => o.tripCode === tripDetails.tripCode) 3049 if (trip && !isObjectEmpty(trip) && 3050 tripDetails.fromStation === trip.fromStation && 3051 tripDetails.boardingPoint === trip.boardingPoint && 3052 tripDetails.toStation === trip.toStation && 3053 tripDetails.droppingPoint === trip.droppingPoint) { 3054 isDefined = true; 3055 } 3056 3057 return isDefined; 3058 } 3059 3060 if (isTripRoutDefined(tripDetails)) { 3061 if (confirm("Are you sure you want to change Bus?")) { 3062 // regConnTrip.TRIP_FARE.splice(regConnTrip.CURRENT_SEQ, 0, tripTotFare);// set trip total fare with respective sequence 3063 regConnTrip.TKT_BLK_BOOK_DETAILS.orderDetails.splice(regConnTrip.CURRENT_SEQ, 1, tripDetails); 3064 // regConnTrip.TRIP_MAP.set(tripDetails.tripCode, tripDetails);// update the map with new tripDetails 3065 showBookDetailAgainstTripSequence(); 3066 3067 return; // If the user confirms, stop the execution 3068 } 3069 } 3070 3071 // ok 3072 function showBookDetailAgainstTripSequence() { 3073 const $disDom = $masterTrip.find(`input[name^="station_"][data-tripSequence="${regConnTrip.CURRENT_SEQ}"]`).closest('li').find('.stationCollapseCtrlC'); 3074 const fetchDataForTripDetais = () => { 3075 return { 3076 "SeatName": $('#seats-container .seat-list').html(), 3077 "SeatFares": $('#seats-fare-container .seat-fare').html(), 3078 "Discount": $('#discount-container .discount').html(), 3079 "Tax": $('#service-container .total-service').html(), 3080 "Payable": $('.payable .fare').html(), 3081 } 3082 } 3083 let details = fetchDataForTripDetais(); 3084 regConnTrip.SEQUENCE_TRIP_F_T_D_AMOUNT.set(tripDetails.tripCode, details); 3085 3086 $disDom.find('.seat-name').html(details.SeatName); 3087 $disDom.find('.raw-fare').html(details.SeatFares); 3088 $disDom.find('.discount').html(details.Discount); 3089 $disDom.find('.tax').html(details.Tax); 3090 $disDom.find('.payable-fare').html(details.Payable); 3091 3092 } 3093 3094 // Add the new trip if it's not already added 3095 if (!regConnTrip.TRIP_SET.has(tripDetails.tripCode)) { 3096 regConnTrip.TRIP_SET.add(tripDetails.tripCode); // Add the tripCode to the set 3097 regConnTrip.TKT_BLK_BOOK_DETAILS.orderDetails.splice(regConnTrip.CURRENT_SEQ, 0, tripDetails); 3098 regConnTrip.SEQUENCE_TRIP_CODE.splice(regConnTrip.CURRENT_SEQ, 0, tripDetails.tripCode); // Insert the trip code at the correct sequence 3099 showBookDetailAgainstTripSequence();//ok 3100 } else { 3101 alert("Not allowed to modify passenger ticket details"); 3102 } 3103 3104 // which means final step is reached ==> (regConnTrip.CURRENT_SEQ === regConnTrip.TOTAL_SEQ) 3105 if (regConnTrip.SEQ_STATUS === 'DROPPING') { 3106 connectTripDetais(connetSchedule); 3107 return; 3108 } else { 3109 const $input = $masterTrip.find(`input[name^="station_"][data-tripSequence="${regConnTrip.CURRENT_SEQ + 1}"]`); 3110 if ($input.length > 0) { 3111 $input.prop('checked', true).trigger('change'); // Trigger the change event for that input 3112 } 3113 } 3114} 3115 3116function getEmergencyExitClass(seatStatus, layer, row, matrix, seatTypeMap) { 3117 var aboveRow = row - 1; 3118 var hasSleeper = false;
3119 var hasSeater = false; 3120 3121 if (aboveRow >= matrix.rowmin) { 3122 for (var col = matrix.colmin; col <= matrix.colmax; col++) { 3123 var pos = '' + layer + aboveRow + col; 3124 var info = seatStatus[pos]; 3125 3126 if (info && seatTypeMap[info.seatType]) { 3127 var category = seatTypeMap[info.seatType].category; 3128 if (category === 'SLEEPER') hasSleeper = true; 3129 if (category === 'SEATER') hasSeater = true; 3130 } 3131 } 3132 } 3133 3134 if (hasSeater && !hasSleeper) { 3135 return 'emergency-exit-seater-filer'; 3136 } 3137 3138 return 'emergency-exit-sleeper-filer'; 3139} 3140 3141function renderBusSeats(obj) { 3142 // var seatGenderClass = { 3143 // "M": "seat-booked-gents", // Booked for Male 3144 // "F": "seat-booked-ladies" // Booked for Female 3145 // }; 3146 var seatStatusClass = { 3147 "AM": "seat-select-visibility seat-available-gents", // Available male 3148 "AF": "seat-select-visibility seat-available-ladies", // Available female 3149 "AY": "seat-select-visibility seat-available-you", // Allocated for You 3150 "AL": "seat-select-visibility", // Available 3151 "BO": "seat-booked", // Booked 3152 "BM": "seat-booked-gents", // Booked for Male 3153 "BF": "seat-booked-ladies", // Booked for Female 3154 "AO": "seat-booked-gents", // Booked 3155 "UK": "seat-booked-gents", // Booked 3156 "TBL": "seat-booked-gents", // Blocked 3157 "PBL": "seat-booked-gents", // Booked 3158 "BL": "seat-booked-gents", // Blocked 3159 "SDBL": "seat-blocked-socialdis" // Blocked 3160 }; 3161 var seatType = { 3162 // seater 3163 "SS": { name: "Semi Sleeper", class: "seat-lay-search", category: "SEATER" }, 3164 "SSS": { name: "Single Semi Sleeper", class: "seat-lay-search", category: "SEATER" }, 3165 "ST": { name: "Seater", class: "seat-lay-search", category: "SEATER" }, 3166 "SST": { name: "Single Seater", class: "seat-lay-search", category: "SEATER" }, 3167 "PB": { name: "Pushback", class: "seat-lay-search", category: "SEATER" }, 3168 "PTY": { name: "Pantry", class: "seat-lay-search", category: "PANTRY" }, 3169 "WST": { name: "Window Seat", class: "seat-lay-search", category: "SEATER" }, 3170 "BKST": { name: "Back Seat", class: "seat-lay-search", category: "SEATER" }, 3171 "PBST": { name: "Pushback Seat", class: "seat-lay-search", category: "SEATER" }, 3172 3173 // sleeper 3174 "SL": { name: "Sleeper", class: "sleeper-lay-search", category: "SLEEPER" }, 3175 "USL": { name: "Upper Sleeper", class: "sleeper-lay-search", category: "SLEEPER" }, 3176 "LSL": { name: "Lower Sleeper", class: "sleeper-lay-search", category: "SLEEPER" }, 3177 "SUSL": { name: "Single Upper Sleeper", class: "sleeper-lay-search", category: "SLEEPER" }, 3178 "SLSL": { name: "Single Lower Sleeper", class: "sleeper-lay-search", category: "SLEEPER" }, 3179 "WSL": { name: "Window Sleeper", class: "sleeper-lay-search", category: "SLEEPER" }, 3180 3181 // restroom 3182 "RRM": { name: "Rest Room", class: "restroom-sleeper-filer", category: "RESTROOM" }, 3183 "FRS": { name: "Free Space", class: "restroom-sleeper-filer", category: "EMPTY" }, 3184 "EME": { name: "Emergency Exit", class: "emergency-exit-filer", category: "EMERGENCYEXIT" }, 3185 }; 3186 3187 // shorthand 3188 var layer = obj.layer; 3189 var matrix = obj.matrix; 3190 var seatStatus = obj.seatStatus; 3191 3192 // flags 3193 var isSleeperSeatFound = false; 3194 var isSeaterFound = false; 3195 3196 // return array 3197 var allSeatNodes = []; 3198 var emptySeatNodes = []; 3199 3200 // construct seats row and col wise 3201 for (var row = matrix.rowmin; row <= matrix.rowmax; row++) { 3202 var rowSeatFound = false; 3203 var hasDefinedSeats = false; // Track if the row has any defined seats 3204 var lastDefinedCol = matrix.colmin - 1; // Track the last column with a defined seat 3205 3206 var definedSeatsInRow = []; 3207 for (var col = matrix.colmin; col <= matrix.colmax; col++) { 3208 var pos = '' + layer + row + col; 3209 if (seatStatus[pos]) { 3210 definedSeatsInRow.push(col); 3211 } 3212 } 3213 for (var col = matrix.colmin; col <= matrix.colmax; col++) { 3214 3215 // position 3216 var pos = '' + layer + row + col; 3217 3218 // position seat details 3219 var seatinfo = seatStatus[pos]; 3220 3221 // seat div 3222 var $seat = $('<div/>'); 3223 3224 // empty seat 3225 if (!seatinfo) { 3226 3227 if (rowSeatFound && isSleeperSeatFound) { 3228 var isBetweenDefinedSeats = false; 3229 for (var i = 0; i < definedSeatsInRow.length - 1; i++) { 3230 if (col >
3230 definedSeatsInRow[i] && col < definedSeatsInRow[i + 1]) { 3231 isBetweenDefinedSeats = true; 3232 break; 3233 } 3234 } 3235 if (!isBetweenDefinedSeats) { 3236 continue; 3237 } 3238 } 3239 3240 $seat.html(' '); 3241 3242 emptySeatNodes.push($seat.get(0)); 3243 allSeatNodes.push($seat.get(0)); 3244 continue; 3245 } 3246 hasDefinedSeats = true; 3247 lastDefinedCol = col; 3248 3249 $.each(allSeatNodes, function () { 3250 var $this = $(this); 3251 var $container = $this.closest('.busmap-card'); 3252 $container.addClass('busmap-card-' + layer); 3253 }); 3254 3255 $eme = ''; 3256 3257 if (seatinfo.emergencyExitDoor !== 'NA') { 3258 $eme = '<span class="emergengcy-' + seatinfo.emergencyExitDoor + '-filer"></span>'; 3259 } 3260 3261 var seatTypeClass = seatType[seatinfo.seatType] ? seatType[seatinfo.seatType].class : null; 3262 if (seatinfo.seatType === 'EME') { 3263 seatTypeClass = getEmergencyExitClass(seatStatus, layer, row, matrix, seatType); 3264 } 3265 3266 $seat 3267 .addClass(seatTypeClass) // seat type class 3268 .addClass(seatStatusClass[seatinfo.status.code]) // seat status class 3269 // .addClass(seatGenderClass[seatinfo.genderstatus.code]) // seat gender class 3270 .addClass(seatType[seatinfo.seatType].category) // seat category 3271 .attr('data-code', seatinfo.code) 3272 .attr('data-fare', seatinfo.fare) 3273 .attr('data-discount', seatinfo.discountFare) 3274 .attr('data-service', seatinfo.serviceTax) 3275 .attr('data-seattype', seatinfo.status.code) 3276 .html(seatinfo.seatName+$eme) // seat name 3277 3278 3279 3280 if (seatinfo.status.code === "BO" && seatinfo.genderstatus.code === "M") { 3281 $seat.addClass("seat-booked-gents"); 3282 } else if (seatinfo.status.code === "BO" && seatinfo.genderstatus.code === "F") { 3283 $seat.addClass("seat-booked-ladies"); 3284 } 3285 3286 if (seatinfo.status.code === "BL" && seatinfo.genderstatus.code === "M") { 3287 $seat.addClass("seat-booked-gents"); 3288 } else if (seatinfo.status.code === "BL" && seatinfo.genderstatus.code === "F") { 3289 $seat.removeClass("seat-booked-gents"); 3290 $seat.addClass("seat-booked-ladies"); 3291 } 3292 3293 // for quota seats 3294 if ((seatinfo.status.code === "QS") && seatinfo.genderstatus.code === "M") { 3295 $seat.addClass("seat-booked-gents"); 3296 } else if ((seatinfo.status.code === "QS") && seatinfo.genderstatus.code === "F") { 3297 $seat.removeClass("seat-booked-gents"); 3298 $seat.addClass("seat-booked-ladies"); 3299 } 3300 3301 if (seatinfo.status.code === '') { 3302 $seat.addClass('seat-select-visibility'); 3303 } 3304 3305 if (seatType[seatinfo.seatType]) { 3306 if (seatType[seatinfo.seatType].category === 'SLEEPER') isSleeperSeatFound = true; 3307 if (seatType[seatinfo.seatType].category === 'SEATER') isSeaterFound = true; 3308 } 3309 3310 // vertical layout 3311 if (seatinfo.orientation == 1) { 3312 $seat.addClass('vertical-seat'); 3313 } 3314 3315 // rest Room 3316 if (seatinfo.seatType == 'RRM') {
3317 var $restroom = $('<div/>').addClass('restroom-lay').attr('title', seatType[seatinfo.seatType].name); 3318 $seat.removeClass(seatStatusClass[seatinfo.status.code]).html($restroom); 3319 } 3320 3321 // free space 3322 if (seatinfo.seatType == 'FRS') { 3323 $seat.removeClass(seatStatusClass[seatinfo.status.code]).empty(); 3324 } 3325 3326 // emergency exit 3327 if (seatinfo.seatType == 'EME') { 3328 var $emeCard = $('<div/>').addClass('emergency-lay').attr('title', seatType[seatinfo.seatType].name); 3329 $seat.removeClass(seatStatusClass[seatinfo.status.code]).html($emeCard).append($eme); 3330 } 3331 3332 // tooltip 3333 var toolipTitle = function () { 3334 if (['RRM', 'PTY', 'EME'].includes(seatinfo.seatType)) { 3335 return '<small>' + seatType[seatinfo.seatType].name + '</small>'; 3336 } 3337 3338 if (['AM', 'AF', 'AL', 'AY'].includes(seatinfo.status.code)) { 3339 var seattype = seatType[seatinfo.seatType] ? seatType[seatinfo.seatType].name : ''; 3340 var fare = currencySymbol + seatinfo.fare; 3341 var status = seatinfo.status.code == 'AF' ? 'Available for Female' : 'Available'; 3342 return '<small>' + seattype + ' - ' + fare + '<br/>' + status + '</small>'; 3343 } 3344 3345 return '<small>Booked</small>'; 3346 } 3347 3348 $seat.tooltip({ 3349 container: '.busmap-container', 3350 html: true, 3351 placement: 'top', 3352 boundary: 'viewport', 3353 title: toolipTitle() 3354 }); 3355 3356 rowSeatFound = true; 3357 allSeatNodes.push($seat.get(0)); 3358 } 3359 3360 var $clearfix = $('<div/>').addClass('clearfix'); 3361 allSeatNodes.push($clearfix.get(0)); 3362 } 3363 3364 if (isSeaterFound) { 3365 $(emptySeatNodes).addClass('seat-lay-search'); 3366 } else if (isSleeperSeatFound) { 3367 $(emptySeatNodes).addClass('sleeper-lay-search'); 3368 } 3369 3370 return allSeatNodes; 3371} 3372 3373function calculateSeatFare(busmap) { 3374 var reschedule = +getQueryParametersFromURL(); 3375 var $busmap = $('#trip-' + busmap.busmap.tripCode).find('.busmap-layers'); 3376 var $selected = $busmap.find('.seat-selected'); 3377 var seatCount = $selected.length; 3378 3379 var fare = 0; 3380 var gst = 0; 3381 var discount = 0; 3382 var seatnames = []; 3383 var totalfare = 0; 3384 3385 $selected.each(function (i, seat) { 3386 var $seat = $(seat); 3387 3388 var seatCode = $seat.data('code'); 3389 var seatDetails = busmap.seatDetails[seatCode]; 3390 3391 seatnames.push(seatDetails.seatName); 3392 if (Number(seatDetails.fare)) { // base fare 3393 fare += seatDetails.fare; 3394 } 3395 if (Number(seatDetails.serviceTax)) { // service tax 3396 gst += seatDetails.serviceTax; 3397 } 3398 if (Number(seatDetails.discountFare)) { // discount 3399 discount += seatDetails.discountFare; 3400 } 3401 }); 3402 3403 // Boarding Fare 3404 var boardingFare = 0; 3405 // var selectedBoarding = $('#boarding-point-list').val(); 3406 var selectedBoarding = $('input[name="boarding-point"]:checked').val(); 3407 $.each(busmap.busmap.fromStation.stationPoint || [], function (i, boarding) { 3408 if (boarding.code == selectedBoarding && Number(boarding.fare) > 0) { 3409 boardingFare = Number(boarding.fare) * seatCount; 3410 return false; 3411 } 3412 }); 3413 3414 // Dropping Fare 3415 var droppingFare = 0; 3416 // var selectedDropping = $('#dropping-point-list').val(); 3417 var selectedDropping = $('input[name="dropping-point"]:checked').val(); 3418 $.each(busmap.busmap.toStation.stationPoint || [], function (i, dropping) { 3419 if (dropping.code == selectedDropping && Number(dropping.fare) > 0) { 3420 droppingFare = Number(dropping.fare) * seatCount; 3421 return false; 3422 } 3423 }); 3424 3425 if (reschedule > 0) { 3426 totalfare = fare + boardingFare + droppingFare - discount; 3427 // GST 3428 if (gst > 0) { 3429 const GSTPERCENTAGE = 5; 3430 gst = percentageOf(GSTPERCENTAGE, totalfare); 3431 totalfare += gst; 3432 } 3433 3434 // footer 3435 $('#selected-seat-name').html(seatnames.join(', ')); 3436 $('#selected-seat-fare').html(Number(fare).toFixed(2)); 3437 3438 if (Number(gst) > 0) { 3439 $('#selected-seat-gst').removeClass('d-none'); 3440 $('#selected-seat-gst').html(Number(gst).toFixed(2)); 3441 } 3442 $('#selected-seat-discount-title').addClass('d-none'); 3443 3444 // if (Number(discount) > 0) { 3445 // $('#selected-seat-discount').removeClass('d-none'); 3446 // $('#selected-seat-discount').html(Number(discount).toFixed(2)); 3447 // } 3448 3449 // $('#selected-seat-discount').html(Number(discount).toFixed(2)) 3450 // .closest('.row').toggleClass('d-none', !Boolean(discount)); 3451 } else { 3452 // Total Fare 3453 totalfare = fare + boardingFare + droppingFare - discount; 3454 3455 // GST 3456 if (gst > 0) { 3457 const GSTPERCENT = 5; 3458 gst = percentageOf(GSTPERCENT, totalfare); 3459 totalfare += gst; 3460 } 3461 3462 // footer 3463 $('#selected-seat-name').html(seatnames.join(', ')); 3464 $('#selected-seat-fare').html(Number(fare).toFixed(2)); 3465 3466 if (Number(gst) > 0) { 3467 $('#selected-seat-gst').removeClass('d-none'); 3468 $('#selected-seat-gst').html(Number(gst).toFixed(2)); 3469 } 3470 3471 if (Number(discount) > 0) { 3472 $('#selected-seat-discount').removeClass('d-none'); 3473 $('#selected-seat-discount').html(Number(discount).toFixed(2)); 3474 } 3475 3476 $('#selected-seat-discount').html(Number(discount).toFixed(2)) 3477 .closest('.row').toggleClass('d-none', !Boolean(discount)); 3478 } 3479 3480 $('#selected-seat-pickupcharges').html(Number(boardingFare).toFixed(2)) 3481 .closest('.row').toggleClass('d-none', !Boolean(boardingFare)); 3482 $('#selected-seat-droppingcharges').html(Number(droppingFare).toFixed(2)) 3483 .closest('.row').toggleClass('d-none', !Boolean(droppingFare)); 3484 $('#selected-seat-gst').html(Number(gst).toFixed(2)) 3485 .closest('.row').toggleClass('d-none', !Boolean(gst)); 3486 // $('#selected-seat-discount').html(Number(discount).toFixed(2)) 3487 // .closest('.row').toggleClass('d-none', !Boolean(discount)); 3488 $('#selected-seat-total').html(Number(totalfare).toFixed(2)); 3489 3490 var overallAmountTooltipContent = ""; 3491 overallAmountTooltipContent += "Fare: " + currencySymbol + Number(fare).toFixed(2) + "<br>"; 3492 if (Number(gst) > 0) { 3493 overallAmountTooltipContent += "Service Tax (GST): " + currencySymbol + Number(gst).toFixed(2) + "<br>"; 3494 } 3495 3496 if (Number(discount) > 0) { 3497 overallAmountTooltipContent += "Discount: " + currencySymbol + Number(discount).toFixed(2) + "<br>"; 3498 } 3499 3500 if (Number(boardingFare) > 0) { 3501 overallAmountTooltipContent += "Boarding Fare: " + currencySymbol + Number(boardingFare).toFixed(2) + "<br>"; 3502 } 3503 3504 if (Number(droppingFare) > 0) { 3505 overallAmountTooltipContent += "Dropping Fare: " + currencySymbol + Number(droppingFare).toFixed(2) + "<br>"; 3506 } 3507 overallAmountTooltipContent += "Total Fare: " + currencySymbol + Number(totalfare).toFixed(2) + "<br>"; 3508 3509 $('.overall-amount-details .overall-amount-tooltip').html(overallAmountTooltipContent); 3510 3511 // $('#toggle-seat-fareinfo') 3512 // .toggleClass('d-none', (gst > 0 && discount > 0)) 3513 // .on('click', function () { 3514 // $(this).remove(); 3515 // $('#selected-seat-fareinfo').removeClass('d-none'); 3516 // }); 3517} 3518 3519function getQueryParametersFromURL() { 3520 var currentURL = location.href; 3521 var urlParts = currentURL.split('?'); 3522 3523 if (urlParts.length === 2) { 3524 var queryParams = urlParts[1]; 3525 var paramPairs = queryParams.split('&'); 3526 3527 var paramObject = {}; 3528 for (var i = 0; i < paramPairs.length; i++) { 3529 var pair = paramPairs[i].split('='); 3530 if (pair.length === 2) { 3531 var key = decodeURIComponent(pair[0]); 3532 var value = decodeURIComponent(pair[1]);
3533 paramObject[key] = value; 3534 } 3535 } 3536 3537 return paramObject.reschedule; 3538 } else { 3539 return null; 3540 } 3541} 3542 3543function getBookingData(tripinfo) { 3544 // shorthand 3545 var busmap = tripinfo.busmap; 3546 3547 var data = {}; 3548 data.tripCode = busmap.tripCode; 3549 data.tripStageCode = busmap.tripStageCode; 3550 data.fromStation = {}; 3551 data.fromStation.code = busmap.fromStation.code; 3552 data.fromStation.name = busmap.fromStation.name; 3553 data.fromStation.dateTime = busmap.fromStation.dateTime; 3554 data.toStation = {}; 3555 data.toStation.code = busmap.toStation.code; 3556 data.toStation.name = busmap.toStation.name; 3557 data.toStation.dateTime = busmap.toStation.dateTime; 3558 data.bus = {}; 3559 data.bus.code = busmap.bus.code; 3560 data.bus.categoryCode = busmap.bus.categoryCode; 3561 data.bus.busType = busmap.bus.busType; 3562 data.discountList = busmap.discountList; 3563 data.schedule = {}; 3564 data.schedule.code = busmap.schedule.code; 3565 data.city = busmap.fromStation.name; 3566 data.state = busmap.fromStation.state.name; 3567 data.cityCode = busmap.fromStation.code; 3568 data.stateCode = busmap.fromStation.state.code; 3569 3570 data.terms = tripinfo.terms || []; 3571 3572 data.fromStation.stationPoint = {}; // boarding point 3573 // var selectedBoarding = $('#boarding-point-list').val(); 3574 var selectedBoarding = $('input[name="boarding-point"]:checked').val(); 3575 $.each(busmap.fromStation.stationPoint || [], function (i, boarding) { 3576 if (boarding.code == selectedBoarding) { 3577 data.fromStation.stationPoint.code = boarding.code; 3578 data.fromStation.stationPoint.name = boarding.name; 3579 data.fromStation.stationPoint.dateTime = boarding.dateTime; 3580 data.fromStation.stationPoint.fare = Number(boarding.fare) || 0; 3581 return false; 3582 } 3583 }); 3584 3585 data.toStation.stationPoint = {}; // dropping point 3586 // var selectedDropping = $('#dropping-point-list').val(); 3587 var selectedDropping = $('input[name="dropping-point"]:checked').val(); 3588 $.each(busmap.toStation.stationPoint || [], function (i, dropping) { 3589 if (dropping.code == selectedDropping) { 3590 data.toStation.stationPoint.code = dropping.code; 3591 data.toStation.stationPoint.name = dropping.name; 3592 data.toStation.stationPoint.dateTime = dropping.dateTime; 3593 data.toStation.stationPoint.fare = Number(dropping.fare) || 0; 3594 return false; 3595 } 3596 }); 3597 3598 data.seatDetails = []; // seats 3599 $('#trip-' + data.tripCode).find('.busmap-layers .seat-selected').each(function (i, seat) { 3600 var $seat = $(seat); 3601 3602 var seatCode = $seat.data('code'); 3603 var seatDetail = tripinfo.seatDetails[seatCode]; 3604 seatDetail.seatCode = seatCode; 3605 data.seatDetails.push(seatDetail); 3606 }); 3607 3608 return data; 3609} 3610 3611function gotoPassengerDetails(reschedule = false) { 3612 var bookingData = sessionStorage.getItem('BOOKINGDATA'); 3613 sessionStorage.removeItem('BOOKINGDATA'); 3614 3615 if (!bookingData) { 3616 return; 3617 } 3618 3619 // submit form 3620 $('#form-seats-data').val(bookingData); 3621 $('#form-seats').attr('action', reschedule ? 'reschedule/passenger-info' : 'passenger-info').submit(); 3622} 3623 3624function autofillPassInfo() { 3625 var data = {}; 3626 data.mobileNumber = $('#pass-mobile').val().trim(); 3627 data.seatCount = $('.pass-info').length; 3628 3629 if (!validate.isMobile(data.mobileNumber)) { 3630 return; 3631 } 3632 if ($('#pass-mobile').data('oldvalue') == data.mobileNumber) { 3633 return; 3634 } 3635 3636 $('#pass-mobile').data('oldvalue', data.mobileNumber); 3637 3638 $.ajax({ 3639 type: 'POST', 3640 url: 'passenger-info/autofill-info', 3641 data: data, 3642 dataType: 'json', 3643 success: function (result) { 3644 if (result.status == 1) { 3645 var ticketDetails = result.data.ticketDetails; 3646 $('#pass-email').val(result.data.passegerEmailId); 3647 $('.pass-info').each(function (i) { 3648 if (i >= ticketDetails.length) return false; 3649 $this = $(this); 3650 3651 $this.find('.pass-name').val(ticketDetails[i].passengerName); 3652 $this.find('.pass-age').val(ticketDetails[i].passengerAge); 3653 $this.find('.pass-gender[value="' + ticketDetails[i].passengerGendar + '"]:not(:disabled)').prop('checked', true); 3654 }); 3655 } 3656 } 3657 }); 3658} 3659 3660function toggleRequestInvoice() { 3661 $('.gst-field').toggleClass('d-none'); 3662 $('#pass-gstemail').val($('#pass-email').val()); 3663} 3664 3665function toggleAllPassInfo() { 3666 var state = $('#all-pass-details').is(':checked'); 3667 3668 $('#onward-trip, #return-trip') 3669 .find('.pass-info:not(:first)') 3670 .find('.pass-name, .pass-age, .seat-name') 3671 .toggleClass('d-none', !state); 3672} 3673 3674function toggleConnRequestInvoice() { 3675 $('.gst-field').slideToggle('slow'); 3676 $('#pass-gstemail').val($('#pass-email').val()); 3677} 3678 3679function calculateTicketFare(offerData) { 3680 var { onwardData, returnData, rescheduleData } = getPassengerTicketData(); 3681 var addonCharges = getAddonCharges(); 3682 3683 var femaleDiscount; 3684 $.each(onwardData.discountList || [], function (i, discount) { 3685 if (discount.femaleDiscountFlag) { 3686 femaleDiscount = discount; 3687 } 3688 }); 3689 3690 var onwardfare = 0; 3691 var returnfare = 0; 3692 var boardingfare = 0; 3693 var droppingfare = 0; 3694 var gst = 0; 3695 var discount = 0; 3696 3697 var faredifference = 0; 3698 3699 var onwardSeatCount = onwardData.seatDetails.length; 3700 $.each(onwardData.seatDetails || [], function (i, seat) { 3701 onwardfare += seat.fare; 3702 gst += seat.serviceTax; 3703 discount += seat.discountFare; 3704 3705 if (femaleDiscount) { 3706 var gender = $('.onward-trip [data-code="' + seat.seatCode + '"]').find('.pass-gender:checked').val(); 3707 3708 if (gender === 'F') { 3709 discount += (femaleDiscount.percentageFlag) 3710 ? percentageOf(femaleDiscount.discountValue, seat.fare) 3711 : femaleDiscount.discountValue; 3712 } 3713 } 3714 }); 3715 3716 if (onwardData.fromStation.stationPoint && Number(onwardData.fromStation.stationPoint.fare) > 0) { 3717 boardingfare += Number(onwardData.fromStation.stationPoint.fare) * onwardSeatCount; 3718 } 3719 3720 if (onwardData.toStation.stationPoint && Number(onwardData.toStation.stationPoint.fare) > 0) { 3721 droppingfare += Number(onwardData.toStation.stationPoint.fare) * onwardSeatCount; 3722 } 3723 3724 if (returnData) { 3725 var returnSeatCount = returnData.seatDetails.length; 3726 $.each(returnData.seatDetails || [], function (i, seat) { 3727 returnfare += seat.fare; 3728 gst += seat.serviceTax; 3729 discount += seat.discountFare; 3730 }); 3731 3732 if (returnData.fromStation.stationPoint && Number(returnData.fromStation.stationPoint.fare) > 0) { 3733 boardingfare += Number(returnData.fromStation.stationPoint.fare) * returnSeatCount; 3734 } 3735 if (returnData.toStation.stationPoint && Number(returnData.toStation.stationPoint.fare) > 0) { 3736 droppingfare += Number(returnData.toStation.stationPoint.fare) * returnSeatCount; 3737 } 3738 } 3739 3740 $('#apply-offer-help').html(''); 3741 if (offerData) { 3742 var offerValue = (offerData.percentageFlag) ? percentageOf(offerData.value, fare) : offerData.value;
3743 var offerAmount = Math.max((offerData.maxvalue || 0), offerValue); 3744 3745 $('#apply-offer-help').html('A discount of ' + currencySymbol + Number(offerAmount).toFixed(2) + ' has been applied'); 3746 discount += offerAmount; 3747 } 3748 3749 var totalfare = onwardfare + returnfare + boardingfare + droppingfare - discount; 3750 3751 if (gst > 0) { 3752 const GSTPERCENT = 5; 3753 gst = percentageOf(GSTPERCENT, totalfare); 3754 totalfare += gst; 3755 } 3756 3757 if (rescheduleData) { 3758 faredifference = Math.max(0, totalfare - rescheduleData.totalPaid + discount); 3759 totalfare = faredifference + rescheduleData.reschedulableAmount; 3760 } 3761 3762 var gogreen = $('#gogreen-addon-cb').is(':checked'); 3763 if (addonCharges.GOGREEN && gogreen) { 3764 totalfare += addonCharges.GOGREEN; 3765 } 3766 3767 var pgcharges = 0; 3768 var pgchargepercent = Number($('input[name="payment-options"]:checked').data('pgcharges')) || 0; 3769 if (pgchargepercent > 0) { 3770 pgcharges = percentageOf(pgchargepercent, totalfare); 3771 totalfare += pgcharges; 3772 } 3773 3774 // totalfare = Math.round(totalfare); 3775 3776 $faretable = $('#pass-fare-details').empty(); 3777 3778 if (rescheduleData) { 3779 if (faredifference > 0) { 3780 $faretable.append(buildFareRow('NEWTICKET', onwardfare)); 3781 // $faretable.append(buildFareRow('DISCOUNT', discount)); 3782 $faretable.append(buildFareRow('GST', gst)); 3783 $faretable.append(buildFareRow('OLDTICKET', rescheduleData.totalPaid)); 3784 $faretable.append(emptyFareRow('<div class="border-top" />')); 3785 $faretable.append(buildFareRow('FAREDIFF', faredifference)); 3786 } 3787 $faretable.append(buildFareRow('RESCHARGE', rescheduleData.reschedulableAmount)); 3788 $faretable.append(buildFareRow('PGCHARGE', pgcharges)); 3789 } else { 3790 $faretable.append(buildFareRow(returnfare ? 'ONWARD' : 'BASEFARE', onwardfare)); 3791 $faretable.append(buildFareRow('RETURN', returnfare)); 3792 $faretable.append(buildFareRow('PICKUP', boardingfare)); 3793 $faretable.append(buildFareRow('DROPPING', droppingfare)); 3794 $faretable.append(buildFareRow('DISCOUNT', discount)); 3795 $faretable.append(buildFareRow('GST', gst)); 3796 $faretable.append(buildFareRow('PGCHARGE', pgcharges)); 3797 if (gogreen) { 3798 $faretable.append(buildFareRow('GOGREEN', addonCharges.GOGREEN)); 3799 } 3800 } 3801 $faretable.append(emptyFareRow()); 3802 $faretable.append(buildFareRow('TOTAL', totalfare)); 3803 3804 if (totalfare == 0) { 3805 $('#pg-accordion, #pg-redirect-hint').addClass('d-none'); 3806 $('#block-ticket-btn').html('Continue'); 3807 } 3808} 3809 3810function buildFareRow(code, value) { 3811 var entities = { 3812 'BASEFARE': { name: 'Ticket Fare', type: 'Cr', class: 'ticket-fare-tr' }, 3813 'ONWARD': { name: 'Onward Ticket Fare', type: 'Cr', class: '' }, 3814 'RETURN': { name: 'Return Ticket Fare', type: 'Cr', class: '' }, 3815 'PICKUP': { name: 'Pickup Charges', type: 'Cr', class: '' }, 3816 'DROPPING': { name: 'Dropping Charges', type: 'Cr', class: '' }, 3817 'DISCOUNT': { name: 'Discount', type: 'Dr', class: '' }, 3818 'GST': { name: 'GST', type: 'Cr', class: '' }, 3819 'PGCHARGE': { name: 'Payment Gateway Charges', type: 'Cr', class: '' }, 3820 'GOGREEN': { name: 'Go Green', type: 'Cr', class: 'text-success' }, 3821 'NEWTICKET': { name: 'New Ticket Fare', type: 'Cr', class: '' }, 3822 'OLDTICKET': { name: 'Old Ticket Fare', type: 'Dr', class: '' }, 3823 'FAREDIFF': { name: 'Fare Difference', type: 'Cr', class: '' }, 3824 'RESCHARGE': { name: 'Reschedule Charges', type: 'Cr', class: '', allowZero: true }, 3825 'TOTAL': { name: 'Total Fare', type: 'NA', class: 'total-fare-tr', allowZero: true }, 3826 'GRANDTOTAL': { name: 'Grand Total', type: 'NA', class: 'total-fare-tr', allowZero: true }, 3827 'ONWFARE': { name: 'Onward Bus Fare', type: 'Cr', class: '' }, 3828 'BUSFARE': { name: 'Bus Fare', type: 'Cr', class: '' }, 3829 'ONWDISCOUNT': { name: 'Discount', type: 'Ar', class: '' }, 3830 'ONWGST': { name: 'Tax', type: 'Cr', class: '' }, 3831 'ONWTOTAL': { name: 'Total Fare', type: 'NA', class: 'total-fare-tr' }, 3832 'RETFARE': { name: 'Return Bus Fare', type: 'Cr', class: '' }, 3833 'RETDISCOUNT': { name: 'Discount', type: 'Ar', class: '' }, 3834 'RETGST': { name: 'Tax', type: 'Cr', class: '' }, 3835 'RETTOTAL': { name: 'Total Fare', type: 'NA', class: 'total-fare-tr' }, 3836 'HOTELFARE': { name: 'Room Fare', type: 'Cr', class: 'hotel-fare' }, 3837 'HOTELPERSONFARE': { name: 'Extra Person Fare', type: 'Cr', class: 'hotel-person-fare' }, 3838 'HOTELDISCOUNT': { name: 'Discount', type: 'Ar', class: 'hotel-discount' }, 3839 'HOTELGST': { name: 'Tax', type: 'Cr', class: 'hotel-gst' }, 3840 'HOTELTOTAL': { name: 'Total Hotel Fare', type: 'NA', class: 'hotel-total' }, 3841 'OVRTOTAL': { name: 'Total Bus Fare', type: 'NA', class: '' }, 3842 'TOTALDISCOUNT': { name: 'Total Discount Fare', type: 'NA', class: '' }, 3843 'TAXTOTAL': { name: 'Tax', type: 'NA', class: '' }, 3844 }; 3845 3846 if (!entities[code] || (!entities[code].allowZero && Number(value) <= 0)) { 3847 return null; 3848 } 3849 3850 var $tr = $('<tr />').addClass(entities[code].class); 3851 $('<td />').addClass('text-left').addClass(entities[code].class).addClass('fare-clr').text(entities[code].name).appendTo($tr); 3852 $('<td />').addClass('text-right').addClass(entities[code].class).html('<i class="fa fa-rupee-sign fa-fw"></i> ' + (entities[code].type == 'Dr' ? '-' : '') + Number(value).toFixed(2)).appendTo($tr); 3853 3854 return $tr; 3855} 3856 3857function emptyFareRow(content) { 3858 var $tr = $('<tr />'); 3859 $('<td colspan="2"/>').html(content).appendTo($tr); 3860 3861 return $tr; 3862} 3863 3864function processTicketData(ticketData, type) { 3865 $('#pass-alert').html(''); 3866 3867 var data = {}; 3868 data.mobileNumber = $('#pass-mobile').val().trim(); 3869 data.emailId = $('#pass-email').val().trim(); 3870 data.offerDiscountCode = $('#pass-offercode').val().trim(); 3871 data.gatewayPartner = {}; 3872 data.gatewayPartner.code = $('input[name="payment-options"]:checked').val() || ''; 3873 data.orderDetails = []; 3874 data.addexOrder = []; // addex array 3875 3876 var err = 0; 3877 if (!validate.isMobile(data.mobileNumber)) { 3878 $('#pass-mobile').addClass('is-invalid'); 3879 err++; 3880 } 3881 if (!validate.isEmail(data.emailId)) { 3882 $('#pass-email').addClass('is-invalid'); 3883 err++; 3884 } 3885 if (!type) { 3886 if ($('input[name="payment-options"]').length && data.gatewayPartner.code == '') { 3887 $('input[name="payment-options"]').addClass('is-invalid'); 3888 err++; 3889 } 3890 } 3891 3892 // autofill first seat name
3893 var allPassDetails = $('#all-pass-details').is(':checked'); 3894 if (!allPassDetails) { 3895 $('#onward-trip, #return-trip').find('.pass-info:first').each(function () { 3896 var $firstseat = $(this); 3897 var $hiddenseats = $firstseat.siblings('.pass-info'); 3898 3899 $hiddenseats.find('.pass-name').val($firstseat.find('.pass-name').val()); 3900 $hiddenseats.find('.pass-age').val($firstseat.find('.pass-age').val()); 3901 }); 3902 } 3903 3904 var { onwardData, returnData, hotelData } = ticketData; 3905 3906 var addonCharges = getAddonCharges(); 3907 3908 var onwardTicket = {}; 3909 onwardTicket.journeyType = 'OW'; 3910 onwardTicket.tripCode = onwardData.tripCode; 3911 onwardTicket.fromStation = {}; 3912 onwardTicket.fromStation.code = onwardData.fromStation.code; 3913 onwardTicket.toStation = {}; 3914 onwardTicket.toStation.code = onwardData.toStation.code; 3915 onwardTicket.boardingPoint = onwardData.fromStation.stationPoint; 3916 onwardTicket.droppingPoint = onwardData.toStation.stationPoint; 3917 onwardTicket.travelDate = moment(onwardData.fromStation.dateTime).format('YYYY-MM-DD'); 3918 onwardTicket.ticketDetails = []; 3919 $.each(onwardData.seatDetails || [], function (i, seatDetail) { 3920 var $seat = $('#onward-trip .pass-info[data-code="' + seatDetail.seatCode + '"]') 3921 3922 var seat = {}; 3923 seat.seatCode = seatDetail.seatCode; 3924 seat.seatName = seatDetail.seatName; 3925 seat.seatFare = seatDetail.fare; 3926 seat.passengerName = $seat.find('.pass-name').val().trim(); 3927 seat.passengerAge = $seat.find('.pass-age').val().trim(); 3928 seat.passengerGendar = $seat.find('.pass-gender:checked').val() || ''; 3929 onwardTicket.ticketDetails.push(seat); 3930 3931 if (seat.passengerName == '') { 3932 $seat.find('.pass-name').addClass('is-invalid'); 3933 err++; 3934 } 3935 if (seat.passengerAge == '') { 3936 $seat.find('.pass-age').addClass('is-invalid'); 3937 err++; 3938 } 3939 if (seat.passengerGendar == '') { 3940 $seat.find('.pass-gender').addClass('is-invalid'); 3941 err++; 3942 } 3943 }); 3944 3945 data.orderDetails.push(onwardTicket); 3946 3947 if (returnData) { 3948 var returnTicket = {}; 3949 returnTicket.journeyType = 'RT'; 3950 returnTicket.tripCode = returnData.tripCode; 3951 returnTicket.fromStation = {}; 3952 returnTicket.fromStation.code = returnData.fromStation.code; 3953 returnTicket.toStation = {}; 3954 returnTicket.toStation.code = returnData.toStation.code; 3955 returnTicket.boardingPoint = returnData.fromStation.stationPoint; 3956 returnTicket.droppingPoint = returnData.toStation.stationPoint; 3957 returnTicket.travelDate = moment(returnData.fromStation.dateTime).format('YYYY-MM-DD'); 3958 returnTicket.ticketDetails = []; 3959 $.each(returnData.seatDetails || [], function (i, seatDetail) { 3960 var $seat = $('#return-trip .pass-info[data-code="' + seatDetail.seatCode + '"]') 3961 3962 var seat = {}; 3963 seat.seatCode = seatDetail.seatCode; 3964 seat.seatName = seatDetail.seatName; 3965 seat.seatFare = seatDetail.fare; 3966 seat.passengerName = $seat.find('.pass-name').val().trim(); 3967 seat.passengerAge = $seat.find('.pass-age').val().trim(); 3968 seat.passengerGendar = $seat.find('.pass-gender:checked').val() || ''; 3969 returnTicket.ticketDetails.push(seat); 3970 3971 if (seat.passengerName == '') { 3972 $seat.find('.pass-name').addClass('is-invalid'); 3973 err++; 3974 } 3975 if (seat.passengerAge == '') { 3976 $seat.find('.pass-age').addClass('is-invalid'); 3977 err++; 3978 } 3979 if (seat.passengerGendar == '') { 3980 $seat.find('.pass-gender').addClass('is-invalid'); 3981 err++; 3982 } 3983 }); 3984 3985 data.orderDetails.push(returnTicket); 3986 } 3987 3988 if (hotelData && $('.hotel-details-card').hasClass('selected')) { 3989 3990 var addonHotel = {}; 3991 var addonCode = $('.hotel-details-card.selected').data('addon-code'); 3992 var hotelDetails = $.each(hotelData || [], function (i, hotel) { 3993 return addonCode == hotel.code 3994 }); 3995 const currentDate = new Date(); 3996 3997 addonHotel.orderDate = formatHotelDate(onwardData.toStation.dateTime); 3998 addonHotel.transactionDate = formatHotelDate(currentDate); 3999 4000 addonHotel.serviceType = {}; 4001 addonHotel.serviceType.code = $('.hotel-details-card.selected').data('addon-service-code'); 4002 4003 addonHotel.addon = {}; 4004 addonHotel.addon.code = addonCode; 4005 addonHotel.addon.criteriaCode = $('.hotel-details-card.selected').data('addon-criteria-code');
4006 addonHotel.inventoryCode = $('.hotel-details-card.selected').data('addon-inv-code'); 4007 4008 addonHotel.orderDetails = {}; 4009 addonHotel.orderDetails.checkIn = $('.hotel-details-card.selected').data('addon-c-in'); 4010 addonHotel.orderDetails.checkOut = $('.hotel-details-card.selected').data('addon-c-out'); 4011 addonHotel.orderDetails.personCount = onwardData.seatDetails.length; 4012 4013 var roomCount = $('.hotel-details-card.selected').find('.hotel-rooms-number').text(); 4014 var personcount = $('.hotel-details-card.selected').find('.hotel-person-number').text(); 4015 addonHotel.orderDetails.addonCount = convertToNumber(roomCount); 4016 addonHotel.orderDetails.extraPersonCount = convertToNumber(personcount); 4017 4018 var custname = ''; 4019 $('#onward-trip, #return-trip').find('.pass-info:first').each(function () { 4020 var $firstseat = $(this); 4021 custname = $firstseat.find('.pass-name').val().trim(); 4022 }); 4023 addonHotel.customerName = custname; 4024 addonHotel.customerMobileNumber = $('#pass-mobile').val().trim(); 4025 addonHotel.activeFlag = 1; 4026 addonHotel.ticketAmount = $('#ticket-amount').val(); 4027 4028 data.addexOrder.push(addonHotel); 4029 } 4030 4031 data.additionalAttributes = {}; 4032 data.additionalAttributes.WHATSAPP_NOTIFICATION_FLAG = $('input[name="whatsapp-flag"]:checked').length === 0 ? 1 : 0; 4033 data.additionalAttributes.CITY_CODE = $('#pass-city').data('code'); 4034 data.additionalAttributes.STATE_CODE = $('#pass-state').data('code'); 4035 var alternateMobileNo = $('#pass-mobile-alt').val().trim(); 4036 if (validate.isMobile(alternateMobileNo)) { 4037 data.additionalAttributes.ALTERNATE_MOBILE = alternateMobileNo; 4038 } 4039 4040 if ($('#pass-gst-invoice').is(':checked')) { 4041 data.additionalAttributes.GST_IN = $('#pass-gstin').val().trim(); 4042 data.additionalAttributes.GST_TRADE_NAME = $('#pass-gsttrade').val().trim(); 4043 data.additionalAttributes.GST_EMAIL = $('#pass-gstemail').val().trim(); 4044 4045 if (!validate.isGSTIN(data.additionalAttributes.GST_IN)) { 4046 $('#pass-gstin').addClass('is-invalid'); 4047 err++; 4048 } 4049 if (data.additionalAttributes.GST_TRADE_NAME == '') { 4050 $('#pass-gsttrade').addClass('is-invalid'); 4051 err++; 4052 } 4053 if (!validate.isEmail(data.additionalAttributes.GST_EMAIL)) { 4054 $('#pass-gstemail').addClass('is-invalid'); 4055 err++; 4056 } 4057 } 4058 4059 var gogreen = $('#gogreen-addon-cb').is(':checked'); 4060 if (gogreen && addonCharges.GOGREEN) { 4061 data.additionalAttributes.GO_GREEN = addonCharges.GOGREEN; 4062 } 4063 4064 if (err) { 4065 $('#pass-alert').danger().on('detach', function () { 4066 $('.is-invalid').removeClass('is-invalid'); 4067 }); 4068 return false; 4069 } 4070 4071 return data; 4072} 4073 4074function validateOffer(ticketData, type) { 4075 4076 if (type == 'CONN') { 4077 var data = processConnTicketData(ticketData); 4078 } else { 4079 var data = processTicketData(ticketData, 'addon'); 4080 } 4081 4082 if (!data || !data.offerDiscountCode) { 4083 // calculateTicketFare(); 4084 if (type == 'CONN') { 4085 connCalculation(); 4086 } else { 4087 newTicketCalculation(); 4088 } 4089 return; 4090 } 4091 4092 $('#apply-offer-help').html(''); 4093 $('#apply-offer-btn') 4094 .prop('disabled', true) 4095 .html('Apply'); 4096 4097 $.ajax({ 4098 type: 'POST', 4099 url: 'passenger-info/validate-offer', 4100 data: data, 4101 dataType: 'json', 4102 success: function (result) { 4103 $('#apply-offer-btn').prop('disabled', false).html('Apply'); 4104 if (result.status == 1) { 4105 // calculateTicketFare(result.data); 4106 if (type == 'CONN') { 4107 connCalculation(result.data); 4108 } else { 4109 newTicketCalculation(result.data); 4110 } 4111 4112 $('#apply-offer-help') 4113 .removeClass('text-danger') 4114 .addClass('text-success'); 4115 } else { 4116 $('#apply-offer-help') 4117 .addClass('text-danger') 4118 .removeClass('text-success') 4119 .html(result.errorDesc); 4120 } 4121 } 4122 }); 4123} 4124 4125 4126function processConnTicketData(ticketData) { 4127 $('#pass-alert').html(''); 4128 4129 var data = {}; 4130 data.mobileNumber = $('#pass-mobile').val().trim(); 4131 data.emailId = $('#pass-email').val().trim(); 4132 data.offerDiscountCode = ''; 4133 data.gatewayPartner = {}; 4134 data.gatewayPartner.code = $('input[name="payment-options"]:checked').val() || ''; 4135 data.city = $('#pass-city').val().trim(); 4136 data.state = $('#pass-state').val().trim(); 4137 4138 data.addexOrder = []; // addex array 4139 4140 var err = 0; 4141 if (!validate.isMobile(data.mobileNumber)) { 4142 $('#pass-mobile').addClass('is-invalid'); 4143 err++; 4144 } 4145 if (!validate.isEmail(data.emailId)) { 4146 $('#pass-email').addClass('is-invalid'); 4147 err++; 4148 } 4149 if ($('input[name="payment-options"]').length && data.gatewayPartner.code == '') { 4150 $('input[name="payment-options"]').addClass('is-invalid'); 4151 err++; 4152 } 4153 4154 data.additionalAttributes = {}; 4155 data.additionalAttributes.WHATSAPP_NOTIFICATION_FLAG = $('input[name="whatsapp-flag"]:checked').length === 0 ? 1 : 0; 4156 data.additionalAttributes.CITY_CODE = $('#pass-city').data('code'); 4157 data.additionalAttributes.STATE_CODE = $('#pass-state').data('code'); 4158 data.additionalAttributes.TRIP_CONNECT = $('#conn-schedule-code').val(); 4159 var alternateMobileNo = $('#pass-mobile-alt').val().trim(); 4160 if (validate.isMobile(alternateMobileNo)) { 4161 data.additionalAttributes.ALTERNATE_MOBILE = alternateMobileNo; 4162 } 4163 4164 if ($('#pass-gst-invoice').is(':checked')) { 4165 data.additionalAttributes.GST_IN = $('#pass-gstin').val().trim();
4166 data.additionalAttributes.GST_TRADE_NAME = $('#pass-gsttrade').val().trim(); 4167 data.additionalAttributes.GST_EMAIL = $('#pass-gstemail').val().trim(); 4168 4169 if (!validate.isGSTIN(data.additionalAttributes.GST_IN)) { 4170 $('#pass-gstin').addClass('is-invalid'); 4171 err++; 4172 } 4173 if (data.additionalAttributes.GST_TRADE_NAME == '') { 4174 $('#pass-gsttrade').addClass('is-invalid'); 4175 err++; 4176 } 4177 if (!validate.isEmail(data.additionalAttributes.GST_EMAIL)) { 4178 $('#pass-gstemail').addClass('is-invalid'); 4179 err++; 4180 } 4181 } 4182 4183 const lastEleOfOrderDetails = ticketData.connectOrderDetails[ticketData.connectOrderDetails.length - 1]; 4184 if (ticketData.hotelData && $('.hotel-details-card').hasClass('selected')) { 4185 4186 var addonHotel = {}; 4187 var addonCode = $('.hotel-details-card.selected').data('addon-code'); 4188 // var hotelDetails = $.each(hotelData || [], function (i, hotel) { 4189 // return addonCode == hotel.code 4190 // }); 4191 const currentDate = new Date(); 4192 4193 addonHotel.orderDate = formatHotelDate(lastEleOfOrderDetails.bus.toStationTime); 4194 addonHotel.transactionDate = formatHotelDate(currentDate); 4195 4196 addonHotel.serviceType = {}; 4197 addonHotel.serviceType.code = $('.hotel-details-card.selected').data('addon-service-code'); 4198 4199 addonHotel.addon = {}; 4200 addonHotel.addon.code = addonCode; 4201 addonHotel.addon.criteriaCode = $('.hotel-details-card.selected').data('addon-criteria-code'); 4202 addonHotel.inventoryCode = $('.hotel-details-card.selected').data('addon-inv-code'); 4203 4204 addonHotel.orderDetails = {}; 4205 addonHotel.orderDetails.checkIn = $('.hotel-details-card.selected').data('addon-c-in'); 4206 addonHotel.orderDetails.checkOut = $('.hotel-details-card.selected').data('addon-c-out'); 4207 addonHotel.orderDetails.personCount = lastEleOfOrderDetails.ticketDetails.length; 4208 4209 var roomCount = $('.hotel-details-card.selected').find('.hotel-rooms-number').text(); 4210 var personcount = $('.hotel-details-card.selected').find('.hotel-person-number').text();
4211 addonHotel.orderDetails.addonCount = convertToNumber(roomCount); 4212 addonHotel.orderDetails.extraPersonCount = convertToNumber(personcount); 4213 4214 var custname = ''; 4215 $('#connecting-trip').find('.pass-info:first').each(function () { 4216 var $firstseat = $(this); 4217 custname = $firstseat.find('.pass-name').val().trim(); 4218 }); 4219 addonHotel.customerName = custname; 4220 addonHotel.customerMobileNumber = $('#pass-mobile').val().trim(); 4221 addonHotel.activeFlag = 1; 4222 addonHotel.ticketAmount = $('#conn-ticket-amount').val(); 4223 4224 data.addexOrder.push(addonHotel); 4225 } 4226 4227 data.orderDetails = transformConnTicketDataArray(ticketData.connectOrderDetails); 4228 4229 // var allPassDetails = $('#all-pass-details').is(':checked'); 4230 // if (allPassDetails) { 4231 // // If the checkbox is checked, fill all pass-name fields with the name from the first seat 4232 // var firstSeatName = $('#connecting-trip').find('.pass-info:first .pass-name').val().trim(); 4233 // $('#connecting-trip').find('.pass-name').val(firstSeatName); 4234 // } else { 4235 // // If the checkbox is not checked, only fill the siblings of the first seat 4236 // $('#connecting-trip').find('.pass-info:first').each(function () { 4237 // var $firstseat = $(this); 4238 // var $hiddenseats = $firstseat.siblings('.pass-info'); 4239 4240 // $hiddenseats.find('.pass-name').val($firstseat.find('.pass-name').val()); 4241 // $hiddenseats.find('.pass-age').val($firstseat.find('.pass-age').val()); 4242 // }); 4243 // } 4244 4245 // var ticketDetailsLength = lastEleOfOrderDetails.ticketDetails.length; 4246 // if (ticketDetailsLength > 0) { 4247 // var firstSeatName = $('#connecting-trip').find('.pass-info:first .pass-name').val().trim(); 4248 // for (var i = 0; i < ticketDetailsLength; i++) { 4249 // $('#connecting-trip').find('.pass-name').eq(i).val(firstSeatName); 4250 // } 4251 // } 4252 4253 $('#connecting-trip').find('.pass-name').each(function () { 4254 if ($(this).val().trim() === '') { 4255 $(this).addClass('is-invalid'); 4256 err++; 4257 } 4258 }); 4259 4260 $('#connecting-trip').find('.pass-age').each(function () { 4261 if ($(this).val().trim() === '') { 4262 $(this).addClass('is-invalid'); 4263 err++; 4264 } 4265 }); 4266 4267 $('#connecting-trip').find('.pass-info').each(function () { 4268 var $genderInputs = $(this).find('.pass-gender'); 4269 if (!$genderInputs.is(':checked')) { 4270 $genderInputs.addClass('is-invalid'); 4271 err++; 4272 } 4273 }); 4274 4275 if (err) { 4276 $('#pass-alert').danger().on('detach', function () { 4277 $('.is-invalid').removeClass('is-invalid'); 4278 }); 4279 return false; 4280 } 4281 4282 return data; 4283} 4284 4285function transformConnTicketDataArray(dataArray) { 4286 let transformedArray = dataArray.map(conndata => { 4287 4288 let transformedData = { 4289 tripCode: conndata.tripCode || '', 4290 travelDate: conndata.travelDate || '', 4291 journeyType: conndata.journeyType || '', 4292 fromStation: { 4293 code: conndata.fromStation || '', 4294 name: conndata.fromStationName || '', 4295 }, 4296 boardingPoint: { 4297 code: conndata.boardingPoint || '', 4298 name: conndata.boardingPointName || '', 4299 }, 4300 toStation: { 4301 code: conndata.toStation || '', 4302 name: conndata.toStationName || '', 4303 }, 4304 droppingPoint: { 4305 code: conndata.droppingPoint || '', 4306 name: conndata.droppingPointName || '', 4307 }, 4308 ticketDetails: [] 4309 }; 4310 4311 conndata.ticketDetails.forEach(ticket => { 4312 let transformedTicketDetail = { 4313 seatCode: ticket.seatCode || '', 4314 passengerGendar: ticket.passengerGendar || '', 4315 passengerName: ticket.passengerName || '', 4316 passengerAge: ticket.passengerAge || '', 4317 seatFare: ticket.fare || 0, 4318 seatName: ticket.seatName || '', 4319 idProof: null 4320 }; 4321 4322 const $passInfoBlock = $('#connecting-trip').find(`.pass-info[data-code="${ticket.seatCode}"]`); 4323 const passengerName = $passInfoBlock.find('.pass-name').val().trim(); 4324 const passengerAge = $passInfoBlock.find('.pass-age').val().trim(); 4325 const passengerGender = $passInfoBlock.find('.pass-gender:checked').val(); 4326 4327 transformedTicketDetail.passengerName = passengerName; 4328 transformedTicketDetail.passengerAge = passengerAge; 4329 transformedTicketDetail.passengerGendar = passengerGender; 4330 4331 transformedData.ticketDetails.push(transformedTicketDetail); 4332 }); 4333 4334 return transformedData; 4335 }); 4336 4337 return transformedArray; 4338} 4339 4340function initBlockSeats(ticketData) { 4341 var data = processTicketData(ticketData); 4342 4343 if (!$('#pass-terms').is(':checked')) { 4344 $('#pass-terms').addClass('is-invalid'); 4345 return; 4346 } 4347 4348 if (!data) { 4349 return; 4350 } 4351 4352 $('#block-ticket-btn') 4353 .prop('disabled', true) 4354 .html( 4355 '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> ' + 4356 'Please wait...' 4357 ); 4358 4359 $.ajax({ 4360 type: 'POST', 4361 url: 'passenger-info/block-seats', 4362 data: data, 4363 dataType: 'json', 4364 success: function (result) { 4365 if (result.status == 1) { 4366 if (result.data.paymentGatewayProcessFlag) { 4367 if (result.data.gatewayCode == 'RAZORPAY') { 4368 var options = result.data.gatewayInputDetails; 4369 options.image = 'assets/images/logo.png'; 4370 options.theme = {}; 4371 options.theme.color = getComputedStyle(document.documentElement).getPropertyValue('--theme-primary-color').trim(); 4372 options.modal = {}; 4373 options.modal.escape = false;
4374 options.modal.confirm_close = true; 4375 options.modal.ondismiss = function () { 4376 location.href = 'passenger-info/payment-response?orderCode=' + result.data.code; 4377 }; 4378 var rzp1 = new Razorpay(options); 4379 rzp1.open(); 4380 return 4381 } 4382 4383 var formControl = ''; 4384 $.each(result.data.gatewayInputDetails || [], function (rekey, reval) { 4385 formControl += '<input name="' + rekey + '" id="' + rekey + '" value="' + reval + '" />'; 4386 }); 4387 $('body').append('<form action="' + result.data.paymentRequestUrl + '" name="frm_payment" id="frm_payment" method="post" style="display:none;">' + formControl + '</form>'); 4388 $('#frm_payment').submit(); 4389 } else { 4390 location.href = 'passenger-info/payment-response?orderCode=' + result.data.code; 4391 } 4392 } else { 4393 $('#pass-alert').danger(result.errorDesc); 4394 } 4395 $('#block-ticket-btn').prop('disabled', false).html('Continue'); 4396 } 4397 }); 4398} 4399 4400function doAgentLogin(event) { 4401 event.preventDefault(); 4402 4403 var data = { 4404 username: $('#agent-login-username').val().trim(), 4405 password: $('#agent-login-password').val().trim() 4406 }; 4407 4408 var err = 0; 4409 4410 if (data.username === '') { 4411 $('#agent-login-username').addClass('is-invalid'); 4412 err++; 4413 } 4414 4415 if (data.password.length < 6) { 4416 $('#agent-login-password').addClass('is-invalid'); 4417 err++; 4418 } 4419 4420 if (err) { 4421 $('#agent-login-alert').danger().on('detach', function () { 4422 $('#agent-login-form .is-invalid').removeClass('is-invalid'); 4423 }); 4424 return; 4425 } 4426 4427 $('#agent-login-btn').html('Loading...').attr('disabled', true); 4428 4429 $.ajax({ 4430 type: 'POST', 4431 url: 'user/authenticate', 4432 data: data, 4433 dataType: 'json', 4434 success: function (result) { 4435 $('#agent-login-btn').text('Get Details').attr('disabled', false); 4436 4437 if (result && result.status == 1) { 4438 let groupCode = result.data?.group?.code || null; 4439 4440 let profileGroup = result?.otpVerifyGroup || []; 4441 let profileGroupCode = profileGroup[0]?.code || null; 4442 4443 let matchFound = true; // default to true 4444 4445 let groupMatch = false; // default to false 4446 groupMatch = profileGroup.some(group => group.code === groupCode); 4447 4448 if (groupCode && profileGroupCode) { 4449 if (groupMatch) { 4450 matchFound = false; // if same, set to false 4451 } 4452 } 4453 4454 if (matchFound) { 4455 4456 const operatorCode = $('#op').val() || ''; 4457 if (operatorCode !== 'jbconnect') { 4458 window.open('user/dashboard', '_blank'); 4459 } 4460 $('#agent-login-alert').success({ 4461 message: 'Login success', 4462 delay: 1500 4463 }).on('detach', function () { 4464 location.replace(''); 4465 }); 4466 4467 $('#otp-section-two').hide(); 4468 $('#otp-verify-btn').hide(); 4469 $('#otp-verifyed-btn').hide(); 4470 } else { 4471 generateOtpLogin(); // fallback if group mismatch 4472 } 4473 4474 } else { 4475 // Show login error if status is not 1 or data is invalid 4476 let errorMsg = result?.errorDesc || 'Login failed'; 4477 $('#agent-login-alert').html('<div class="alert alert-danger">' + errorMsg + '</div>').show(); 4478 } 4479 }, 4480 }); 4481} 4482 4483function generateOtpLogin() { 4484 var data = {}; 4485 $.ajax({ 4486 type: 'POST', 4487 url: 'user/generate-otp', 4488 data: data, 4489 dataType: 'json', 4490 success: function (response) { 4491 if (response.status == 1) { 4492 $('#otp-section-two').show(); 4493 $('#otp-verify-btn').show(); 4494 $('#otp-verifyed-btn').hide(); 4495 $('#agent-login-btn').hide(); 4496 $('#agent-login-otps').val(''); 4497 $('#agent-login-username').prop('readonly', true); 4498 $('#agent-login-password').prop('readonly', true); 4499 $('#agent-login-alert').html('<div class="alert alert-danger">' + (response.message || 'Failed to generate OTP') + '</div>').hide(); 4500 // window.authToken = authToken; 4501 } else { 4502 $('#otp-verify-btn').hide(); 4503 $('#otp-verifyed-btn').show(); 4504 $('#otp-section-two').show(); 4505 $('#agent-login-btn').hide(); 4506 } 4507 } 4508 }); 4509} 4510 4511function verifyOtpNumber() { 4512 4513 var data = {}; 4514 data.otpNumber = $('#agent-login-otps').val().trim(); 4515 var err = 0; 4516 4517 if (data.otpNumber.length < 6) { 4518 $('#agent-login-otps').addClass('is-invalid'); 4519 err++; 4520 } 4521 4522 if (err > 0) { 4523 $('#agent-login-alert').html('<div class="alert alert-danger">Please enter the 6-digit OTP.</div>').show(); 4524 return; 4525 } 4526 4527 $('#otp-verify-btn') 4528 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Verifying...') 4529 .attr('disabled', true); 4530 4531 $.ajax({ 4532 type: 'POST', 4533 url: 'user/verifynumber', 4534 data: data, 4535 dataType: 'json', 4536 success: function (result) { 4537 4538 $('#otp-verify-btn').text('Verify OTP').attr('disabled', false); 4539 if (result.status == 1) { 4540 window.open('user/dashboard', '_blank'); 4541 $('#agent-login-alert').success({ 4542 message: 'Login success', 4543 delay: 1500 4544 }).on('detach', function () { 4545 location.replace(''); 4546 }); 4547 4548 $('#otp-section-two').hide(); 4549 $('#otp-verify-btn').hide(); 4550 $('#otp-verifyed-btn').hide(); 4551 4552 4553 } else { 4554 $('#agent-login-alert').html('<div class="alert alert-danger">' + (result.errorDesc || 'OTP verification failed') + '</div>').show(); 4555 } 4556 } 4557 }); 4558} 4559 4560function verifyedUserNumber() { 4561 var data = {}; 4562 data.otpNumber = $('#agent-login-otps').val().trim(); 4563 4564 var err = 0; 4565 4566 if (data.otpNumber.length < 6) { 4567 $('#agent-login-otps').addClass('is-invalid'); 4568 err++; 4569 } 4570 4571 if (err > 0) { 4572 $('#agent-login-alert').html('<div class="alert alert-danger">Please enter the 6-digit OTP.</div>').show(); 4573 return; 4574 } 4575 4576 $('#otp-verify-btn') 4577 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Verifying...') 4578 .attr('disabled', true); 4579 4580 $.ajax({ 4581 type: 'POST', 4582 url: 'user/verify-user-number', 4583 data: data, 4584 dataType: 'json', 4585 success: function (result) { 4586 $('#otp-verifyed-btn').text('Verify OTP').attr('disabled', false); 4587 if (result.status == 1) { 4588 window.open('user/dashboard', '_blank'); 4589 $('#agent-login-alert').success({ 4590 message: 'Login success', 4591 delay: 1500 4592 }).on('detach', function () { 4593 location.replace(''); 4594 }); 4595 4596 $('#otp-section-two').hide(); 4597 $('#otp-verify-btn').hide(); 4598 $('#otp-verifyed-btn').hide(); 4599 } else { 4600 $('#agent-login-alert').html('<div class="alert alert-danger">' + (result.errorDesc || 'OTP verification failed') + '</div>').show(); 4601 } 4602 } 4603 }); 4604} 4605 4606function toggleSearchBar() { 4607 $(event.target).closest('header') 4608 .find('.topbar, .searchbar').toggleClass('d-none') 4609 .find('.search-input:visible').focus(); 4610} 4611 4612function filterBranches() { 4613 var value = event.target.value || ''; 4614 value = value.trim().toLowerCase(); 4615 $('.state, .branch').toggleClass('d-none', value !== ''); 4616 $('.branch[data-branch*="' + value + '"]').removeClass('d-none'); 4617} 4618 4619function filterStationPoints() { 4620 var value = event.target.value || ''; 4621 value = value.trim().toLowerCase(); 4622 $('.station, .stationpoint').toggleClass('d-none', value !== ''); 4623 $('.stationpoint[data-stationpoint*="' + value + '"]').removeClass('d-none'); 4624} 4625 4626function clearSearch(selector) { 4627 $(selector).val('').trigger('keyup'); 4628} 4629 4630function sendFeedback() { 4631 event && event.preventDefault(); 4632 4633 var data = {}, 4634 err = 0; 4635 data.name = $('#feedback-name').val().trim(); 4636 data.mobile = $('#feedback-mobile').val().trim(); 4637 data.email = $('#feedback-email').val().trim(); 4638 data.comments = $('#feedback-comments').val().trim(); 4639 data.ticketCode = $('#feedback-pnr:hidden').val().trim(); 4640 4641 if (data.name === '') { 4642 $('#feedback-name').addClass('is-invalid'); 4643 err++; 4644 } 4645 if (!validate.isMobile(data.mobile)) { 4646 $('#feedback-mobile').addClass('is-invalid'); 4647 err++; 4648 } 4649 if (!validate.isEmail(data.email)) { 4650 $('#feedback-email').addClass('is-invalid'); 4651 err++; 4652 } 4653 if (data.comments === '') { 4654 $('#feedback-comments').addClass('is-invalid'); 4655 err++; 4656 } 4657 4658 if (err) { 4659 $('#feedback-alert').danger().on('detach', function () { 4660 $('#feedback-form .is-invalid').removeClass('is-invalid'); 4661 }); 4662 return; 4663 } 4664 4665 $('#feedback-btn').text('Submitting...').attr('disabled', true); 4666 4667 $.ajax({ 4668 type: 'POST', 4669 url: 'feedback/send-feedback', 4670 data: data, 4671 dataType: 'json', 4672 success: function (result) { 4673 $('#feedback-btn').text('Feedback').attr('disabled', false); 4674 if (result.status == 1) { 4675 $('#feedback-alert').success().on('detach', function () { 4676 location.reload(); 4677 }); 4678 } else { 4679 $('#feedback-alert').danger(result.errorDesc); 4680 } 4681 } 4682 }); 4683 4684} 4685 4686function getTicketDetailsPrint() { 4687 event && event.preventDefault(); 4688 4689 $('#print-ticket-cont, #print-ticket-alert').html(''); 4690 4691 var data = {}; 4692 data.ticketCode = $('#print-ticket-pnr').val().trim(); 4693 4694 if (data.ticketCode == '') { 4695 $('#print-ticket-pnr').addClass('is-invalid'); 4696 $('#print-ticket-alert').danger().on('detach', function () { 4697 $('#print-ticket-form .is-invalid').removeClass('is-invalid'); 4698 }); 4699 return; 4700 } 4701 4702 $('#print-ticket-btn') 4703 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...') 4704 .attr('disabled', true); 4705 4706 $.ajax({ 4707 type: 'POST', 4708 url: 'print-ticket/get-ticket-details', 4709 data: data, 4710 dataType: 'json', 4711 success: function (result) { 4712 if (result.status == 1) { 4713 $('#print-ticket-btn').text('Get Details').attr('disabled', false); 4714 $('#print-ticket-cont').html(result.data); 4715 } else { 4716 $('#print-ticket-alert').invalidTicket({ message: result['errorDesc'] }).on('detach', function () { 4717 $('#print-ticket-pnr .is-invalid').removeClass('is-invalid'); 4718 }); 4719 $('#print-ticket-btn').text('Get Details').attr('disabled', false); 4720 } 4721 } 4722 }); 4723 4724} 4725 4726function sendTicketSMS() { 4727 event && event.preventDefault(); 4728 4729 $('#print-ticket-cont, #print-ticket-alert').html(''); 4730 4731 var data = {}; 4732 data.ticketCode = $('#print-ticket-pnr').val().trim(); 4733 4734 if (data.ticketCode == '') { 4735 $('#print-ticket-pnr').addClass('is-invalid'); 4736 $('#print-ticket-alert').danger().on('detach', function () { 4737 $('#print-ticket-form .is-invalid').removeClass('is-invalid'); 4738 }); 4739 return; 4740 } 4741 4742 $('#sms-ticket-btn') 4743 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Sending...') 4744 .attr('disabled', true); 4745 4746 $.ajax({ 4747 type: 'POST', 4748 url: 'print-ticket/send-ticket-sms', 4749 data: data, 4750 dataType: 'json', 4751 success: function (result) { 4752 $('#sms-ticket-btn').text('Send SMS').attr('disabled', false); 4753 4754 if (result.status == 1) { 4755 $('#print-ticket-alert').success('SMS has been sent successfully'); 4756 } else { 4757 $('#print-ticket-alert').danger(result.errorDesc); 4758 } 4759 } 4760 }); 4761 4762} 4763 4764function getTrackingDetails() { 4765 event && event.preventDefault(); 4766 4767 $('#ticket-tracking-cont, #ticket-tracking-alert').html(''); 4768 4769 var data = {}; 4770 data.ticketCode = $('#ticket-tracking-pnr').val().trim(); 4771 data.type = 1; // for html return; 4772 4773 if (data.ticketCode == '') { 4774 $('#ticket-tracking-pnr').addClass('is-invalid'); 4775 $('#ticket-tracking-alert').danger().on('detach', function () { 4776 $('#ticket-tracking-form .is-invalid').removeClass('is-invalid'); 4777 }); 4778 return; 4779 } 4780 4781 $('#ticket-tracking-btn') 4782 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...') 4783 .attr('disabled', true); 4784 4785 $.ajax({ 4786 type: 'POST', 4787 url: 'track-my-bus/get-tracking-details', 4788 data: data, 4789 dataType: 'html', 4790 success: function (result) { 4791 $('#ticket-tracking-btn').text('Get Details').attr('disabled', false); 4792 $('#ticket-tracking-cont').html(result); 4793 } 4794 }); 4795 4796} 4797 4798function getCancelDetails() { 4799 event && event.preventDefault(); 4800 4801 $('#cancel-ticket-cont, #cancel-ticket-alert').html(''); 4802 4803 var data = {}, 4804 err = 0; 4805 data.ticketCode = $('#cancel-ticket-pnr').val().trim(); 4806 data.emailId = $('#cancel-ticket-email').val().trim(); 4807 4808 if (data.ticketCode == '') { 4809 $('#cancel-ticket-pnr').addClass('is-invalid'); 4810 err++; 4811 } 4812 4813 if (err) { 4814 $('#cancel-ticket-pnr').addClass('is-invalid'); 4815 $('#cancel-ticket-alert').danger().on('detach', function () { 4816 $('#cancel-ticket-form .is-invalid').removeClass('is-invalid'); 4817 }); 4818 return; 4819 } 4820 4821 $('#cancel-ticket-btn') 4822 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...') 4823 .attr('disabled', true); 4824 4825 $.ajax({ 4826 type: 'POST', 4827 url: 'cancel-ticket/get-cancel-details', 4828 data: data, 4829 dataType: 'html', 4830 success: function (result) { 4831 $('#cancel-ticket-btn').text('Get Details').attr('disabled', false); 4832 $('#cancel-ticket-cont').html(result); 4833 } 4834 }); 4835 4836} 4837 4838function getTicketRefundDetails() { 4839 event && event.preventDefault(); 4840 4841 $('#ticket-refund-status-cont, #ticket-refund-status-alert').html(''); 4842 4843 var data = {}; 4844 data.ticketCode = $('#ticket-refund-status-pnr').val().trim(); 4845 4846 if (data.ticketCode == '') { 4847 $('#ticket-refund-status-pnr').addClass('is-invalid'); 4848 $('#ticket-refund-status-alert').danger().on('detach', function () { 4849 $('#ticket-refund-status-form .is-invalid').removeClass('is-invalid'); 4850 }); 4851 return; 4852 } 4853 4854 $('#ticket-refund-status-btn') 4855 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...') 4856 .attr('disabled', true); 4857 4858 $.ajax({ 4859 type: 'POST', 4860 url: 'ticket-refund-status/get-refund-ticket-details', 4861 data: data, 4862 dataType: 'html', 4863 success: function (result) { 4864 $('#ticket-refund-status-btn').text('Get Details').attr('disabled', false); 4865 $('#ticket-refund-status-cont').html(result); 4866 } 4867 }); 4868 4869} 4870 4871function doCancelTicket() { 4872 if (!confirm('Do you want to cancel the selected seats?')) { 4873 return; 4874 } 4875 4876 var data = {}; 4877 data.ticketCode = $('#cancel-pnr:hidden').val().trim(); 4878 data.emailId = $('#cancel-email:hidden').val().trim(); 4879 data.mobileNumber = $('#cancel-mobile:hidden').val().trim();
4880 data.seatCodeList = $('.cancel-ticket-cb:checked').map(function (i, cb) { 4881 return $(cb).data('code'); 4882 }).get().join(','); 4883 4884 if (data.seatCodeList == '') { 4885 alert('Please select atleast one seat'); 4886 return; 4887 } 4888 4889 var regularSeatList = $('#cancel-seat-list:hidden').val().trim(); 4890 var connSeatList = $('#cancel-conn-seat-list:hidden').val().trim(); 4891 4892 // Split strings [] 4893 var selectedSeats = data.seatCodeList.split(',').filter(Boolean); 4894 var existingSeats = connSeatList.split(',').filter(Boolean); 4895 4896 // remove duplicates 4897 var combinedSeats = [...new Set([...selectedSeats, ...existingSeats])]; 4898 4899 data.seatCodeList = combinedSeats.length > 1 ? combinedSeats.join(',') : combinedSeats[0] || ''; 4900 4901 $('#confirm-cancel-btn') 4902 .prop('disabled', true) 4903 .html( 4904 '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> ' + 4905 'Cancelling...' 4906 ); 4907 4908 $.ajax({ 4909 type: 'POST', 4910 url: 'cancel-ticket/confirm-cancel', 4911 data: data, 4912 dataType: 'json', 4913 success: function (result) { 4914 $('#confirm-cancel-btn').prop('disabled', false).html('Cancel'); 4915 if (result.status == 1) { 4916 $('#confirm-cancel-alert').success().on('detach', function () { 4917 location.reload(); 4918 }); 4919 } else { 4920 $('#confirm-cancel-alert').danger(result.errorDesc); 4921 } 4922 } 4923 }); 4924} 4925 4926 4927async function sendOTP() { 4928 var data = {},err = 0; 4929 data.mobileNumber = $('#otp-login-mobile').val().trim(); 4930 4931 if (!validate.isMobile(data.mobileNumber)) { 4932 $('#otp-login-mobile').addClass('is-invalid'); 4933 err++; 4934 } 4935 4936 var captchaInput = $('#captchaCode').val().trim(); 4937 if (!captchaInput) { 4938 $('#captchaCode').addClass('is-invalid'); 4939 $('#otp-login-alert').danger().on('detach', function () { 4940 $('#captchaCode .is-invalid').removeClass('is-invalid'); 4941 }); 4942 err++; 4943 } 4944 4945 if (err) { 4946 $('#otp-login-alert').danger().on('detach', function () { 4947 $('#mobile-section .is-invalid').removeClass('is-invalid'); 4948 $('#captchaCode .is-invalid').removeClass('is-invalid'); 4949 }); 4950 return; 4951 } 4952 4953 // Captcha is verified server-side within send-otp; send it in the payload. 4954 data.captacha = captchaInput; 4955 4956 $('#otp-login-alert').html(''); 4957 $('#send-otp-btn') 4958 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Sending...') 4959 .attr('disabled', true); 4960 4961 $.ajax({ 4962 type: 'POST', 4963 url: 'user/sending-otp', 4964 data: data, 4965 dataType: 'json', 4966 success: function (result) { 4967 $('#send-otp-btn').prop('disabled', false).html('Submit'); 4968 if (result.status == 1) { 4969 subscribeWebOTP(); 4970 $('#otp-login-alert').success(); 4971 $('#mobile-section').addClass('d-none'); 4972 $('#otp-section').removeClass('d-none'); 4973 } else { 4974 genCaptcha(); // reset on failure 4975 $('#otp-login-alert').danger(result.errorDesc); 4976 } 4977 }, 4978 error: function () { 4979 $('#send-otp-btn').prop('disabled', false).html('Submit'); 4980 genCaptcha(); 4981 } 4982 }); 4983} 4984 4985 4986function validateOTP() { 4987 var data = {}, 4988 err = 0; 4989 data.mobileNumber = $('#otp-login-mobile').val().trim(); 4990 data.otpNumber = $('#otp-login-pin').val().trim(); 4991 4992 if (data.otpNumber == '') { 4993 $('#otp-login-pin').addClass('is-invalid'); 4994 err++; 4995 } 4996 4997 if (err) { 4998 $('#otp-login-validate-alert').danger().on('detach', function () { 4999 $('#otp-section .is-invalid').removeClass('is-invalid'); 5000 }); 5001 return; 5002 } 5003 5004 $('#otp-login-validate-alert').html(''); 5005 $('#validate-otp-btn') 5006 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Validating...') 5007 .attr('disabled', true); 5008 5009 $.ajax({ 5010 type: 'POST', 5011 url: 'user/validate-otp', 5012 data: data, 5013 dataType: 'json', 5014 success: function (result) { 5015 if (result.status == 1) { 5016 $('#otp-login-validate-alert').success(); 5017 5018 location.href = ''; 5019 } else if (result.status == 2) { 5020 $('#otp-login-validate-alert').success(); 5021 5022 $('#otp-section').addClass('d-none'); 5023 $('#register-section').removeClass('d-none'); 5024 } else { 5025 $('#otp-login-validate-alert').danger(result.errorDesc); 5026 $('#validate-otp-btn').prop('disabled', false).html('Submit'); 5027 } 5028 } 5029 }); 5030} 5031 5032function registerUser() { 5033 var data = {}, 5034 err = 0; 5035 data.name = $('#otp-register-fname').val().trim(); 5036 data.lastname = $('#otp-register-lname').val().trim(); 5037 data.email = $('#otp-register-email').val().trim(); 5038 data.mobile = $('#otp-login-mobile').val().trim(); 5039 5040 if (data.name == '') { 5041 $('#otp-register-fname').addClass('is-invalid'); 5042 err++; 5043 } 5044 if (!validate.isEmail(data.email)) { 5045 $('#otp-register-fname').addClass('is-invalid'); 5046 err++; 5047 } 5048 5049 if (err) { 5050 $('#otp-login-register-alert').danger().on('detach', function () { 5051 $('#register-section .is-invalid').removeClass('is-invalid'); 5052 }); 5053 return; 5054 } 5055 5056 $('#otp-login-register-alert').html(''); 5057 $('#otp-register-btn') 5058 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Submitting...') 5059 .attr('disabled', true); 5060 5061 $.ajax({ 5062 type: 'POST', 5063 url: 'user/update-profile', 5064 data: data, 5065 dataType: 'json', 5066 success: function (result) { 5067 $('#otp-register-btn').prop('disabled', false).html('Submit'); 5068 if (result.status == 1) { 5069 $('#otp-login-register-alert').success(); 5070 5071 location.href = ''; 5072 } else { 5073 $('#otp-login-register-alert').danger(result.errorDesc); 5074 } 5075 } 5076 }); 5077} 5078 5079function subscribeWebOTP() { 5080 if (!window.OTPCredential) return; 5081 5082 const input = document.querySelector('#otp-login-pin'); 5083 const button = document.querySelector('#validate-otp-btn'); 5084 if (!input || !button) return; 5085 5086 const ac = new AbortController(); 5087 button.addEventListener('click', e => { 5088 ac.abort(); 5089 }); 5090 5091 navigator.credentials.get({ 5092 otp: { transport: ['sms'] }, 5093 signal: ac.signal 5094 }).then(otp => {
5095 input.value = otp.code; 5096 button.click(); 5097 }).catch(err => { 5098 console.log(err); 5099 }); 5100} 5101 5102function initPWA() { 5103 if ('serviceWorker' in navigator) { 5104 try { 5105 navigator.serviceWorker.register('serviceWorker.js'); 5106 } catch (error) { 5107 console.log('Service Worker Registration Failed'); 5108 } 5109 } 5110} 5111 5112function formatMobileNo(event) { 5113 if (!event.target) return; 5114 var value = event.target.value || ''; 5115 value = value.replace(/[^0-9]/g, ''); 5116 if (value.length > 0 && /^[6-9]/.test(value)) { 5117 event.target.value = value.substring(0, 10); 5118 } else { 5119 event.target.value = ''; 5120 } 5121} 5122 5123function formatName(event) { 5124 if (!event.target) return; 5125 var value = event.target.value || ''; 5126 value = value.replace(/[^a-zA-Z\s]/g, ''); 5127 event.target.value = value; 5128} 5129 5130function formatAge(event) { 5131 if (!event.target) return; 5132 var value = event.target.value || ''; 5133 value = value.replace(/[^0-9]/g, ''); 5134 event.target.value = value; 5135} 5136 5137function manageTicket() { 5138 event && event.preventDefault(); 5139 5140 $('#manage-ticket-cont, #manage-ticket-alert').html(''); 5141 5142 var data = {}, 5143 err = 0; 5144 error = 0; 5145 data.ticketCode = $('#manage-ticket-pnr').val().trim(); 5146 5147 var inputData = $('#manage-ticket-email-mobile').val().trim(); 5148 5149 if (validate.isMobile(inputData)) { 5150 data.mobileNumber = inputData; 5151 } else if (validate.isEmail(inputData)) { 5152 data.emailId = inputData; 5153 } else { 5154 $('#manage-ticket-email-mobile').addClass('is-invalid'); 5155 err++; 5156 } 5157 5158 var opreation = $('[name="manage-ticket-radio"]:checked').val(); 5159 5160 if (data.ticketCode == '') { 5161 $('#manage-ticket-pnr').addClass('is-invalid'); 5162 error++; 5163 err--; 5164 } 5165 5166 if (err) { 5167 $('#manage-ticket-alert').emailmobile().on('detach', function () { 5168 $('#manage-ticket-form .is-invalid').removeClass('is-invalid'); 5169 }); 5170 return; 5171 } 5172 5173 if (error) { 5174 $('#manage-ticket-alert').danger().on('detach', function () { 5175 $('#manage-ticket-form .is-invalid').removeClass('is-invalid'); 5176 }); 5177 return; 5178 } 5179 5180 $('#manage-ticket-btn') 5181 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...') 5182 .attr('disabled', true); 5183 5184 const url = {}; 5185 url['PRINT'] = 'print-ticket/get-ticket-details'; 5186 url['DOWNLOAD'] = 'print-ticket/get-ticket-details'; 5187 url['SMS'] = 'print-ticket/send-ticket-sms'; 5188 url['CANCEL'] = 'cancel-ticket/get-cancel-details'; 5189 url['BOARDING'] = 'modify-ticket/boardingpoint-modify-details'; 5190 url['TRACK'] = 'track-my-bus/get-tracking-details'; 5191 url['RESCHEDULE'] = 'reschedule/get-reschedule-details'; 5192 url['INVOICE'] = 'modify-ticket/ticket-invoice-details'; 5193 url['REFUND'] = 'ticket-refund-status/get-refund-ticket-details'; 5194 5195 switch (opreation) { 5196 case 'PRINT': 5197 case 'DOWNLOAD': 5198 case 'CANCEL': 5199 case 'BOARDING': 5200 case 'TRACK': 5201 case 'RESCHEDULE': 5202 case 'INVOICE': 5203 case 'REFUND': 5204 $.ajax({ 5205 type: 'POST', 5206 url: url[opreation], 5207 data: data, 5208 dataType: 'json', 5209 success: function (result) { 5210 if (result.status == 1) { 5211 $('#manage-ticket-form-cont').addClass('d-none'); 5212 $('#manage-ticket-body-cont').removeClass('d-none'); 5213 $('#manage-ticket-body').html(result.data); 5214 5215 // Check if the element #print-tiket-return-pnr exists 5216 // if ($('#print-tiket-return-pnr').length) { 5217 // $('#manage-ticket-return').removeClass('d-none'); 5218 // $('#manage-ticket-onward').removeClass('d-none'); 5219 // const returnPnr = $('#print-tiket-return-pnr').val(); 5220 // } else { 5221 // $('#manage-ticket-return').addClass('d-none'); 5222 // $('#manage-ticket-onward').addClass('d-none'); 5223 // } 5224 } else { 5225 $('#manage-ticket-alert').invalidTicket({ message: result['errorDesc'] }).on('detach', function () { 5226 $('#manage-ticket-form .is-invalid').removeClass('is-invalid'); 5227 }); 5228 $('#manage-ticket-btn').text('Next').attr('disabled', false); 5229 } 5230 } 5231 }); 5232 break; 5233 case 'SMS': 5234 $.ajax({ 5235 type: 'POST', 5236 url: url[opreation], 5237 data: data, 5238 dataType: 'json', 5239 success: function (result) { 5240 $('#manage-ticket-btn').text('Next').attr('disabled', false); 5241 5242 if (result.status == 1) { 5243 $('#manage-ticket-alert').success('SMS has been sent successfully'); 5244 } else { 5245 $('#manage-ticket-alert').danger(result.errorDesc); 5246 } 5247 } 5248 }); 5249 break; 5250 } 5251 5252} 5253 5254function manageTicketBack() { 5255 $('.onward-ticket').addClass('d-none'); 5256 $('.return-ticket').addClass('d-none'); 5257 $('#manage-ticket-btn').text('Next').attr('disabled', false); 5258 $('#manage-ticket-form-cont').removeClass('d-none'); 5259 $('#manage-ticket-body-cont').addClass('d-none'); 5260} 5261 5262function modifyMobileNumer() { 5263 event && event.preventDefault(); 5264 5265 $('#modify-ticket-cont, #modify-ticket-alert').html(''); 5266 5267 var data = {}, 5268 err = 0; 5269 data.ticketCode = $('#modify-ticket-pnr').val().trim(); 5270 data.emailId = $('#modify-ticket-email').val().trim(); 5271 5272 if (data.ticketCode == '') { 5273 $('#modify-ticket-pnr').addClass('is-invalid'); 5274 err++; 5275 } 5276 5277 if (!validate.isEmail(data.emailId)) { 5278 $('#modify-ticket-email').addClass('is-invalid'); 5279 err++; 5280 } 5281 5282 if (err) { 5283 $('#modify-ticket-pnr').addClass('is-invalid'); 5284 $('#modify-ticket-alert').danger().on('detach', function () { 5285 $('#modify-ticket-form .is-invalid').removeClass('is-invalid'); 5286 }); 5287 return; 5288 } 5289 5290 $('#modify-mobile-btn') 5291 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...') 5292 .attr('disabled', true); 5293 5294 $.ajax({ 5295 type: 'POST', 5296 url: 'modify-ticket/mobileno-modify-details', 5297 data: data, 5298 dataType: 'html', 5299 success: function (result) { 5300 $('#modify-ticket-form-cont').addClass('d-none'); 5301 $('#modify-ticket-body-cont').removeClass('d-none'); 5302 $('#modify-ticket-body').html(result); 5303 } 5304 }); 5305} 5306 5307function updateMobileNo() { 5308 var data = {}, 5309 err = 0; 5310 data.ticketCode = $('#manage-ticket-pnr').val().trim(); 5311 data.emailId = $('#manage-ticket-email-mobile').val().trim(); 5312 data.oldMobileNumber = $('#modify-mobile-oldno').val().trim();
5313 data.newMobileNumber = $('#modify-mobile-newno').val().trim(); 5314 5315 if (!validate.isMobile(data.newMobileNumber)) { 5316 $('#modify-mobile-newno').addClass('is-invalid'); 5317 err++; 5318 } 5319 5320 if (err) { 5321 $('#modify-mobile-alert').danger().on('detach', function () { 5322 $('#register-section .is-invalid').removeClass('is-invalid'); 5323 }); 5324 return; 5325 } 5326 5327 $('#modify-mobile-alert').html(''); 5328 $('#update-mobile-btn') 5329 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Updating...') 5330 .attr('disabled', true); 5331 5332 $.ajax({ 5333 type: 'POST', 5334 url: 'modify-ticket/update-mobile-no', 5335 data: data, 5336 dataType: 'json', 5337 success: function (result) { 5338 $('#update-mobile-btn').prop('disabled', false).html('Save Mobile Number'); 5339 if (result.status == 1) { 5340 $('#modify-mobile-alert').success('New mobile number has been updated. <a href="print-ticket?pnr=' + data.ticketCode + '">View Ticket Details</a>'); 5341 } else { 5342 $('#modify-mobile-alert').danger(result.errorDesc); 5343 } 5344 } 5345 }); 5346} 5347 5348function modifyTicketBack() { 5349 $('#modify-boarding-btn').text('Edit Boarding Point').attr('disabled', false); 5350 $('#modify-mobile-btn').text('Edit Mobile Number').attr('disabled', false); 5351 $('#modify-ticket-form-cont').removeClass('d-none'); 5352 $('#modify-ticket-body-cont').addClass('d-none'); 5353} 5354 5355function modifyBoardingPoint() { 5356 event && event.preventDefault(); 5357 5358 $('#modify-ticket-cont, #modify-ticket-alert').html(''); 5359 5360 var data = {}, 5361 err = 0; 5362 data.ticketCode = $('#modify-ticket-pnr').val().trim(); 5363 data.emailId = $('#modify-ticket-email').val().trim(); 5364 5365 if (data.ticketCode == '') { 5366 $('#modify-ticket-pnr').addClass('is-invalid'); 5367 err++; 5368 } 5369 5370 if (!validate.isEmail(data.emailId)) { 5371 $('#modify-ticket-email').addClass('is-invalid'); 5372 err++; 5373 } 5374 5375 if (err) { 5376 $('#modify-ticket-pnr').addClass('is-invalid'); 5377 $('#modify-ticket-alert').danger().on('detach', function () { 5378 $('#modify-ticket-form .is-invalid').removeClass('is-invalid'); 5379 }); 5380 return; 5381 } 5382 5383 $('#modify-boarding-btn') 5384 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...') 5385 .attr('disabled', true); 5386 5387 $.ajax({ 5388 type: 'POST', 5389 url: 'modify-ticket/boardingpoint-modify-details', 5390 data: data, 5391 dataType: 'html', 5392 success: function (result) { 5393 $('#modify-ticket-form-cont').addClass('d-none'); 5394 $('#modify-ticket-body-cont').removeClass('d-none'); 5395 $('#modify-ticket-body').html(result); 5396 } 5397 }); 5398} 5399 5400function updateBoardingPoint() { 5401 var data = {}, 5402 err = 0; 5403 data.ticketCode = $('#manage-ticket-pnr').val().trim(); 5404 data.emailId = $('#manage-ticket-email-mobile').val().trim(); 5405 data.oldBoardingPointCode = $('#modify-boardingpoint-old').val().trim(); 5406 data.newBoardingPointCode = $('#modify-boardingpoint-new').val().trim(); 5407 5408 if (data.newBoardingPointCode == '') { 5409 $('#modify-boardingpoint-new').addClass('is-invalid'); 5410 err++; 5411 } 5412 5413 if (err) { 5414 $('#modify-boarding-alert').danger().on('detach', function () { 5415 $('#register-section .is-invalid').removeClass('is-invalid'); 5416 }); 5417 return; 5418 } 5419 5420 $('#modify-boarding-alert').html(''); 5421 $('#update-boarding-btn') 5422 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Updating...') 5423 .attr('disabled', true); 5424 5425 $.ajax({ 5426 type: 'POST', 5427 url: 'modify-ticket/update-boarding-point', 5428 data: data, 5429 dataType: 'json', 5430 success: function (result) { 5431 $('#update-boarding-btn').prop('disabled', false).html('Save Boarding Number'); 5432 if (result.status == 1) { 5433 $('#modify-boarding-alert').success('New boarding number has been updated. <a href="print-ticket?pnr=' + data.ticketCode + '">View Ticket Details</a>'); 5434 } else { 5435 $('#modify-boarding-alert').danger(result.errorDesc); 5436 } 5437 } 5438 }); 5439} 5440 5441function updateInvoiceDetails() { 5442 var data = {}, 5443 err = 0; 5444 data.gstin = $('#invoice-gstin').val().trim(); 5445 data.tradeName = $('#invoice-tradename').val().trim(); 5446 data.ticketCode = $('#manage-ticket-pnr').val().trim(); 5447 5448 if (!validate.isGSTIN(data.gstin)) { 5449 $('#invoice-gstin').addClass('is-invalid'); 5450 err++; 5451 } 5452 5453 if (data.tradeName == '') { 5454 $('#invoice-tradename').addClass('is-invalid'); 5455 err++; 5456 } 5457 5458 if (err) { 5459 $('#invoice-details-alert').danger().on('detach', function () { 5460 $('#invoice-details-panel .is-invalid').removeClass('is-invalid'); 5461 }); 5462 return; 5463 } 5464 5465 $('#invoice-details-alert').html(''); 5466 $('#update-invoice-btn') 5467 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Updating...') 5468 .attr('disabled', true); 5469 5470 $.ajax({ 5471 type: 'POST', 5472 url: 'modify-ticket/update-ticket-invoice', 5473 data: data, 5474 dataType: 'json', 5475 success: function (result) { 5476 $('#update-invoice-btn').prop('disabled', false).html('Save Invoice Details'); 5477 if (result.status == 1) { 5478 manageTicket(); 5479 $('#invoice-details-alert').success(); 5480 } else { 5481 $('#invoice-details-alert').danger(result.errorDesc); 5482 } 5483 } 5484 }); 5485} 5486 5487function getCancellationPolicy(tripCode, fromStationCode, toStationCode, travelDate) { 5488 var data = {}; 5489 data.tripCode = tripCode; 5490 data.fromStationCode = fromStationCode; 5491 data.toStationCode = toStationCode; 5492 data.travelDate = travelDate; 5493 5494 $('#cancel-policy-cont').html('<div class="h5 p-5 text-center">Loading...</div>'); 5495 5496 $.ajax({ 5497 type: 'POST', 5498 url: 'search/cancellation-terms', 5499 data: data, 5500 dataType: 'json', 5501 success: function (result) { 5502 if (result.status == 1) { 5503 var template = $('#template-cancellation-policy').html(); 5504 var $terms = $(template); 5505 var $tbody = $terms.find('tbody'); 5506 $.each(result.data.policyList || [], function (i, policy) { 5507 var $tr = $('<tr/>'); 5508 $('<td/>').html(policy.term).appendTo($tr); 5509 $('<td/>').html(policy.deductionAmountTxt + ' (' + policy.chargesTxt + ')').appendTo($tr); 5510 $('<td/>').html(policy.refundAmountTxt).appendTo($tr); 5511 $tr.appendTo($tbody); 5512 }); 5513 $('#cancel-policy-cont').html($terms); 5514 } else { 5515 $('#cancel-policy-cont').danger({ message: result.errorDesc, delay: 10e6 }); 5516 } 5517 } 5518 }); 5519} 5520 5521function gotoPrintPage() { 5522 var data = {}; 5523 data.pnr = $('#print-tkt-pnr').val().trim(); 5524 5525 if (!data.pnr) { 5526 $('#print-tkt-pnr').addClass('is-invalid'); 5527 return; 5528 } 5529 location.href = 'print-ticket?' + $.param(data); 5530} 5531 5532function gotoTrackPage() { 5533 var data = {}; 5534 data.pnr = $('#track-bus-pnr').val().trim(); 5535 5536 if (!data.pnr) { 5537 $('#track-bus-pnr').addClass('is-invalid'); 5538 return; 5539 } 5540 location.href = 'track-my-bus?' + $.param(data); 5541} 5542 5543function getRescheduleDetails() { 5544 event && event.preventDefault(); 5545 5546 $('#reschedule-ticket-cont, #reschedule-ticket-alert').html(''); 5547 5548 var data = {}, 5549 err = 0; 5550 data.ticketCode = $('#reschedule-ticket-pnr').val().trim(); 5551 5552 if (data.ticketCode == '') { 5553 $('#reschedule-ticket-pnr').addClass('is-invalid'); 5554 err++; 5555 } 5556 5557 var inputData = $('#reschedule-ticket-email-mobile').val().trim(); 5558 5559 if (validate.isMobile(inputData)) { 5560 data.mobileNumber = inputData; 5561 } else if (validate.isEmail(inputData)) { 5562 data.emailId = inputData; 5563 } else { 5564 $('#reschedule-ticket-email-mobile').addClass('is-invalid'); 5565 err++; 5566 } 5567 5568 if (err) { 5569 $('#reschedule-ticket-pnr').addClass('is-invalid'); 5570 $('#reschedule-ticket-alert').danger().on('detach', function () { 5571 $('#reschedule-ticket-form .is-invalid').removeClass('is-invalid'); 5572 }); 5573 return; 5574 } 5575 5576 $('#reschedule-ticket-btn') 5577 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...') 5578 .attr('disabled', true); 5579 5580 $.ajax({ 5581 type: 'POST', 5582 url: 'reschedule/get-reschedule-details', 5583 data: data, 5584 dataType: 'html', 5585 success: function (result) { 5586 $('#reschedule-ticket-btn').text('Get Details').attr('disabled', false); 5587 $('#reschedule-ticket-cont').html(result); 5588 } 5589 }); 5590} 5591 5592function initRescheduleSeats() { 5593 var { onwardData, returnData } = getPassengerTicketData(); 5594 5595 var data = {}; 5596 data.transferBoardingPoint = {}; 5597 data.transferBoardingPoint.code = onwardData.fromStation.stationPoint.code; 5598 data.transferDroppingPoint = {}; 5599 data.transferDroppingPoint.code = onwardData.toStation.stationPoint.code; 5600 data.captureFareDifferece = true; 5601 data.captureTransferCharge = true; 5602 data.notificationFlag = false;
5603 data.paymentPartnerCode = $("input[name='payment-options']:checked").val(); 5604 data.transferTripStageCode = onwardData.tripStageCode; 5605 data.transferTripCode = onwardData.tripCode; 5606 data.ticketCode = $('#reschedule-ticket-code').val(); 5607 data.myAccountFlag = false; 5608 data.transferFromStation = {}; 5609 data.transferFromStation.code = onwardData.fromStation.code; 5610 data.transferToStation = {}; 5611 data.transferToStation.code = onwardData.toStation.code; 5612 data.transferTravelDate = moment(onwardData.fromStation.dateTime).format('YYYY-MM-DD'); 5613 data.seatCode = []; 5614 data.transferSeatCode = []; 5615 $('#onward-trip .pass-info').each(function () { 5616 data.seatCode.push($(this).data('oldseatcode')); 5617 data.transferSeatCode.push($(this).data('code')); 5618 }); 5619 5620 var err = 0; 5621 if ($('input[name="payment-options"]').length && data.paymentPartnerCode == '') { 5622 $('input[name="payment-options"]').addClass('is-invalid'); 5623 err++; 5624 } 5625 5626 if (!$('#pass-terms').is(':checked')) { 5627 $('#pass-terms').addClass('is-invalid'); 5628 err++; 5629 } 5630 5631 if (err) { 5632 $('#pass-alert').danger().on('detach', function () { 5633 $('.is-invalid').removeClass('is-invalid'); 5634 }); 5635 return false; 5636 } 5637 5638 $('#block-ticket-btn') 5639 .prop('disabled', true) 5640 .html( 5641 '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> ' + 5642 'Please wait...' 5643 ); 5644 5645 $.ajax({ 5646 type: 'POST', 5647 url: 'reschedule/block-seats', 5648 data: data, 5649 dataType: 'json', 5650 success: function (result) { 5651 if (result.status == 1) { 5652 if (result.data.paymentGatewayProcessFlag) { 5653 if (result.data.gatewayCode == 'RAZORPAY') { 5654 var options = result.data.gatewayInputDetails; 5655 options.image = 'assets/images/logo.png'; 5656 options.theme = {}; 5657 options.theme.color = getComputedStyle(document.documentElement).getPropertyValue('--theme-primay-color'); 5658 options.modal = {}; 5659 options.modal.escape = false;
5660 options.modal.confirm_close = true; 5661 options.modal.ondismiss = function () { 5662 location.href = 'reschedule/payment-response?orderCode=' + result.data.code; 5663 }; 5664 var rzp1 = new Razorpay(options); 5665 rzp1.open(); 5666 return 5667 } 5668 5669 var formControl = ''; 5670 $.each(result.data.gatewayInputDetails || [], function (rekey, reval) { 5671 formControl += '<input name="' + rekey + '" id="' + rekey + '" value="' + reval + '" />'; 5672 }); 5673 $('body').append('<form action="' + result.data.paymentRequestUrl + '" name="frm_payment" id="frm_payment" method="post" style="display:none;">' + formControl + '</form>'); 5674 $('#frm_payment').submit(); 5675 } else { 5676 location.href = 'reschedule/payment-response?orderCode=' + result.data.code; 5677 } 5678 } else { 5679 $('#pass-alert').danger(result.errorDesc); 5680 } 5681 $('#block-ticket-btn').prop('disabled', false).html('Continue'); 5682 } 5683 }); 5684} 5685 5686function scrollToTop() { 5687 window.scrollTo({ top: 0, behavior: 'smooth' }); 5688} 5689 5690function countUp(selector, options = {}) { 5691 function formatNumberWithSuffix(value) { 5692 if (value >= 1e7) return (value / 1e7).toFixed(1).replace(/\.0$/, '') + 'Cr'; // Crore 5693 if (value >= 1e5) return (value / 1e5).toFixed(1).replace(/\.0$/, '') + 'L'; // Lakh 5694 if (value >= 1e9) return (value / 1e9).toFixed(1).replace(/\.0$/, '') + 'b'; 5695 if (value >= 1e6) return (value / 1e6).toFixed(1).replace(/\.0$/, '') + 'm'; 5696 if (value >= 1e3) return (value / 1e3).toFixed(1).replace(/\.0$/, '') + 'k'; 5697 return value.toString(); 5698 } 5699 5700 function onIntersection(entries) { 5701 entries.forEach(entry => { 5702 if (!entry.isIntersecting) return; 5703 observer.unobserve(entry.target); 5704 5705 const defaults = { 5706 duration: 1000, 5707 easing: 'swing', 5708 step: function () { 5709 const val = Math.ceil(this.counter); 5710 this.textContent = formatNumberWithSuffix(val); 5711 }, 5712 complete: function () { 5713 const target = $(this).data('target'); 5714 this.textContent = formatNumberWithSuffix(target); 5715 } 5716 }; 5717 5718 const settings = $.extend(true, defaults, options); 5719 5720 $(entry.target).prop('counter', 0).animate({ 5721 counter: $(entry.target).data('target') 5722 }, settings); 5723 }); 5724 } 5725 5726 const observer = new IntersectionObserver(onIntersection, { threshold: 1 }); 5727 document.querySelectorAll(selector).forEach(el => observer.observe(el)); 5728} 5729 5730function initViaRouteMap(stations) { 5731 var map = L.map('via-map', { attributionControl: false }).setView([20.5937, 78.9629], 5); 5732 5733 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map); 5734 5735 var markerLayer = L.featureGroup(); 5736 $.each(stations || [], function (i, station) { 5737 $.each(station.fromStation.stationPoint || [], function (i, point) { 5738 L.marker([point.latitude, point.longitude]) 5739 .bindPopup('<b>' + point.name + '</b> : ' + moment(point.dateTime).format('hh:mm A') + '<br/>' + point.landmark) 5740 .addTo(markerLayer); 5741 }); 5742 }); 5743 5744 markerLayer.addTo(map); 5745 map.fitBounds(markerLayer.getBounds()); 5746} 5747 5748function retryPayment(tc) { 5749 var data = {}; 5750 5751 $('#retry-payment-btn') 5752 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...') 5753 .attr('disabled', true); 5754 5755 $.ajax({ 5756 type: 'POST', 5757 url: 'passenger-info/payment-info', 5758 data: data, 5759 dataType: 'json', 5760 success: function (res) { 5761 // $('#retry-payment-btn').text('Get Details').attr('disabled', false); 5762 location.href = 'passenger-info/payment-info?orderCode=' + tc; 5763 } 5764 }); 5765} 5766 5767// function to make the whatsapp qr code to visible / hidden 5768$(".wa-float-icon").hover(function () { 5769 $(".wt-qr_code").stop(true, true).fadeToggle(600); 5770}); 5771 5772// whatsapp qr code 5773window.addEventListener("load", function() { 5774 document.querySelectorAll(".whatsapp").forEach(function(el) { 5775 5776 // Step 1: Show after small delay 5777 setTimeout(function() { 5778 el.classList.add("show-on-load"); 5779 5780 // Step 2: Hide after 1 second 5781 setTimeout(function() { 5782 el.classList.remove("show-on-load"); 5783 }, 1000); 5784 5785 }, 200); 5786 5787 }); 5788 }); 5789function isPM(time) { 5790 var timeParts = time.split(' '); 5791 var timeHourPart = timeParts[1].split(':')[0]; 5792 var hours = parseInt(timeHourPart); 5793 5794 return hours >= 12 && hours < 24; 5795} 5796 5797function renderBusSeatsV4(obj) { 5798 var seatGenderClass = { 5799 "M": "seat-booked-gents", // Booked for Male 5800 "F": "seat-booked-ladies" // Booked for Female 5801 }; 5802 var seatStatusClass = { 5803 "AM": "seat-select-visibilitys seat-available-gents", // Available male 5804 "AF": "seat-select-visibilitys seat-available-ladies", // Available female 5805 "AY": "seat-select-visibilitys seat-available-you", // Allocated for You 5806 "AL": "seat-select-visibilitys", // Available 5807 "BO": "seat-booked", // Booked 5808 "BM": "seat-booked-gents", // Booked for Male 5809 "BF": "seat-booked-ladies", // Booked for Female 5810 "AO": "seat-booked-gents", // Booked 5811 "UK": "seat-booked-gents", // Booked 5812 "TBL": "seat-booked-gents", // Blocked 5813 "PBL": "seat-booked-gents", // Booked 5814 "BL": "seat-booked-gents", // Blocked 5815 "SDBL": "seat-blocked-socialdis" // Blocked 5816 }; 5817 5818 var seatType = { 5819 // seater 5820 "SS": { name: "Semi Sleeper", class: "seat-lay-searchs", category: "SEATER" }, 5821 "SSS": { name: "Single Semi Sleeper", class: "seat-lay-searchs", category: "SEATER" }, 5822 "ST": { name: "Seater", class: "seat-lay-searchs", category: "SEATER" }, 5823 "SST": { name: "Single Seater", class: "seat-lay-searchs", category: "SEATER" }, 5824 "PB": { name: "Pushback", class: "seat-lay-searchs", category: "SEATER" }, 5825 "PTY": { name: "Pantry", class: "seat-lay-searchs", category: "PANTRY" }, 5826 "WST": { name: "Window Seat", class: "seat-lay-searchs", category: "SEATER" }, 5827 "BKST": { name: "Back Seat", class: "seat-lay-searchs", category: "SEATER" }, 5828 "PBST": { name: "Pushback Seat", class: "seat-lay-searchs", category: "SEATER" }, 5829 5830 // sleeper 5831 "SL": { name: "Sleeper", class: "sleeper-lay-searchs", category: "SLEEPER" }, 5832 "USL": { name: "Upper Sleeper", class: "sleeper-lay-searchs", category: "SLEEPER" }, 5833 "LSL": { name: "Lower Sleeper", class: "sleeper-lay-searchs", category: "SLEEPER" }, 5834 "SUSL": { name: "Single Upper Sleeper", class: "sleeper-lay-searchs", category: "SLEEPER" }, 5835 "SLSL": { name: "Single Lower Sleeper", class: "sleeper-lay-searchs", category: "SLEEPER" }, 5836 "WSL": { name: "Window Sleeper", class: "sleeper-lay-searchs", category: "SLEEPER" }, 5837 5838 // restroom 5839 "RRM": { name: "Rest Room", class: "restroom-sleeper-filer", category: "RESTROOM" }, 5840 "FRS": { name: "Free Space", class: "restroom-sleeper-filer", category: "EMPTY" }, 5841 "EME": { name: "Emergency Exit", class: "emergency-exit-filer", category: "EMERGENCYEXIT" }, 5842 }; 5843 5844 // shorthand 5845 var layer = obj.layer; 5846 var matrix = obj.matrix; 5847 var seatStatus = obj.seatStatus; 5848 5849 // flags 5850 var isSleeperSeatFound = false;
5851 var isSeaterFound = false; 5852 5853 // return array 5854 var allSeatNodes = []; 5855 var emptySeatNodes = []; 5856 5857 // construct seats row and col wise 5858 for (var row = matrix.rowmin; row <= matrix.rowmax; row++) { 5859 var rowSeatFound = false; 5860 var hasDefinedSeats = false; // Track if the row has any defined seats 5861 var lastDefinedCol = matrix.colmin - 1; // Track the last column with a defined seat 5862 5863 var definedSeatsInRow = []; 5864 for (var col = matrix.colmin; col <= matrix.colmax; col++) { 5865 var pos = '' + layer + row + col; 5866 if (seatStatus[pos]) { 5867 definedSeatsInRow.push(col); 5868 } 5869 } 5870 for (var col = matrix.colmin; col <= matrix.colmax; col++) { 5871 5872 // position 5873 var pos = '' + layer + row + col; 5874 5875 // position seat details 5876 var seatinfo = seatStatus[pos]; 5877 5878 // seat div 5879 var $seat = $('<div/>'); 5880 5881 // empty seat 5882 if (!seatinfo) { 5883 5884 if (rowSeatFound && isSleeperSeatFound) { 5885 var isBetweenDefinedSeats = false; 5886 for (var i = 0; i < definedSeatsInRow.length - 1; i++) { 5887 if (col > definedSeatsInRow[i] && col < definedSeatsInRow[i + 1]) { 5888 isBetweenDefinedSeats = true; 5889 break; 5890 } 5891 } 5892 if (!isBetweenDefinedSeats) { 5893 continue; 5894 } 5895 } 5896 5897 $seat.html(' '); 5898 5899 emptySeatNodes.push($seat.get(0)); 5900 allSeatNodes.push($seat.get(0)); 5901 continue; 5902 } 5903 hasDefinedSeats = true; 5904 lastDefinedCol = col; 5905 5906 // emergency exit (mini busmap) 5907 if (seatinfo.seatType == 'EME') { 5908 $seat 5909 .addClass('emergency-exit-filer') 5910 .attr('data-code', seatinfo.code) 5911 .attr('data-discount', seatinfo.discountFare) 5912 .html($('<div/>').attr('title', seatType[seatinfo.seatType].name)); 5913 5914 rowSeatFound = true; 5915 allSeatNodes.push($seat.get(0)); 5916 continue; 5917 } 5918 5919 $eme = ''; 5920 5921 if (seatinfo.emergencyExitDoor !== 'NA') { 5922 $eme = '<span class="emergengcy-' + seatinfo.emergencyExitDoor + '-filer"></span>'; 5923 } 5924 5925 var seatTypeClass = seatType[seatinfo.seatType] ? seatType[seatinfo.seatType].class : null; 5926 5927 $seat.addClass(seatTypeClass) 5928 .addClass(seatStatusClass[seatinfo.status]) 5929 .addClass(seatGenderClass[seatinfo.genderstatus.code]) 5930 .attr('data-code', seatinfo.code) 5931 .attr('data-fare', seatinfo.fare) 5932 .attr('data-discount', seatinfo.discountFare) 5933 .attr('data-service', seatinfo.serviceTax) 5934 .html($eme) // seat name 5935 5936 if (seatType[seatinfo.seatType]) { 5937 if (seatType[seatinfo.seatType].category === 'SLEEPER') isSleeperSeatFound = true; 5938 if (seatType[seatinfo.seatType].category === 'SEATER') isSeaterFound = true; 5939 } 5940 5941 if (seatinfo.status === "BO" && seatinfo.genderstatus.code === "M") { 5942 $seat.addClass("seat-booked-gents"); 5943 } else if (seatinfo.status === "BO" && seatinfo.genderstatus.code === "F") { 5944 $seat.addClass("seat-booked-ladies"); 5945 } 5946 5947 if (seatinfo.status === "BL" && seatinfo.genderstatus.code === "M") { 5948 $seat.addClass("seat-booked-gents"); 5949 } else if (seatinfo.status === "BL" && seatinfo.genderstatus.code === "F") { 5950 $seat.removeClass("seat-booked-gents"); 5951 $seat.addClass("seat-booked-ladies"); 5952 } 5953 5954 // for quota seats 5955 if ((seatinfo.status === "QS") && seatinfo.genderstatus.code === "M") { 5956 $seat.addClass("seat-booked-gents"); 5957 } else if ((seatinfo.status === "QS") && seatinfo.genderstatus.code === "F") { 5958 $seat.removeClass("seat-booked-gents"); 5959 $seat.addClass("seat-booked-ladies"); 5960 } 5961 5962 // vertical layout 5963 if (seatinfo.orientation == 1) { 5964 $seat.addClass('vertical-seat'); 5965 } 5966 5967 // rest Room 5968 if (seatinfo.seatType == 'RRM') {
5969 var $restroom = $('<div/>').addClass('').attr('title', seatType[seatinfo.seatType].name); 5970 $seat.removeClass(seatStatusClass[seatinfo.status]).html($restroom); 5971 } 5972 5973 // free space 5974 if (seatinfo.seatType == 'FRS') { 5975 $seat.removeClass(seatStatusClass[seatinfo.status]).empty(); 5976 } 5977 5978 rowSeatFound = true; 5979 allSeatNodes.push($seat.get(0)); 5980 } 5981 5982 var $clearfix = $('<div/>').addClass('clearfix'); 5983 allSeatNodes.push($clearfix.get(0)); 5984 } 5985 5986 if (isSeaterFound) { 5987 $(emptySeatNodes).addClass('seat-lay-searchs'); 5988 } else if (isSleeperSeatFound) { 5989 $(emptySeatNodes).addClass('sleeper-lay-searchs'); 5990 } 5991 5992 return allSeatNodes; 5993} 5994 5995 5996function setCookie(name, value, days) { 5997 const d = new Date(); 5998 d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000)); // Set expiration time 5999 const expires = "expires=" + d.toUTCString(); 6000 document.cookie = name + "=" + value + ";" + expires + ";path=/"; 6001} 6002 6003function getCookie(name) { 6004 const nameEQ = name + "="; 6005 const ca = document.cookie.split(';'); 6006 for (let i = 0; i < ca.length; i++) { 6007 let c = ca[i]; 6008 while (c.charAt(0) === ' ') c = c.substring(1, c.length); 6009 if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); 6010 } 6011 return null; 6012} 6013 6014function generateRandomNumber() { 6015 const numbers = [1, 2, 3]; // Only 3 numbers 6016 const randomIndex = Math.floor(Math.random() * numbers.length); 6017 return numbers[randomIndex]; 6018} 6019 6020function getofferDesignNumber() { 6021 const lastSetDate = getCookie('lastSetDate'); 6022 const currentDate = new Date(); 6023 const currentTime = currentDate.getTime(); 6024 6025 const randomNumber = generateRandomNumber(); 6026 6027 if (!lastSetDate) { 6028 setCookie('offerdesignNumber', randomNumber, 2); // Expire in 2 days 6029 setCookie('lastSetDate', currentDate.toISOString(), 2); // Expire in 2 days 6030 return randomNumber; 6031 } 6032 6033 const previousDate = new Date(lastSetDate); 6034 const timeDifference = currentTime - previousDate.getTime(); 6035 const daysPassed = Math.floor(timeDifference / (1000 * 3600 * 24)); 6036 6037 const designCycle = 3; 6038 6039 const currentofferDesignNumber = (Math.floor(daysPassed / 2) % designCycle) + 1; 6040 6041 if (currentofferDesignNumber !== parseInt(getCookie('offerdesignNumber'))) { 6042 setCookie('offerdesignNumber', currentofferDesignNumber, 2); // Expire in 2 days 6043 setCookie('lastSetDate', currentDate.toISOString(), 2); // Expire in 2 days 6044 } 6045 6046 return currentofferDesignNumber; 6047} 6048 6049function initImageSlider($slider) { 6050 const $slides = $slider.find('.slick-slide'); 6051 let currentIndex = 0; 6052 6053 $slides.each((index, slide) => { 6054 $(slide).css('transform', `translateX(${100 * index}%)`).show(); 6055 }); 6056 6057 function updateSlides() { 6058 $slides.each((index, slide) => { 6059 const offset = 100 * (index - currentIndex); 6060 $(slide).css('transform', `translateX(${offset}%)`); 6061 }); 6062 updateArrowVisibility(); 6063 } 6064 6065 function updateArrowVisibility() { 6066 $('.slick-prev').toggle(currentIndex > 0); 6067 $('.slick-next').toggle(currentIndex < $slides.length - 1); 6068 } 6069 $('.slick-prev').show(); 6070 $('.slick-next').show(); 6071 $('.slick-prev').off('click').on('click', function () { 6072 if (currentIndex > 0) { 6073 currentIndex--; 6074 updateSlides(); 6075 } 6076 }); 6077 6078 $('.slick-next').off('click').on('click', function () { 6079 if (currentIndex < $slides.length - 1) { 6080 currentIndex++; 6081 updateSlides(); 6082 } 6083 }); 6084 updateSlides(); 6085} 6086 6087function droppingChange() { 6088 if ($('input[name="boarding-point"]:checked').val() && $('input[name="dropping-point"]:checked').val()) { 6089 $(".bpdpSelecting").addClass("d-none"); 6090 $(".bpdpHeight").addClass("d-none"); 6091 6092 $(".boardingPointCard").removeClass("d-none"); 6093 $(".droppingPointCard").removeClass("d-none"); 6094 return; 6095 } 6096 6097 $(".boarding-point-title").removeClass("boardingdroppingbold"); 6098 $(".dropping-point-title").addClass("boardingdroppingbold"); 6099 6100 $(".boarding-design").addClass("d-none"); 6101 $(".dropping-design").removeClass("d-none"); 6102 6103 $(".boarding-point-list-card").addClass("d-none"); 6104 $(".dropping-point-list-card").removeClass("d-none"); 6105} 6106 6107function boardingDroppingSelected() { 6108 6109 if (regConnTrip.SEQ_STATUS == 'DROPPING') { 6110 return; 6111 } 6112 6113 if (!$('input[name="boarding-point"]:checked').val()) { 6114 $(".dropping-point-title").removeClass("boardingdroppingbold"); 6115 $(".boarding-design, .boarding-point-list-card").removeClass("d-none"); 6116 $(".boarding-point-title").addClass("boardingdroppingbold"); 6117 $(".dropping-design, .dropping-point-list-card").addClass("d-none"); 6118 return; 6119 } 6120 6121 $(".bpdpSelecting").addClass("d-none"); 6122 $(".bpdpHeight").addClass("d-none"); 6123 6124 $(".boardingPointCard").removeClass("d-none"); 6125 $(".droppingPointCard").removeClass("d-none"); 6126} 6127 6128function showBoardingDropping(ele) { 6129 $(".boardingPointCard").addClass("d-none"); 6130 $(".droppingPointCard").addClass("d-none"); 6131 6132 if (ele == 'board') { 6133 $(".dropping-point-title").removeClass("boardingdroppingbold"); 6134 $(".boarding-design, .boarding-point-list-card").removeClass("d-none"); 6135 $(".boarding-point-title").addClass("boardingdroppingbold"); 6136 $(".dropping-design, .dropping-point-list-card").addClass("d-none"); 6137 } else { 6138 $(".boarding-point-title").removeClass("boardingdroppingbold"); 6139 $(".dropping-design, .dropping-point-list-card").removeClass("d-none"); 6140 $(".dropping-point-title").addClass("boardingdroppingbold"); 6141 $(".boarding-design, .boarding-point-list-card").addClass("d-none"); 6142 } 6143 6144 $(".bpdpHeight, .bpdpSelecting").removeClass("d-none"); 6145} 6146 6147function zeroSeat() { 6148 $(".boardingPointCard").addClass("d-none"); 6149 $(".droppingPointCard").addClass("d-none"); 6150 $("#booking-card").addClass("d-none"); 6151 6152 if (isConnecting) { 6153 $(".connecting-content").removeClass("d-none"); 6154 $(".bpdpHeight").addClass("d-none"); 6155 } 6156 6157 $(".select-info-card").removeClass("d-none"); 6158 if (!isConnecting) { 6159 $(".bpdpHeight, .bpdpSelecting").removeClass("d-none"); 6160 } 6161 6162 $('input[name="boarding-point"]').prop('checked', false); 6163 $('input[name="dropping-point"]').prop('checked', false); 6164 6165 $(".boarding-point-title").addClass("boardingdroppingbold"); 6166 $(".boarding-design, .boarding-point-list-card").removeClass("d-none"); 6167 6168 $(".dropping-point-title").removeClass("boardingdroppingbold"); 6169 $(".dropping-design, .dropping-point-list-card").addClass("d-none"); 6170} 6171 6172function seatWithBoardingDropping() { 6173 $(".bpdpSelecting").addClass("d-none"); 6174} 6175 6176function boardingTab() { 6177 // if (!$('input[name="dropping-point"]:checked').val()){ 6178 // return; 6179 // } 6180 $(".boarding-point-title").addClass("boardingdroppingbold"); 6181 $(".dropping-point-title").removeClass("boardingdroppingbold"); 6182 $(".boarding-design, .boarding-point-list-card").removeClass("d-none"); 6183 $(".dropping-design, .dropping-point-list-card").addClass("d-none"); 6184} 6185 6186function droppingTab() { 6187 // if (!$('input[name="boarding-point"]:checked').val()){ 6188 // return; 6189 // } 6190 $(".dropping-point-title").addClass("boardingdroppingbold"); 6191 $(".dropping-design, .dropping-point-list-card").removeClass("d-none"); 6192 $(".boarding-point-title").removeClass("boardingdroppingbold"); 6193 $(".boarding-design, .boarding-point-list-card").addClass("d-none"); 6194} 6195 6196function generateSharingLink(tripdetails) { 6197 if (!tripdetails || !tripdetails.fromStation || !tripdetails.toStation) { 6198 return; 6199 } 6200 6201 var data = {}; 6202 data.from = tripdetails.fromStation.code;
6203 data.to = tripdetails.toStation.code; 6204 data.fS = tripdetails.fromStation.name; 6205 data.tS = tripdetails.toStation.name; 6206 data.date = tripdetails.travelDate || (tripdetails.fromStation.dateTime 6207 ? moment(tripdetails.fromStation.dateTime).format('YYYY-MM-DD') 6208 : ''); 6209 data.code = tripdetails.tripCode; 6210 6211 $('#retry-payment-btn') 6212 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...') 6213 .attr('disabled', true); 6214 6215 $.ajax({ 6216 type: 'POST', 6217 url: 'search/sharing-link', 6218 data: data, 6219 dataType: 'json', 6220 success: function (res) { 6221 const tempInput = document.createElement('input'); 6222 tempInput.value = res.data.url; 6223 document.body.appendChild(tempInput); 6224 tempInput.select(); 6225 document.execCommand('copy'); 6226 document.body.removeChild(tempInput); 6227 6228 $('#COPYConntooltip-' + tripdetails.tripCode) 6229 .fadeIn(300) 6230 .delay(2000) 6231 .fadeOut(300); 6232 6233 $('#COPYtooltip-' + tripdetails.tripCode) 6234 .fadeIn(300) 6235 .delay(2000) 6236 .fadeOut(300); 6237 } 6238 }); 6239} 6240 6241function openSharedTrip() { 6242 const tripCode = $('#shared-trip-code').val().trim(); 6243 if (!tripCode) return; 6244 6245 $('#trip-' + tripCode).find('.tripinfo-container').trigger('click'); 6246} 6247 6248function trackEvent(eventCategory, eventAction, eventLabel) { 6249 if (typeof gtag === "function") { 6250 gtag('event', eventAction, { 6251 'event_category': eventCategory, 6252 'event_label': eventLabel 6253 }); 6254 } 6255} 6256 6257function toggleAllPassInfoSeat() { 6258 var state = $('#all-pass-details').is(':checked'); 6259 6260 $('#onward-trip, #return-trip') 6261 .find('.pass-info:not(:first)') 6262 .find('.pass-name, .pass-age, .seat-name') 6263 .toggleClass('d-none', !state); 6264} 6265 6266function forLoadingHtml() { 6267 $('.loading').addClass('d-none'); 6268 $('.sorting-card, .conn-total-trip-count-div, .trip-panel').removeClass('d-none'); 6269} 6270 6271function removeNumber() { 6272 event.preventDefault(); 6273 6274 $('#remove-user-help').html(''); 6275 var data = {}; 6276 data.mobileNumber = $('#removeMobileNumber').val(); 6277 6278 if (data.mobileNumber == '' || data.mobileNumber.length < 10) { 6279 $('#removeMobileNumber').addClass('is-invalid'); 6280 $('#remove-user-help').danger({ 6281 message: 'Invalid mobile number', 6282 delay: 5000 6283 }).on('detach', function () { 6284 $('#remove-user-form .is-invalid').removeClass('is-invalid'); 6285 }); 6286 return; 6287 } 6288 6289 $('.remove-user-btn').prop('disabled', true).html( 6290 '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> ' + 6291 'Deleting...' 6292 ); 6293 $('#removeMobileNumber').prop('disabled', true); 6294 6295 $.ajax({ 6296 type: 'POST', 6297 url: 'app/remove-user', 6298 data: data, 6299 dataType: 'json', 6300 success: function (result) { 6301 $('.remove-user-btn').prop('disabled', false).html('Delete'); 6302 $('#removeMobileNumber').prop('disabled', false).removeClass('is-invalid'); 6303 if (result.status == 1) { 6304 $('#remove-user-help').success('Your Account has been removed successfully'); 6305 } else { 6306 $('#remove-user-help').danger({ 6307 message: result.errorDesc, 6308 delay: 100000 6309 }); 6310 } 6311 } 6312 }); 6313} 6314 6315// for connevting trips 6316function listViewConnMaster(data, result, $tripContent) { 6317 var id = 1; 6318 $tripContent; 6319 var minConnFare = 0; 6320 6321 $.each(result, function (cbkey, cbval) { 6322 let currencySymbol = cbval.currencySymbol; 6323 var tripListConn = $($('#template-bus-list-conn-master').html()); 6324 6325 tripListConn.attr({ 6326 'id': `cmTrip-${cbval.tripCode}`, 6327 'data-trip-code': cbval.tripCode, 6328 'data-schedule-code-master': cbval.scheduleCode, 6329 'data-available-seat-count': cbval.availableSeatCount, 6330 'data-total-sequence': cbval.connPoints.length - 1, 6331 'data-departure': moment(cbval.fromStation.dateTime).valueOf(), 6332 'data-duriation': moment.duration(moment(cbval.toStation.dateTime, "YYYY-MM-DD HH:mm:ss").diff(moment(cbval.fromStation.dateTime, "YYYY-MM-DD HH:mm:ss"))), 6333 'data-availability': cbval.availableSeatCount, 6334 'data-from-sta-code': cbval.fromStation.code, 6335 'data-from-sta-name': cbval.fromStation.name, 6336 'data-conn-t-stations': cbval.connPoints.map(p => p.name).join(',') 6337 // 'data-fare': minFare//-- need to fix it 6338 }); 6339 6340 let conn_trip_info_cnt = $(`<div class="d-flex justify-content-between _mx-10 _my-10"></div>`); 6341 const connPointsLen = cbval.connPoints.length; 6342 let conn_trip_info_temp = ''; 6343 cbval.connPoints.map((p, i) => { 6344 6345 if (i === 0) {// boarding station 6346 conn_trip_info_temp += 6347 `<div class="conn-brdSta _mt-10"> 6348 <div class="d-flex fd-c align-items-center"> 6349 <div class="_my-10"><img src="assets/images/search/boarding-location.svg" width="24px" class="_ml-5" />
6349<span class="bold _px-5">${p.name}</span></div> 6350 <div class="_fs-12">${i == 0 ? '(' + formatDateTime(p.dateTime, 'ddd-mon-time') + ')' : ''}</div> 6351 </div> 6352 </div> 6353 <div class="d-flex align-items-center fd-c "> 6354 <div class=" _px-9 _py-1 "><img src="assets/images/search/night-time.svg" width="15px" height="15px" class="_ml-5" ><span class="_fs-10">${cbval.connPoints[i].travelTime} hrs</span></div> 6355 <div class="conn-line"></div> 6356 </div>`; 6357 6358 } else if (i < (connPointsLen - 1)) { // connection station 6359 let waitingTime = cbval.waitingTime[`${p.fromStation}-${p.toStation}`].map(wt => wt.waitTime); 6360 conn_trip_info_temp += 6361 `<div class=_mt-10> 6362 <div class="d-flex fd-c align-items-center"> 6363 <div class="_my-10"><img src="assets/images/search/swap-bus.svg" width="24px" class="_ml-5" /><span class="bold _px-5">${p.name}</span></div> 6364 <div class="_fs-12" ><img src="assets/images/search/waiting-time.svg" width="24px" class="_ml-5" /><span class="bold color-primary _px-5">${waitingTime[0]}</span></div> 6365 </div> 6366 </div> 6367 <div class="d-flex align-items-center fd-c"> 6368 <div class=""><img src="assets/images/search/night-time.svg" width="15px" height="15px" class="_ml-5"><span class="_fs-10">${cbval.connPoints[i].travelTime} hrs</span></div> 6369 <div class="conn-line" ></div> 6370 </div>`; 6371 6372 } else {// dropping station 6373 conn_trip_info_temp += 6374 `<div class=_mt-10> 6375 <div class="d-flex fd-c align-items-end"> 6376 <div class="_my-10"><img src="assets/images/search/dropping-location.svg" width="24px" class="_ml-5" /><span class="bold _px-5">${p.name}</span></div> 6377 <div class="_fs-12">${i == connPointsLen - 1 ? '(' + formatDateTime(p.dateTime, 'ddd-mon-time') + ')' : ''}</div> 6378 </div> 6379 </div>`; 6380 6381 } 6382 6383 }) 6384 conn_trip_info_cnt.html(conn_trip_info_temp);// add temp to conn_trip_info_cnt 6385 6386 6387 tripListConn.find('.conn_trip_info').html(conn_trip_info_cnt);// add conn_trip_info_cnt to conn_trip_info 6388 6389 // Set fromStation and toStation names in the HTML 6390 tripListConn.find('.bp-sta').html(cbval.fromStation.name); 6391 tripListConn.find('.dp-sta').html(cbval.toStation.name); 6392 6393 // Loop through each connection point (connPoints) and create the list items 6394 for (let index = 0, stI = 0, endI = (connPointsLen - 1); index < cbval.connPoints.length; index++) { 6395 let $li = $(` 6396 6397 <div id="li_${cbval.tripCode}_${index}" class="closestdiv col-md"> 6398 <div class="sequence-card"> 6399 <input type="radio" hidden> 6400 <div class="station-head" 6401 title="${cbval.connPoints[index].name}" 6402 style="${cbval.connPoints[index].name.length > 15 ? 'white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: inline-block; max-width: 115px;' : ''}" 6403 >${cbval.connPoints[index].name} 6404 </div> 6405 <div class="borderofStation"><img src="assets/images/search/notselectedsequence.svg"></div> 6406 </div> 6407 </div> 6408 `); 6409 6410 // Set attributes and styles for the list item 6411 $li.attr({ 6412 'data-title': cbval.connPoints[index].title, 6413 'data-station-name': cbval.connPoints[index].name, 6414 'data-tripcount': cbval.connPoints[index].tripCount, 6415 'data-index': index, 6416 }); 6417 6418 // Radio button setup 6419 let $radio = $li.find('input[type="radio"]'); 6420 $radio.attr({ 6421 name: `station_${cbval.tripCode}`, 6422 value: cbval.connPoints[index].code, 6423 'data-fromStation': cbval.connPoints[index].code, 6424 'data-tripSequence': index 6425 }) 6426 6427 // set toStation value to it additionally except last radio 6428 if (index !== endI) { 6429 $li.attr({// set values for automation 6430 'data-from-station': cbval.connPoints[index].fromStation, 6431 'data-from-station-name': cbval.connPoints[index].fromStationName, 6432 'data-bp-point': cbval.connPoints[index].bpPoint, 6433 'data-bp-point-name': cbval.connPoints[index].bpPointName, 6434 'data-to-station': cbval.connPoints[index].toStation, 6435 'data-to-station-name': cbval.connPoints[index].toStationName, 6436 'data-dp-point': cbval.connPoints[index].dpPoint, 6437 'data-dp-point-name': cbval.connPoints[index].dpPointName, 6438 }) 6439 $radio.attr('data-toStation', cbval.connPoints[index + 1].code) 6440 } 6441 6442 6443 // Set the default radio button to be checked (first station) 6444 if (index === stI) { 6445 $radio.prop('checked', true); 6446 } 6447 6448 // Hide the radio button for the last station and remove border 6449 if (index === endI) { 6450 $radio.addClass('d-none'); 6451 $li.css({ 6452 'border-bottom': 'none', 6453 }); 6454 6455 $li.find('.station-info').css({ 6456 'color': "green" 6457 }) 6458 6459 $li.find('.stationCollapseCtrlP').removeClass('point_cur'); 6460 $li.find('.stationCollapseCtrlC').addClass('d-none'); 6461 } 6462 6463 // Accordion parent/master control (label + radio button) 6464 $li.find('.stationCollapseCtrlP').attr({ 6465 'data-target': `#collapse_${cbval.tripCode}_${index}`, 6466 'aria-controls': `collapse_${cbval.tripCode}_${index}` 6467 }).css({ 6468 'flex': '1 0 auto' 6469 }) 6470 6471 // Accordion child/slave control (collapse section) 6472 $li.find('.stationCollapseCtrlC').attr({ 6473 'id': `collapse_${cbval.tripCode}_${index}`, 6474 'aria-labelledby': `li_${cbval.tripCode}_${index}`, 6475 }).css({ 6476 // 'border': '1px solid #b7b7b7', 6477 // 'border-radius': '5px', 6478 // 'margin': '7px 0px', 6479 // 'background': '#fff', 6480 // 'height': 'auto', 6481 }); 6482 6483 // Append the list item to the accordion container 6484 tripListConn.find('#conn-trip-pts-accordion').append($li); 6485 } 6486 6487 // Update the connection trip points text and available seats master card details 6488 tripListConn.find('.conn-txt').html(cbval.noOfConnPoints + ' Connections');
6489 tripListConn.find('.seat-avail').html(cbval.availableSeatCount > 0 ? `<span class="bold">${cbval.availableSeatCount}</span> Seats Available` : 'Seats not Available'); 6490 6491 // Show discount availability if it exists 6492 if (cbval.discountAvail !== null || cbval.discountAvail === '') { 6493 tripListConn.find('.dis-avail').html(`Flat <span class="hl-off-percent">${cbval.discountAvail} % </span><span class="hl-off">OFF</span>`).closest('.dis-cont').removeClass('d-none'); 6494 } 6495 6496 // minConnFare += Math.min.apply(null, cbval.seatFare); 6497 6498 // const minConnFare = cbval.seatFare.reduce((a, b) => a + b, 0); // total fare in master trip card 6499 const minConnFare = Math.min(...cbval.seatFare); 6500 6501 tripListConn.find('.fare').html(currencySymbol + minConnFare); 6502 6503 if (cbval.seatFare.length > 1) 6504 tripListConn.find('.starts-from').removeClass('d-none'); 6505 6506 // Generate and append the trip cards 6507 // const tripListArray = listViewRegular(data, res, cbval.trip);// regular trip card design 6508 const tripListArray = listViewConnTrip(data, result, cbval.trip);// new regular trip card design for connecting trips 6509 6510 tripListArray.forEach(tripList => { 6511 tripList.removeClass('row').find('.buslist-card').css({ 6512 'box-shadow': '0px 1px 1px 1px #00000047', 6513 'border': '1px solid #efe3e34d' 6514 }).closest('.trip-infos').addClass('d-none'); 6515 6516 6517 tripListConn.find('.conn-trips').append(tripList); 6518 }); 6519 6520 // tripListConn.find('.info-cont').addClass('hide') 6521 6522 // Append the generated trip list container to the main container 6523 $tripContent.append(tripListConn); 6524 6525 // Events 6526 $('.trip-filter-panel').on('change', function (e) { 6527 return; 6528 applyTripListFilter(cbval); 6529 }); 6530 }); 6531 6532 // $tripContent.append(html); 6533 6534 $(document).find('.c-m-trip-infos').find('.info-cont').addClass('d-none') 6535 // bind on clik functionality for connecting trip 6536 6537 $(document).on('click', '.c-m-trip-infos', function (e, r) { 6538 const $this = $(this); 6539 6540 // retrun it info-cont element 6541 if ($this.find('.info-cont').has(e.target).length > 0) return; 6542 if ($(e.target).is('.share-link-conn')) { 6543 6544 $this.find('.COPYConntooltip').attr('id', 'COPYConntooltip-' + $this.data('tripCode')); 6545 6546 const connTrips = Array.isArray(result) ? result : Object.values(result || {}); 6547 const trip = connTrips.find(t => t.tripCode === $this.data('tripCode')); 6548 if (!trip) { 6549 return; 6550 } 6551 generateSharingLink(trip); 6552 trackEvent('Share Trip', 'click', 'Share Link'); 6553 return; 6554 } 6555 6556 // reset booking info if connecting master trip is chaged 6557 resetConnectingLogicDatas(); 6558 6559 if (!triggerConnEle.is($(this))) { 6560 triggerConnEle = $(this); 6561 } 6562 6563 $('.c-m-trip-infos').not($this).find('.info-cont').addClass('d-none'); 6564 6565 // $this.find('.info-cont').toggleClass('hide'); 6566 if ($this.find('.info-cont').hasClass('d-none')) { 6567 $this.find('.info-cont').removeClass('d-none'); 6568 $this.find('.c-v-btn').removeClass('c-h-btn').addClass('c-hide-btn').html('Hide Buses <i class="fa fa-chevron-up _ml-5">'); 6569 } else { 6570 $this.find('.info-cont').addClass('d-none'); 6571 $this.find('.c-v-btn').addClass('c-h-btn').removeClass('c-hide-btn').html('View Buses <i class="fa fa-chevron-down _ml-5">'); 6572 } 6573 6574 $('html, body').animate({ 6575 scrollTop: $this.offset().top - 125 6576 }, 100); 6577 }); 6578 6579 // bind change event for radio button to show respective bus card for station 6580 $(document).on('change', 'input[name^="station_"]', function () { 6581 const $this = $(this); 6582 const ckdSta = $this.val(); 6583 const $li = $this.closest('.closestdiv'); 6584 const title = $li.data('title'); 6585 const tripCount = $li.data('tripcount'); 6586 const $tripContainer = $this.closest('.c-m-trip-infos'); 6587 6588 const totalSeq = $tripContainer.data('total-sequence'); 6589 6590 let $title = `<div><b>${title} (${tripCount}</b> ${tripCount > 1 ? 'Buses found' : 'Bus found'} <b>)</b></div>` 6591 $tripContainer.find('.conn-title').html($title); 6592 $tripContainer.find('.c-ticket-row').each(function () { 6593 let $this = $(this); 6594 if ($this.data('from') === ckdSta) { 6595 $this.closest('.c-trip-infos').removeClass('d-none'); 6596 } else { 6597 $this.closest('.c-trip-infos').addClass('d-none'); 6598 } 6599 }); 6600 // update the sequence of trip based on value seleced 6601 regConnTrip.CURRENT_SEQ = Number($this.attr('data-tripSequence'));// typecase 6602 regConnTrip.SEQ_STATUS = (regConnTrip.CURRENT_SEQ === 0) ? "BOARDING" : (regConnTrip.CURRENT_SEQ !== regConnTrip.TOTAL_SEQ) ? 'CONNECTING' : 'DROPPING'; 6603 6604 if (regConnTrip.SEQ_STATUS == 'BOARDING') { 6605 $li.addClass('blue-checked'); 6606 } 6607 if (regConnTrip.SEQ_STATUS == 'CONNECTING') { 6608 $li.addClass('blue-checked'); 6609 } 6610 if (regConnTrip.SEQ_STATUS == 'DROPPING') { 6611 $li.removeClass('middle-checked'); 6612 $li.addClass('blue-checked'); 6613 } 6614 6615 $('.closestdiv').each(function () { 6616 const $currentDiv = $(this); 6617 const currentSeq = Number($currentDiv.data('index')); 6618 6619 if (currentSeq <= regConnTrip.CURRENT_SEQ) { 6620 $currentDiv.addClass('blue-checked'); 6621 } else { 6622 $currentDiv.removeClass('blue-checked'); 6623 } 6624 }); 6625 }); 6626 6627 6628 $(document).on('click', '.sequence-card', function () { 6629 const $radio = $(this).find('input[type="radio"]'); 6630 const isLastCard = $(this).closest('#conn-trip-pts-accordion').children('.closestdiv').last()[0] === $(this).closest('.closestdiv')[0]; 6631 if (isLastCard) { 6632 return; 6633 } 6634 if (!$radio.prop('checked')) { 6635 $radio.prop('checked', true).trigger('change'); 6636 } 6637 }); 6638 6639 // Trigger the change event for the initially for first radio button as default 6640 setTimeout(() => { 6641 $('.c-m-trip-infos').each(function () { 6642 $(this).find('input[name^="station_"]:first').prop('checked', true).trigger('change'); 6643 handleRadioClick($(this)); 6644 }); 6645 }, 100); 6646} 6647 6648function handleRadioClick($radio) { 6649 var $closestDiv = $radio.closest('.closestdiv'); 6650 if ($radio.is(':checked')) { 6651 $closestDiv.addClass('checked'); 6652 } else { 6653 $closestDiv.removeClass('checked'); 6654 } 6655} 6656 6657// regular trip card list-view rendering 6658function listViewConnTrip(data, res, resData) { 6659 6660 return $.map(resData, function (bval, bkey) { 6661 6662 currencySymbol = bval.currencySymbol; 6663 6664 // if (trip.tripStatus.code !== 'TPO' ) { 6665 // return; 6666 // } 6667 6668 var template = $($('#template-bus-list-conn').html()); 6669 var $tpl = $(template); 6670 6671 6672 var onwardsTag = ' <small>Starts From</small>'; 6673 var perSeat = 'Per Seat from'; 6674 // stage fare 6675 var stageFares = []; 6676 var discountFares = []; 6677 $.each(bval.fare || [], function (i, stage) {
6678 if (stage.availableSeatCount > 0) { 6679 stageFares.push(stage.fare); 6680 } else { 6681 stageFares.push(stage.fare); 6682 } 6683 discountFares.push(stage.discountFare || 0); 6684 }); 6685 var minFare = Math.min.apply(null, stageFares); 6686 var minDiscountFare = Math.min.apply(null, discountFares); 6687 6688 var offer = parseInt(minDiscountFare / minFare * 100); 6689 6690 // amenities 6691 var amenities = []; 6692 $.each(bval.amenities || [], function (i, amenity) { 6693 amenities.push('<span class="ezeeicon-amenities" title="' + amenity.name + '" data-toggle="tooltip" data-amenities=' + amenity.code + '></span>'); 6694 }); 6695 6696 // via routes 6697 var viaStations = []; 6698 var viaStationslide = []; 6699 $.each(bval.viaStations || [], function (i, via) { 6700 viaStations.push(via.name); 6701 if (via.name.length > 15) { 6702 let viaroutecutstring = via.name.substring(0, 15) + '...'; 6703 viaStationslide.push(viaroutecutstring); 6704 } else { 6705 viaStationslide.push(via.name); 6706 } 6707 }); 6708 6709 // badges 6710 var badges = []; 6711 if (new String(bval.busCategoryCode).split('|').includes('CC01')) { 6712 badges.push('<span class="badge badge-primary" title="Air Conditioned Bus">AC</span>'); 6713 } 6714 6715 // templating 6716 $tpl.attr('id', 'trip-' + bval.tripCode); 6717 6718 // $tpl.find('.trip-bustype').html(bval.schedule.displayName.length > 15 ? bval.schedule.displayName : bval.bus.busType); 6719 $tpl.find('.trip-badges').html(badges.join('')); 6720 $tpl.find('.trip-offer-amount').html(minDiscountFare) 6721 $tpl.find('.trip-offer-ribbon').toggleClass('d-none', !minDiscountFare); 6722 $tpl.find('.c-ticket-row').attr('data-from', bval.fromStation.code).attr('data-to', bval.toStation.code); 6723 6724 $tpl.find('.trip-offer').toggleClass('d-none', !minDiscountFare); 6725 $tpl.find('.hl-off-percent').html(offer + '%'); 6726 6727 offerNumber = getofferDesignNumber(); 6728 6729 if (offerNumber == 1) { 6730 $tpl.find('.trip-offer').addClass('offer-1'); 6731 $tpl.find('.offer-icon').html('<img src="assets/images/search/offer-symbol-1.svg" alt="Rating User icon" class="">'); 6732 if (minDiscountFare > 0) 6733 $tpl.find('.fare-margin').removeClass('fare-margin'); 6734 } else if (offerNumber == 2) { 6735 $tpl.find('.trip-offer').addClass('offer-2'); 6736 $tpl.find('.offer-icon').html('<img src="assets/images/search/offer-symbol-2.svg" alt="Rating User icon" class="">'); 6737 $tpl.find('.hl-off-percent').addClass('offer-colour'); 6738 if (minDiscountFare > 0) 6739 $tpl.find('.fare-margin').removeClass('fare-margin'); 6740 } else if (offerNumber == 3) { 6741 $tpl.find('.trip-offer').addClass('offer-3'); 6742 $tpl.find('.offer-icon').html('<img src="assets/images/search/offer-symbol-2.svg" alt="Rating User icon" class="">'); 6743 $tpl.find('.hl-off-percent').addClass('offer-colour'); 6744 if (minDiscountFare > 0) 6745 $tpl.find('.fare-margin').removeClass('fare-margin'); 6746 } 6747 6748 $tpl.find('.trip-fare').html(currencySymbol + (minFare - minDiscountFare)); 6749 $tpl.find('.trip-onwards').html(stageFares.length > 1 && onwardsTag); 6750 $tpl.find('.trip-perseat-from').html(stageFares.length > 1 && perSeat); 6751 $tpl.find('.trip-fare-original').html(currencySymbol + minFare).toggleClass('d-none', !minDiscountFare); 6752 $tpl.find('.trip-starttime').html(moment(bval.fromStation.dateTime).format('hh:mm A')); 6753 $tpl.find('.trip-endtime').html(moment(bval.toStation.dateTime).format('hh:mm A')); 6754 $tpl.find('.trip-startdate').html(moment(bval.fromStation.dateTime).format('DD MMM')); 6755 $tpl.find('.trip-enddate').html(moment(bval.toStation.dateTime).format('DD MMM')); 6756 $tpl.find('.trip-startday').html(moment(bval.fromStation.dateTime).format('ddd')); 6757 $tpl.find('.trip-endday').html(moment(bval.toStation.dateTime).format('ddd')); 6758 $tpl.find('.trip-duration').html(bval.travelTime + ' hrs'); 6759 $tpl.find('.trip-seatsavail').attr('title', 'Total ' + bval.seatCount + ' Seats').html(bval.availableSeatCount); 6760 $tpl.find('.trip-via').html(viaStations.join(', ')); 6761 $tpl.find('.trip-amenities').html(amenities.join('')); 6762 $tpl.find('.trip-reststop-count').html(bval.travelStopCount); 6763 $tpl.find('[data-triptab="RESTSTOPS"]').toggleClass('d-none', !bval.travelStopCount); 6764 $tpl.find('.rest-stop').toggleClass('d-none', !bval.travelStopCount); 6765 6766 if (amenities.length == 0) { 6767 $tpl.find('[data-triptab="AMENITIES"]').addClass('d-none') 6768 } 6769
6770 if (bval.availableSeatCount === 0) { 6771 $tpl.find('.trip-seatsavail').parent().hide(); 6772 $tpl.find('.trip-viewbusmap').html('Sold Out').removeClass('btn-primary').addClass('btn-danger').css({ 'padding': '4px 15px' }); 6773 $tpl.find('.trip-viewbusmap, .tripinfo-container').addClass('no-map'); 6774 } else { 6775 $tpl.find('.trip-viewbusmap').html(bval.availableSeatCount + ' Seats') 6776 } 6777 6778 $tpl.find('.COPYConntooltip').attr('id', 'COPYConntooltip-' + bval.tripCode); 6779 6780 $.each(bval.fromStation.stationPoint || [], function (k, bp) { 6781 $tpl.find('.trip-fromstationpoint').html(bp.name); 6782 return false; 6783 }); 6784 6785 $.each((bval.toStation.stationPoint || []).reverse(), function (k, dp) { 6786 $tpl.find('.trip-tostationpoint').html(dp.name); 6787 return false; 6788 }); 6789 6790 //bus image profile 6791 if (bval.busImageDetails && bval.busImageDetails.PROFILE && bval.busImageDetails.PROFILE.length > 0) { 6792 6793 const imageUrl = bval.busImageDetails.PROFILE[0].imageUrlSlugs; 6794 $tpl.find('.bus-profile').css('background-image', 'url(' + imageUrl + ')'); 6795 } else { 6796 $tpl.find('.bus-profile').addClass('d-none'); 6797 } 6798 6799 6800 var currentStationIndex = 0; 6801 var $viaRoutesContainer = $tpl.find('.all-via-routes'); 6802 $viaRoutesContainer.html('<span class="">' + viaStationslide[currentStationIndex] + '</span>'); 6803 $viaRoutesContainer.addClass('show'); 6804 setInterval(function () { 6805 if (currentStationIndex >= viaStationslide.length) { 6806 currentStationIndex = 0; 6807 } 6808 $viaRoutesContainer.removeClass('show'); 6809 $viaRoutesContainer.html('<span class="">' + viaStationslide[currentStationIndex] + '</span>'); 6810 setTimeout(function () { 6811 $viaRoutesContainer.addClass('show'); 6812 }, 100); 6813 currentStationIndex++; 6814 }, 3000); 6815 6816 6817 //journey status 6818 var currentDate = new Date(); // current date 6819 var year = currentDate.getFullYear(); 6820 var month = ('0' + (currentDate.getMonth() + 1)).slice(-2); 6821 var day = ('0' + currentDate.getDate()).slice(-2); 6822 6823 var hours = ('0' + currentDate.getHours()).slice(-2); 6824 var minutes = ('0' + currentDate.getMinutes()).slice(-2); 6825 var seconds = ('0' + currentDate.getSeconds()).slice(-2); 6826 6827 var formattedDate = year + '-' + month + '-' + day; // date only 6828 var formattedDateTime = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds; // date time 6829 var formattedDateTimeObj = new Date(formattedDateTime); // current date time 6830 6831 // from station 6832 var fromDateTime = Object.values(bval.fromStation.stationPoint)[0]; 6833 if (fromDateTime && fromDateTime.dateTime) { 6834 var fromDateTimeObj = new Date(fromDateTime.dateTime); // from station point date time 6835 } 6836 6837 var timeDifference = formattedDateTimeObj - fromDateTimeObj; 6838 var timeDifferenceInSeconds = Math.floor(timeDifference / 1000); 6839 var timeDifferenceInMinutes = Math.floor(timeDifferenceInSeconds / 60); 6840 6841 var absoluteTimeDifferenceInMinutes = Math.abs(timeDifferenceInMinutes); // minutes 6842 var absoluteTimeDifference = Math.abs(timeDifference); // hours 6843 6844 var timeDifferenceHours = Math.round(absoluteTimeDifference / (1000 * 60 * 60)); 6845 6846 // to station 6847 var toStationPoint = Object.values(bval.toStation.stationPoint); 6848 var toDateTime = toStationPoint[toStationPoint.length - 1]; 6849 6850 if (toStationPoint.length > 0 && toStationPoint && toDateTime.dateTime) { 6851 var toDateTimeObj = new Date(toDateTime.dateTime); // to station point date time 6852 } 6853 6854 var formattedTravelDate = new Date(bval.travelDate); 6855 var formatTravelDate = formattedTravelDate.toISOString().split('T')[0]; // travel date 6856 6857 if (formattedDateTimeObj > fromDateTimeObj) { 6858 if (bval.tripStatus.code == "TCA" || (bval.tripStatus.code == "TPC" && bval.bookedSeatCount == 0)) { 6859 $tpl.find('#bus-status').removeClass('d-none').addClass('mt-35'); 6860 } else { 6861 $tpl.find('#bus-status').removeClass('d-none').addClass('in-journey').html('In Journey'); 6862 } 6863 } else if (timeDifferenceHours == 0) { 6864 if (bval.tripStatus.code == "TCA" || (bval.tripStatus.code == "TPC" && bval.bookedSeatCount == 0)) { 6865 $tpl.find('#bus-status').removeClass('d-none').addClass('mt-35'); 6866 } else { 6867 $tpl.find('#bus-status').removeClass('d-none').addClass('hg-g').html('Depart in ' + absoluteTimeDifferenceInMinutes + ' Mins'); 6868 } 6869 } else if (formattedDateTimeObj < fromDateTimeObj) { 6870 if (bval.tripStatus.code == "TCA" || (bval.tripStatus.code == "TPC" && bval.bookedSeatCount == 0)) { 6871 $tpl.find('#bus-status').removeClass('d-none').addClass('mt-35'); 6872 } else { 6873 $tpl.find('#bus-status').removeClass('d-none').addClass('hg-g').html('Depart in ' + timeDifferenceHours + ' Hrs'); 6874 } 6875 } 6876 6877 if (formatTravelDate == formattedDate) { 6878 $tpl.find('#bus-status').removeClass('d-none'); 6879 } else { 6880 $tpl.find('#bus-status').addClass('d-none'); 6881 } 6882 6883 // comingFrom-station 6884 var fromStationFirstBoarding = Object.values(bval.fromStation.stationPoint)[0]; 6885 6886 if (fromStationFirstBoarding.name.length > 13) { 6887 let stationName = fromStationFirstBoarding.name.substring(0, 13) + '...'; 6888 if (formattedDateTimeObj > fromDateTimeObj) { 6889 $tpl.find('.comingFrom-station').html('Starting from ' + stationName) 6890 } else { 6891 $tpl.find('.comingFrom-station').html('Coming from ' + stationName) 6892 } 6893 } else { 6894 if (formattedDateTimeObj > fromDateTimeObj) { 6895 $tpl.find('.comingFrom-station').html('Starting from ' + fromStationFirstBoarding.name) 6896 } else { 6897 $tpl.find('.comingFrom-station').html('Coming from ' + fromStationFirstBoarding.name) 6898 } 6899 } 6900 6901 if (bval.tripInfo.registrationNumber != '') { 6902 $tpl.find('.vehicle-number').removeClass('d-none'); 6903 $tpl.find('.veh-register-no').html(bval.tripInfo.registrationNumber); 6904 } 6905 6906 if (bval.totalSingleSeat != 0) { 6907 $tpl.find('.single-seat-details').removeClass('d-none'); 6908 $tpl.find('.single-seat').html(bval.totalSingleSeat + ' Single'); 6909 } 6910 6911 if (bval.totalWindowSeat != 0) { 6912 $tpl.find('.window-seat-details').removeClass('d-none'); 6913 $tpl.find('.window-seat').html(bval.totalWindowSeat + ' Window'); 6914 } 6915
6916 $tpl.find('.boardingpoint-count').html(bval.fromStation.stationPoint.length); 6917 $tpl.find('.droppingpoint-count').html(bval.toStation.stationPoint.length); 6918 6919 if (isPM(bval.fromStation.dateTime)) { 6920 $tpl.find('.travelTime').html('<img class="mr_2" src="assets/images/search/night-time.svg" width="17px" height= "17px">' + bval.travelTime + ' hrs'); 6921 } else { 6922 $tpl.find('.travelTime').html('<img class="mr_2" src="assets/images/search/day-time.svg" width="17px" height= "17px">' + bval.travelTime + ' hrs'); 6923 } 6924 6925 var punctualityHtml = renderPunctuality(bval.punctualityList, bval.travelDate, bval.fromStation.code, bval.toStation.code); 6926 $tpl.find('.trip-punctuality').html(punctualityHtml).toggleClass('d-none', !punctualityHtml); 6927 6928 // lower 6929 var lower = renderBusSeatsV4({ 6930 layer: 1, 6931 matrix: bval.lmatrix, 6932 seatStatus: bval.seatStatus 6933 }); 6934 6935 $tpl.find('.mini-lower-layer-seats').html(lower); 6936 6937 // upper 6938 if (bval.umatrix) { 6939 var upper = renderBusSeatsV4({ 6940 layer: 2, 6941 matrix: bval.umatrix, 6942 seatStatus: bval.seatStatus 6943 }); 6944 6945 $tpl.find('.mini-upper-layer-seats').html(upper); 6946 $tpl.find('.mini-upper-layer, .mini-layer-name').removeClass('d-none'); 6947 } 6948 6949 // busmap 6950 // $tpl.find('.trip-viewbusmap').on('click', function (e) { 6951 // if (isLoadingBusMap) return; 6952 6953 // if (!$(e.target).is('.boardingpoint-count, .droppingpoint-count')) { 6954 // !$(this).hasClass('no-map') && initBusMap(trip); 6955 // } else { 6956 // renderTripTab('STATIONPOINTS', trip); 6957 // } 6958 // }); 6959 // $tpl.find('.tripinfo-container trip-tab-div').addClass('d-none'); 6960 6961 // var scrollInProgress = false; 6962 $tpl.find('.tripinfo-container').on('click', function (e) { 6963 6964 $('#trip-' + bval.tripCode).find('.trip-tabs-content').removeClass('busgallery-background'); 6965 6966 var tripElement = $('#trip-' + bval.tripCode); 6967 if (tripElement.length && !$(this).hasClass('no-map') && 6968 !$(e.target).is('.share-link') && 6969 !$(e.target).closest('.trip-punctuality-wrap').length && 6970 !$(e.target).is('.boardingpoint-count') && 6971 !$(e.target).is('.droppingpoint-count') && 6972 !$(e.target).hasClass('rest-stop') && 6973 !$(e.target).hasClass('via-routes') && 6974 !$(e.target).hasClass('bus-gallery') && 6975 !$(e.target).hasClass('bus-profile')) { 6976 6977 $('html, body').animate({ 6978 scrollTop: tripElement.offset().top - 60 6979 }, 1000, 'swing', function () { 6980 tripElement.find('.trip-tab-content').slideToggle(300); 6981 $('.trip-tab-content').not(tripElement.find('.trip-tab-content')).slideUp(300); 6982 }); 6983 } 6984 6985 if (isLoadingBusMap) return; 6986 if ($(e.target).closest('.trip-tabs').length > 0) { 6987 return; 6988 } 6989 6990 if ($(e.target).is('.share-link')) { 6991 generateSharingLink(bval); 6992 trackEvent('Share Trip', 'click', 'Share Link'); 6993 return; 6994 } 6995 6996 if ($(e.target).closest('.trip-punctuality-wrap').length) { 6997 return; 6998 } 6999 7000 if ($(e.target).is('.boardingpoint-count, .droppingpoint-count')) { 7001 renderTripTab('STATIONPOINTS', bval); 7002 trackEvent('Trip Info', 'click', 'STATIONPOINTS'); 7003 return; 7004 } 7005 7006 if ($(e.target).hasClass('rest-stop')) { 7007 renderTripTab('RESTSTOPS', bval); 7008 trackEvent('Trip Info', 'click', 'RESTSTOPS'); 7009 return; 7010 } 7011 7012 if ($(e.target).hasClass('bus-gallery') || $(e.target).hasClass('bus-profile')) { 7013 $('#trip-' + bval.tripCode).find('.trip-tabs-content').addClass('busgallery-background'); 7014 renderTripTab('BUSPHOTOS', bval); 7015 trackEvent('Trip Info', 'click', 'BUSPHOTOS'); 7016 return; 7017 } 7018 7019 if ($(e.target).hasClass('via-routes')) { 7020 renderTripTab('VIAROUTES', bval); 7021 trackEvent('Trip Info', 'click', 'VIAROUTES'); 7022 return; 7023 } 7024 7025 if (!$(this).hasClass('no-map')) { 7026 $(this).find('.trip-viewbusmap').html('Hide seats'); 7027 initBusMap(bval, 'conn'); 7028 } 7029 }); 7030 7031 // tabs 7032 // ordering 7033 $tpl 7034 .attr('data-departure', moment(bval.fromStation.dateTime).valueOf()) 7035 .attr('data-availability', bval.availableSeatCount) 7036 .attr('data-fare', minFare); 7037 7038 // tooltips 7039 $tpl.find('[data-toggle="tooltip"]').tooltip({ 7040 container: template, 7041 html: true, 7042 placement: 'top', 7043 boundary: 'viewport', 7044 }); 7045 7046 // hide some futures on busmap card for CONN type 7047 // if (isConnecting) { 7048 // // if need use it 7049 // } 7050 7051 // $tripListCont.append(tripList); 7052 return $tpl; 7053 }); 7054} 7055 7056function resetConnectingLogicDatas() { 7057 // get regConnTrip.WAITING_TIME data before reset regConnTrip 7058 let waitingTime = regConnTrip.WAITING_TIME; 7059 regConnTrip = initOrResetRegConnTrip(); 7060 // set waitingTime back to regConnTrip.WAITING_TIME to avoid js error 7061 regConnTrip.WAITING_TIME = waitingTime 7062 7063 $(document).find('.conn-stations').each(function () {
7064 let $this = $(this); 7065 // reset conn station to begining 7066 $(this).find('input[name^="station_"]:first').prop('checked', true).trigger('change'); 7067 // remove toggleing functionality 7068 $this.find('.stationCollapseCtrlP').attr('data-toggle', ''); 7069 let $stationCollapseCtrlC = $this.find('.stationCollapseCtrlC'); 7070 // reset conn station trip UI trip info 7071 $stationCollapseCtrlC.find('.seat-name').html('-'); 7072 $stationCollapseCtrlC.find('.raw-fare').html('-'); 7073 $stationCollapseCtrlC.find('.discount').html('-'); 7074 $stationCollapseCtrlC.find('.tax').html('-'); 7075 $stationCollapseCtrlC.find('.payable-fare').html('-'); 7076 }); 7077 7078} 7079 7080function formatDateTime(dateString, format) { 7081 const date = new Date(dateString); 7082 7083 const formatYear = () => date.getFullYear(); 7084 7085 const padZero = (num) => String(num).padStart(2, '0'); 7086 7087 const formatTime12Hour = () => { 7088 let hour = date.getHours(); 7089 const minute = date.getMinutes(); 7090 const isPM = hour >= 12; 7091 const period = isPM ? 'PM' : 'AM'; 7092 if (hour > 12) { 7093 hour -= 12; 7094 } else if (hour === 0) { 7095 hour = 12; 7096 } 7097 const paddedMinute = minute < 10 ? '0' + minute : minute; 7098 return `${hour}:${paddedMinute} ${period}`; 7099 }; 7100 7101 const formatTime24Hour = (withSeconds = false) => {
7102 const month = String(date.getMonth() + 1).padStart(2, '0'); 7103 const day = String(date.getDate()).padStart(2, '0'); 7104 const hours = String(date.getHours()).padStart(2, '0'); 7105 const minutes = String(date.getMinutes()).padStart(2, '0'); 7106 const seconds = String(date.getSeconds()).padStart(2, '0'); 7107 if (withSeconds) { 7108 return `${formatYear()}-${month}-${day} ${hours}:${minutes}:${seconds}`; 7109 } else { 7110 return `${formatYear()}-${month}-${day} ${hours}:${minutes}`; 7111 } 7112 }; 7113 7114 const formatDayOfWeek = () => date.toLocaleString('en-US', { weekday: 'short' }); 7115 7116 const formatMonth = () => date.toLocaleString('en-US', { month: 'short' }); 7117 7118 const formatDayWithSuffix = () => { 7119 const day = date.getDate(); 7120 const suffix = (day >= 11 && day <= 13) ? 'th' : (['1', '21', '31'].indexOf(day.toString()) !== -1) ? 'st' : (['2', '22'].indexOf(day.toString()) !== -1) ? 'nd' : (['3', '23'].indexOf(day.toString()) !== -1) ? 'rd' : 'th'; 7121 return `${day}${suffix}`; 7122 }; 7123 7124 7125 const formatFullDateWithDay = () => { 7126 return `${formatDayOfWeek()} ${formatMonth()} ${padZero(date.getDate())} ${formatYear()}`; 7127 }; 7128 7129 const formatFullDate = () => { 7130 return `${formatDayWithSuffix()} ${date.toLocaleString('default', { month: 'long' })} ${formatYear()}`; 7131 }; 7132 7133 const formatISODate = () => { 7134 return `${formatYear()}-${padZero(date.getMonth() + 1)}-${padZero(date.getDate())}`; 7135 }; 7136 7137 const formatMonDDMonTime = () => { 7138 return `${formatDayOfWeek()} ${padZero(date.getDate())} ${formatMonth()}, ${formatTime12Hour()}`; 7139 }; 7140 7141 // Switch based on format type 7142 switch (format) { 7143 case '12-hour-time': 7144 return formatTime12Hour(); 7145 case '24-hour-time': 7146 return formatTime24Hour(false); 7147 case '24-hour-time-ws': 7148 return formatTime24Hour(true); 7149 case 'full-date-with-day': 7150 return formatFullDateWithDay(); 7151 case 'full-date': 7152 return formatFullDate(); 7153 case 'iso-date': 7154 return formatISODate(); 7155 case 'ddd DD-MM-YYYY': 7156 return moment(dateString).format('ddd DD-MM-YYYY'); 7157 case 'ddd-mon-time': 7158 return `${formatDayWithSuffix()} ${formatMonth()} ${formatTime12Hour()}`; 7159 case 'd-mon-yr-time': 7160 return formatMonDDMonTime(); 7161 default: 7162 return dateString; 7163 } 7164} 7165 7166function forseatSelectZero() { 7167 $('#booking-card').addClass('d-none'); 7168 $('.select-info-card').removeClass('d-none'); 7169 $('.connecting-content').removeClass('d-none'); 7170 $('.bpdpHeight').addClass('d-none'); 7171 7172 $('.seat-select-visibility').each(function () { 7173 $(this).removeClass('seat-selected'); 7174 $(this).removeClass('seater-selected'); 7175 $(this).removeClass('sleeper-selected'); 7176 }); 7177 7178 $('.conn-selected').empty(); 7179} 7180 7181function initConnBlockSeats(conndata) { // for block seat connecting 7182 var data = processConnTicketData(conndata); 7183 7184 if (!$('#pass-terms').is(':checked')) { 7185 $('#pass-terms').addClass('is-invalid'); 7186 return; 7187 } 7188 7189 if (!data) { 7190 return; 7191 } 7192 7193 $('#conn-block-ticket-btn') 7194 .prop('disabled', true) 7195 .html( 7196 '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> ' + 7197 'Please wait...' 7198 ); 7199 7200 7201 $.ajax({ 7202 type: 'POST', 7203 url: 'passenger-info/block-seats', 7204 data: data, 7205 dataType: 'json', 7206 success: function (result) { 7207 if (result.status == 1) { 7208 if (result.data.paymentGatewayProcessFlag) { 7209 if (result.data.gatewayCode == 'RAZORPAY') { 7210 var options = result.data.gatewayInputDetails; 7211 options.image = 'assets/images/logo.png'; 7212 options.theme = {}; 7213 options.theme.color = getComputedStyle(document.documentElement).getPropertyValue('--theme-primary-color').trim(); 7214 options.modal = {}; 7215 options.modal.escape = false;
7216 options.modal.confirm_close = true; 7217 options.modal.ondismiss = function () { 7218 location.href = 'passenger-info/payment-response?orderCode=' + result.data.code; 7219 }; 7220 var rzp1 = new Razorpay(options); 7221 rzp1.open(); 7222 return 7223 } 7224 7225 var formControl = ''; 7226 $.each(result.data.gatewayInputDetails || [], function (rekey, reval) { 7227 formControl += '<input name="' + rekey + '" id="' + rekey + '" value="' + reval + '" />'; 7228 }); 7229 $('body').append('<form action="' + result.data.paymentRequestUrl + '" name="frm_payment" id="frm_payment" method="post" style="display:none;">' + formControl + '</form>'); 7230 $('#frm_payment').submit(); 7231 } else { 7232 location.href = 'passenger-info/payment-response?orderCode=' + result.data.code; 7233 } 7234 } else { 7235 $('#pass-alert').danger(result.errorDesc); 7236 } 7237 $('#conn-block-ticket-btn').prop('disabled', false).html('Continue'); 7238 } 7239 }); 7240} 7241 7242function connectTripDetais(connetSchedule) { 7243 let data = {}; 7244 data.isConnecting = true; 7245 data.orderDetails = regConnTrip.TKT_BLK_BOOK_DETAILS.orderDetails; 7246 data.additional = regConnTrip.TKT_BLK_BOOK_DETAILS.additionalAttributes;
7247 // data.additional = connetSchedule; 7248 7249 $.each(connDetails, function (i, res) { 7250 data.connPoints = res.connPoints; 7251 data.waitingTime = res.waitingTime; 7252 }); 7253 7254 let fromDate, toDate, timeString = ''; 7255 7256 // for data showing in payment page; 7257 $.each(regConnTrip.TKT_BLK_BOOK_DETAILS.orderDetails, function (i, res) { 7258 7259 if (i === 0) { 7260 data.fromstationname = res.fromStationName; 7261 data.fromstationbp = res.boardingPointName; 7262 fromDate = new Date(res.travelDate); 7263 data.fromTravelDate = formatDateTime(res.travelDate, 'd-mon-yr-time'); 7264 data.fromtraveldate = res.travelDate; 7265 data.fromcode = res.fromStation; 7266 } 7267 7268 if (i === regConnTrip.TKT_BLK_BOOK_DETAILS.orderDetails.length - 1) { 7269 data.tostationname = res.toStationName; 7270 data.tostationdp = res.droppingPointName; 7271 toDate = new Date(res.travelDate); 7272 data.toTravelDate = formatDateTime(res.travelDate, 'd-mon-yr-time'); 7273 data.totraveldate = res.travelDate; 7274 data.tocode = res.toStation; 7275 } 7276 7277 if (fromDate && toDate) { // difference of from date & to date 7278 let timeDifference = toDate - fromDate; 7279 let days = Math.floor(timeDifference / (1000 * 60 * 60 * 24)); 7280 let hours = Math.floor((timeDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); 7281 timeString = `${days} Days ${hours} Hours`; 7282 } 7283 7284 data.dayFromToDiff = timeString; 7285 }); 7286 7287 gotoConnPassengerDetails(data); 7288 // calculateConnectingFare(regConnTrip.TKT_BLK_BOOK_DETAILS.orderDetails); 7289} 7290 7291function gotoConnPassengerDetails(bookingData) { 7292 7293 if (!bookingData) { 7294 return; 7295 } 7296 7297 $('#selected-seat-next') 7298 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Please Wait...') 7299 .attr('disabled', true); 7300 7301 // submit form 7302 $('#form-seats-data').val(JSON.stringify(bookingData)); 7303 $('#form-seats').attr('action', 'passenger-info').submit(); 7304} 7305 7306// for passenger 7307function newTicketCalculation(offerData, hotelRelated = false) { 7308 var { onwardData, returnData, rescheduleData } = getPassengerTicketData(); 7309 var addonCharges = getAddonCharges(); 7310 7311 7312 var femaleDiscount; 7313 $.each(onwardData.discountList || [], function (i, discount) { 7314 if (discount.femaleDiscountFlag) { 7315 femaleDiscount = discount; 7316 } 7317 }); 7318 7319 var totalfare = 0; 7320 var faredifference = 0; 7321 var offerDiscount = 0; 7322 7323 var onwardfare = 0; 7324 var onwardboardingfare = 0; 7325 var onwarddroppingfare = 0; 7326 var onwardgst = 0; 7327 var onwarddiscount = 0; 7328 7329 var returnfare = 0; 7330 var returnboardingfare = 0; 7331 var returndroppingfare = 0; 7332 var returngst = 0; 7333 var returndiscount = 0; 7334 7335 var hotelFare = 0; 7336 var hotelPersonFare = 0; 7337 var hotelDiscount = 0; 7338 var hotelGst = 0; 7339 7340 var overallTotal = 0; 7341 var overallTotalRound = 0; 7342 var discountTotal = 0; 7343 var taxTotal = 0; 7344 var hotelTotal = 0; 7345 var grandTotal = 0; 7346 7347 var ticketAmount = 0; // for to addon details ticketAmount 7348 7349 var onwardSeatCount = onwardData.seatDetails.length; 7350 $.each(onwardData.seatDetails || [], function (i, seat) { 7351 onwardfare += seat.fare; 7352 onwardgst += seat.serviceTax; 7353 onwarddiscount += seat.discountFare; 7354 7355 if (femaleDiscount) { 7356 var gender = $('.onward-trip [data-code="' + seat.seatCode + '"]').find('.pass-gender:checked').val(); 7357 7358 if (gender === 'F') { 7359 onwarddiscount += (femaleDiscount.percentageFlag) 7360 ? percentageOf(femaleDiscount.discountValue, seat.fare) 7361 : femaleDiscount.discountValue; 7362 } 7363 } 7364 }); 7365 7366 if (onwardData.fromStation.stationPoint && Number(onwardData.fromStation.stationPoint.fare) > 0) { 7367 onwardboardingfare += Number(onwardData.fromStation.stationPoint.fare) * onwardSeatCount; 7368 } 7369 7370 if (onwardData.toStation.stationPoint && Number(onwardData.toStation.stationPoint.fare) > 0) { 7371 onwarddroppingfare += Number(onwardData.toStation.stationPoint.fare) * onwardSeatCount; 7372 } 7373 7374 if (returnData) { 7375 var returnSeatCount = returnData.seatDetails.length; 7376 $.each(returnData.seatDetails || [], function (i, seat) { 7377 returnfare += seat.fare; 7378 returngst += seat.serviceTax; 7379 returndiscount += seat.discountFare; 7380 }); 7381 7382 if (returnData.fromStation.stationPoint && Number(returnData.fromStation.stationPoint.fare) > 0) { 7383 returnboardingfare += Number(returnData.fromStation.stationPoint.fare) * returnSeatCount; 7384 } 7385 if (returnData.toStation.stationPoint && Number(returnData.toStation.stationPoint.fare) > 0) { 7386 returndroppingfare += Number(returnData.toStation.stationPoint.fare) * returnSeatCount; 7387 } 7388 } 7389 7390 $('#apply-offer-help').html(''); 7391 if (offerData) { 7392 7393 var fare = onwardfare + onwardboardingfare + onwarddroppingfare; 7394 if (returnData) { 7395 fare += returnfare + returnboardingfare + returndroppingfare; 7396 } 7397 var offerValue = (offerData.percentageFlag) ? percentageOf(offerData.value, fare) : offerData.value;
7398 var offerAmount = Math.max((offerData.maxvalue || 0), offerValue); 7399 7400 $('#apply-offer-help').html('A discount of ' + currencySymbol + Number(offerAmount).toFixed(2) + ' has been applied'); 7401 // discount += offerAmount; 7402 7403 // returndiscount += offerAmount; 7404 if (returnData) { 7405 offerDiscount += offerAmount; 7406 } else { 7407 onwarddiscount += offerAmount; 7408 } 7409 } 7410 7411 var onwardTotal = onwardfare + onwardboardingfare + onwarddroppingfare - onwarddiscount; 7412 var returnTotal = returnfare + returnboardingfare + returndroppingfare - returndiscount; 7413 7414 var onwardTotaRound = onwardfare + onwardboardingfare + onwarddroppingfare; 7415 var returnTotaRound = returnfare + returnboardingfare + returndroppingfare; 7416 7417 if (onwardgst > 0) { 7418 const GSTPERCENT = 5; 7419 onwardgst = percentageOf(GSTPERCENT, onwardTotal); 7420 // onwardTotal += onwardgst; 7421 } 7422 7423 if (returngst > 0) { 7424 const GSTPERCENT = 5; 7425 returngst = percentageOf(GSTPERCENT, returnTotal); 7426 // returnTotal += returngst; 7427 } 7428 7429 7430 hotelFare = $('.text-right.hotel-fare').text(); 7431 hotelPersonFare = $('.text-right.hotel-person-fare').text(); 7432 hotelDiscount = $('.text-right.hotel-discount').text(); 7433 hotelGst = $('.text-right.hotel-gst').text(); 7434 7435 var HotelRoomCount = 0; 7436 var HotelPersonCount = 0; 7437 7438 HotelRoomCount = $('.hotel-details-card.selected').find('.hotel-rooms-number').text(); 7439 HotelPersonCount = $('.hotel-details-card.selected').find('.hotel-person-number').text(); 7440 7441 $('.text-left.hotel-fare').text('Room Fare (' + HotelRoomCount + ' Room(s))'); 7442 $('.text-left.hotel-person-fare').text('Extra Person Fare (' + HotelPersonCount + ' Person(s))'); 7443 7444 if (hotelRelated && !$('.hotel-details-card').hasClass('selected')) { 7445 hotelFare = '0'; 7446 hotelPersonFare = '0'; 7447 hotelGst = '0'; 7448 hotelDiscount = '0'; 7449 $('.text-left.hotel-fare').text('Room Fare'); 7450 $('.text-left.hotel-person-fare').text('Extra Person Fare'); 7451 } 7452 7453 hotelFare = convertToNumber(hotelFare); 7454 hotelPersonFare = convertToNumber(hotelPersonFare); 7455 hotelDiscount = convertToNumber(hotelDiscount); 7456 hotelGst = convertToNumber(hotelGst); 7457 7458 // totalfare = Math.round(totalfare); 7459 // onwardTotal = Math.round(onwardTotal); 7460 // returnTotal = Math.round(returnTotal); 7461 7462 // onwardTotaRound = Math.round(onwardTotaRound); 7463 // returnTotaRound = Math.round(returnTotaRound); 7464 7465 7466 overallTotal = onwardTotal + returnTotal; 7467 overallTotalRound = onwardTotaRound + returnTotaRound; 7468 hotelTotal = hotelFare + hotelPersonFare; 7469 discountTotal = onwarddiscount + returndiscount + hotelDiscount + offerDiscount; 7470 taxTotal = onwardgst + returngst + hotelGst; 7471 7472 // grandTotal = overallTotal + hotelTotal + taxTotal - discountTotal; 7473 grandTotal = overallTotalRound + hotelTotal + taxTotal - discountTotal; 7474 totalfare = onwardfare + onwardboardingfare + onwarddroppingfare - onwarddiscount + onwardgst; 7475 7476 ticketAmount = overallTotalRound + onwardgst + returngst - onwarddiscount - returndiscount; 7477 // ticketAmount = Math.round(ticketAmount); 7478 7479 $('#ticket-amount').val(ticketAmount); 7480 7481 if (rescheduleData) { 7482 faredifference = Math.max(0, totalfare - rescheduleData.totalPaid + onwarddiscount); 7483 grandTotal = faredifference + rescheduleData.reschedulableAmount; 7484 } 7485 7486 var gogreen = $('#gogreen-addon-cb').is(':checked'); 7487 if (addonCharges.GOGREEN && gogreen) { 7488 grandTotal += addonCharges.GOGREEN 7489 onwardTotal += addonCharges.GOGREEN 7490 } 7491 7492 var pgcharges = 0; 7493 var pgchargepercent = Number($('input[name="payment-options"]:checked').data('pgcharges')) || 0; 7494 if (pgchargepercent > 0) { 7495 pgcharges = percentageOf(pgchargepercent, grandTotal); 7496 grandTotal += pgcharges; 7497 onwardTotal += pgcharges 7498 } 7499 7500 // onwardTotal = Math.round(onwardTotal); 7501 // grandTotal = Math.round(grandTotal); 7502 7503 $('.grandtotfare').html(currencySymbol + grandTotal.toFixed(2)); // grand total in top 7504 7505 $onwardfaretable = $('#onward-pass-fare-details').empty(); 7506 if (returnData) { 7507 $onwardfaretable.append(buildFareRow('ONWFARE', onwardfare)); 7508 } else { 7509 $onwardfaretable.append(buildFareRow('BUSFARE', onwardfare)); 7510 } 7511 $onwardfaretable.append(buildFareRow('PICKUP', onwardboardingfare)); 7512 $onwardfaretable.append(buildFareRow('DROPPING', onwarddroppingfare)); 7513 $onwardfaretable.append(buildFareRow('ONWDISCOUNT', onwarddiscount)); 7514 $onwardfaretable.append(buildFareRow('ONWGST', onwardgst)); 7515 if (!returnData) { 7516 if (gogreen) { 7517 $onwardfaretable.append(buildFareRow('GOGREEN', addonCharges.GOGREEN)); 7518 } 7519 $onwardfaretable.append(buildFareRow('PGCHARGE', pgcharges)); 7520 $onwardfaretable.append(emptyFareRow()); 7521 $onwardfaretable.append(buildFareRow('GRANDTOTAL', totalfare)); 7522 } 7523 7524 $returnfaretable = $('#return-pass-fare-details').empty(); 7525 $returnfaretable.append(buildFareRow('RETFARE', returnfare)); 7526 $returnfaretable.append(buildFareRow('PICKUP', returnboardingfare)); 7527 $returnfaretable.append(buildFareRow('DROPPING', returndroppingfare)); 7528 $returnfaretable.append(buildFareRow('RETDISCOUNT', returndiscount)); 7529 $returnfaretable.append(buildFareRow('RETGST', returngst)); 7530 7531 $farebreakuptable = $('#breakup-pass-fare-details').empty(); 7532 if (rescheduleData) { 7533 if (faredifference > 0) { 7534 $farebreakuptable.append(buildFareRow('NEWTICKET', onwardfare)); 7535 // $farebreakuptable.append(buildFareRow('DISCOUNT', discount)); 7536 $farebreakuptable.append(buildFareRow('GST', onwardgst)); 7537 $farebreakuptable.append(buildFareRow('OLDTICKET', rescheduleData.totalPaid)); 7538 $farebreakuptable.append(emptyFareRow('<div class="border-top" />')); 7539 $farebreakuptable.append(buildFareRow('FAREDIFF', faredifference)); 7540 } 7541 $farebreakuptable.append(buildFareRow('RESCHARGE', rescheduleData.reschedulableAmou
7541nt)); 7542 $farebreakuptable.append(buildFareRow('PGCHARGE', pgcharges)); 7543 } else { 7544 $farebreakuptable.append(buildFareRow('OVRTOTAL', overallTotalRound)); 7545 $farebreakuptable.append(buildFareRow('HOTELTOTAL', hotelTotal)); 7546 $farebreakuptable.append(buildFareRow('TOTALDISCOUNT', discountTotal)); 7547 $farebreakuptable.append(buildFareRow('TAXTOTAL', taxTotal)); 7548 if (gogreen) { 7549 $farebreakuptable.append(buildFareRow('GOGREEN', addonCharges.GOGREEN)); 7550 } 7551 $farebreakuptable.append(buildFareRow('PGCHARGE', pgcharges)); 7552 } 7553 $farebreakuptable.append(emptyFareRow()); 7554 $farebreakuptable.append(buildFareRow('GRANDTOTAL', grandTotal)); 7555 7556 if (onwardTotal == 0) { 7557 $('#pg-accordion, #pg-redirect-hint').addClass('d-none'); 7558 $('#block-ticket-btn').html('Continue'); 7559 } 7560} 7561 7562function formatHotelDate(date) { 7563 var d = new Date(date); 7564 7565 var year = d.getFullYear(); 7566 var month = ("0" + (d.getMonth() + 1)).slice(-2); 7567 var day = ("0" + d.getDate()).slice(-2); 7568 var hours = ("0" + d.getHours()).slice(-2); 7569 var minutes = ("0" + d.getMinutes()).slice(-2); 7570 var seconds = ("0" + d.getSeconds()).slice(-2); 7571 7572 return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds; 7573} 7574 7575function calculateGSTExclusive(tot, gst) { 7576 let tax = (gst / 100) * tot; 7577 let payable = Number(tot) + Number(tax); 7578 return { payable: payable, tax: tax }; 7579} 7580 7581function calculateGSTInclusive(tot, gst) { 7582 let payable = (tot * (100 / (100 + gst))) 7583 let tax = Number(tot) - Number(payable); 7584 return { payable: payable, tax: tax }; 7585} 7586 7587function convertToNumber(value) { 7588 value = value.replace(/[^0-9.-]+/g, '').trim(); 7589 if (value === '' || value === ' ') { 7590 return 0; 7591 } 7592 return parseFloat(value); 7593} 7594 7595function connTripFilter(element, id, filterType) { 7596 let currentOrderBy = element.dataset.orderby; 7597 let newOrderBy = ''; 7598 switch (currentOrderBy) { 7599 case 'asc': 7600 newOrderBy = 'desc'; 7601 break; 7602 case 'desc': 7603 newOrderBy = 'none'; 7604 break; 7605 default: 7606 newOrderBy = 'asc'; 7607 break; 7608 } 7609 7610 // Update the dataset orderby attribute 7611 element.dataset.orderby = newOrderBy; 7612 7613 // var $tripcont = $('#trip-list-container-' + id + " .conn-trips"); 7614 var $tripcont = $(element).closest('.info-cont').find('.conn-trips'); 7615 var tripInfos = $tripcont.find('.c-trip-infos').not('.hide'); 7616 var sortOrder = $tripcont.data('sortOrder') || 'asc'; 7617 7618 7619 // Switch based on filterType 7620 switch (filterType) { 7621 case 'byDays': 7622 tripInfos.each(function () { 7623 var departureTimestamp = $(this).data('departure'); 7624 var departureDate = new Date(departureTimestamp); 7625 $(this).data('departureDate', departureDate); 7626 }); 7627 7628 tripInfos.sort(function (a, b) { 7629 var dateA = $(a).data('departureDate'); 7630 var dateB = $(b).data('departureDate'); 7631 7632 if (sortOrder === 'asc') { 7633 return dateA - dateB; 7634 } else if (sortOrder === 'desc') { 7635 return dateB - dateA; 7636 } 7637 }); 7638 break; 7639 7640 case 'byFare': 7641 tripInfos.each(function () { 7642 var fare = parseFloat($(this).data('fare')); 7643 $(this).data('fareValue', fare); 7644 }); 7645 7646 tripInfos.sort(function (a, b) { 7647 var fareA = $(a).data('fareValue'); 7648 var fareB = $(b).data('fareValue'); 7649 7650 if (sortOrder === 'asc') { 7651 return fareA - fareB; 7652 } else { 7653 return fareB - fareA; 7654 } 7655 }); 7656 break; 7657 7658 case 'bySeat': 7659 tripInfos.each(function () { 7660 var seat = parseFloat($(this).data('availability')); 7661 $(this).data('seatValue', seat); 7662 }); 7663 7664 tripInfos.sort(function (a, b) { 7665 var seatA = $(a).data('seatValue'); 7666 var seatB = $(b).data('seatValue'); 7667 7668 if (sortOrder === 'asc') { 7669 return seatA - seatB; 7670 } else { 7671 return seatB - seatA; 7672 } 7673 }); 7674 break; 7675 7676 case 'byTime': 7677 tripInfos.each(function () { 7678 var duration = parseFloat($(this).data('duration')); 7679 $(this).data('durationValue', duration); 7680 }); 7681 7682 tripInfos.sort(function (a, b) { 7683 var durationA = $(a).data('durationValue'); 7684 var durationB = $(b).data('durationValue'); 7685 7686 if (sortOrder === 'asc') { 7687 return durationA - durationB; 7688 } else { 7689 return durationB - durationA; 7690 } 7691 }); 7692 break; 7693 7694 default: 7695 return; 7696 } 7697 7698 $tripcont.append(tripInfos); 7699 $tripcont.data('sortOrder', sortOrder === 'asc' ? 'desc' : 'asc'); 7700} 7701 7702async function sendOTPNew() { 7703 var data = {}, 7704 err = 0; 7705 data.mobileNumber = $('#otp-login-mobiles').val().trim(); 7706 7707 if (!validate.isMobile(data.mobileNumber)) { 7708 $('#otp-login-mobiles').addClass('is-invalid'); 7709 err++; 7710 } 7711 7712 var captchaInput = $('#captchaCode').val().trim(); 7713 if (!captchaInput) { 7714 $('#captchaCode').addClass('is-invalid'); 7715 $('#otp-login-alerts').danger().on('detach', function () { 7716 $('#captchaCode .is-invalid').removeClass('is-invalid'); 7717 }); 7718 err++; 7719 } 7720 7721 if (err) { 7722 $('#otp-login-alerts').danger().on('detach', function () { 7723 $('#mobile-sections .is-invalid').removeClass('is-invalid'); 7724 $('#captchaCode .is-invalid').removeClass('is-invalid'); 7725 }); 7726 return; 7727 } 7728 7729 // Captcha is verified server-side within send-otp; send it in the payload. 7730 data.captacha = captchaInput; 7731 7732 $('#otp-login-alerts').html(''); 7733 $('#send-otp-btns') 7734 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Sending...') 7735 .attr('disabled', true); 7736 7737 $.ajax({ 7738 type: 'POST', 7739 url: 'user/sending-otp', 7740 data: data, 7741 dataType: 'json', 7742 success: function (result) { 7743 $('#send-otp-btns').prop('disabled', false).html('Submit'); 7744 if (result.status == 1) { 7745 // subscribeWebOTPNew(); 7746 $('#forresendmob').val(data.mobileNumber); 7747 let mb = data.mobileNumber.replace(/(?<=\d{5})\d/g, "X"); 7748 $('#otp-login-alerts').success(); 7749 // $('#otp-login-mobiles').val(''); 7750 // $('#mobile-hide').addClass('d-none'); 7751 $('#mobile-sections').addClass('d-none'); 7752 $('#otp-sections').removeClass('d-none'); 7753 $('.mobile-mask').html('Enter OTP We have send to this ' + mb + '.'); 7754 $('.inputContainer input[name="pin1"]').focus(); 7755 } else { 7756 if (result.status == 0 && result.errorCode == "TR01B") { 7757 $('#otp-login-alerts').timeExceed(); 7758 } else { 7759 genCaptcha(); // reset on failure 7760 $('#otp-login-alerts').danger(result.errorDesc); 7761 } 7762 } 7763 }, 7764 error: function () { 7765 $('#send-otp-btns').prop('disabled', false).html('Submit'); 7766 genCaptcha(); 7767 } 7768 }); 7769} 7770 7771function validateOTPNew() { 7772 var data = {}, 7773 err = 0; 7774 data.mobileNumber = $('#forresendmob').val().trim(); 7775 7776 const otpInputs = document.querySelectorAll('.inputContainer input'); 7777 let otpNumber = ''; 7778
7779 otpInputs.forEach(input => { 7780 if (input.value.trim().length === 1) { 7781 otpNumber += input.value.trim(); 7782 } else { 7783 otpNumber += ''; // or throw an error 7784 } 7785 }); 7786 7787 data.otpNumber = otpNumber; 7788 7789 $('#otp-login-validate-alerts').html(''); 7790 $('#validate-otp-btns') 7791 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Validating...') 7792 .attr('disabled', true); 7793 7794 $.ajax({ 7795 type: 'POST', 7796 url: 'user/validate-otp', 7797 data: data, 7798 dataType: 'json', 7799 success: function (result) { 7800 if (result.status == 1) { 7801 $('#otp-login-validate-alerts').success(); 7802 // if(location.pathname.includes('/passenger-info')){ 7803 location.reload(); 7804 // autofillPassInfo(); 7805 // } 7806 } else if (result.status == 2) { 7807 $('#otp-login-validate-alerts').success(); 7808 7809 $('#otp-sections').addClass('d-none'); 7810 $('#register-sections').removeClass('d-none'); 7811 } else { 7812 $('#otp-login-validate-alerts').danger(result.errorDesc); 7813 $('#validate-otp-btns').prop('disabled', false).html('Submit'); 7814 } 7815 } 7816 }); 7817} 7818 7819 7820function registerUserNew() { 7821 var data = {}, 7822 err = 0; 7823 data.name = $('#otp-register-fnames').val().trim(); 7824 data.lastname = $('#otp-register-lnames').val().trim(); 7825 data.email = $('#otp-register-emails').val().trim(); 7826 data.mobile = $('#forresendmob').val().trim(); 7827 7828 if (data.name == '') { 7829 $('#otp-register-fnames').addClass('is-invalid'); 7830 err++; 7831 } 7832 if (!validate.isEmail(data.email)) { 7833 $('#otp-register-fnames').addClass('is-invalid'); 7834 err++; 7835 } 7836 7837 if (err) { 7838 $('#otp-login-register-alerts').danger().on('detach', function () { 7839 $('#register-sections .is-invalid').removeClass('is-invalid'); 7840 }); 7841 return; 7842 } 7843 7844 $('#otp-login-register-alerts').html(''); 7845 $('#otp-register-btns') 7846 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Submitting...') 7847 .attr('disabled', true); 7848 7849 $.ajax({ 7850 type: 'POST', 7851 url: 'user/update-profile', 7852 data: data, 7853 dataType: 'json', 7854 success: function (result) { 7855 $('#otp-register-btns').prop('disabled', false).html('Submit'); 7856 if (result.status == 1) { 7857 $('#otp-login-register-alerts').success(); 7858 // if(location.pathname.includes('/passenger-info')){ 7859 location.reload(); 7860 // autofillPassInfo(); 7861 // } 7862 } else { 7863 $('#otp-login-register-alerts').danger(result.errorDesc); 7864 } 7865 } 7866 }); 7867} 7868 7869function subscribeWebOTPNew() { 7870 if (!window.OTPCredential) return; 7871 7872 const input = document.querySelector('#otp-login-pins'); 7873 const button = document.querySelector('#validate-otp-btns'); 7874 if (!input || !button) return; 7875 7876 const ac = new AbortController(); 7877 button.addEventListener('click', e => { 7878 ac.abort(); 7879 }); 7880 7881 navigator.credentials.get({ 7882 otp: { transport: ['sms'] }, 7883 signal: ac.signal 7884 }).then(otp => { 7885 input.value = otp.code; 7886 button.click(); 7887 }).catch(err => { 7888 console.log(err); 7889 }); 7890} 7891 7892const handleInput = (inputNumber) => { 7893 const currentInput = document.querySelector(`.inputContainer input:nth-child(${inputNumber})`); 7894 const nextInput = document.querySelector(`.inputContainer input:nth-child(${inputNumber + 1})`); 7895 7896 if (isNaN(currentInput.value)) return false; 7897 7898 if (currentInput.value.length === 1 && nextInput) { 7899 nextInput.disabled = false; 7900 nextInput.focus(); 7901 } 7902 7903 const allInputsFilled = Array.from(document.querySelectorAll('.inputContainer input')) 7904 .every(input => input.value.length === 1); 7905 7906 const verifyBtn = document.querySelector('.verifyBtn'); 7907 verifyBtn.disabled = !allInputsFilled; 7908} 7909 7910const handleBackspace = (inputNumber, event) => { 7911 if (event.key == 'Backspace') { 7912 const currentInput = document.querySelector(`.inputContainer input:nth-child(${inputNumber})`); 7913 const prevInput = document.querySelector(`.inputContainer input:nth-child(${inputNumber - 1})`); 7914 7915 if (currentInput.value.length === 0 && prevInput) { 7916 currentInput.disabled = true; 7917 currentInput.value = ""; 7918 prevInput.focus(); 7919 } 7920 7921 const allInputsFilled = Array.from(document.querySelectorAll('.inputContainer input')) 7922 .every(input => input.value.length === 1); 7923 7924 const verifyBtn = document.querySelector('.verifyBtn'); 7925 verifyBtn.disabled = !allInputsFilled; 7926 } 7927} 7928 7929const onlyNumber = (event) => { 7930 const value = event.target.value.replace(/[^0-9]/g, ''); 7931 event.target.value = value; 7932}; 7933 7934function resendOTP() { 7935 var data = {}, 7936 err = 0; 7937 // Use the mobile stored during the initial send as the resend key. The 7938 // server verifies this key before resending the OTP and only then removes 7939 // the single-time captcha from the session. 7940 var resendMobile = $('#forresendmob').val().trim(); 7941 data.resendKey = resendMobile; 7942 7943 if (!validate.isMobile(resendMobile)) { 7944 $('#otp-login-validate-alerts').danger('Unable to resend OTP. Please start again.'); 7945 return; 7946 } 7947 7948 $('#otp-login-validate-alerts').html(''); 7949 $('.mobile-resend') 7950 .html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Sending...') 7951 .attr('disabled', true); 7952 7953 $.ajax({ 7954 type: 'POST', 7955 url: 'user/resend-otp', 7956 data: data, 7957 dataType: 'json', 7958 success: function (result) { 7959 $('.mobile-resend').prop('disabled', false).html('Resend OTP'); 7960 if (result.status == 1) { 7961 $('#otp-login-validate-alerts').success(); 7962 } else { 7963 $('#otp-login-validate-alerts').danger(result.errorDesc); 7964 } 7965 } 7966 }); 7967} 7968 7969function loginInPassengerInfo() { 7970 $('a[data-toggle="modal"][data-target="#otp-login"]').trigger('click'); 7971 $('.login-card .modal-header').html('<span class="p-2">Login is required to proceed with ticket booking.</span>'); 7972 $('.login-card .modal-header').css('padding', '2rem 0 0'); 7973} 7974 7975function viewAllOffer(ticketData, type) { 7976 7977 if (discountCoupon.length > 0) { 7978 // If coupons are already loaded or content is visible, just toggle the display 7979 $('.view-all-offer i').toggleClass('rotate-180');
7980 $('#coupon-details').slideToggle('slow'); 7981 if (discountCoupon.length > 0) { 7982 let coupon = $('#pass-offercode').val() ?? ''; 7983 couponHtml(discountCoupon, coupon); 7984 } 7985 return; 7986 } 7987 7988 if (type == 'CONN') { 7989 var data = processConnTicketData(ticketData); 7990 } else { 7991 var data = processTicketData(ticketData, 'coupon'); 7992 } 7993 7994 if (!data) { 7995 // Validation failed - don't rotate icon or slide content 7996 // calculateTicketFare(); 7997 if (type == 'CONN') { 7998 connCalculation(); 7999 } else { 8000 newTicketCalculation(); 8001 } 8002 return; 8003 } 8004 8005 // Validation passed - rotate icon and slide content 8006 $('.view-all-offer i').addClass('rotate-180'); 8007 $('#coupon-details').slideDown('slow'); 8008 $('#coupon-details').html('<div class="text-center">Loading...</div>'); 8009 $('#apply-offer-btn') 8010 .prop('disabled', true) 8011 .html('Apply'); 8012 8013 $.ajax({ 8014 type: 'POST', 8015 url: 'passenger-info/view-all-offer', 8016 data: data, 8017 dataType: 'json', 8018 success: function (result) { 8019 $('#apply-offer-btn').prop('disabled', false).html('Apply'); 8020 if (result.status == 1) { 8021 if(result.data.length == 0){ 8022 $('#coupon-details').html('<div class="text-center">No offers found</div>'); 8023 // Set discountCoupon to empty array so toggle behavior works 8024 discountCoupon = []; 8025 return; 8026 } 8027 discountCoupon = result.data; 8028 couponHtml(result.data, '', ticketData); 8029 }else{ 8030 $('#coupon-details').html('<div class="text-center">No offers found</div>'); 8031 // Set discountCoupon to empty array so toggle behavior works 8032 discountCoupon = []; 8033 } 8034 } 8035 }); 8036} 8037 8038function couponHtml(data, coupon, ticketData) { 8039 8040 $('#pass-offercode').html(''); 8041 $('#coupon-details').html(''); 8042 data.forEach(item => { 8043 var html = ` 8044 <div class="coupon-item-modern"> 8045 <label class="coupon-radio-label"> 8046 <input type="radio" name="coupon-item" value="${item.coupon}" class="coupon-item-radio" ${coupon == item.coupon ? 'checked' : ''}> 8047 <span class="custom-radio"></span> 8048 </label> 8049 <div class="coupon-content"> 8050 <div class="coupon-desc"> 8051 <span class="coupon-title">Avail ${item.activeDesription || 'special'} offer on bus ticket booking in ${item.parentName || ''}</span> 8052 <div class="coupon-brand-container"> 8053 <div class="coupon-brand"> 8054 <img src="assets/images/search/offer-symbol-2.svg" alt="Rating User icon" class=""> 8055 <span class="brand-badge">${item.coupon}</span> 8056 </div> 8057 <div class="coupon-brand-value"> 8058 Flat ${currencySymbol} ${item.value.toFixed(2)} off 8059 </div> 8060 </div> 8061 </div> 8062 <div class="coupon-img"> 8063 <img src="assets/images/search/giftbox.svg" alt="Gift box icon" class=""> 8064 </div> 8065 </div> 8066 </div>`; 8067 $('#coupon-details').append(html); 8068 }); 8069 8070 // Add event listener for radio button selection 8071 $('.coupon-item-radio').on('change', function() { 8072 if ($(this).is(':checked')) { 8073 var couponValue = $(this).val(); 8074 $('#pass-offercode').val(couponValue); 8075 validateOffer(ticketData); 8076 } 8077 }); 8078} 8079 8080$(document).on('click', '.coupon-item-modern', function(e) { 8081 if (!$(e.target).is('.coupon-item-radio')) { 8082 $(this).find('.coupon-item-radio').prop('checked', true).trigger('change'); 8083 } 8084}); 8085 8086 8087function genCaptcha() { 8088 $('.captcha-refresh').addClass('rotate'); 8089 setTimeout(function() { 8090 $('.captcha-refresh').removeClass('rotate'); 8091 }, 500); 8092 8093 $('#captchaCode').val(''); 8094 $.ajax({ 8095 type: 'GET', 8096 url: 'user/generate-captcha', 8097 dataType: 'json', 8098 success: function (response) { 8099 if(response.status == 1){ 8100 $('.captcha-image').attr('src', response.data); 8101 } 8102 } 8103 }); 8104} 8105 8106function verifyCaptcha(captcha) { 8107 return new Promise(function(resolve) { 8108 $.ajax({ 8109 type: 'POST', 8110 url: 'user/verify-captcha', 8111 data: JSON.stringify({ captacha: captcha }), 8112 dataType: 'json', 8113 contentType: 'application/json', 8114 success: function(res) { 8115 resolve(res.status === 1); 8116 }, 8117 error: function() { 8118 resolve(false); 8119 } 8120 }); 8121 }); 8122}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.