| Lines 121-127
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 121 |             dataType: 'json', | 121 |             dataType: 'json', | 
        
          | 122 |             type: 'GET' | 122 |             type: 'GET' | 
        
          | 123 |         }); | 123 |         }); | 
          
            
              | 124 |      | 124 |  | 
        
          | 125 |         // Fetch list of existing bookings | 125 |         // Fetch list of existing bookings | 
        
          | 126 |         let bookingsFetch = $.ajax({ | 126 |         let bookingsFetch = $.ajax({ | 
        
          | 127 |             url: '/api/v1/bookings?biblio_id=' + biblionumber, | 127 |             url: '/api/v1/bookings?biblio_id=' + biblionumber, | 
  
    | Lines 135-141
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 135 |             dataType: 'json', | 135 |             dataType: 'json', | 
        
          | 136 |             type: 'GET' | 136 |             type: 'GET' | 
        
          | 137 |         }); | 137 |         }); | 
          
            
              | 138 |      | 138 |  | 
        
          | 139 |         // Update item select2 and period flatpickr | 139 |         // Update item select2 and period flatpickr | 
        
          | 140 |         $.when(itemsFetch, bookingsFetch, checkoutsFetch).then( | 140 |         $.when(itemsFetch, bookingsFetch, checkoutsFetch).then( | 
        
          | 141 |             function(itemsFetch,bookingsFetch, checkoutsFetch){ | 141 |             function(itemsFetch,bookingsFetch, checkoutsFetch){ | 
  
    | Lines 157-163
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 157 |                     }; | 157 |                     }; | 
        
          | 158 |                     bookings.unshift(booking); | 158 |                     bookings.unshift(booking); | 
        
          | 159 |                 } | 159 |                 } | 
          
            
              | 160 |      | 160 |  | 
        
          | 161 |                 // Item select2 | 161 |                 // Item select2 | 
        
          | 162 |                 $("#booking_item_id").select2({ | 162 |                 $("#booking_item_id").select2({ | 
        
          | 163 |                     dropdownParent: $(".modal-content", "#placeBookingModal"), | 163 |                     dropdownParent: $(".modal-content", "#placeBookingModal"), | 
  
    | Lines 166-178
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 166 |                     minimumResultsForSearch: 20, | 166 |                     minimumResultsForSearch: 20, | 
        
          | 167 |                     placeholder: __("Select item") | 167 |                     placeholder: __("Select item") | 
        
          | 168 |                 }); | 168 |                 }); | 
          
            
              | 169 |      | 169 |  | 
        
          | 170 |                 // Update flatpickr mode | 170 |                 // Update flatpickr mode | 
        
          | 171 |                 periodPicker.set('mode', 'range'); | 171 |                 periodPicker.set('mode', 'range'); | 
          
            
              | 172 |      | 172 |  | 
        
          | 173 |                 // Total bookable items | 173 |                 // Total bookable items | 
        
          | 174 |                 let bookable = 0; | 174 |                 let bookable = 0; | 
          
            
              | 175 |      | 175 |  | 
        
          | 176 |                 for (item of bookable_items) { | 176 |                 for (item of bookable_items) { | 
        
          | 177 |                     bookable++; | 177 |                     bookable++; | 
        
          | 178 |                     // Populate item select (NOTE: Do we still need this check for pre-existing select option here?) | 178 |                     // Populate item select (NOTE: Do we still need this check for pre-existing select option here?) | 
  
    | Lines 183-211
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 183 |                         $('#booking_item_id').append(newOption); | 183 |                         $('#booking_item_id').append(newOption); | 
        
          | 184 |                     } | 184 |                     } | 
        
          | 185 |                 } | 185 |                 } | 
          
            
              | 186 |      | 186 |  | 
        
          | 187 |                 // Set disable function for periodPicker | 187 |                 // Set disable function for periodPicker | 
        
          | 188 |                 let disableExists = periodPicker.config.disable.filter(f => f.name === 'dateDisable'); | 188 |                 let disableExists = periodPicker.config.disable.filter(f => f.name === 'dateDisable'); | 
        
          | 189 |                 if ( disableExists.length === 0 ) { | 189 |                 if ( disableExists.length === 0 ) { | 
        
          | 190 |                     periodPicker.config.disable.push(function dateDisable(date){ | 190 |                     periodPicker.config.disable.push(function dateDisable(date){ | 
          
            
              | 191 |          | 191 |  | 
        
          | 192 |                         // set local copy of selectedDates | 192 |                         // set local copy of selectedDates | 
        
          | 193 |                         let selectedDates = periodPicker.selectedDates; | 193 |                         let selectedDates = periodPicker.selectedDates; | 
          
            
              | 194 |          | 194 |  | 
        
          | 195 |                         // set booked counter | 195 |                         // set booked counter | 
        
          | 196 |                         let booked = 0; | 196 |                         let booked = 0; | 
          
            
              | 197 |          | 197 |  | 
        
          | 198 |                         // reset the unavailable items array | 198 |                         // reset the unavailable items array | 
        
          | 199 |                         let unavailable_items = []; | 199 |                         let unavailable_items = []; | 
          
            
              | 200 |          | 200 |  | 
        
          | 201 |                         // reset the biblio level bookings array | 201 |                         // reset the biblio level bookings array | 
        
          | 202 |                         let biblio_bookings = []; | 202 |                         let biblio_bookings = []; | 
          
            
              | 203 |          | 203 |  | 
        
          | 204 |                         // disable dates before selected date | 204 |                         // disable dates before selected date | 
        
          | 205 |                         if (!selectedDates[1] && (selectedDates[0] && selectedDates[0] > date)) { | 205 |                         if (!selectedDates[1] && (selectedDates[0] && selectedDates[0] > date)) { | 
        
          | 206 |                             return true; | 206 |                             return true; | 
        
          | 207 |                         } | 207 |                         } | 
          
            
              | 208 |          | 208 |  | 
        
          | 209 |                         // iterate existing bookings | 209 |                         // iterate existing bookings | 
        
          | 210 |                         for (booking of bookings) { | 210 |                         for (booking of bookings) { | 
        
          | 211 |  | 211 |  | 
  
    | Lines 216-225
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 216 |  | 216 |  | 
        
          | 217 |                             let start_date = flatpickr.parseDate(booking.start_date); | 217 |                             let start_date = flatpickr.parseDate(booking.start_date); | 
        
          | 218 |                             let end_date = flatpickr.parseDate(booking.end_date); | 218 |                             let end_date = flatpickr.parseDate(booking.end_date); | 
          
            
              | 219 |          | 219 |  | 
        
          | 220 |                             // patron has selected a start date (end date checks) | 220 |                             // patron has selected a start date (end date checks) | 
        
          | 221 |                             if (selectedDates[0]) { | 221 |                             if (selectedDates[0]) { | 
          
            
              | 222 |          | 222 |  | 
        
          | 223 |                                 // new booking start date is between existing booking start and end dates | 223 |                                 // new booking start date is between existing booking start and end dates | 
        
          | 224 |                                 if (selectedDates[0] >= start_date && selectedDates[0] <= end_date) { | 224 |                                 if (selectedDates[0] >= start_date && selectedDates[0] <= end_date) { | 
        
          | 225 |                                     if (booking.item_id) { | 225 |                                     if (booking.item_id) { | 
  
    | Lines 232-238
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 232 |                                         } | 232 |                                         } | 
        
          | 233 |                                     } | 233 |                                     } | 
        
          | 234 |                                 } | 234 |                                 } | 
          
            
              | 235 |          | 235 |  | 
        
          | 236 |                                 // new booking end date would be between existing booking start and end dates | 236 |                                 // new booking end date would be between existing booking start and end dates | 
        
          | 237 |                                 else if (date >= start_date && date <= end_date) { | 237 |                                 else if (date >= start_date && date <= end_date) { | 
        
          | 238 |                                     if (booking.item_id) { | 238 |                                     if (booking.item_id) { | 
  
    | Lines 245-251
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 245 |                                         } | 245 |                                         } | 
        
          | 246 |                                     } | 246 |                                     } | 
        
          | 247 |                                 } | 247 |                                 } | 
          
            
              | 248 |          | 248 |  | 
        
          | 249 |                                 // new booking would span existing booking | 249 |                                 // new booking would span existing booking | 
        
          | 250 |                                 else if (selectedDates[0] <= start_date && date >= end_date) { | 250 |                                 else if (selectedDates[0] <= start_date && date >= end_date) { | 
        
          | 251 |                                     if (booking.item_id) { | 251 |                                     if (booking.item_id) { | 
  
    | Lines 258-269
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 258 |                                         } | 258 |                                         } | 
        
          | 259 |                                     } | 259 |                                     } | 
        
          | 260 |                                 } | 260 |                                 } | 
          
            
              | 261 |          | 261 |  | 
        
          | 262 |                                 // new booking would not conflict | 262 |                                 // new booking would not conflict | 
        
          | 263 |                                 else { | 263 |                                 else { | 
        
          | 264 |                                     continue; | 264 |                                     continue; | 
        
          | 265 |                                 } | 265 |                                 } | 
          
            
              | 266 |          | 266 |  | 
        
          | 267 |                                 // check that there are available items | 267 |                                 // check that there are available items | 
        
          | 268 |                                 // available = all bookable items - booked items - booked biblios | 268 |                                 // available = all bookable items - booked items - booked biblios | 
        
          | 269 |                                 let total_available = bookable_items.length - unavailable_items.length - biblio_bookings.length; | 269 |                                 let total_available = bookable_items.length - unavailable_items.length - biblio_bookings.length; | 
  
    | Lines 271-291
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 271 |                                     return true; | 271 |                                     return true; | 
        
          | 272 |                                 } | 272 |                                 } | 
        
          | 273 |                             } | 273 |                             } | 
          
            
              | 274 |          | 274 |  | 
        
          | 275 |                             // patron has not yet selected a start date (start date checks) | 275 |                             // patron has not yet selected a start date (start date checks) | 
        
          | 276 |                             else if (date <= end_date && date >= start_date) { | 276 |                             else if (date <= end_date && date >= start_date) { | 
          
            
              | 277 |          | 277 |  | 
        
          | 278 |                                 // same item, disable date | 278 |                                 // same item, disable date | 
        
          | 279 |                                 if (booking.item_id && booking.item_id == booking_item_id) { | 279 |                                 if (booking.item_id && booking.item_id == booking_item_id) { | 
        
          | 280 |                                     return true; | 280 |                                     return true; | 
        
          | 281 |                                 } | 281 |                                 } | 
          
            
              | 282 |          | 282 |  | 
        
          | 283 |                                 // count all clashes, both item and biblio level | 283 |                                 // count all clashes, both item and biblio level | 
        
          | 284 |                                 booked++; | 284 |                                 booked++; | 
        
          | 285 |                                 if (booked == bookable) { | 285 |                                 if (booked == bookable) { | 
        
          | 286 |                                     return true; | 286 |                                     return true; | 
        
          | 287 |                                 } | 287 |                                 } | 
          
            
              | 288 |          | 288 |  | 
        
          | 289 |                                 // FIXME: The above is not intelligent enough to spot | 289 |                                 // FIXME: The above is not intelligent enough to spot | 
        
          | 290 |                                 // cases where an item must be used for a biblio level booking | 290 |                                 // cases where an item must be used for a biblio level booking | 
        
          | 291 |                                 // due to all other items being booking within the biblio level | 291 |                                 // due to all other items being booking within the biblio level | 
  
    | Lines 301-315
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 301 |                         } | 301 |                         } | 
        
          | 302 |                     }); | 302 |                     }); | 
        
          | 303 |                 }; | 303 |                 }; | 
          
            
              | 304 |                  | 304 |  | 
        
          | 305 |                 // Setup listener for item select2 | 305 |                 // Setup listener for item select2 | 
        
          | 306 |                 $('#booking_item_id').on('select2:select', function(e) { | 306 |                 $('#booking_item_id').on('select2:select', function(e) { | 
        
          | 307 |                     booking_item_id = e.params.data.id ? e.params.data.id : null; | 307 |                     booking_item_id = e.params.data.id ? e.params.data.id : null; | 
          
            
              | 308 |      | 308 |  | 
        
          | 309 |                     // redraw pariodPicker taking selected item into account | 309 |                     // redraw pariodPicker taking selected item into account | 
        
          | 310 |                     periodPicker.redraw(); | 310 |                     periodPicker.redraw(); | 
        
          | 311 |                 }); | 311 |                 }); | 
          
            
              | 312 |      | 312 |  | 
        
          | 313 |                 // Set onChange for flatpickr | 313 |                 // Set onChange for flatpickr | 
        
          | 314 |                 let changeExists = periodPicker.config.onChange.filter(f => f.name ==='periodChange'); | 314 |                 let changeExists = periodPicker.config.onChange.filter(f => f.name ==='periodChange'); | 
        
          | 315 |                 if(changeExists.length === 0) { | 315 |                 if(changeExists.length === 0) { | 
  
    | Lines 321-327
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 321 |                             let picker_end = dayjs(selectedDates[1]).endOf('day'); | 321 |                             let picker_end = dayjs(selectedDates[1]).endOf('day'); | 
        
          | 322 |                             $('#booking_start_date').val(picker_start.toISOString()); | 322 |                             $('#booking_start_date').val(picker_start.toISOString()); | 
        
          | 323 |                             $('#booking_end_date').val(picker_end.toISOString()); | 323 |                             $('#booking_end_date').val(picker_end.toISOString()); | 
          
            
              | 324 |          | 324 |  | 
        
          | 325 |                             // set available items in select2 | 325 |                             // set available items in select2 | 
        
          | 326 |                             let booked_items = bookings.filter(function(booking) { | 326 |                             let booked_items = bookings.filter(function(booking) { | 
        
          | 327 |                                 let start_date = flatpickr.parseDate(booking.start_date); | 327 |                                 let start_date = flatpickr.parseDate(booking.start_date); | 
  
    | Lines 360-377
          $('#placeBookingModal').on('show.bs.modal', function(e) {
      
      
        Link Here | 
        
          | 360 |                         } | 360 |                         } | 
        
          | 361 |                     }); | 361 |                     }); | 
        
          | 362 |                 }; | 362 |                 }; | 
          
            
              | 363 |      | 363 |  | 
        
          | 364 |                 // Enable flatpickr now we have date function populated | 364 |                 // Enable flatpickr now we have date function populated | 
        
          | 365 |                 periodPicker.redraw(); | 365 |                 periodPicker.redraw(); | 
        
          | 366 |                 $("#period_fields :input").prop('disabled', false); | 366 |                 $("#period_fields :input").prop('disabled', false); | 
          
            
              | 367 |      | 367 |  | 
        
          | 368 |                 // Redraw select with new options and enable | 368 |                 // Redraw select with new options and enable | 
        
          | 369 |                 $('#booking_item_id').trigger('change'); | 369 |                 $('#booking_item_id').trigger('change'); | 
        
          | 370 |                 $("#booking_item_id").prop("disabled", false); | 370 |                 $("#booking_item_id").prop("disabled", false); | 
        
          | 371 |  | 371 |  | 
        
          | 372 |                 // Set the flag to indicate that data has been fetched | 372 |                 // Set the flag to indicate that data has been fetched | 
        
          | 373 |                 dataFetched = true; | 373 |                 dataFetched = true; | 
          
            
              | 374 |          | 374 |  | 
        
          | 375 |                 // Set form values | 375 |                 // Set form values | 
        
          | 376 |                 setFormValues(patron_id,booking_item_id,start_date,end_date,periodPicker); | 376 |                 setFormValues(patron_id,booking_item_id,start_date,end_date,periodPicker); | 
        
          | 377 |             }, | 377 |             }, | 
  
    | Lines 459-465
          $("#placeBookingForm").on('submit', function(e) {
      
      
        Link Here | 
        
          | 459 |                 "patron_id": $('#booking_patron_id').find(':selected').val() | 459 |                 "patron_id": $('#booking_patron_id').find(':selected').val() | 
        
          | 460 |             }) | 460 |             }) | 
        
          | 461 |         ); | 461 |         ); | 
          
            
              | 462 |      | 462 |  | 
        
          | 463 |         posting.done(function(data) { | 463 |         posting.done(function(data) { | 
        
          | 464 |             // Update bookings store for subsequent bookings | 464 |             // Update bookings store for subsequent bookings | 
        
          | 465 |             bookings.push(data); | 465 |             bookings.push(data); | 
  
    | Lines 485-498
          $("#placeBookingForm").on('submit', function(e) {
      
      
        Link Here | 
        
          | 485 |                 }); | 485 |                 }); | 
        
          | 486 |                 timeline.focus(data.booking_id); | 486 |                 timeline.focus(data.booking_id); | 
        
          | 487 |             } | 487 |             } | 
          
            
              | 488 |      | 488 |  | 
        
          | 489 |             // Update bookings counts | 489 |             // Update bookings counts | 
        
          | 490 |             $('.bookings_count').html(parseInt($('.bookings_count').html(), 10)+1); | 490 |             $('.bookings_count').html(parseInt($('.bookings_count').html(), 10)+1); | 
          
            
              | 491 |      | 491 |  | 
        
          | 492 |             // Close modal | 492 |             // Close modal | 
        
          | 493 |             $('#placeBookingModal').modal('hide'); | 493 |             $('#placeBookingModal').modal('hide'); | 
        
          | 494 |         }); | 494 |         }); | 
          
            
              | 495 |      | 495 |  | 
        
          | 496 |         posting.fail(function(data) { | 496 |         posting.fail(function(data) { | 
        
          | 497 |             $('#booking_result').replaceWith('<div id="booking_result" class="alert alert-danger">'+_("Failure")+'</div>'); | 497 |             $('#booking_result').replaceWith('<div id="booking_result" class="alert alert-danger">'+_("Failure")+'</div>'); | 
        
          | 498 |         }); | 498 |         }); | 
  
    | Lines 510-516
          $("#placeBookingForm").on('submit', function(e) {
      
      
        Link Here | 
        
          | 510 |                 "patron_id": $('#booking_patron_id').find(':selected').val() | 510 |                 "patron_id": $('#booking_patron_id').find(':selected').val() | 
        
          | 511 |             }) | 511 |             }) | 
        
          | 512 |         }); | 512 |         }); | 
          
            
              | 513 |      | 513 |  | 
        
          | 514 |         putting.done(function(data) { | 514 |         putting.done(function(data) { | 
        
          | 515 |             update_success = 1; | 515 |             update_success = 1; | 
        
          | 516 |  | 516 |  | 
  
    | Lines 539-549
          $("#placeBookingForm").on('submit', function(e) {
      
      
        Link Here | 
        
          | 539 |                 }); | 539 |                 }); | 
        
          | 540 |                 timeline.focus(data.booking_id); | 540 |                 timeline.focus(data.booking_id); | 
        
          | 541 |             } | 541 |             } | 
          
            
              | 542 |      | 542 |  | 
        
          | 543 |             // Close modal | 543 |             // Close modal | 
        
          | 544 |             $('#placeBookingModal').modal('hide'); | 544 |             $('#placeBookingModal').modal('hide'); | 
        
          | 545 |         }); | 545 |         }); | 
          
            
              | 546 |      | 546 |  | 
        
          | 547 |         putting.fail(function(data) { | 547 |         putting.fail(function(data) { | 
        
          | 548 |             $('#booking_result').replaceWith('<div id="booking_result" class="alert alert-danger">'+__("Failure")+'</div>'); | 548 |             $('#booking_result').replaceWith('<div id="booking_result" class="alert alert-danger">'+__("Failure")+'</div>'); | 
        
          | 549 |         }); | 549 |         }); | 
            
              | 550 | -  |  |  |