From 7f3e66d67c4c2595a73d41c24072ed2d16f4c8fa Mon Sep 17 00:00:00 2001 From: Martin Renvoize <martin.renvoize@ptfs-europe.com> Date: Tue, 19 Oct 2021 13:57:00 +0100 Subject: [PATCH] Bug 33736: Add pendingbookings report This patch adds a 'Bookings to collect' page to circulation that allows for a workflow similar to 'Holds to pull', but for bookings. NOTE: Refinements still required --- api/v1/swagger/paths/bookings.yaml | 4 + circ/pendingbookings.pl | 49 ++++ .../prog/en/modules/circ/circulation-home.tt | 5 +- .../prog/en/modules/circ/pendingbookings.tt | 209 ++++++++++++++++++ 4 files changed, 266 insertions(+), 1 deletion(-) create mode 100755 circ/pendingbookings.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt diff --git a/api/v1/swagger/paths/bookings.yaml b/api/v1/swagger/paths/bookings.yaml index f1dcb9f9be9..68e5218c18b 100644 --- a/api/v1/swagger/paths/bookings.yaml +++ b/api/v1/swagger/paths/bookings.yaml @@ -74,6 +74,10 @@ x-koha-authorization: permissions: catalogue: 1 + x-koha-embed: + - biblio + - item + - patron post: operationId: addBooking parameters: diff --git a/circ/pendingbookings.pl b/circ/pendingbookings.pl new file mode 100755 index 00000000000..45a9a2605e7 --- /dev/null +++ b/circ/pendingbookings.pl @@ -0,0 +1,49 @@ +#!/usr/bin/perl + +# Copyright PTFS Europe 2021 +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see <http://www.gnu.org/licenses>. + +use Modern::Perl; + +use CGI qw ( -utf8 ); + +use C4::Output qw( output_html_with_http_headers ); +use C4::Auth qw( get_template_and_user ); + +use Koha::DateUtils qw(dt_from_string); + +my $input = CGI->new; +my ( $template, $borrowernumber, $cookie, $flags ) = get_template_and_user( + { + template_name => "circ/pendingbookings.tt", + query => $input, + type => "intranet", + flagsrequired => { circulate => 'manage_bookings' }, + } +); + +my $today = dt_from_string(); +my $startdate = $today->truncate( to => 'day' ); +my $enddate = $startdate->clone->add( days => 1 ); + +$template->param( + todaysdate => $today, + from => $startdate, + to => $enddate +); + +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt index cec04724898..530b25f48b0 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt @@ -75,7 +75,7 @@ </div> <div class="col-sm-5 col-md-4"> - <h3>Holds</h3> + <h3>Holds & Bookings</h3> <ul class="buttons-list"> <li> @@ -95,6 +95,9 @@ <li> <a class="circ-button" href="/cgi-bin/koha/circ/reserveratios.pl"><i class="fa-solid fa-chart-line"></i> Hold ratios</a> </li> + <li> + <a class="circ-button" href="/cgi-bin/koha/circ/pendingbookings.pl"><i class="fa fa-hand-grab-o"></i> Bookings to collect</a> + </li> </ul> [% IF Koha.Preference('UseRecalls') and CAN_user_recalls %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt new file mode 100644 index 00000000000..11cb47241fb --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt @@ -0,0 +1,209 @@ +[% USE raw %] +[% USE Asset %] +[% USE Koha %] +[% USE KohaDates %] +[% USE TablesSettings %] +[% PROCESS 'i18n.inc' %] +[% SET footerjs = 1 %] +[% INCLUDE 'doc-head-open.inc' %] +<title>[% FILTER collapse %] + [% t("Bookings to collect") | html %] › + [% t("Circulation") | html %] › + [% t("Koha") | html %] +[% END %]</title> +[% INCLUDE 'doc-head-close.inc' %] +</head> + +<body id="circ_pendingbookings" class="circ"> + [% INCLUDE 'header.inc' %] + [% INCLUDE 'circ-search.inc' %] + + <nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb"> + <ol> + <li> + <a href="/cgi-bin/koha/mainpage.pl">Home</a> + </li> + <li> + <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a> + </li> + <li> + <a href="#" aria-current="page"> + Bookings to collect + </a> + </li> + </ol> + </nav> + + <div class="main container-fluid"> + <div class="row"> + + <!-- Results --> + <div class="col-sm-10 col-sm-push-2"> + <main> + <h2>Items required for bookings between <span id="from_date">[% from | $KohaDates %]</span> and <span id="to_date">[% to | $KohaDates %]</span></h2> + <h3>Reported on [% todaysdate | $KohaDates %]</h3> + <p>The following items have not been collected for bookings. Please retrieve them + and check them in.</p> + <div id="searchresults"> + <table id="bookingst"></table> + </div> + </main> + </div> + + <!-- Filters --> + <div class="col-sm-2 col-sm-pull-10"> + <aside> + <div id="filters"> + <form id="bookingsf"> + <fieldset class="brief"> + <h4>Refine results</h4> + <ol> + <li> + <label for="from">Start date: </label> + <input type="text" size="10" id="from" name="from" value="[% from | html %]" class="flatpickr" data-date_to="to"/> + </li> + <li> + <label for="to">End date: </label> + <input type="text" size="10" id="to" name="to" value="[% to | html %]" class="flatpickr"/> + </li> + </ol> + + <fieldset class="action"> + <input type="submit" name="run_report" value="Submit" class="submit"/> + </fieldset> + </fieldset> + </form> + </div> + </aside> + </div> + </div> + <!-- /.row --> + + [% MACRO jsinclude BLOCK %] + [% INCLUDE 'calendar.inc' %] + [% INCLUDE 'datatables.inc' %] + [% INCLUDE 'columns_settings.inc' %] + [% Asset.js("lib/jquery/plugins/jquery.dataTables.columnFilter.js") | $raw %] + [% INCLUDE 'js-biblio-format.inc' %] + [% INCLUDE 'js-date-format.inc' %] + [% INCLUDE 'js-patron-format.inc' %] + <script> + let table_settings = [% TablesSettings.GetTableSettings( 'circ', 'bookings', 'bookings-to-collect', 'json' ) | $raw %]; + $(document).ready(function() { + + let additional_filters = { + start_date: function() { + let fromdate = $("#from"); + let isoFrom; + if ( fromdate.val() !== '' ) { + isoFrom = fromdate.get(0)._flatpickr.selectedDates[0].toISOString().substring(0,10); + } + + let todate = $("#to"); + let isoTo; + if ( todate.val() !== '' ) { + isoTo = todate.get(0)._flatpickr.selectedDates[0].toISOString().substring(0,10); + } + + return { '>=': isoFrom, '<=': isoTo }; + } + }; + + var bookings_table_url = '/api/v1/bookings?'; + var bookings_table = $("#bookingst").kohaTable({ + "ajax": { + "url": bookings_table_url + }, + "embed": [ + "biblio", + "item", + "patron" + ], + "order": [[ 1, "asc" ]], + "columns": [{ + "data": "booking_id", + "title": "Booking ID", + "visible": false + }, + { + "data": "biblio.title", + "title": "Title", + "searchable": true, + "orderable": true, + "render": function(data,type,row,meta) { + return $biblio_to_html(row.biblio, { + link: 'bookings' + }); + } + }, + { + "data": "item.external_id", + "title": "Item", + "searchable": true, + "orderable": true, + "defaultContent": "Any item", + "render": function(data,type,row,meta) { + if ( row.item ) { + return row.item.external_id + " (" + row.booking_id + ")"; + } else { + return null; + } + } + }, + { + "data": "item.callnumber", + "title": "Callnumber", + "searchable": true, + "orderable": true, + "render": function(data,type,row,meta) { + if ( row.item ) { + return row.item.callnumber; + } else { + return null; + } + } + }, + { + "data": "patron.firstname:patron.surname", + "title": "Patron", + "searchable": true, + "orderable": true, + "render": function(data, type, row, meta) { + return $patron_to_html(row.patron, { + display_cardnumber: true, + url: true + }); + } + }, + { + "data": "start_date", + "name": "start_date", + "title": "Booking dates", + "type": "date", + "searchable": false, + "orderable": true, + "render": function(data, type, row, meta) { + return $date(row.start_date) + ' - ' + $date(row.end_date); + } + }, + { + "name": "actions", + "title": "Actions", + "searchable": false, + "orderable": false, + "render": function(data,type,row,meta){ + return ""; + } + }] + }, table_settings, 1, additional_filters); + + /** Date filtering */ + $("#bookingsf").on("submit", function(e){ + /* stop form from submitting normally */ + e.preventDefault(); + bookings_table.DataTable().draw(); + }); + }); + </script> + [% END %] + [% INCLUDE 'intranet-bottom.inc' %] -- 2.43.0