Bug 29002: Add bookings view

This patch adds a new view to the biblio details page to display any
bookings that may have been made.

Test plan
1) Run through the steps from the previous patch
2) Note the appearance of a new 'Bookings' option in the left menu
3) Click the bookings option to load the new bookings page for the
   biblio
4) See that the booking from the previous patch appears on the page
5) Sign off

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Janet McGowan <janet.mcgowan@ptfs-europe.com>
Signed-off-by: Caroline Cyr La Rose <caroline.cyr-la-rose@inlibro.com>
Signed-off-by: Laurence Rault <laurence.rault@biblibre.com>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
Martin Renvoize 2023-05-15 16:30:26 +01:00 committed by Tomas Cohen Arazi
parent 9fff2e1f4e
commit 902d7e4fb0
No known key found for this signature in database
GPG Key ID: 0A272EA1B2F3C15F
5 changed files with 205 additions and 1 deletions

View File

@ -342,6 +342,9 @@
x-koha-authorization:
permissions:
circulation: "1"
x-koha-embed:
- item
- patron
"/biblios/{biblio_id}/checkouts":
get:
x-mojo-to: Biblios#get_checkouts

46
bookings/list.pl Executable file
View File

@ -0,0 +1,46 @@
#!/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 );
my $input = CGI->new;
my ( $template, $borrowernumber, $cookie, $flags ) = get_template_and_user(
{
template_name => "bookings/list.tt",
query => $input,
type => "intranet",
flagsrequired => { circulation => 1 },
}
);
my $biblionumber = $input->param('biblionumber');
my $biblio = Koha::Biblios->find($biblionumber);
$template->param(
biblionumber => $biblionumber,
biblio => $biblio,
bookingsview => 1,
);
output_html_with_http_headers $input, $cookie, $template->output;

View File

@ -50,6 +50,14 @@
<a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% biblio_object_id | url %]">Items</a>
</li>
[%- IF ( bookingsview ) -%]
<li class="active">
[%- ELSE -%]
<li>
[%- END -%]
<a href="/cgi-bin/koha/bookings/list.pl?biblionumber=[% biblio_object_id | url %]">Bookings</a>
</li>
[%- IF ( CAN_user_reserveforothers ) -%]
[%- IF ( holdsview ) -%]
<li class="active">

View File

@ -0,0 +1,141 @@
[% USE raw %]
[% USE Asset %]
[% USE KohaDates %]
[% SET footerjs = 1 %]
[% INCLUDE 'doc-head-open.inc' %]
<title>Bookings for [% INCLUDE 'biblio-title-head.inc' %] &rsaquo; Bookings &rsaquo; Circulation &rsaquo; Koha</title>
[% INCLUDE 'doc-head-close.inc' %]
</head>
<body id="circ_request" class="catalog">
[% 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/catalogue/search.pl">Catalog</a>
</li>
<li>
[% INCLUDE 'biblio-title.inc' link =1 %]
</li>
<li>
<a href="#" aria-current="page">
Bookings
</a>
</li>
</ol>
</nav>
<div class="main container-fluid">
<div class="row">
<div class="col-sm-10 col-sm-push-2">
<main>
<div class="row">
<div class="btn-toolbar">
<div class="btn-group">
<button id="placbooking" class="btn btn-default" data-toggle="modal" data-target="#placeBookingModal" data-biblionumber="[% biblionumber | html %]"><i class="fa fa-calendar"></i> Place booking</button>
</div>
</div>
<h1>Bookings for [% INCLUDE 'biblio-title-head.inc' %]</h1>
<div class="page-section">
<table id="bookings_table"></table>
</div>
</div>
</main>
</div> <!-- /.col-sm-10.col-sm-push-2 -->
<div class="col-sm-2 col-sm-pull-10">
<aside>
[% INCLUDE 'biblio-view-menu.inc' %]
</aside>
</div> <!-- /.col-sm-2.col-sm-pull-10 -->
</div> <!-- /.row -->
[% INCLUDE modals/place_booking.inc %]
[% MACRO jsinclude BLOCK %]
[% Asset.js("lib/dayjs/dayjs.min.js") | $raw %]
[% INCLUDE 'datatables.inc' %]
[% INCLUDE 'columns_settings.inc' %]
[% INCLUDE 'calendar.inc' %]
[% INCLUDE 'select2.inc' %]
[% INCLUDE 'js-date-format.inc' %]
[% Asset.js("js/place_booking_modal.js") | $raw %]
<script>
var bookings_table;
$(document).ready(function(){
var bookings_table_url = "/api/v1/biblios/[% biblionumber | uri %]/bookings";
bookings_table = $('#bookings_table').kohaTable({
"ajax": {
"url": bookings_table_url
},
"embed": [
"item",
"patron"
],
"columns": [{
"data": "booking_id",
"title": "Booking ID",
"visible": false,
"searchable": false,
"orderable": false
},
{
"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;
} else {
return null;
}
}
},
{
"data": "patron.firstname:patron.surname",
"title": "Patron",
"searchable": true,
"orderable": true,
"render": function(data, type, row, meta) {
var fullname;
if ( row.patron.firstname == null ) {
fullname = row.patron.surname;
}
else {
fullname = row.patron.firstname + " " + row.patron.surname;
}
return escape_str(fullname);
}
},
{
"data": "start_date",
"title": "Start date",
"searchable": true,
"orderable": true,
"render": function(data, type, row, meta) {
return $date(row.start_date);
}
},
{
"data": "end_date",
"title": "End date",
"searchable": true,
"orderable": true,
"render": function(data, type, row, meta) {
return $date(row.end_date);
}
}]
}, [], 1);
});
</script>
[% END %]
[% INCLUDE 'intranet-bottom.inc' %]

View File

@ -308,9 +308,15 @@ $("#placeBookingForm").on('submit', function(e) {
);
posting.done(function(data) {
// Update bookings page as required
if (typeof bookings_table !== 'undefined' && bookings_table !== null) {
bookings_table.api().ajax.reload();
}
// Close modal
$('#placeBookingModal').modal('hide');
// Reset modal form
// Reset form
$('#booking_patron_id').val(null).trigger('change');
$('#booking_item_id').val(null).trigger('change');
$("#period").get(0)._flatpickr.clear();