From: Jane Sandberg Date: Tue, 4 Sep 2018 21:31:57 +0000 (-0700) Subject: LP1790727: Add a daily schedule view of existing bookings X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=6c9040045385bdc55c7f93edd73c479463bdfd78;p=working%2FEvergreen.git LP1790727: Add a daily schedule view of existing bookings To test: 1) Apply this commit. 2) Add some booking resources. The quickest way to do this is to open up a bib record in Holdings View, right click on an item, and Make it Bookable. 3) Add some reservations to those booking resources. A simple way to do this is to go to a patron's record, click Other > Create / Cancel Booking Reservations, and entering the barcodes from step 1. 4) Go to Booking > Daily Schedule. 5) Select the correct Library, Resource, and Date. 6) Make sure that you can view all those reservations you added at step 3. 7) Make sure that pressing Print prints the schedule in a satisfactory way. 8) Make sure that all the advanced options work as expected. Signed-off-by: Jane Sandberg --- diff --git a/Open-ILS/src/eg2/src/app/staff/nav.component.html b/Open-ILS/src/eg2/src/app/staff/nav.component.html index feed30bcb5..564fd34de7 100644 --- a/Open-ILS/src/eg2/src/app/staff/nav.component.html +++ b/Open-ILS/src/eg2/src/app/staff/nav.component.html @@ -310,6 +310,10 @@ trending_down Return Reservations + + schedule + Daily Schedule + diff --git a/Open-ILS/src/templates/staff/booking/t_daily_schedule.tt2 b/Open-ILS/src/templates/staff/booking/t_daily_schedule.tt2 new file mode 100644 index 0000000000..41c21cbda6 --- /dev/null +++ b/Open-ILS/src/templates/staff/booking/t_daily_schedule.tt2 @@ -0,0 +1,55 @@ +

[% l('Daily Schedule') %]

+
+
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+
+
+
+ +
+
+
+ + +
+
[% l('Make sure the start time is before the end time') %]
+
+
+
+
+

{{date | date:date_format}}

+
+
+
{{sched.row|date:time_format}}
+
+
+ + [% l('[_1], [_2] [_3]', + '{{r.patron.family_name()}}', + '{{r.patron.first_given_name()}}', + '{{r.patron.second_given_name()}}') %] + [% l('Busy') %] + ({{r.start_time | egOrgDate:'h:mm':context_ou}} - {{r.end_time | egOrgDate: 'h:mm':context_ou}}) + [% l(', ') %] + + +
+
+
+
+
diff --git a/Open-ILS/src/templates/staff/css/booking.css.tt2 b/Open-ILS/src/templates/staff/css/booking.css.tt2 new file mode 100644 index 0000000000..9be08be97e --- /dev/null +++ b/Open-ILS/src/templates/staff/css/booking.css.tt2 @@ -0,0 +1,17 @@ +.schedule-row { + border-top: 1px dotted #777; + height: 30px; +} + +.bg-primary { + height: 30px; +} + +.start-after { + top: 5px; +} + +.end-before { + bottom: 5px; +} + diff --git a/Open-ILS/src/templates/staff/navbar.tt2 b/Open-ILS/src/templates/staff/navbar.tt2 index 1c47eb008c..75b64be112 100644 --- a/Open-ILS/src/templates/staff/navbar.tt2 +++ b/Open-ILS/src/templates/staff/navbar.tt2 @@ -464,6 +464,12 @@ [% l('Return Reservations') %] +
  • + + + [% l('Daily Schedule') %] + +
  • diff --git a/Open-ILS/src/templates/staff/share/print_templates/t_booking_daily_schedule.tt2 b/Open-ILS/src/templates/staff/share/print_templates/t_booking_daily_schedule.tt2 new file mode 100644 index 0000000000..dfacb244d7 --- /dev/null +++ b/Open-ILS/src/templates/staff/share/print_templates/t_booking_daily_schedule.tt2 @@ -0,0 +1,20 @@ +

    {{barcode}} - {{date | date:date_format}}

    + + + + + +
    {{sched.row|date:time_format}} + + + [% l('[_1], [_2] [_3]', + '{{r.patron.family_name()}}', + '{{r.patron.first_given_name()}}', + '{{r.patron.second_given_name()}}') %] + [% l('Busy') %] + ({{r.start_time | egOrgDate:'h:mm':context_ou}} - {{r.end_time | egOrgDate: 'h:mm':context_ou}}) + + ... + + +
    diff --git a/Open-ILS/web/js/ui/default/staff/booking/app.js b/Open-ILS/web/js/ui/default/staff/booking/app.js index 5f116d1461..c1d8ce1391 100644 --- a/Open-ILS/web/js/ui/default/staff/booking/app.js +++ b/Open-ILS/web/js/ui/default/staff/booking/app.js @@ -17,6 +17,13 @@ angular.module('egBooking', resolve : resolver }); + // daily view + $routeProvider.when('/booking/daily_schedule', { + templateUrl: './booking/t_daily_schedule', + controller: 'BookingDailyScheduleCtrl', + resolve : resolver + }); + // default page $routeProvider.otherwise({ templateUrl : './t_splash', @@ -24,6 +31,135 @@ angular.module('egBooking', }); }]) +.controller('BookingDailyScheduleCtrl', + ['$scope', 'egCore', 'egOrgDateFilter', + function($scope, egCore, egOrgDateFilter) { + $scope.context_ou = egCore.org.get(egCore.auth.user().ws_ou()); + $scope.date = new Date(); + $scope.date.setHours(0, 0, 0, 0); + $scope.startTime = new Date($scope.date.getTime() + egCore.date.intervalToSeconds('9 hours')); + $scope.endTime = new Date($scope.date.getTime() + egCore.date.intervalToSeconds('17 hours')); + + $scope.date_format = 'mediumDate'; + egCore.org.settings(['format.date']).then(function(set) { + if (set['format.date']) $scope.date_format = set['format.date']; + }); + $scope.time_format = 'shortTime'; + $scope.resource_list = []; + egCore.hatch.getItem('booking.daily_schedule.resource_id') + .then(function(resource_id){ + if (resource_id) $scope.resource = resource_id; + }); + + egCore.hatch.getItem('booking.daily_schedule.show_names') + .then(function(show_names){ + if (show_names) $scope.show_names = show_names; + }); + $scope.on_show_names_changed = function(){ + egCore.hatch.setItem('booking.daily_schedule.show_names', $scope.show_names); + } + + $scope.$watch('startTime',function(newValue,oldValue){ + $scope.fix_date(newValue); + $scope.populate_display(); + }); + $scope.$watch('endTime',function(newValue,oldValue){ + $scope.fix_date(newValue); + $scope.populate_display(); + }); + $scope.$watch('resource',function(newValue,oldValue){ + $scope.populate_display(); + egCore.hatch.setItem('booking.daily_schedule.resource_id', $scope.resource); + }); + $scope.$watch('date',function(newValue,oldValue){ + if ($scope.resource) { + $scope.populate_display(); + } + $scope.guess_display_times(); + $scope.fix_date($scope.startTime); + $scope.fix_date($scope.endTime); + }); + + $scope.fix_date = function(time) { + time.setFullYear($scope.date.getFullYear(), $scope.date.getMonth(), $scope.date.getDate()); + time.setSeconds(0); + } + + $scope.populate_display = function() { + if ($scope.resource) { + egCore.pcrud.search('bresv', + {target_resource: $scope.resource, + start_time: {"<": egOrgDateFilter($scope.endTime, 'yyyy-MM-dd HH:mm:ss', $scope.context_ou)}, + end_time: {">": egOrgDateFilter($scope.startTime, 'yyyy-MM-dd HH:mm:ss', $scope.context_ou)}}, + {flesh: 1, flesh_fields: {'bresv' : ['usr']}}, {atomic: true}).then( + function(response) { + $scope.schedule = [] + var start_distance_from_half_hour = ($scope.startTime.getMinutes() % 30); + var current_working_time = new Date($scope.startTime.getTime()); + $scope.fix_date(current_working_time); + var working_end_time = new Date($scope.endTime.getTime()); + $scope.fix_date(working_end_time); + var next_working_time = new Date(current_working_time.getTime()); + do { + next_working_time.setMinutes(current_working_time.getMinutes() + ((current_working_time.getMinutes() % 30) ? (30 - (current_working_time.getMinutes() % 30)) : 30)); + var reservations = []; + angular.forEach(response, function (r) { + rs = new Date(r.start_time()); + re = new Date(r.end_time()); + if ((rs < next_working_time) && (re > current_working_time)) { + reservation = {patron: r.usr(), end_time: re}; + reservation.continuation = (rs < current_working_time) ? true : false; + reservation.ends_early = (re < next_working_time) ? true : false; + reservation.starts_late = (rs > current_working_time) ? true : false; + reservation.start_time = (rs >= current_working_time) ? rs : undefined; + reservations.push(reservation); + }}) + $scope.schedule.push({'row': current_working_time.getTime(), 'reservations': reservations}); + current_working_time.setTime(next_working_time.getTime()); + } while (current_working_time < working_end_time) + })}}; + + $scope.print_schedule = function() { + print_data = { schedule: $scope.schedule, + show_names: $scope.show_names, + time_format: $scope.time_format, + date_format: $scope.date_format, + date: $scope.date, + barcode: egCore.idl.toHash($scope.resource_list).find(r => {return r.id == $scope.resource}).barcode } + return egCore.print.print({ + template : 'booking_daily_schedule', + scope: print_data + }); + } + + $scope.get_booking_resources = function() { + egCore.pcrud.search('brsrc', {owner: $scope.context_ou.id()}, {}, {atomic: true}) + .then(function(list) { + $scope.resource_list = list; + }); + }; + + $scope.handle_changed_ou = function () { + $scope.guess_display_times(); + $scope.get_booking_resources(); + } + + $scope.guess_display_times = function() { + var selected_day = $scope.date.getDay(); + egCore.pcrud.retrieve('aouhoo', $scope.context_ou.id()).then(function(hours){ + $scope.hours = hours; + selected_day_eg_style = (selected_day + 6) % 7; + o = ($scope.$eval("hours.dow_" + selected_day_eg_style + "_open()")).split(':'); + c = ($scope.$eval("hours.dow_" + selected_day_eg_style + "_close()")).split(':'); + $scope.startTime = new Date($scope.date.getTime()); + $scope.startTime.setSeconds(egCore.date.intervalToSeconds(o[0] + ' hours') + egCore.date.intervalToSeconds(o[1] + ' minutes')); + $scope.endTime = new Date($scope.date.getTime()); + $scope.endTime.setSeconds(egCore.date.intervalToSeconds(c[0] + ' hours') + egCore.date.intervalToSeconds(c[1] + ' minutes')); + }); + } + +}]) + .controller('EmbedBookingCtl', ['$scope','$routeParams','$location','egCore', function($scope , $routeParams , $location , egCore) { @@ -43,4 +179,3 @@ function($scope , $routeParams , $location , egCore) { console.log('Loading Booking URL: ' + $scope.booking_url); }]) -