1/** 2 * Copyright CRP Solutions GmbH 3 * You are not allowed to copy or reproduce this code. 4 * However, you are allowed to get inspired. 5 * 6 * EK 7 */ 8 9let order = { 10 store_id: 1 11}; 12 13// count obj length 14Object.keys = function (obj) { 15 let keys = [], key; 16 for (key in obj) { 17 if (obj.hasOwnProperty(key)) 18 keys.push(key); 19 } 20 return keys; 21}; 22 23jQuery.datetimepicker.setLocale('de'); 24 25// prevent mouse scroll data change 26 27$('.datetime_picker').off('scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove', 28function (ev) { 29 ev.preventDefault(); 30 ev.stopPropagation(); 31 return false; 32}); 33 34$('td.xdsoft_date.xdsoft_date').off('scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove', 35function (ev) { 36 ev.preventDefault(); 37 ev.stopPropagation(); 38 return false; 39}); 40 41// pre select booking duration 42window.addEventListener('load', function(event) { 43 44 let preset_location = null; 45 46 let match_location = window.location.hash.match(/standort=([^,\s]+)/); 47 48 // if location is not set, set to default for server 49 if (match_location && match_location[1]) { 50 preset_location = match_location[1]; 51 } 52 53 select_item('li[data-location="' + preset_location + '"]'); 54 55}); 56 57let cancelPanning = false; 58 59/* 60 * Select start date 61 * @param {type} dp 62 * @param {type} date 63 * @returns {undefined} 64 * 65 */ 66function select_start_date(dp, date) { 67 68 let d = date.val().split('.'); 69 70 removeLoader(); 71 72 draw.clear(); 73 74 renderLoader($('#position-block')); 75 76 // select order start date 77 order.start = d[2] + '-' + d[1] + '-' + d[0]; 78 79 ajaxcall( 80 { 81 booking_start: order.start, 82 booking_duration: order.duration 83 }, 84 '/booking/calculate_booking', 85 $(this), 86 function ($this, response) { 87 if (response && response.order) { 88 console.log(response.order); 89 order = response.order; 90 91 // special discount detected! 92 if (response.message) { 93 94 let config = { 95 title: response.message.title, 96 html: response.message.message, 97 showCloseButton: true, 98 confirmButtonText: 'Super!' 99 }; 100 if (response.message.image) { 101 config.imageUrl = response.message.image; 102 } 103 104 swal(config).then(() => { 105 set_start_date(order.start, order.end); 106 }); 107 } else { 108 set_start_date(order.start, order.end); 109 } 110 } else if (response.error) { 111 // we send detailed messages here but do not display 112 BOOKING_FAIL_WAIT_TOO_LONG(); 113 } 114 }, 115 function ($this, err) { 116 BOOKING_FAIL_WAIT_TOO_LONG(); 117 } 118 ); 119} 120 121/** 122 * @returns {undefined} 123 */ 124function set_start_date() { 125 126 dataLayer.push({event: 'checkout_select_day'}); 127 128 // remove order and payment block 129 $('#order-block').fadeOut(); 130 $('#payment-block').fadeOut(); 131 132 cancelPanning = false; 133 if (cancelPanning) 134 return; 135 136 // display pre calculated dates 137 $('.order-start').text(formatDate(order.start)); 138 139 // correct time depending on day of week 140 let d = new Date(order.end); 141 let end_date = ''; 142 if (d.getDay() === 6) { 143 end_date = formatDate(order.end) + ' bis 15 Uhr<br>'; 144 } else { 145 end_date = formatDate(order.end) + ' bis 17 Uhr<br>'; 146 } 147 $('.order-end').html(end_date); 148 149 // correct time depending on day of week 150 d = new Date(order.prepare); 151 let prepare_date = ''; 152 if (d.getDay() === 6) { 153 prepare_date = formatDate(order.prepare) + ' zwischen 15-16 Uhr<br>'; 154 } else { 155 prepare_date = formatDate(order.prepare) + ' zwischen 17-18 Uhr<br>'; 156 } 157 $('.order-start-day-before').html( 158 prepare_date + '<i>oder ' + formatDate(order.start) + ' zwischen 9-10 Uhr</i>' 159 ); 160 161 // some action - show change 162 if (order.action_booking.duration) { 163 $('.order-duration').html('<s>' + order.action_booking.duration + ' Tage</s> ' + order.duration + ' Tage ð'); 164 } else { 165 $('.order-duration').text(order.duration + ' Tage'); 166 } 167
168 $('.rentperiod-detail').show(); 169 170 let show_id = '#position-block'; 171 let message = 'Wo soll dein Stand stehen?'; 172 173 $('.flag-booking-start').removeClass('badge-light').addClass('badge-success'); 174 175 // unset shelf badge because now none is selected 176 $('.flag-booking-position').removeClass('badge-success').addClass('badge-light'); 177 178 // enable refuse 14 days booking withdrawal 179 if (order.days_to_start && order.days_to_start <= 14) { 180 $('.enable-withdrawal').show(); 181 } else { 182 $('.enable-withdrawal').hide(); 183 } 184 185 console.log(order.days_to_start); 186 187 message && toast(message); 188 189 $(show_id).fadeIn(); 190 scrollToTarget(show_id); 191 192 load_shelfs(order.store_id, order.start, order.duration); 193} 194 195function set_location(location) { 196 197 dataLayer.push({event: 'checkout_location'}); 198 199 // maybe duration was already selected 200 let duration = window.location.hash.match(/dauer=([^,\s]+)/); 201 202 if (duration && duration[1]) { 203 duration = duration[1]; 204 } 205 206 let location_data = locations[location]; 207 208 if (location && location_data) { 209 let retval = changeLocation( 210 location_data.domain + '/buchen#' + (duration ? 'dauer=' + duration : '') + 211 (location_data ? ',standort=' + location_data.key : ''), 212 location 213 ); 214 215 // we change location. stop everything else. 216 if (retval === true) { 217 return false; 218 } 219 220 location_description = location_data.street + ', ' + location_data.zip + ' ' + location_data.city; 221 renderLoader($('#location-block')); 222 223 order.location = location; 224 } 225 226 removeLoader(); 227 228 console.log('Set location ' + location_description); 229 $('.order-location').text(location_description); 230 231 // reset shelf selected before 232 ekselect.shelf = null; 233 order.shelf_type = null; 234 ekselect.duration = null; 235 order.duration = null; 236 237 if (duration) { 238 // delay selection 239 setTimeout(() => {select_item('li[data-rent="' + duration + '"]');}, 500); 240 } 241} 242 243/** 244 * Set Rent duration 245 * @param {type} duration 246 * @returns {undefined} 247 */ 248function set_rent(duration) { 249 250 dataLayer.push({event: 'add_to_cart'}); 251 dataLayer.push({event: 'checkout_duration'}); 252 253 order.duration = duration; 254 255 removeLoader(); 256 257 $('.order-duration').text(duration + ' Tage'); 258 259 // reset shelf selected before 260 order.shelf_type = null; 261 reset_item('shelf'); 262} 263 264/** 265 * Set the type of shelf needed. Collects information about the availability. 266 * @param {type} shelf_type 267 * @returns {undefined} 268 */ 269function set_shelf_type(shelf_type) { 270 271 dataLayer.push({event: 'checkout_shelf_type'}); 272 273 renderLoader($('#date-block')); 274 order.shelf_type = shelf_type; 275 276 // hide preselected day 277 $('.rentperiod-detail').hide(); 278 $('#position-block').hide(); 279 // reset shelf display 280 draw.clear(); 281 // select delivery date 282 if ($('.datetime_picker')[0]) { 283 $('.datetime_picker').datetimepicker('destroy'); 284 } 285 286 ajaxcall({order: order}, '/booking/calculate_shelf_availability', $(this), 287 function ($this, response) { 288 if (response && response !== false) { 289 console.log(response); 290 291 removeLoader(); 292 293 // cycle through the days until free booking available 294 let cycle_day = new Date(); 295 cycle_day.setDate(cycle_day.getDate() + 1); 296 cycle_day.setHours(01, 00, 00); 297 298 let secureCounter = 0; 299 while( 300 secureCounter < 150 && 301 response.content.days_not_available.includes(formatDateMYSQL(cycle_day).toString()) 302 ){ 303 cycle_day.setDate(cycle_day.getDate() + 1); 304 secureCounter++; 305 } 306 307 // most recent booking day found 308 let d = cycle_day; 309 310 let currentDay = (d.getDate()); 311 let currentMonth = (d.getMonth() + 1); 312 let currentYear = (d.getFullYear()); 313 314 d.setDate(d.getDate() + 150); 315 let maxDate = d.getFullYear() + '/' + (d.getMonth() + 1) + '/' + d.getDate(); // getMonth GFYS! :D 316 317 $('.datetime_picker').datetimepicker({ 318 inline: true, 319 startDate: currentYear + '/' + currentMonth + '/' + currentDay, 320 minDate: '+1970/01/02', // new: start just the next day 321 // TODO: set day depending from current time (same day possible, if 322 // booking before 2 pm)? 323 maxDate: maxDate, // selection restricted // yeah, try to disable this in console to cheat :P 324 dayOfWeekStart: 1, 325 disabledWeekDays: [0], 326 timepicker: false, 327 timepickerScrollbar: false, 328 disabledDates: response.content.days_not_available, // disable booked days 329 formatDate:'Y-m-d', 330 scrollInput: false, 331 scrollTime: false,
332 scrollMonth: false, 333 format: 'd.m.Y', 334 onChangeDateTime: select_start_date, 335 onGenerate:function( ct ){ 336 $('.datetime_picker'). 337 on('scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove', 338 function (ev) { 339 ev.preventDefault(); 340 ev.stopPropagation(); 341 return false; 342 }); 343 344 $('td.xdsoft_date.xdsoft_date'). 345 on('scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove', 346 function (ev) { 347 ev.preventDefault(); 348 ev.stopPropagation(); 349 return false; 350 }); 351 352 ajaxcall( 353 { 354 month: ct.getMonth() + 1, 355 year: ct.getFullYear(), 356 duration: order.duration 357 }, 358 '/booking/actions/getActionsDates', $(this), 359 function($this, actions) { 360 if (!actions) { 361 return; 362 } 363 actions.forEach(function(action) { 364 action.days.forEach(function(d){ 365 let actionDay = new Date(d); 366 $('td[data-date="' + actionDay.getDate() + '"]' + 367 '[data-month="' + (actionDay.getMonth()) + '"]' + 368 '[data-year="' + actionDay.getFullYear() + '"]') 369 .attr('title', action.calendar_title); 370 $('td[data-date="' + actionDay.getDate() + '"]' + 371 '[data-month="' + (actionDay.getMonth()) + '"]' + 372 '[data-year="' + actionDay.getFullYear() + '"]') 373 .append('<div style="position:relative">' + 374 '<div style="position: absolute;top: -34px;font-size: 30px;">' + 375 action.calendar_icon + 'ï¸</div></div>'); 376 }); 377 }); 378 }, 379 function() { 380 Swal.fire('Ein Fehler ist aufgetreten', 'Bitte die Buchung neu starten.', 'error'); 381 } 382 ) 383 } 384 }); 385 386 387 } else if (response === false) { 388 Swal.fire( 389 'Keine Regale mehr frei für den laufenden Monat.', 390 'Bitte den nächsten Monat probieren.', 391 'error' 392 ); 393 } else if (response.error) { 394 // we send detailed messages here but do not display 395 BOOKING_FAIL_WAIT_TOO_LONG(); 396 } 397 }, 398 function ($this, err) { 399 BOOKING_FAIL_WAIT_TOO_LONG(); 400 } 401 ); 402} 403 404/** 405 * Set Shelf Location 406 * @param {event} e 407 * @returns {undefined} 408 */ 409function select_shelf(e) { 410 411 dataLayer.push({event: 'checkout_shelf_location'}); 412 413 dataLayer.push({event: 'begin_checkout'}); 414 415 let shelf_obj = e.currentTarget.childNodes[0]; 416 console.log(shelf_obj); 417 418 // init shelf 419 if (!ekselect['shelf_id']) { 420 ekselect['shelf_id'] = null; 421 } 422 423 // check if shelf not selected 424 if (!SVG(shelf_obj).data('selected')) { 425 // highlight selected shelf 426 SVG(shelf_obj).data('selected', true); 427 SVG(shelf_obj).fill('#3af'); 428 429 if (ekselect['shelf_id']) { 430 // remove highlight on old selected shelf 431 SVG(ekselect['shelf_id']).data('selected', false); 432 SVG(ekselect['shelf_id']).fill('lightgreen'); 433 } 434 435 // save selected shelf 436 ekselect['shelf_id'] = shelf_obj; 437 } else { 438 439 // remove highlight on unselected shelf 440 SVG(shelf_obj).data('selected', false); 441 SVG(shelf_obj).fill('lightgreen'); 442 443 ekselect['shelf_id'] = null; 444 } 445 446 // unset shelf badge if no shelf remains selected 447 if (ekselect['shelf_id'] === null) { 448 $('.flag-booking-position').removeClass('badge-success').addClass('badge-light'); 449 450 // remove order and payment block 451 $('#order-block').fadeOut(); 452 $('#payment-block').fadeOut(); 453 } else { 454 // set badge on success 455 $('.flag-booking-position').removeClass('badge-light').addClass('badge-success'); 456 457 // show order block 458 $('#order-block').fadeIn(); 459 460 scrollToTarget('#order-block'); 461 } 462 463 if (ekselect['shelf_id']) { 464 order.shelf_id = SVG(ekselect['shelf_id']).data('shelf_id'); 465 $('.order-shelf').text(SVG(ekselect['shelf_id']).data('shelf_label')); 466 467 let message = 'Du hast dir Stand ' + SVG(ekselect['shelf_id']).data('shelf_label') + ' ausgesucht.'; 468 message && toast(message); 469 470 } else { 471 order.shelf_id = null; 472 } 473 474 ajaxcall(null, '/booking/calculate_booking', $(this), 475 function ($this, response) { 476 if (response && response.order) { 477 $('.order-shelf-type').text(response.order.shelf_type_description); 478 479 // some action - show price change 480 if (response.order.action_booking.rent_price) { 481 $('.order-rent-price').html( 482 '<s>' + 483 response.order.action_booking.rent_price.toLocaleStr
483ing( 484 'de-DE', 485 { 486 style: 'currency', 487 currency: 'EUR' 488 } 489 ) + 490 '</s> ' + 491 response.order.booking_price.toLocaleString( 492 'de-DE', 493 { 494 style: 'currency', 495 currency: 'EUR' 496 } 497 ) + 498 ' ð'); 499 } else { 500 $('.order-rent-price').text( 501 response.order.booking_price.toLocaleString( 502 'de-DE', 503 { 504 style: 'currency', 505 currency: 'EUR' 506 } 507 ) + 508 ''); 509 } 510 511 // affiliate coupon 512 let coupon = getCookie('affiliate_coupon'); 513 if (coupon && coupon !== 'undefined') { 514 $('#coupon_code').val(coupon); 515 516 validate_coupon(false); 517 } 518 } else if (response.error) { 519 BOOKING_FAIL_WAIT_TOO_LONG(); 520 } 521 }, 522 function ($this, err) { 523 BOOKING_FAIL_WAIT_TOO_LONG(); 524 } 525 ); 526} 527 528/** 529 * Loads and Renders Shelfs for Location and Rent Beginn + Duration 530 * @param {type} store_id 531 * @returns {undefined} 532 */ 533function load_shelfs(store_id = null) { 534 535 ajaxcall({store_id: store_id}, '/booking/get_location_shelfs', $(this), 536 function ($this, response) { 537 if (response) { 538 539 shelfs = response.content.shelfs; 540 shelf_groups = response.content.groups; 541 shelf_type = response.content.types; 542 shelf_booked = response.content.booked; 543 544 if (!shelf_map_set) { 545 for(let group in shelf_groups) { 546 547 let group_shelfs = []; 548 549 // collect shelfs in group 550 for(let shelf in shelfs) { 551 if (shelfs[shelf].group_id === shelf_groups[group].id) { 552 group_shelfs.push(shelfs[shelf]); 553 } 554 } 555 556 shelf_map.push({ 557 type: 'group', 558 x: shelf_groups[group].x, 559 y: shelf_groups[group].y, 560 rotation: shelf_groups[group].rotation, 561 shelfs: group_shelfs 562 }); 563 } 564 // set only once 565 shelf_map_set = true; 566 } 567 568 render_shelfs(); 569 570 removeLoader(); 571 572 // render movement for mobile 573 if (window.innerWidth <= 767) { 574 setTimeout(() => { 575 $('#shelfmap svg').addClass('shelfs-left-right'); 576 }, 1000); 577 578 setTimeout(() => { 579 $('#shelfmap svg').removeClass('shelfs-left-right'); 580 }, 3000); 581 } 582 583 } else if (response.error) { 584 BOOKING_FAIL_WAIT_TOO_LONG(); 585 } 586 }, 587 function ($this, err) { 588 BOOKING_FAIL_WAIT_TOO_LONG(); 589 } 590 ); 591} 592 593let shelfs = []; 594let shelf_type = {}; 595let shelf_map_set = false;
596let shelf_groups = []; 597let shelf_map = []; 598let shelf_booked = []; 599let draw = SVG().addTo('#shelfmap').size('900', '900'); 600 601function get_shelf_type(id) { 602 for(let type in shelf_type) { 603 if (shelf_type[type].id === parseInt(id)) { 604 //console.log(['MATCH SHELF TYPE', type, shelf_type[type]]); 605 return shelf_type[type]; 606 } 607 } 608} 609 610function render_shelfs() { 611 draw.clear(); 612 draw.addClass('canvas'); 613 draw.attr('viewBox', '0 0 900 900'); 614 615 for (let i in shelf_map) { 616 // clone data otherwise calculated dimensions will persist in object and get added 617 let group = JSON.parse(JSON.stringify(shelf_map[i])); 618 619 if (group.type === 'group') { 620 render_group(draw, group); 621 } 622 } 623} 624 625function render_group(draw = null, group = []) { 626 627 group.w = 0; 628 group.h = 0; 629 630 // calculate width/height for group 631 for (let i in group.shelfs) { 632 let shelf = group.shelfs[i]; 633 let type = get_shelf_type(shelf.type_id); 634 635 let shelf_x = group.x + ((shelf.x - 1) * type.width); 636 let shelf_y = group.y + ((shelf.y - 1) * type.depth); 637 638 if ((shelf_x + type.width) > group.w) { 639 group.w = shelf_x + type.width; 640 } 641 642 if ((shelf_y + type.depth) > group.h) { 643 group.h = shelf_y + type.depth; 644 } 645 } 646 647 // render shelfs 648 for (let i in group.shelfs) { 649 650 let shelf = group.shelfs[i]; 651 652 // do not render removed shelves 653 if (shelf.type_id === 99) { 654 continue; 655 } 656 657 // because: label can be a number, and as such, json_encode stores this value as number. 658 // but SVG renderer does some text methods with this value, which would break. so we transform it here to string 659 shelf.label += ''; 660 661 let type = get_shelf_type(shelf.type_id); 662 // mark as booked if: 663 // * in list of booked 664 // * not the type of shelf needed 665 shelf.booked = (shelf_booked[shelf.shelf_id] || shelf.type_id !== order.shelf_type) ? true : false; 666 667 shelf.x = group.x + ((shelf.x - 1) * 30); 668 shelf.y = group.y + ((shelf.y - 1) * 30); 669 670 //console.log(shelf); 671 672 let g = draw.group(); 673 674 let s = draw.rect(type.width, type.depth).move(shelf.x, shelf.y) 675 .fill((type.inactive === 'false' && shelf.booked) ? '#ff8080' : type.fill); 676 s.addClass('shelf'); 677 s.attr('id', 'shelf_' + shelf.shelf_id); 678 s.data('shelf_id', shelf.shelf_id); 679 s.data('shelf_label', shelf.label); 680 g.add(s); 681 682 let text = draw.text(shelf.label).move(shelf.x + (type.width / 2), shelf.y + (type.depth / 2) - 7) 683 .fill(type.color ? type.color : ((shelf.booked) ? '#fff' : '#000')); 684 text.font({family: 'Helvetica', size: 14, anchor: 'middle'}); 685 text.addClass('shelf-text'); 686 687 g.add(text); 688 689 g.add(draw.line(0, 0, type.width, 0) 690 .move(shelf.x, shelf.y) 691 .stroke({color: type.border ? type.border : '#000', width: 1})); 692 g.add(draw.line(0, 0, type.width, 0) 693 .move(shelf.x, shelf.y + type.depth) 694 .stroke({color: type.border ? type.border : '#000', width: 1})); 695 g.add(draw.line(0, 0, 0, type.depth) 696 .move(shelf.x, shelf.y) 697 .stroke({color: type.border ? type.border : '#000', width: 1})); 698 g.add(draw.line(0, 0, 0, type.depth) 699 .move(shelf.x + type.width, shelf.y) 700 .stroke({color: type.border ? type.border : '#000', width: 1})); 701 702 g.rotate(shelf.rotation, shelf.x, shelf.y); // rotate element 703 g.rotate(group.rotation, group.x, group.y); // rotate group 704 705 if (shelf.booked || (type.inactive && type.inactive === 'true')) { 706 707 } else { 708 s.addClass('shelf-active'); 709 text.addClass('shelf-text-active'); 710 711 g.on('mouseover', function (e) { 712 if (!SVG(e.currentTarget.childNodes[0]).data('selected')) { 713 SVG(e.currentTarget.childNodes[0]).fill('#3af'); 714 } 715 //SVG(e.currentTarget.childNodes[0]).transform({scale: 3}); 716 }); 717 718 g.on('mouseout', function (e) { 719 //console.log(this); 720 if (!SVG(e.currentTarget.childNodes[0]).data('selected')) { 721 SVG(e.currentTarget.childNodes[0]).fill(type.fill); 722 } 723 }); 724 725 g.on('click', select_shelf); 726 } 727 } 728} 729 730$('.action_check_coupon').off('click').on('click', function () { 731 validate_coupon(); 732}); 733 734function validate_coupon(verbose = true) {
735 let coupon = $('#coupon_code').val(); 736 737 if (coupon === '') { 738 return; 739 } 740 741 if (verbose) 742 swal({ 743 title: "Gutschein wird eingelöst...", 744 showConfirmButton: false, 745 type: 'info' 746 }); 747 748 ajaxcall({coupon: coupon}, '/booking/validate_coupon', $(this), 749 function ($this, response) { 750 if (response && response.error === false) { 751 752 let config = { 753 title: response.message.title || "Gutschein eingelöst!", 754 html: response.message.message, 755 showCloseButton: true, 756 confirmButtonText: 'Ok', 757 type: response.message.type || 'error' 758 }; 759 760 if (verbose) 761 swal(config).then(() => { 762 if (response.message.jsaction) { 763 eval(response.message.jsaction); 764 } 765 }); 766 767 if (response && response.order) { 768 769 $('.order-shelf-type').text(response.order.shelf_type_description); 770 771 // some action - show price change 772 if (response.order.action_booking && response.order.action_booking.rent_price) { 773 $('.order-rent-price').html( 774 '<s>' + 775 response.order.action_booking.rent_price.toLocaleString( 776 'de-DE', 777 { 778 style: 'currency', 779 currency: 'EUR' 780 } 781 ) + 782 '</s> ' + 783 response.order.booking_price.toLocaleString( 784 'de-DE', 785 { 786 style: 'currency', 787 currency: 'EUR' 788 } 789 ) + 790 ' ð'); 791 } else { 792 $('.order-rent-price').text( 793 response.order.booking_price.toLocaleString( 794 'de-DE', 795 { 796 style: 'currency', 797 currency: 'EUR' 798 } 799 ) + 800 ''); 801 } 802 803 if (response.coupon && response.coupon.bypass_payment) { 804 $('.order-rent-price').text('Ãber Gutschein bezahlt.'); 805 } 806 } else if (response.error) { 807 if (verbose) BOOKING_FAIL_WAIT_TOO_LONG(); 808 } 809 810 } else if(response.message) { 811 let config = { 812 title: response.message.title, 813 html: response.message.message, 814 showCloseButton: true, 815 confirmButtonText: 'Ok', 816 type: 'error' 817 }; 818 819 if (verbose) 820 swal(config).then(() => { 821 if (response.message.jsaction) { 822 eval(response.message.jsaction); 823 } 824 }); 825 } else if(response.error) { 826 // formular wrong 827 console.log({'FORM ERROR':response.error}); 828 $('input').each(function () { 829 let id = $(this).attr('id'); 830 if (response.error[id]) { 831 $('#' + id).addClass('is-invalid'); 832 $('.' + id + '-message').html(response.error[id]); 833 } else { 834 $('#' + id).removeClass('is-invalid'); 835 $('.' + id + '-message').html(); 836 } 837 }); 838 839 if (verbose) 840 swal({
841 title: "Der Gutschein ist unbekannt oder kann nicht verwendet werden.", 842 showConfirmButton: true, 843 type: 'error' 844 }); 845 } 846 }, 847 function ($this, err) { 848 if (verbose) BOOKING_FAIL_WAIT_TOO_LONG(); 849 } 850 ); 851}; 852 853// we use this function to initiate payment inline 854activate_pay_button(); 855 856function insertPayPalPayment() { 857 let jsinsert = document.getElementById('jsinsert'); 858 jsinsert.children[0] && jsinsert.removeChild(jsinsert.children[0]); 859 860 let button = document.getElementById('paypal-button-container'); 861 if (button) { 862 button.innerHTML = null; 863 button.innerHTML = ''; 864 } 865 866 ajaxcall({}, '/booking/paypalpayment/render_paypal', $(this), 867 function ($this, response) { 868 let script = document.createElement('script'); 869 script.text = response; 870 document.getElementById('jsinsert').appendChild(script); 871 }, 872 function ($this, err) { 873 BOOKING_FAIL_WAIT_TOO_LONG(); 874 } 875 ); 876} 877 878function renderLoader(element) { 879 let div = element.prepend('<div class="loaderdiv"><div class="loader"></div></div>'); 880 console.log(['Show loader for: ' + element.attr('id'), div]); 881} 882 883function removeLoader() { 884 $('div.loader').remove(); 885} 886 887function formatDateMYSQL(date) { 888 var d = new Date(date), 889 month = '' + (d.getMonth() + 1), 890 day = '' + d.getDate(), 891 year = d.getFullYear(); 892 893 if (month.length < 2) 894 month = '0' + month; 895 if (day.length < 2) 896 day = '0' + day; 897 898 return [year, month, day].join('-'); 899} 900function doPayPalCheckout() { 901 902 console.log('Payment call'); 903 904 const formData = new FormData(); 905 formData.append('ci_csrf_token', csrf_token_value); 906 907 fetch('/booking/paypalpayment/pay', { 908 method: 'POST', 909 body: formData, 910 }) 911 .then(function (response) { 912 return response.json(); 913 }) 914 .then(function (session) { 915 console.log(session.links); 916 for(let link in session.links) { 917 if (session.links[link].rel === 'approve') { 918 location.href = session.links[link].href; 919 return true; 920 } 921 } 922 }); 923}; 924 925
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.