| Lines 421-599
          $("#placeBookingModal").on("show.bs.modal", function (e) {
      
      
        Link Here | 
        
          | 421 |                     f => f.name === "dateDisable" | 421 |                     f => f.name === "dateDisable" | 
        
          | 422 |                 ); | 422 |                 ); | 
        
          | 423 |                 if (disableExists.length === 0) { | 423 |                 if (disableExists.length === 0) { | 
          
            
              | 424 |                     periodPicker.config.disable.push(function dateDisable( | 424 |                     periodPicker.config.disable.push( | 
            
              | 425 |                         date | 425 |                         function dateDisable(date) { | 
            
              | 426 |                     ) { | 426 |                             // set local copy of selectedDates | 
            
              | 427 |                         // set local copy of selectedDates | 427 |                             let selectedDates = periodPicker.selectedDates; | 
            
              | 428 |                         let selectedDates = periodPicker.selectedDates; |  |  | 
            
              | 429 |  | 
            
              | 430 |                         // set booked counter | 
            
              | 431 |                         let booked = 0; | 
        
          | 432 |  | 428 |  | 
          
            
              | 433 |                         // reset the unavailable items array | 429 |                             // set booked counter | 
            
              | 434 |                         let unavailable_items = []; | 430 |                             let booked = 0; | 
        
          | 435 |  | 431 |  | 
          
            
              | 436 |                         // reset the biblio level bookings array | 432 |                             // reset the unavailable items array | 
            
              | 437 |                         let biblio_bookings = []; | 433 |                             let unavailable_items = []; | 
        
          | 438 |  | 434 |  | 
          
            
              | 439 |                         // disable dates before selected date | 435 |                             // reset the biblio level bookings array | 
            
              | 440 |                         if ( | 436 |                             let biblio_bookings = []; | 
            
              | 441 |                             !selectedDates[1] && |  |  | 
            
              | 442 |                             selectedDates[0] && | 
            
              | 443 |                             selectedDates[0] > date | 
            
              | 444 |                         ) { | 
            
              | 445 |                             return true; | 
            
              | 446 |                         } | 
        
          | 447 |  | 437 |  | 
          
            
              | 448 |                         // iterate existing bookings | 438 |                             // disable dates before selected date | 
            
              | 449 |                         for (booking of bookings) { |  |  | 
            
              | 450 |                             // Skip if we're editing this booking | 
        
          | 451 |                             if ( | 439 |                             if ( | 
          
            
              | 452 |                                 booking_id && | 440 |                                 !selectedDates[1] && | 
            
              | 453 |                                 booking_id == booking.booking_id | 441 |                                 selectedDates[0] && | 
            
              |  |  | 442 |                                 selectedDates[0] > date | 
        
          | 454 |                             ) { | 443 |                             ) { | 
          
            
              | 455 |                                 continue; | 444 |                                 return true; | 
        
          | 456 |                             } | 445 |                             } | 
        
          | 457 |  | 446 |  | 
          
            
              | 458 |                             let start_date = flatpickr.parseDate( | 447 |                             // iterate existing bookings | 
            
              | 459 |                                 booking.start_date | 448 |                             for (booking of bookings) { | 
            
              | 460 |                             ); | 449 |                                 // Skip if we're editing this booking | 
            
              | 461 |                             let end_date = flatpickr.parseDate( |  |  | 
            
              | 462 |                                 booking.end_date | 
            
              | 463 |                             ); | 
            
              | 464 |  | 
            
              | 465 |                             // patron has selected a start date (end date checks) | 
            
              | 466 |                             if (selectedDates[0]) { | 
            
              | 467 |                                 // new booking start date is between existing booking start and end dates | 
        
          | 468 |                                 if ( | 450 |                                 if ( | 
          
            
              | 469 |                                     selectedDates[0] >= start_date && | 451 |                                     booking_id && | 
            
              | 470 |                                     selectedDates[0] <= end_date | 452 |                                     booking_id == booking.booking_id | 
        
          | 471 |                                 ) { | 453 |                                 ) { | 
          
            
              | 472 |                                     if (booking.item_id) { | 454 |                                     continue; | 
            
              | 473 |                                         if ( |  |  | 
            
              | 474 |                                             unavailable_items.indexOf( | 
            
              | 475 |                                                 booking.item_id | 
            
              | 476 |                                             ) === -1 | 
            
              | 477 |                                         ) { | 
            
              | 478 |                                             unavailable_items.push( | 
            
              | 479 |                                                 booking.item_id | 
            
              | 480 |                                             ); | 
            
              | 481 |                                         } | 
            
              | 482 |                                     } else { | 
            
              | 483 |                                         if ( | 
            
              | 484 |                                             biblio_bookings.indexOf( | 
            
              | 485 |                                                 booking.booking_id | 
            
              | 486 |                                             ) === -1 | 
            
              | 487 |                                         ) { | 
            
              | 488 |                                             biblio_bookings.push( | 
            
              | 489 |                                                 booking.booking_id | 
            
              | 490 |                                             ); | 
            
              | 491 |                                         } | 
            
              | 492 |                                     } | 
        
          | 493 |                                 } | 455 |                                 } | 
        
          | 494 |  | 456 |  | 
          
            
              | 495 |                                 // new booking end date would be between existing booking start and end dates | 457 |                                 let start_date = flatpickr.parseDate( | 
            
              | 496 |                                 else if ( | 458 |                                     booking.start_date | 
            
              | 497 |                                     date >= start_date && | 459 |                                 ); | 
            
              | 498 |                                     date <= end_date | 460 |                                 let end_date = flatpickr.parseDate( | 
            
              | 499 |                                 ) { | 461 |                                     booking.end_date | 
            
              | 500 |                                     if (booking.item_id) { | 462 |                                 ); | 
            
              | 501 |                                         if ( | 463 |  | 
            
              | 502 |                                             unavailable_items.indexOf( | 464 |                                 // patron has selected a start date (end date checks) | 
            
              | 503 |                                                 booking.item_id | 465 |                                 if (selectedDates[0]) { | 
            
              | 504 |                                             ) === -1 | 466 |                                     // new booking start date is between existing booking start and end dates | 
            
              | 505 |                                         ) { | 467 |                                     if ( | 
            
              | 506 |                                             unavailable_items.push( | 468 |                                         selectedDates[0] >= start_date && | 
            
              | 507 |                                                 booking.item_id | 469 |                                         selectedDates[0] <= end_date | 
            
              | 508 |                                             ); | 470 |                                     ) { | 
            
              | 509 |                                         } | 471 |                                         if (booking.item_id) { | 
            
              | 510 |                                     } else { | 472 |                                             if ( | 
            
              | 511 |                                         if ( | 473 |                                                 unavailable_items.indexOf( | 
            
              | 512 |                                             biblio_bookings.indexOf( | 474 |                                                     booking.item_id | 
            
              | 513 |                                                 booking.booking_id | 475 |                                                 ) === -1 | 
            
              | 514 |                                             ) === -1 | 476 |                                             ) { | 
            
              | 515 |                                         ) { | 477 |                                                 unavailable_items.push( | 
            
              | 516 |                                             biblio_bookings.push( | 478 |                                                     booking.item_id | 
            
              | 517 |                                                 booking.booking_id | 479 |                                                 ); | 
            
              | 518 |                                             ); | 480 |                                             } | 
            
              |  |  | 481 |                                         } else { | 
            
              | 482 |                                             if ( | 
            
              | 483 |                                                 biblio_bookings.indexOf( | 
            
              | 484 |                                                     booking.booking_id | 
            
              | 485 |                                                 ) === -1 | 
            
              | 486 |                                             ) { | 
            
              | 487 |                                                 biblio_bookings.push( | 
            
              | 488 |                                                     booking.booking_id | 
            
              | 489 |                                                 ); | 
            
              | 490 |                                             } | 
        
          | 519 |                                         } | 491 |                                         } | 
        
          | 520 |                                     } | 492 |                                     } | 
            
              | 521 |                                 } |  |  | 
        
          | 522 |  | 493 |  | 
          
            
              | 523 |                                 // new booking would span existing booking | 494 |                                     // new booking end date would be between existing booking start and end dates | 
            
              | 524 |                                 else if ( | 495 |                                     else if ( | 
            
              | 525 |                                     selectedDates[0] <= start_date && | 496 |                                         date >= start_date && | 
            
              | 526 |                                     date >= end_date | 497 |                                         date <= end_date | 
            
              | 527 |                                 ) { | 498 |                                     ) { | 
            
              | 528 |                                     if (booking.item_id) { | 499 |                                         if (booking.item_id) { | 
            
              | 529 |                                         if ( | 500 |                                             if ( | 
            
              | 530 |                                             unavailable_items.indexOf( | 501 |                                                 unavailable_items.indexOf( | 
            
              | 531 |                                                 booking.item_id | 502 |                                                     booking.item_id | 
            
              | 532 |                                             ) === -1 | 503 |                                                 ) === -1 | 
            
              | 533 |                                         ) { | 504 |                                             ) { | 
            
              | 534 |                                             unavailable_items.push( | 505 |                                                 unavailable_items.push( | 
            
              | 535 |                                                 booking.item_id | 506 |                                                     booking.item_id | 
            
              | 536 |                                             ); | 507 |                                                 ); | 
            
              |  |  | 508 |                                             } | 
            
              | 509 |                                         } else { | 
            
              | 510 |                                             if ( | 
            
              | 511 |                                                 biblio_bookings.indexOf( | 
            
              | 512 |                                                     booking.booking_id | 
            
              | 513 |                                                 ) === -1 | 
            
              | 514 |                                             ) { | 
            
              | 515 |                                                 biblio_bookings.push( | 
            
              | 516 |                                                     booking.booking_id | 
            
              | 517 |                                                 ); | 
            
              | 518 |                                             } | 
        
          | 537 |                                         } | 519 |                                         } | 
          
            
              | 538 |                                     } else { | 520 |                                     } | 
            
              | 539 |                                         if ( | 521 |  | 
            
              | 540 |                                             biblio_bookings.indexOf( | 522 |                                     // new booking would span existing booking | 
            
              | 541 |                                                 booking.booking_id | 523 |                                     else if ( | 
            
              | 542 |                                             ) === -1 | 524 |                                         selectedDates[0] <= start_date && | 
            
              | 543 |                                         ) { | 525 |                                         date >= end_date | 
            
              | 544 |                                             biblio_bookings.push( | 526 |                                     ) { | 
            
              | 545 |                                                 booking.booking_id | 527 |                                         if (booking.item_id) { | 
            
              | 546 |                                             ); | 528 |                                             if ( | 
            
              |  |  | 529 |                                                 unavailable_items.indexOf( | 
            
              | 530 |                                                     booking.item_id | 
            
              | 531 |                                                 ) === -1 | 
            
              | 532 |                                             ) { | 
            
              | 533 |                                                 unavailable_items.push( | 
            
              | 534 |                                                     booking.item_id | 
            
              | 535 |                                                 ); | 
            
              | 536 |                                             } | 
            
              | 537 |                                         } else { | 
            
              | 538 |                                             if ( | 
            
              | 539 |                                                 biblio_bookings.indexOf( | 
            
              | 540 |                                                     booking.booking_id | 
            
              | 541 |                                                 ) === -1 | 
            
              | 542 |                                             ) { | 
            
              | 543 |                                                 biblio_bookings.push( | 
            
              | 544 |                                                     booking.booking_id | 
            
              | 545 |                                                 ); | 
            
              | 546 |                                             } | 
        
          | 547 |                                         } | 547 |                                         } | 
        
          | 548 |                                     } | 548 |                                     } | 
            
              | 549 |                                 } |  |  | 
        
          | 550 |  | 549 |  | 
          
            
              | 551 |                                 // new booking would not conflict | 550 |                                     // new booking would not conflict | 
            
              | 552 |                                 else { | 551 |                                     else { | 
            
              | 553 |                                     continue; | 552 |                                         continue; | 
            
              | 554 |                                 } | 553 |                                     } | 
        
          | 555 |  | 554 |  | 
          
            
              | 556 |                                 // check that there are available items | 555 |                                     // check that there are available items | 
            
              | 557 |                                 // available = all bookable items - booked items - booked biblios | 556 |                                     // available = all bookable items - booked items - booked biblios | 
            
              | 558 |                                 let total_available = | 557 |                                     let total_available = | 
            
              | 559 |                                     bookable_items.length - | 558 |                                         bookable_items.length - | 
            
              | 560 |                                     unavailable_items.length - | 559 |                                         unavailable_items.length - | 
            
              | 561 |                                     biblio_bookings.length; | 560 |                                         biblio_bookings.length; | 
            
              | 562 |                                 if (total_available === 0) { | 561 |                                     if (total_available === 0) { | 
            
              | 563 |                                     return true; | 562 |                                         return true; | 
            
              |  |  | 563 |                                     } | 
        
          | 564 |                                 } | 564 |                                 } | 
            
              | 565 |                             } |  |  | 
        
          | 566 |  | 565 |  | 
          
            
              | 567 |                             // patron has not yet selected a start date (start date checks) | 566 |                                 // patron has not yet selected a start date (start date checks) | 
            
              | 568 |                             else if (date <= end_date && date >= start_date) { | 567 |                                 else if ( | 
            
              | 569 |                                 // same item, disable date | 568 |                                     date <= end_date && | 
            
              | 570 |                                 if ( | 569 |                                     date >= start_date | 
            
              | 571 |                                     booking.item_id && |  |  | 
            
              | 572 |                                     booking.item_id == booking_item_id | 
        
          | 573 |                                 ) { | 570 |                                 ) { | 
          
            
              | 574 |                                     return true; | 571 |                                     // same item, disable date | 
            
              | 575 |                                 } | 572 |                                     if ( | 
            
              |  |  | 573 |                                         booking.item_id && | 
            
              | 574 |                                         booking.item_id == booking_item_id | 
            
              | 575 |                                     ) { | 
            
              | 576 |                                         return true; | 
            
              | 577 |                                     } | 
        
          | 576 |  | 578 |  | 
          
            
              | 577 |                                 // count all clashes, both item and biblio level | 579 |                                     // count all clashes, both item and biblio level | 
            
              | 578 |                                 booked++; | 580 |                                     booked++; | 
            
              | 579 |                                 if (booked == bookable) { | 581 |                                     if (booked == bookable) { | 
            
              | 580 |                                     return true; | 582 |                                         return true; | 
            
              | 581 |                                 } | 583 |                                     } | 
        
          | 582 |  | 584 |  | 
          
            
              | 583 |                                 // FIXME: The above is not intelligent enough to spot | 585 |                                     // FIXME: The above is not intelligent enough to spot | 
            
              | 584 |                                 // cases where an item must be used for a biblio level booking | 586 |                                     // cases where an item must be used for a biblio level booking | 
            
              | 585 |                                 // due to all other items being booking within the biblio level | 587 |                                     // due to all other items being booking within the biblio level | 
            
              | 586 |                                 // booking period... we end up with a clash | 588 |                                     // booking period... we end up with a clash | 
            
              | 587 |                                 // To reproduce: | 589 |                                     // To reproduce: | 
            
              | 588 |                                 // * One bib with two bookable items. | 590 |                                     // * One bib with two bookable items. | 
            
              | 589 |                                 // * Add item level booking | 591 |                                     // * Add item level booking | 
            
              | 590 |                                 // * Add biblio level booking that extends one day beyond the item level booking | 592 |                                     // * Add biblio level booking that extends one day beyond the item level booking | 
            
              | 591 |                                 // * Try to book the item without an item level booking from the day before the biblio level | 593 |                                     // * Try to book the item without an item level booking from the day before the biblio level | 
            
              | 592 |                                 //   booking is to be returned. Note this is a clash, the only item available for the biblio | 594 |                                     //   booking is to be returned. Note this is a clash, the only item available for the biblio | 
            
              | 593 |                                 //   level booking is the item you just booked out overlapping the end date. | 595 |                                     //   level booking is the item you just booked out overlapping the end date. | 
            
              |  |  | 596 |                                 } | 
        
          | 594 |                             } | 597 |                             } | 
        
          | 595 |                         } | 598 |                         } | 
          
            
              | 596 |                     }); | 599 |                     ); | 
        
          | 597 |                 } | 600 |                 } | 
        
          | 598 |  | 601 |  | 
        
          | 599 |                 // Setup listener for itemtype select2 | 602 |                 // Setup listener for itemtype select2 | 
  
    | Lines 713-833
          $("#placeBookingModal").on("show.bs.modal", function (e) {
      
      
        Link Here | 
        
          | 713 |                     f => f.name === "periodChange" | 716 |                     f => f.name === "periodChange" | 
        
          | 714 |                 ); | 717 |                 ); | 
        
          | 715 |                 if (changeExists.length === 0) { | 718 |                 if (changeExists.length === 0) { | 
          
            
              | 716 |                     periodPicker.config.onChange.push(function periodChange( | 719 |                     periodPicker.config.onChange.push( | 
            
              | 717 |                         selectedDates, | 720 |                         function periodChange( | 
            
              | 718 |                         dateStr, | 721 |                             selectedDates, | 
            
              | 719 |                         instance | 722 |                             dateStr, | 
            
              | 720 |                     ) { | 723 |                             instance | 
            
              | 721 |                         // Start date selected | 724 |                         ) { | 
            
              | 722 |                         if (selectedDates[0] && !selectedDates[1]) { | 725 |                             // Start date selected | 
            
              | 723 |                             const startDate = new Date(selectedDates[0]); | 726 |                             if (selectedDates[0] && !selectedDates[1]) { | 
            
              | 724 |  | 727 |                                 const startDate = new Date(selectedDates[0]); | 
            
              | 725 |                             // Custom format function to make specific dates bold | 728 |  | 
            
              | 726 |                             boldDates = [new Date(startDate)]; | 729 |                                 // Custom format function to make specific dates bold | 
            
              | 727 |                             // Add issueLength days after the startDate | 730 |                                 boldDates = [new Date(startDate)]; | 
            
              | 728 |                             const nextDate = new Date(startDate); | 731 |                                 // Add issueLength days after the startDate | 
            
              | 729 |                             nextDate.setDate( | 732 |                                 const nextDate = new Date(startDate); | 
            
              | 730 |                                 nextDate.getDate() + parseInt(issueLength) |  |  | 
            
              | 731 |                             ); | 
            
              | 732 |                             boldDates.push(new Date(nextDate)); | 
            
              | 733 |  | 
            
              | 734 |                             // Add subsequent dates based on renewalsAllowed and renewalLength | 
            
              | 735 |                             for (let i = 0; i < renewalsAllowed; i++) { | 
        
          | 736 |                                 nextDate.setDate( | 733 |                                 nextDate.setDate( | 
          
            
              | 737 |                                     nextDate.getDate() + parseInt(renewalLength) | 734 |                                     nextDate.getDate() + parseInt(issueLength) | 
        
          | 738 |                                 ); | 735 |                                 ); | 
        
          | 739 |                                 boldDates.push(new Date(nextDate)); | 736 |                                 boldDates.push(new Date(nextDate)); | 
            
              | 740 |                             } |  |  | 
        
          | 741 |  | 737 |  | 
          
            
              | 742 |                             // Calculate the maximum date based on the selected start date | 738 |                                 // Add subsequent dates based on renewalsAllowed and renewalLength | 
            
              | 743 |                             let totalRenewalLength = | 739 |                                 for (let i = 0; i < renewalsAllowed; i++) { | 
            
              | 744 |                                 parseInt(renewalsAllowed) * | 740 |                                     nextDate.setDate( | 
            
              | 745 |                                 parseInt(renewalLength); | 741 |                                         nextDate.getDate() + | 
            
              | 746 |                             let totalIssueLength = | 742 |                                             parseInt(renewalLength) | 
            
              | 747 |                                 parseInt(issueLength) + | 743 |                                     ); | 
            
              | 748 |                                 parseInt(totalRenewalLength); | 744 |                                     boldDates.push(new Date(nextDate)); | 
            
              | 749 |  | 745 |                                 } | 
            
              | 750 |                             const maxDate = new Date(startDate.getTime()); |  |  | 
            
              | 751 |                             maxDate.setDate( | 
            
              | 752 |                                 maxDate.getDate() + totalIssueLength | 
            
              | 753 |                             ); | 
        
          | 754 |  | 746 |  | 
          
            
              | 755 |                             // Update the maxDate option of the flatpickr instance | 747 |                                 // Calculate the maximum date based on the selected start date | 
            
              | 756 |                             instance.set("maxDate", maxDate); | 748 |                                 let totalRenewalLength = | 
            
              | 757 |                         } | 749 |                                     parseInt(renewalsAllowed) * | 
            
              | 758 |                         // Range set, update hidden fields and set available items | 750 |                                     parseInt(renewalLength); | 
            
              | 759 |                         else if (selectedDates[0] && selectedDates[1]) { | 751 |                                 let totalIssueLength = | 
            
              | 760 |                             // set form fields from picker | 752 |                                     parseInt(issueLength) + | 
            
              | 761 |                             let picker_start = dayjs(selectedDates[0]); | 753 |                                     parseInt(totalRenewalLength); | 
            
              | 762 |                             let picker_end = dayjs(selectedDates[1]).endOf( | 754 |  | 
            
              | 763 |                                 "day" | 755 |                                 const maxDate = new Date(startDate.getTime()); | 
            
              | 764 |                             ); | 756 |                                 maxDate.setDate( | 
            
              | 765 |                             $("#booking_start_date").val( | 757 |                                     maxDate.getDate() + totalIssueLength | 
            
              | 766 |                                 picker_start.toISOString() | 758 |                                 ); | 
            
              | 767 |                             ); |  |  | 
            
              | 768 |                             $("#booking_end_date").val( | 
            
              | 769 |                                 picker_end.toISOString() | 
            
              | 770 |                             ); | 
        
          | 771 |  | 759 |  | 
          
            
              | 772 |                             // set available items in select2 | 760 |                                 // Update the maxDate option of the flatpickr instance | 
            
              | 773 |                             let booked_items = bookings.filter(function ( | 761 |                                 instance.set("maxDate", maxDate); | 
            
              | 774 |                                 booking | 762 |                             } | 
            
              | 775 |                             ) { | 763 |                             // Range set, update hidden fields and set available items | 
            
              | 776 |                                 let start_date = flatpickr.parseDate( | 764 |                             else if (selectedDates[0] && selectedDates[1]) { | 
            
              | 777 |                                     booking.start_date | 765 |                                 // set form fields from picker | 
            
              |  |  | 766 |                                 let picker_start = dayjs(selectedDates[0]); | 
            
              | 767 |                                 let picker_end = dayjs(selectedDates[1]).endOf( | 
            
              | 768 |                                     "day" | 
        
          | 778 |                                 ); | 769 |                                 ); | 
          
            
              | 779 |                                 let end_date = flatpickr.parseDate( | 770 |                                 $("#booking_start_date").val( | 
            
              | 780 |                                     booking.end_date | 771 |                                     picker_start.toISOString() | 
        
          | 781 |                                 ); | 772 |                                 ); | 
          
            
              | 782 |                                 // This booking ends before the start of the new booking | 773 |                                 $("#booking_end_date").val( | 
            
              | 783 |                                 if (end_date <= selectedDates[0]) { | 774 |                                     picker_end.toISOString() | 
            
              | 784 |                                     return false; | 775 |                                 ); | 
            
              | 785 |                                 } | 776 |  | 
            
              | 786 |                                 // This booking starts after then end of the new booking | 777 |                                 // set available items in select2 | 
            
              | 787 |                                 if (start_date >= selectedDates[1]) { | 778 |                                 let booked_items = bookings.filter( | 
            
              | 788 |                                     return false; | 779 |                                     function (booking) { | 
            
              | 789 |                                 } | 780 |                                         let start_date = flatpickr.parseDate( | 
            
              | 790 |                                 // This booking overlaps | 781 |                                             booking.start_date | 
            
              | 791 |                                 return true; |  |  | 
            
              | 792 |                             }); | 
            
              | 793 |                             $("#booking_item_id > option").each(function () { | 
            
              | 794 |                                 let option = $(this); | 
            
              | 795 |                                 if ( | 
            
              | 796 |                                     booking_item_id && | 
            
              | 797 |                                     booking_item_id == option.val() | 
            
              | 798 |                                 ) { | 
            
              | 799 |                                     option.prop("disabled", false); | 
            
              | 800 |                                 } else if ( | 
            
              | 801 |                                     booked_items.some(function (booked_item) { | 
            
              | 802 |                                         return ( | 
            
              | 803 |                                             option.val() == booked_item.item_id | 
        
          | 804 |                                         ); | 782 |                                         ); | 
          
            
              | 805 |                                     }) | 783 |                                         let end_date = flatpickr.parseDate( | 
            
              | 806 |                                 ) { | 784 |                                             booking.end_date | 
            
              | 807 |                                     option.attr("data-available", false); | 785 |                                         ); | 
            
              | 808 |                                     option.prop("disabled", true); | 786 |                                         // This booking ends before the start of the new booking | 
            
              | 809 |                                 } else { | 787 |                                         if (end_date <= selectedDates[0]) { | 
            
              | 810 |                                     option.attr("data-available", true); | 788 |                                             return false; | 
            
              | 811 |                                     if (option.data("pickup")) { | 789 |                                         } | 
            
              | 812 |                                         option.prop("disabled", false); | 790 |                                         // This booking starts after then end of the new booking | 
            
              |  |  | 791 |                                         if (start_date >= selectedDates[1]) { | 
            
              | 792 |                                             return false; | 
            
              | 793 |                                         } | 
            
              | 794 |                                         // This booking overlaps | 
            
              | 795 |                                         return true; | 
        
          | 813 |                                     } | 796 |                                     } | 
          
            
              | 814 |                                 } | 797 |                                 ); | 
            
              | 815 |                             }); | 798 |                                 $("#booking_item_id > option").each( | 
            
              | 816 |                             $("#booking_item_id").trigger("change.select2"); | 799 |                                     function () { | 
            
              | 817 |                         } | 800 |                                         let option = $(this); | 
            
              | 818 |                         // Range not set, reset field options and flatPickr state | 801 |                                         if ( | 
            
              | 819 |                         else { | 802 |                                             booking_item_id && | 
            
              | 820 |                             boldDates = []; | 803 |                                             booking_item_id == option.val() | 
            
              | 821 |                             instance.set("maxDate", null); | 804 |                                         ) { | 
            
              | 822 |                             $("#booking_item_id > option").each(function () { | 805 |                                             option.prop("disabled", false); | 
            
              | 823 |                                 let option = $(this); | 806 |                                         } else if ( | 
            
              | 824 |                                 if (option.data("pickup")) { | 807 |                                             booked_items.some( | 
            
              | 825 |                                     option.prop("disabled", false); | 808 |                                                 function (booked_item) { | 
            
              | 826 |                                 } | 809 |                                                     return ( | 
            
              | 827 |                             }); | 810 |                                                         option.val() == | 
            
              | 828 |                             $("#booking_item_id").trigger("change.select2"); | 811 |                                                         booked_item.item_id | 
            
              |  |  | 812 |                                                     ); | 
            
              | 813 |                                                 } | 
            
              | 814 |                                             ) | 
            
              | 815 |                                         ) { | 
            
              | 816 |                                             option.attr( | 
            
              | 817 |                                                 "data-available", | 
            
              | 818 |                                                 false | 
            
              | 819 |                                             ); | 
            
              | 820 |                                             option.prop("disabled", true); | 
            
              | 821 |                                         } else { | 
            
              | 822 |                                             option.attr("data-available", true); | 
            
              | 823 |                                             if (option.data("pickup")) { | 
            
              | 824 |                                                 option.prop("disabled", false); | 
            
              | 825 |                                             } | 
            
              | 826 |                                         } | 
            
              | 827 |                                     } | 
            
              | 828 |                                 ); | 
            
              | 829 |                                 $("#booking_item_id").trigger("change.select2"); | 
            
              | 830 |                             } | 
            
              | 831 |                             // Range not set, reset field options and flatPickr state | 
            
              | 832 |                             else { | 
            
              | 833 |                                 boldDates = []; | 
            
              | 834 |                                 instance.set("maxDate", null); | 
            
              | 835 |                                 $("#booking_item_id > option").each( | 
            
              | 836 |                                     function () { | 
            
              | 837 |                                         let option = $(this); | 
            
              | 838 |                                         if (option.data("pickup")) { | 
            
              | 839 |                                             option.prop("disabled", false); | 
            
              | 840 |                                         } | 
            
              | 841 |                                     } | 
            
              | 842 |                                 ); | 
            
              | 843 |                                 $("#booking_item_id").trigger("change.select2"); | 
            
              | 844 |                             } | 
        
          | 829 |                         } | 845 |                         } | 
          
            
              | 830 |                     }); | 846 |                     ); | 
        
          | 831 |                 } | 847 |                 } | 
        
          | 832 |  | 848 |  | 
        
          | 833 |                 // Create a bookings store keyed on date | 849 |                 // Create a bookings store keyed on date | 
  
    | Lines 863-898
          $("#placeBookingModal").on("show.bs.modal", function (e) {
      
      
        Link Here | 
        
          | 863 |                     f => f.name === "dayCreate" | 879 |                     f => f.name === "dayCreate" | 
        
          | 864 |                 ); | 880 |                 ); | 
        
          | 865 |                 if (dayCreateExists.length === 0) { | 881 |                 if (dayCreateExists.length === 0) { | 
          
            
              | 866 |                     periodPicker.config.onDayCreate.push(function dayCreate( | 882 |                     periodPicker.config.onDayCreate.push( | 
            
              | 867 |                         dObj, | 883 |                         function dayCreate(dObj, dStr, instance, dayElem) { | 
            
              | 868 |                         dStr, | 884 |                             const currentDate = dayElem.dateObj; | 
            
              | 869 |                         instance, | 885 |                             const dateString = currentDate | 
            
              | 870 |                         dayElem | 886 |                                 .toISOString() | 
            
              | 871 |                     ) { | 887 |                                 .split("T")[0]; | 
            
              | 872 |                         const currentDate = dayElem.dateObj; | 888 |  | 
            
              | 873 |                         const dateString = currentDate | 889 |                             const isBold = boldDates.some( | 
            
              | 874 |                             .toISOString() | 890 |                                 boldDate => | 
            
              | 875 |                             .split("T")[0]; | 891 |                                     boldDate.getTime() === currentDate.getTime() | 
            
              | 876 |  | 892 |                             ); | 
            
              | 877 |                         const isBold = boldDates.some( | 893 |                             if (isBold) { | 
            
              | 878 |                             boldDate => | 894 |                                 dayElem.classList.add("title"); | 
            
              | 879 |                                 boldDate.getTime() === currentDate.getTime() | 895 |                             } | 
            
              | 880 |                         ); |  |  | 
            
              | 881 |                         if (isBold) { | 
            
              | 882 |                             dayElem.classList.add("title"); | 
            
              | 883 |                         } | 
        
          | 884 |  | 896 |  | 
          
            
              | 885 |                         if (bookingsByDate[dateString]) { | 897 |                             if (bookingsByDate[dateString]) { | 
            
              | 886 |                             const dots = document.createElement("span"); | 898 |                                 const dots = document.createElement("span"); | 
            
              | 887 |                             dots.className = "event-dots"; | 899 |                                 dots.className = "event-dots"; | 
            
              | 888 |                             dayElem.appendChild(dots); | 900 |                                 dayElem.appendChild(dots); | 
            
              | 889 |                             bookingsByDate[dateString].forEach(item => { | 901 |                                 bookingsByDate[dateString].forEach(item => { | 
            
              | 890 |                                 const dot = document.createElement("span"); | 902 |                                     const dot = document.createElement("span"); | 
            
              | 891 |                                 dot.className = "event item_" + item; | 903 |                                     dot.className = "event item_" + item; | 
            
              | 892 |                                 dots.appendChild(dot); | 904 |                                     dots.appendChild(dot); | 
            
              | 893 |                             }); | 905 |                                 }); | 
            
              |  |  | 906 |                             } | 
        
          | 894 |                         } | 907 |                         } | 
          
            
              | 895 |                     }); | 908 |                     ); | 
        
          | 896 |                 } | 909 |                 } | 
        
          | 897 |  | 910 |  | 
        
          | 898 |                 // Add hints for days before the start range and after the end range | 911 |                 // Add hints for days before the start range and after the end range |