Bugzilla – Attachment 70074 Details for
Bug 15492
Stand alone self check-in tool
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 15492: Add SCI module
Bug-15492-Add-SCI-module.patch (text/plain), 21.17 KB, created by
Kyle M Hall (khall)
on 2017-12-21 17:59:54 UTC
(
hide
)
Description:
Bug 15492: Add SCI module
Filename:
MIME Type:
Creator:
Kyle M Hall (khall)
Created:
2017-12-21 17:59:54 UTC
Size:
21.17 KB
patch
obsolete
>From 38f73b4bf54dd9b5cacd6e5e61e8dad599bd63ae Mon Sep 17 00:00:00 2001 >From: Tomas Cohen Arazi <tomascohen@theke.io> >Date: Fri, 10 Nov 2017 15:32:43 -0300 >Subject: [PATCH] Bug 15492: Add SCI module > >This patch adds the SCI module, and adapts C4::Auth to know about it. > >The current behaviour is: >- Requires admin user initialization/login >- Uses the logged users' library >- A form allows to scan multiple barcodes >- A button sends the barcode list to the controller > to batch perform the checkins >- Successful and failed checkins are sent to the template >- Results are displayed >- Logout link > >To test: >- Apply this patches >- Make sure you upgrade: > $ kshell > k$ perl installer/data/mysql/updatedatabase.pl >- Have 'SelfCheckInModule' disabled >- Go to http://kohadev.myDNSname.org:8080/cgi-bin/koha/sci/sci-main.pl [1] >=> SUCCESS: You are rejected because the feature is disabled >- Enable 'SelfCheckInModule' >- Go to the previous URL >=> SUCCESS: You are required to login >- Login with a user WITHOUT self_checkout permissions >=> SUCCESS: You are not allowed to log into the Self check-in module. >- Login with a user WITH self_checkour permissions >=> SUCCESS: You gain access, and are presented the UI >- Go through the several options >=> SUCCESS: All works as it should >- Click the 'Help' link >=> SUCCESS: A help text is displayed on a modal >- Sign off :-D > >- Bonus points: > $ kshell > k$ qa -c 2 -v 2 >=> SUCCESS: All tests green > >[1] Adjust to your dev's OPAC setup > >Signed-off-by: David Bourgault <david.bourgault@inlibro.com> > >Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com> >--- > C4/Auth.pm | 29 +++ > koha-tmpl/opac-tmpl/bootstrap/css/sco.css | 12 + > .../opac-tmpl/bootstrap/en/modules/opac-auth.tt | 4 + > .../opac-tmpl/bootstrap/en/modules/sci/sci-main.tt | 248 +++++++++++++++++++++ > opac/sci/sci-main.pl | 96 ++++++++ > 5 files changed, 389 insertions(+) > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/sci/sci-main.tt > create mode 100755 opac/sci/sci-main.pl > >diff --git a/C4/Auth.pm b/C4/Auth.pm >index 67bdd7e..23cf87c 100644 >--- a/C4/Auth.pm >+++ b/C4/Auth.pm >@@ -207,6 +207,34 @@ sub get_template_and_user { > } > } > >+ # If the user logged in is the SCI user and they try to go out of the SCI module, >+ # log the user out removing the CGISESSID cookie >+ if ( $in->{type} eq 'opac' and $in->{template_name} !~ m|sci/| ) { >+ if ( $user && C4::Context->preference('AutoSelfCheckID') && $user eq C4::Context->preference('AutoSelfCheckID') ) { >+ $template = C4::Templates::gettemplate( 'opac-auth.tt', 'opac', $in->{query} ); >+ my $cookie = $in->{query}->cookie( >+ -name => 'CGISESSID', >+ -value => '', >+ -expires => '', >+ -HttpOnly => 1, >+ ); >+ >+ $template->param( >+ loginprompt => 1, >+ script_name => get_script_name(), >+ ); >+ print $in->{query}->header( >+ { type => 'text/html', >+ charset => 'utf-8', >+ cookie => $cookie, >+ 'X-Frame-Options' => 'SAMEORIGIN' >+ } >+ ), >+ $template->output; >+ safe_exit; >+ } >+ } >+ > my $borrowernumber; > if ($user) { > >@@ -1266,6 +1294,7 @@ sub checkauth { > ); > > $template->param( SCO_login => 1 ) if ( $query->param('sco_user_login') ); >+ $template->param( SCI_login => 1 ) if ( $query->param('sci_user_login') ); > $template->param( OpacPublic => C4::Context->preference("OpacPublic") ); > $template->param( loginprompt => 1 ) unless $info{'nopermission'}; > >diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/sco.css b/koha-tmpl/opac-tmpl/bootstrap/css/sco.css >index ad50406..38fe877 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/css/sco.css >+++ b/koha-tmpl/opac-tmpl/bootstrap/css/sco.css >@@ -193,4 +193,16 @@ i.help { > .table .nosort.sorting { > padding-right: 19px; > background: #EEEEEE none; >+} >+ >+#sci_logout { >+ color: #E8583C; >+} >+ >+#sci_checkin_button, #sci_refresh_button, #sci_append_button { >+ margin-bottom: 10px; >+} >+ >+#sci_refresh_button { >+ color: rgb(51, 51, 51); > } >\ No newline at end of file >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt >index 31cfbc6..2a38e50 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt >@@ -31,6 +31,8 @@ > <p>Sorry, the system doesn't think you have permission to access this page. </p> > [% IF SCO_login %] > <p><a href="/cgi-bin/koha/sco/sco-main.pl?logout.x=1">Log out and try again with a different user.</a></p> >+ [% ELSIF SCI_login %] >+ <p><a href="/cgi-bin/koha/sci/sci-main.pl?logout.x=1">Log out and try again with a different user.</a></p> > [% END %] > </div> > [% END %] >@@ -158,6 +160,8 @@ > > [% IF SCO_login %] > <form action="/cgi-bin/koha/sco/sco-main.pl" name="auth" id="auth" method="post"> >+ [% ELSIF SCI_login %] >+ <form action="/cgi-bin/koha/sci/sci-main.pl" name="auth" id="auth" method="post"> > [% ELSE %] > <form action="[% script_name %]" name="auth" id="auth" method="post"> > [% END %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/sci/sci-main.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/sci/sci-main.tt >new file mode 100644 >index 0000000..c33d6f4 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/sci/sci-main.tt >@@ -0,0 +1,248 @@ >+[%# Includes %] >+[% USE Koha %] >+[% USE KohaDates %] >+[%# Helper template functions %] >+[% BLOCK error_message %] >+ [% IF messages.BadBarcode %] >+ <span>(Barcode not found on the database)</span> >+ [% ELSIF messages.DataCorrupted %] >+ <span>(Data corruption detected. Contact your librarian)</span> >+ [% ELSIF messages.Wrongbranch %] >+ <span>(The item cannot be returned at this library)</span> >+ [% ELSIF messages.withdrawn %] >+ <span>(Item is withdrawn and check-in blocked by policy. Contact your librarian)</span> >+ [% ELSIF messages.NotIssued %] >+ <span>(The book is not currently on loan. Contact your librarian)</span> >+ [% END %] >+[% END %] >+ >+[% INCLUDE 'doc-head-open.inc' %] >+ >+<title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha [% END %] › Self check-in</title> >+ >+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> >+<meta name="generator" content="Koha [% Version %]" /> <!-- leave this for stats --> >+ >+[% IF ( Koha.Preference('OpacFavicon') ) %] >+<link rel="shortcut icon" href="[% Koha.Preference('OpacFavicon') %]" type="image/x-icon" /> >+[% ELSE %] >+<link rel="shortcut icon" href="[% interface %]/[% theme %]/images/favicon.ico" type="image/x-icon" /> >+[% END %] >+<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/lib/bootstrap/css/bootstrap.min.css" /> >+<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/lib/jquery/jquery-ui.css" /> >+<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/lib/font-awesome/css/font-awesome.min.css" /> >+<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/css/sco.css" /> >+[% IF ( Koha.Preference('OPACUserCSS') ) %]<style type="text/css">[% Koha.Preference('OPACUserCSS') %]</style>[% END %] >+[% IF ( Koha.Preference('SCOUserCSS') ) %]<style type="text/css">[% Koha.Preference('SCOUserCSS') %]</style>[% END %] >+<!--[if lt IE 9]> >+ <script src="[% interface %]/[% theme %]/lib/respond.min.js"></script> >+<![endif]--> >+<script type="text/javascript"> >+ function _(s) { return s } // dummy function for gettext >+</script> >+<script type="text/javascript" src="[% interface %]/[% theme %]/lib/modernizr.min.js"></script> >+</head> >+<body id="sci_main" class="sci" onload="dofocus();" onunload="mungeHistory();"> >+ >+[% SET OpacLangSelectorMode = Koha.Preference('OpacLangSelectorMode') %] >+<div id="wrap"> >+ <div class="navbar navbar-inverse navbar-static-top"> >+ <div class="navbar-inner"> >+ <div class="container-fluid"> >+ <a class="brand" href="/cgi-bin/koha/sci/sci-main.pl"><img src="[% interface %]/[% theme %]/images/koha-logo-navbar.png" alt=""></a> >+ <div id="checkouthelp"> >+ <ul class="nav pull-right"> >+ <li><a href="/cgi-bin/koha/sci/sci-main.pl" class="helpModal-trigger" role="button" data-toggle="modal"><i class="icon help"></i> Help</a></li> >+ <li><a id="sci_logout" href="/cgi-bin/koha/sci/sci-main.pl?logout.x=1" class="logout">Logout</a></li> >+ </ul> >+ </div> >+ >+ [% IF Koha.Preference( 'opaclanguagesdisplay' ) %] >+ <div id="members"> >+ <ul class="nav pull-right"> >+ [% INCLUDE 'masthead-langmenu.inc' %] >+ </ul> >+ </div> >+ [% END %] >+ >+ </div> <!-- /.container-fluid --> >+ </div> <!-- /.navbar-inner --> >+ </div> <!-- /.navbar --> >+ >+[% IF Koha.Preference( 'opacheader' ) %] >+ <div class="container-fluid"> >+ <div class="row-fluid"> >+ <div id="opacheader"> >+ [% Koha.Preference( 'opacheader' ) %] >+ </div> >+ </div> >+ </div> >+[% END %] >+ >+ <div class="main"> >+ <div class="container-fluid"> >+ <div class="row-fluid"> >+ <div id="masthead"> >+ <h1>[% LibraryName %] Self check-in</h1> >+ [% IF ( nopermission ) %] >+ [%# This is what is displayed if user doesn't have permission %] >+ <div class="alert"> >+ <h3>Access denied</h3> >+ <p>Sorry, this self check-in station has lost authentication. Please contact the administrator to resolve this problem.</p> >+ </div> >+ [% ELSIF ( different_ip ) %] >+ [%# This is what is displayed if user doesn't have permission %] >+ <div class="alert"> >+ <h3>Session lost</h3> >+ <p>You are accessing self check-in from a different IP address! Please log in again.</p> >+ </div> >+ [% ELSIF ( checkins ) %] >+ [%# We have results from a check-in attempt %] >+ <div id="checkins" class="sci_results_list"> >+ [% IF ( success && success.size > 0 || errors && errors.size > 0 ) %] >+ <h3>Results</h3> >+ <table id="sci_bcheckins_table" class="table table-bordered table-striped dataTable no-footer" style="font-size: initial;"> >+ <thead> >+ <th>Barcode</th> >+ <th>Status</th> >+ </thead> >+ <tbody> >+ [% FOREACH success_line IN success %] >+ <tr><td>[% success_line.barcode %]</td><td>Checked in</td></tr> >+ [% END %] >+ [% FOREACH error IN errors %] >+ <tr> >+ <td>[% error.barcode %]</td> >+ <td>Not checked in [% PROCESS error_message messages=error.messages %]</td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ <div> >+ <form method="post" action="#" id="finish_form"> >+ <button type="submit" class="btn"><i class="icon finish"></i> Finish</button> >+ </form> >+ </div> >+ [% ELSE %] >+ <div class="alert"> >+ <p>Your request included no check-ins.</p> >+ </div> >+ [% END %] >+ </div> >+ [% ELSE %] >+ [%# Prompt for barcodes %] >+ <div id="new_checkins" class="sci_entry"> >+ <form id="scan_form" name="scan_form" >+ method="post" action="/cgi-bin/koha/sci/sci-main.pl"> >+ <fieldset> >+ <div> >+ <label for="barcode_input">Scan the item or enter its barcode:</label> >+ <input id="barcode_input" name="barcode_input" size="20" type="text" class="focus" autocomplete="off" /> >+ <button id="sci_append_button" type="submit" class="btn btn-default btn-sm"> >+ <i class="fa fa-plus" aria-hidden="true"></i> <span>Add</span> >+ </button> >+ </div> >+ <div class="sci_input_append"> >+ <table id="sci_barcodes_table" class="table table-bordered table-striped dataTable no-footer" style="display: none; font-size: initial;"> >+ <thead> >+ <th class="barcodes_column">Barcode</th> >+ </thead> >+ <tbody> >+ </tbody> >+ </table> >+ </div> >+ <input type="hidden" name="op" value="check_in" /> >+ <div id="button_bar"> >+ <button id="sci_checkin_button" type="submit" class="btn btn-default btn-sm" style="display: none;"> >+ <i class="fa fa-check-square-o" aria-hidden="true"></i> <span>Check in</span> >+ </button> >+ <a href="/cgi-bin/koha/sci/sci-main.pl" class="btn btn-default btn-sm" role="button" style="display: none;" id="sci_refresh_button"> >+ <i class="fa fa-refresh" aria-hidden="true"></i> <span>Cancel</span> >+ </a> >+ </div> >+ </fieldset> >+ </form> >+ </div> <!-- / #new_checkins --> >+ [% END %] >+ </div> <!-- / #masthead --> >+ </div> <!-- / .row-fluid --> >+ </div> <!-- / .container-fluid --> >+ >+ [% IF ( Koha.Preference('SCOMainUserBlock' ) ) %] >+ <div id="scomainuserblock">[% Koha.Preference('SCOMainUserBlock' ) %]</div> >+ [% END %] >+ </div> <!-- / .main --> >+ >+ <div id="helpModal" class="modal hide" tabindex="-1" role="dialog" aria-labelledby="helpModalLabel" aria-hidden="true"> >+ >+ <div class="modal-header"> >+ <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ã</button> >+ <h3 id="helpModalLabel">Self check-in help</h3> >+ </div> >+ >+ <div class="modal-body"> >+ <ul> >+ <li>Scan each item or enter its barcode. A list with the entered barcodes will be displayed.</li> >+ <li>Click the 'Check in' button to confirm.</li> >+ <li>The operation results will be displayed for each entered barcode.</li> >+ <li>The 'Finish' button is presented to start over.</li> >+ <li>At any step, clicking the 'Cancel' button will erase the scanned barcodes and start over.</li> >+ </ul> >+ </div> >+ </div> <!-- /#helpModal --> >+</body> >+ >+[% INCLUDE 'opac-bottom.inc' %] >+[% BLOCK jsinclude %] >+ [% INCLUDE 'datatables.inc' %] >+ <script type="text/javascript"> >+ >+ function mungeHistory() { >+ // prevent back button from allowing form resubmission >+ if (history && history.pushState) { >+ history.replaceState(null, document.title, window.location.href); >+ } >+ } >+ >+ function dofocus() { >+ $(".focus:last").select(); >+ } >+ >+ var barcodes = []; >+ >+ $(document).ready(function() { >+ // Barcodes scanning table initially hidden >+ $("#sci_barcodes_table").hide(); >+ // Control de 'append' button behaviour >+ $("#sci_append_button").on('click',function( e ){ >+ // Make sure the form is not submitted by the button >+ e.preventDefault(); >+ var barcode = $('#barcode_input').val(); >+ //var result = validate_barcode( barcode ); >+ $('#sci_barcodes_table tbody').append( >+ '<tr stype="font-size: initial;"><td>' + >+ barcode + >+ '<input type="hidden" name="barcode" value="' + barcode + '" />' + >+ '</td></tr>' ); >+ // Make sure the table is now displayed >+ $("#sci_barcodes_table").show(); >+ $('#sci_checkin_button').show(); >+ $('#sci_refresh_button').show(); >+ barcodes.push(barcode); >+ // clean the input, reset the focus >+ $('#barcode_input').val(''); >+ dofocus(); >+ }); >+ >+ $(".helpModal-trigger").on("click",function(e){ >+ e.preventDefault(); >+ $("#helpModal").modal("show"); >+ }); >+ >+ // set focus at the beginning >+ dofocus(); >+ }); >+ </script> >+ >+ [% IF ( Koha.Preference('SCOUserJS') ) %]<script type="text/javascript">[% Koha.Preference('SCOUserJS') %]</script>[% END %] >+[% END %] >diff --git a/opac/sci/sci-main.pl b/opac/sci/sci-main.pl >new file mode 100755 >index 0000000..a6cb4fe >--- /dev/null >+++ b/opac/sci/sci-main.pl >@@ -0,0 +1,96 @@ >+#!/usr/bin/perl >+ >+# 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::Auth qw(get_template_and_user checkpw); >+use C4::Circulation; >+use C4::Output; >+ >+use List::MoreUtils qw( uniq ); >+use Try::Tiny; >+ >+my $cgi = new CGI; >+ >+# 404 if feature is disabled >+unless ( C4::Context->preference('SelfCheckInModule') ) { >+ print $cgi->redirect("/cgi-bin/koha/errors/404.pl"); >+ exit; >+} >+ >+# Let Auth know this is a SCI context >+$cgi->param( -name => 'sci_user_login', -values => [1] ); >+ >+my ( $template, $loggedinuser, $cookie ) = get_template_and_user( >+ { >+ template_name => "sci/sci-main.tt", >+ authnotrequired => 0, >+ flagsrequired => { circulate => "self_checkout" }, >+ query => $cgi, >+ type => "opac" >+ } >+); >+ >+my $op = $cgi->param('op') // ''; >+ >+if ( $op eq 'check_in' ) { >+ ## Get the barcodes, perform some basic validation >+ # Remove empty ones >+ my @barcodes = grep { $_ ne '' } $cgi->multi_param('barcode'); >+ >+ # Remove duplicates >+ @barcodes = uniq @barcodes; >+ >+ # Read the library we are logged in from userenv >+ my $library = C4::Context->userenv->{'branch'}; >+ my @success; >+ my @errors; >+ >+ # Return items >+ foreach my $barcode (@barcodes) { >+ try { >+ my ( $success, $messages, $checkout, $patron ) = >+ AddReturn( $barcode, $library ); >+ if ($success) { >+ push @success, >+ { >+ barcode => $barcode, >+ messages => $messages, >+ checkout => $checkout, >+ patron => $patron >+ }; >+ } >+ else { >+ push @errors, >+ { >+ barcode => $barcode, >+ messages => $messages, >+ checkout => $checkout, >+ patron => $patron >+ }; >+ } >+ } >+ catch { >+ push @errors, { barcode => $barcode, messages => 'unknown_error' }; >+ }; >+ } >+ $template->param( success => \@success, errors => \@errors, checkins => 1 ); >+} >+ >+output_html_with_http_headers $cgi, $cookie, $template->output, undef, { force_no_caching => 1 }; >-- >2.10.2
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 15492
:
69165
|
69166
|
69167
|
69168
|
69179
|
69664
|
69665
|
70073
|
70074
|
70075
|
70173
|
70174
|
70175
|
70176
|
70177
|
70178
|
70179
|
72053
|
72054
|
72055
|
72056
|
72057
|
72058
|
72059
|
72060
|
72176
|
72177
|
72178
|
72179
|
72180
|
72181
|
72182
|
72183
|
73097