From 6dd9688fdf486ab713435c1ff0cfd0a9b989c645 Mon Sep 17 00:00:00 2001 From: Nicolas Legrand Date: Fri, 27 Mar 2015 16:18:56 +0100 Subject: [PATCH] Bug 13881: Add desk management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Desks can be created for a branch. If a librarian sets a desk in the intranet and check in a document on hold, the document is then attached to a desk. Test plan, basic desk creation/modification/deletion: 1/ perl installer/data/mysql/updatedatabase.pl (create new table desks) 2/ prove t/db_dependent/Desks.t 3/ go to admin page, click on desk management, try to create, modify and delete desks Test plan, setting desk in the intranet: 1/ Go to the intranet administration, remove all desks if you have any. The desks should not appear in the header. 2/ add some desks in administration, without selecting some. The message « NO DESK SET » should appear at the left of the branchname. 3/ set a desk for your session. The desk deskcode should appear beside the branchname. 4/ change desk, the new name should appear also. Test plan, attach holds awaiting pickup to a desk: 1/ Set a desk, put a book on hold, check it in, confirm hold, it should appear in the "holds awaiting pickup" circulation page, it should appear as waiting at the desk on the patron's session. 2/ Suppress desk. The hold is still pending, but desk mentions should have disappear from "holds awaiting pickup" and patron's session. http://bugs.koha-community.org/show_bug.cgi?id=3881 --- C4/Auth.pm | 52 ++++- C4/Context.pm | 7 +- C4/Desks.pm | 183 +++++++++++++++++ C4/Reserves.pm | 20 +- admin/desks.pl | 127 ++++++++++++ circ/returns.pl | 3 +- circ/selectdesk.pl | 92 +++++++++ circ/waitingreserves.pl | 9 + .../atomicupdate/bug_13881-add_desk_management.sql | 12 ++ .../bug_13881_link_desk_to_reserves.sql | 8 + installer/data/mysql/kohastructure.sql | 26 ++- .../intranet-tmpl/prog/en/includes/header.inc | 15 ++ .../prog/en/modules/admin/admin-home.tt | 2 + .../intranet-tmpl/prog/en/modules/admin/desks.tt | 221 +++++++++++++++++++++ .../prog/en/modules/circ/selectdesk.tt | 50 +++++ .../prog/en/modules/circ/waitingreserves.tt | 6 + .../opac-tmpl/bootstrap/en/modules/opac-user.tt | 2 +- opac/opac-user.pl | 7 + t/db_dependent/Desks.t | 70 +++++++ 19 files changed, 894 insertions(+), 18 deletions(-) create mode 100644 C4/Desks.pm create mode 100755 admin/desks.pl create mode 100755 circ/selectdesk.pl create mode 100644 installer/data/mysql/atomicupdate/bug_13881-add_desk_management.sql create mode 100644 installer/data/mysql/atomicupdate/bug_13881_link_desk_to_reserves.sql create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/admin/desks.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/selectdesk.tt create mode 100644 t/db_dependent/Desks.t diff --git a/C4/Auth.pm b/C4/Auth.pm index ef0c585..6fd927b 100644 --- a/C4/Auth.pm +++ b/C4/Auth.pm @@ -29,6 +29,7 @@ use C4::Context; use C4::Templates; # to get the template use C4::Languages; use C4::Branch; # GetBranches +use C4::Desks; use C4::Search::History; use Koha; use Koha::AuthUtils qw(hash_password); @@ -405,6 +406,7 @@ sub get_template_and_user { IntranetmainUserblock => C4::Context->preference("IntranetmainUserblock"), LibraryName => C4::Context->preference("LibraryName"), LoginBranchname => ( C4::Context->userenv ? C4::Context->userenv->{"branchname"} : undef ), + LoginDeskname => ( C4::Context->userenv ? C4::Context->userenv->{"deskname"} : undef ), advancedMARCEditor => C4::Context->preference("advancedMARCEditor"), canreservefromotherbranches => C4::Context->preference('canreservefromotherbranches'), intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"), @@ -425,7 +427,22 @@ sub get_template_and_user { UseKohaPlugins => C4::Context->preference('UseKohaPlugins'), UseCourseReserves => C4::Context->preference("UseCourseReserves"), useDischarge => C4::Context->preference('useDischarge'), - ); + ); + if ( C4::Context->userenv ? C4::Context->userenv->{"branch"} : undef) { + my $desksaref = GetDesks(C4::Context->userenv->{"branch"}); + if ($#$desksaref > -1) { + $template->param( + LoginDeskcode => ( C4::Context->userenv->{"deskcode"} ), + LoginDeskname => ( C4::Context->userenv->{"deskname"} ), + HasDesk => (1), + ); + } + else { + $template->param( + HasDesk => ( undef ), + ); + } + } } else { warn "template type should be OPAC, here it is=[" . $in->{'type'} . "]" unless ( $in->{'type'} eq 'opac' ); @@ -474,6 +491,7 @@ sub get_template_and_user { LibraryName => "" . C4::Context->preference("LibraryName"), LibraryNameTitle => "" . $LibraryNameTitle, LoginBranchname => C4::Context->userenv ? C4::Context->userenv->{"branchname"} : "", + Logindeskname => C4::Context->userenv ? C4::Context->userenv->{"deskname"} : "", OPACAmazonCoverImages => C4::Context->preference("OPACAmazonCoverImages"), OPACFRBRizeEditions => C4::Context->preference("OPACFRBRizeEditions"), OpacHighlightedWords => C4::Context->preference("OpacHighlightedWords"), @@ -762,7 +780,8 @@ sub checkauth { $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), $session->param('emailaddress'), $session->param('branchprinter'), - $session->param('persona'), $session->param('shibboleth') + $session->param('persona'), $session->param('shibboleth'), + $session->param('deskcode'), $session->param('deskname') ); C4::Context::set_shelves_userenv( 'bar', $session->param('barshelves') ); C4::Context::set_shelves_userenv( 'pub', $session->param('pubshelves') ); @@ -986,7 +1005,8 @@ sub checkauth { C4::Context->_unset_userenv($sessionID); } my ( $borrowernumber, $firstname, $surname, $userflags, - $branchcode, $branchname, $branchprinter, $emailaddress ); + $branchcode, $branchname, $branchprinter, $emailaddress, + $deskcode, $deskname); if ( $return == 1 ) { my $select = " @@ -1062,6 +1082,8 @@ sub checkauth { $session->param( 'surname', $surname ); $session->param( 'branch', $branchcode ); $session->param( 'branchname', $branchname ); + $session->param( 'deskcode', $deskcode ); + $session->param( 'deskname', $deskname ); $session->param( 'flags', $userflags ); $session->param( 'emailaddress', $emailaddress ); $session->param( 'ip', $session->remote_addr() ); @@ -1080,6 +1102,8 @@ sub checkauth { $session->param( 'surname', C4::Context->config('user') ); $session->param( 'branch', 'NO_LIBRARY_SET' ); $session->param( 'branchname', 'NO_LIBRARY_SET' ); + $session->param( 'deskcode', 'NO_DESK_SET' ); + $session->param( 'deskname', 'NO_DESK_SET' ); $session->param( 'flags', 1 ); $session->param( 'emailaddress', C4::Context->preference('KohaAdminEmailAddress') ); $session->param( 'ip', $session->remote_addr() ); @@ -1094,7 +1118,8 @@ sub checkauth { $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), $session->param('emailaddress'), $session->param('branchprinter'), - $session->param('persona'), $session->param('shibboleth') + $session->param('persona'), $session->param('shibboleth'), + $session->param('deskcode'), $session->param('deskname') ); } @@ -1343,7 +1368,9 @@ sub check_api_auth { $session->param('cardnumber'), $session->param('firstname'), $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), - $session->param('emailaddress'), $session->param('branchprinter') + $session->param('emailaddress'), $session->param('branchprinter'), + $session->param('persona'), $session->param('shibboleth'), + $session->param('deskcode'), $session->param('deskname') ); my $ip = $session->param('ip'); @@ -1430,7 +1457,8 @@ sub check_api_auth { my ( $borrowernumber, $firstname, $surname, $userflags, $branchcode, $branchname, - $branchprinter, $emailaddress + $branchprinter, $emailaddress, $deskcode, + $deskname ); my $sth = $dbh->prepare( @@ -1491,6 +1519,8 @@ sub check_api_auth { $session->param( 'surname', $surname ); $session->param( 'branch', $branchcode ); $session->param( 'branchname', $branchname ); + $session->param( 'deskcode', $deskcode ); + $session->param( 'deskname', $deskname ); $session->param( 'flags', $userflags ); $session->param( 'emailaddress', $emailaddress ); $session->param( 'ip', $session->remote_addr() ); @@ -1505,6 +1535,8 @@ sub check_api_auth { $session->param( 'surname', C4::Context->config('user') ); $session->param( 'branch', 'NO_LIBRARY_SET' ); $session->param( 'branchname', 'NO_LIBRARY_SET' ); + $session->param( 'deskcode', 'NO_DESK_SET' ); + $session->param( 'deskname', 'NO_DESK_SET' ); $session->param( 'flags', 1 ); $session->param( 'emailaddress', C4::Context->preference('KohaAdminEmailAddress') ); $session->param( 'ip', $session->remote_addr() ); @@ -1515,7 +1547,9 @@ sub check_api_auth { $session->param('cardnumber'), $session->param('firstname'), $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), - $session->param('emailaddress'), $session->param('branchprinter') + $session->param('emailaddress'), $session->param('branchprinter'), + $session->param('persona'), $session->param('shibboleth'), + $session->param('deskcode'), $session->param('deskname'), ); return ( "ok", $cookie, $sessionID ); } else { @@ -1596,7 +1630,9 @@ sub check_cookie_auth { $session->param('cardnumber'), $session->param('firstname'), $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), - $session->param('emailaddress'), $session->param('branchprinter') + $session->param('emailaddress'), $session->param('branchprinter'), + $session->param('persona'), $session->param('shibboleth'), + $session->param('deskcode'), $session->param('deskname'), ); my $ip = $session->param('ip'); diff --git a/C4/Context.pm b/C4/Context.pm index 26eeb40..14a4bdb 100644 --- a/C4/Context.pm +++ b/C4/Context.pm @@ -1047,7 +1047,8 @@ sub userenv { C4::Context->set_userenv($usernum, $userid, $usercnum, $userfirstname, $usersurname, $userbranch, $branchname, $userflags, - $emailaddress, $branchprinter, $persona); + $emailaddress, $branchprinter, $persona, + $desk, $deskcode); Establish a hash of user environment variables. @@ -1058,7 +1059,7 @@ set_userenv is called in Auth.pm #' sub set_userenv { shift @_; - my ($usernum, $userid, $usercnum, $userfirstname, $usersurname, $userbranch, $branchname, $userflags, $emailaddress, $branchprinter, $persona, $shibboleth)= + my ($usernum, $userid, $usercnum, $userfirstname, $usersurname, $userbranch, $branchname, $userflags, $emailaddress, $branchprinter, $persona, $shibboleth, $deskcode, $deskname)= map { Encode::is_utf8( $_ ) ? $_ : Encode::decode('UTF-8', $_) } # CGI::Session doesn't handle utf-8, so we decode it here @_; my $var=$context->{"activeuser"} || ''; @@ -1075,6 +1076,8 @@ sub set_userenv { "emailaddress" => $emailaddress, "branchprinter" => $branchprinter, "persona" => $persona, + "deskcode" => $deskcode, + "deskname" => $deskname, "shibboleth" => $shibboleth, }; $context->{userenv}->{$var} = $cell; diff --git a/C4/Desks.pm b/C4/Desks.pm new file mode 100644 index 0000000..9298b9a --- /dev/null +++ b/C4/Desks.pm @@ -0,0 +1,183 @@ +# This file is part of Koha. +# +# Copyright (C) 2011 Progilone +# Copyright (C) 2015 BULAC +# +# 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 . + +package C4::Desks; + +use Modern::Perl; + +use C4::Context; +use vars qw(@ISA @EXPORT); + +BEGIN { + require Exporter; + @ISA = qw(Exporter); + @EXPORT = qw( + &AddDesk + &ModDesk + &DelDesk + &GetDesk + &GetDesks + ); +} + +=head1 NAME + +C4::Desks - Desk management functions + +=head1 DESCRIPTION + +This module contains an API for manipulating issue desks in Koha. It +is used by circulation. + +=head1 HISTORICAL NOTE + +Developped by Progilone on a customised Koha 3.2 for BULAC +library. The module is ported to Koha 3.19 and up by the BULAC. + +=cut + +=head2 AddDesk + + AddDesk({ + 'deskcode' => $deskcode, + 'deskname' => $deskname, + 'deskdescription' => $deskdescription + 'branchcode' => $branchcode }); + + returns 1 on success, undef on error. A return value greater than 1 + or just -1 means something went wrong. + +=cut + +sub AddDesk { + my ($args) = @_; + C4::Context->dbh->do + ('INSERT INTO desks ' . + '(deskcode, deskname, deskdescription, branchcode) ' . + 'VALUES (?,?,?,?)' , + undef, + $args->{'deskcode'}, + $args->{'deskname'}, + $args->{'deskdescription'}, + $args->{'branchcode'}, + ); +} + +=head2 DelDesk + + DelDesk($deskcode) + + returns 1 on success, undef on error. A return value greater than 1 + or just -1 means something went wrong. + +=cut + +sub DelDesk { + my $deskcode = shift; + C4::Context->dbh->do + ('DELETE FROM desks WHERE deskcode = ?', + undef, + $deskcode + ); +} + +=head2 GetDesk + + $desk_href = GetDesk($deskcode); + + returns undef when no desk matches $deskcode, return a href + containing desk parameters: + {'deskcode' => $deskcode, + 'deskname' => $deskname, + 'deskdescription' => $deskdescription, + 'branchcode' => $branchcode } + +=cut + +sub GetDesk { + my $deskcode = shift; + my $query = ' + SELECT * + FROM desks + WHERE deskcode = ?'; + + my $sth = C4::Context->dbh->prepare($query); + $sth->execute($deskcode); + $sth->fetchrow_hashref; +} + +=head2 GetDesks + + $desk_aref = GetDesks([$branch]) + + returns an array ref containing deskcodes. If no desks are + available, the array is empty. + +=cut + +sub GetDesks { + my $branchcode = shift || ''; + my $retaref = []; + my $query = 'SELECT deskcode FROM desks'; + if ($branchcode) { + $query = $query . ' WHERE branchcode = ?'; + } + my $sth = C4::Context->dbh->prepare($query); + if ($branchcode) { + $sth->execute($branchcode); + } else { + $sth->execute(); + } + while (my $rowaref = $sth->fetchrow_arrayref()) { + push @{ $retaref }, $rowaref->[0]; + } + return $retaref; +} + +=head2 ModDesks + + $deskhref = { + 'deskcode' => $deskcode, + 'deskname' => $deskname, + 'deskdescription' => $deskdescription, + 'branchcode' => $branchcode + } + ModDesks($deskhref) + + Modify desk with $deskcode with values contained in various + $deskhref fields. Returns 1 on success, 0 if no desk were + modified, undef, -1 or an int greater than 1 if something went + terribly wrong. + +=cut + +sub ModDesk { + my ($args) = @_; + C4::Context->dbh->do('UPDATE desks SET deskname = ? , ' . + 'deskdescription = ? , ' . + 'branchcode = ? ' . + 'WHERE deskcode = ?' , + undef, + $args->{'deskname'}, + $args->{'deskdescription'}, + $args->{'branchcode'}, + $args->{'deskcode'} + ); +} + +1; diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 6252b86..9677b06 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -843,7 +843,7 @@ sub GetReservesForBranch { my $dbh = C4::Context->dbh; my $query = " - SELECT reserve_id,borrowernumber,reservedate,itemnumber,waitingdate + SELECT reserve_id,borrowernumber,reservedate,itemnumber,waitingdate, deskcode FROM reserves WHERE priority='0' AND found='W' @@ -1353,7 +1353,7 @@ sub ModReserveStatus { =head2 ModReserveAffect - &ModReserveAffect($itemnumber,$borrowernumber,$diffBranchSend); + &ModReserveAffect($itemnumber,$borrowernumber,$diffBranchSend, $deskcode); This function affect an item and a status for a given reserve The itemnumber parameter is used to find the biblionumber. @@ -1367,7 +1367,7 @@ take care of the waiting status =cut sub ModReserveAffect { - my ( $itemnumber, $borrowernumber,$transferToDo ) = @_; + my ( $itemnumber, $borrowernumber,$transferToDo, $deskcode ) = @_; my $dbh = C4::Context->dbh; # we want to attach $itemnumber to $borrowernumber, find the biblionumber @@ -1398,6 +1398,19 @@ sub ModReserveAffect { AND biblionumber = ? "; } + elsif ($deskcode) { + # add deskcode with waiting + $query = " + UPDATE reserves + SET priority = 0, + found = 'W', + waitingdate = NOW(), + deskcode = '$deskcode', + itemnumber = ? + WHERE borrowernumber = ? + AND biblionumber = ? + "; + } else { # affect the reserve to Waiting as well. $query = " @@ -1405,6 +1418,7 @@ sub ModReserveAffect { SET priority = 0, found = 'W', waitingdate = NOW(), + deskcode = NULL, itemnumber = ? WHERE borrowernumber = ? AND biblionumber = ? diff --git a/admin/desks.pl b/admin/desks.pl new file mode 100755 index 0000000..3b0bc07 --- /dev/null +++ b/admin/desks.pl @@ -0,0 +1,127 @@ +#!/usr/bin/perl +# +# Copyright (C) 2011 Progilone +# Copyright (C) 2015 BULAC +# +# 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + +use Modern::Perl; +use CGI; +use C4::Output; +use C4::Auth; +use C4::Context; +use C4::Koha; +use C4::Branch; +use C4::Desks; + +my $script_name = "/cgi-bin/koha/admin/desks.pl"; + +my $input = new CGI; +my $deskcode = $input->param('deskcode'); +my $branchcode = $input->param('branchcode'); +my $deskname = $input->param('deskname'); +my $deskdescription = $input->param('deskdescription'); +my $op = $input->param('op') || ''; + +my @deskloop; +my $branches = GetBranches; +my @branchloop; +foreach my $thisbranch (sort keys %$branches) { + my %row =(value => $thisbranch, + branchname => $branches->{$thisbranch}->{branchname}, + ); + push @branchloop, \%row; +} + +my ( $template, $borrowernumber, $cookie ) = + get_template_and_user( + { + template_name => "admin/desks.tt", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => { + parameters => 'parameters_remaining_permissions' + }, + debug => 1, + } + ); + +$template->param(branchloop => \@branchloop); + +$template->param(script_name => $script_name); +if ($op) { + $template->param($op => 1); +} else { + $template->param(else => 1); +} +$template->param(deskcode => $deskcode); + +my $desk; + +if ( $op eq 'add_form' || $op eq 'delete_confirm') { + $desk = GetDesk($deskcode); +} +elsif ( $op eq 'add_validate' ) { + $desk = { + 'deskcode' => $deskcode, + 'deskname' => $deskname, + 'deskdescription' => $deskdescription, + 'branchcode' => $branchcode, + }; + if ( GetDesk($deskcode) ) { + $template->param(error => 'ALREADY_EXISTS'); + print $input->redirect('desks.pl'); + exit; + } + if (AddDesk($desk) != 1) { + $template->param(error => 'CANT_ADD'); + } + print $input->redirect('desks.pl'); + exit; +} +elsif ( $op eq 'modify_validate' ) { + $desk = { + 'deskcode' => $deskcode, + 'deskname' => $deskname, + 'deskdescription' => $deskdescription, + 'branchcode' => $branchcode, + }; + if (ModDesk($desk) != 1) { + $template->param(error => 'CANT_MODIFY'); + } + print $input->redirect('desks.pl'); + exit; +} +elsif ( $op eq 'delete_confirmed' ) { + if ( DelDesk($deskcode) != 1) { + $template->param(error => 'CANT_DELETE'); + } + print $input->redirect('desks.pl'); + exit; +} +else { + my $userenv = C4::Context->userenv; + my $desksaref = GetDesks(); + foreach my $d (@$desksaref) { + push @deskloop, GetDesk($d); + } + $template->param(deskloop => \@deskloop); +} + +$template->param(desk => $desk); + +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/circ/returns.pl b/circ/returns.pl index 8084727..de27739 100755 --- a/circ/returns.pl +++ b/circ/returns.pl @@ -144,12 +144,13 @@ if ( $query->param('resbarcode') ) { my $resbarcode = $query->param('resbarcode'); my $diffBranchReturned = $query->param('diffBranch'); my $iteminfo = GetBiblioFromItemNumber($item); + my $deskcode = C4::Context->userenv->{"deskcode"} || undef; # fix up item type for display $iteminfo->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $iteminfo->{'itype'} : $iteminfo->{'itemtype'}; my $diffBranchSend = ($userenv_branch ne $diffBranchReturned) ? $diffBranchReturned : undef; # diffBranchSend tells ModReserveAffect whether document is expected in this library or not, # i.e., whether to apply waiting status - ModReserveAffect( $item, $borrowernumber, $diffBranchSend); + ModReserveAffect( $item, $borrowernumber, $diffBranchSend, $deskcode); # check if we have other reserves for this document, if we have a return send the message of transfer my ( $messages, $nextreservinfo ) = GetOtherReserves($item); diff --git a/circ/selectdesk.pl b/circ/selectdesk.pl new file mode 100755 index 0000000..5b797e3 --- /dev/null +++ b/circ/selectdesk.pl @@ -0,0 +1,92 @@ +#!/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 2 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; +use CGI qw ( -utf8 ); + +use C4::Context; +use C4::Output; +use C4::Auth qw/:DEFAULT get_session/; +use C4::Koha; +use C4::Branch; +use C4::Desks; + +my $query = CGI->new(); + +my ( $template, $borrowernumber, $cookie ) = get_template_and_user( + { + template_name => "circ/selectdesk.tt", + query => $query, + type => "intranet", + debug => 1, + authnotrequired => 0, + flagsrequired => { catalogue => 1, }, + } +); + +my $sessionID = $query->cookie("CGISESSID"); +my $session = get_session($sessionID); + +my $branch = $query->param('branch'); +my $desks; +if ($branch) { + $desks = GetDesks($branch); +} +else { + $desks = GetDesks(); +} +my $deskloop = []; +for my $desk (@$desks) { + push @$deskloop, GetDesk($desk); +} + +my $deskcode = $query->param('deskcode'); + +my $userenv_desk = C4::Context->userenv->{'desk'} || ''; +my $updated = ''; + +if ($deskcode) { + if ( !$userenv_desk or $userenv_desk ne $deskcode ) { + my $desk = GetDesk($deskcode); + $template->param( LoginDeskname => $desk->{'deskname'} ); + $template->param( LoginDeskcode => $desk->{'deskcode'} ); + $session->param( deskname => $desk->{'deskname'} ); + $session->param( deskcode => $desk->{'deskcode'} ); + $updated = 1; + } +} +else { + $deskcode = $userenv_desk; +} + +$template->param( updated => \$updated ); + +unless ( $deskcode ~~ $desks ) { + $deskcode = @$desks[0]; +} + +my $referer = $query->param('oldreferer') || $ENV{HTTP_REFERER}; +if ($updated) { + print $query->redirect( $referer || '/cgi-bin/koha/mainpage.pl' ); +} + +$template->param( + referer => $referer, + deskloop => $deskloop, +); + +output_html_with_http_headers $query, $cookie, $template->output; diff --git a/circ/waitingreserves.pl b/circ/waitingreserves.pl index 5471643..e7f2cf1 100755 --- a/circ/waitingreserves.pl +++ b/circ/waitingreserves.pl @@ -24,6 +24,7 @@ use CGI qw ( -utf8 ); use C4::Context; use C4::Output; use C4::Branch; # GetBranchName +use C4::Desks; use C4::Auth; use C4::Dates qw/format_date/; use C4::Circulation; @@ -93,18 +94,26 @@ foreach my $num (@getreserves) { my $itemnumber = $num->{'itemnumber'}; my $gettitle = GetBiblioFromItemNumber( $itemnumber ); my $borrowernum = $num->{'borrowernumber'}; + my $deskcode = $num->{'deskcode'}; + my $desk = GetDesk($deskcode); + my $deskname; + if ($desk) { + $deskname = $desk->{'deskname'}; + } my $holdingbranch = $gettitle->{'holdingbranch'}; my $homebranch = $gettitle->{'homebranch'}; my %getreserv = ( itemnumber => $itemnumber, borrowernum => $borrowernum, + deskname => $deskname, ); # fix up item type for display $gettitle->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $gettitle->{'itype'} : $gettitle->{'itemtype'}; my $getborrower = GetMember(borrowernumber => $num->{'borrowernumber'}); my $itemtypeinfo = getitemtypeinfo( $gettitle->{'itemtype'} ); # using the fixed up itype/itemtype + $getreserv{'waitingdate'} = $num->{'waitingdate'}; my ( $waiting_year, $waiting_month, $waiting_day ) = split (/-/, $num->{'waitingdate'}); ( $waiting_year, $waiting_month, $waiting_day ) = diff --git a/installer/data/mysql/atomicupdate/bug_13881-add_desk_management.sql b/installer/data/mysql/atomicupdate/bug_13881-add_desk_management.sql new file mode 100644 index 0000000..8488558 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_13881-add_desk_management.sql @@ -0,0 +1,12 @@ +DROP TABLE IF EXISTS desks; +CREATE TABLE desks ( + deskcode varchar(10) NOT NULL, -- desk id + branchcode varchar(10) NOT NULL, -- branch id the desk is attached to + deskname varchar(80) NOT NULL, -- name used for OPAC or intranet printing + deskdescription varchar(300) NOT NULL, -- longer description of the desk + PRIMARY KEY (deskcode), + FOREIGN KEY (branchcode) + REFERENCES branches(branchcode) + ON DELETE CASCADE + ON UPDATE CASCADE +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/installer/data/mysql/atomicupdate/bug_13881_link_desk_to_reserves.sql b/installer/data/mysql/atomicupdate/bug_13881_link_desk_to_reserves.sql new file mode 100644 index 0000000..3d7499b --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_13881_link_desk_to_reserves.sql @@ -0,0 +1,8 @@ +ALTER TABLE reserves ADD COLUMN deskcode VARCHAR(10) DEFAULT NULL AFTER branchcode, + ADD KEY deskcode (deskcode), + ADD FOREIGN KEY (deskcode) REFERENCES desks (deskcode) + ON DELETE SET NULL ON UPDATE SET NULL; +ALTER TABLE old_reserves ADD COLUMN deskcode VARCHAR(10) DEFAULT NULL AFTER branchcode, + ADD KEY deskcode (deskcode), + ADD FOREIGN KEY (deskcode) REFERENCES desks (deskcode) + ON DELETE SET NULL ON UPDATE SET NULL; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 2409bc2..1204081 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -455,7 +455,6 @@ CREATE TABLE `branchtransfers` ( -- information for items that are in transit be CONSTRAINT `branchtransfers_ibfk_3` FOREIGN KEY (`itemnumber`) REFERENCES `items` (`itemnumber`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; - -- -- Table structure for table `browser` -- @@ -960,6 +959,21 @@ CREATE TABLE `deleteditems` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- +-- Table structure for table `desks` +-- + +DROP TABLE IF EXISTS `desks`; +CREATE TABLE `desks` ( + `deskcode` varchar(10) NOT NULL, -- desk id + `branchcode` varchar(10) NOT NULL, -- branch id the desk is attached to + `deskname` varchar(80) NOT NULL, -- name used for OPAC or intranet printing + `deskdescription` varchar(300) NOT NULL, -- longer description of the desk + PRIMARY KEY (`deskcode`), + KEY `fk_desks_branchcode` (`branchcode`), + CONSTRAINT `fk_desks_branchcode` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +-- -- Table structure for table `ethnicity` -- @@ -1654,6 +1668,7 @@ CREATE TABLE `old_reserves` ( -- this table holds all holds/reserves that have b `biblionumber` int(11) default NULL, -- foreign key from the biblio table defining which bib record this hold is on `constrainttype` varchar(1) default NULL, `branchcode` varchar(10) default NULL, -- foreign key from the branches table defining which branch the patron wishes to pick this hold up at + `deskcode` varchar(10) default NULL, -- foreign key from the desks table defining which desk the patron may pick this hold up from `notificationdate` date default NULL, -- currently unused `reminderdate` date default NULL, -- currently unused `cancellationdate` date default NULL, -- the date this hold was cancelled @@ -1672,12 +1687,14 @@ CREATE TABLE `old_reserves` ( -- this table holds all holds/reserves that have b KEY `old_reserves_biblionumber` (`biblionumber`), KEY `old_reserves_itemnumber` (`itemnumber`), KEY `old_reserves_branchcode` (`branchcode`), + KEY `old_reserves_deskcode` (`deskcode`), CONSTRAINT `old_reserves_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE SET NULL, CONSTRAINT `old_reserves_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE SET NULL ON UPDATE SET NULL, CONSTRAINT `old_reserves_ibfk_3` FOREIGN KEY (`itemnumber`) REFERENCES `items` (`itemnumber`) - ON DELETE SET NULL ON UPDATE SET NULL + ON DELETE SET NULL ON UPDATE SET NULL, + CONSTRAINT `old_reserves_ibfk_4` FOREIGN KEY (`deskcode`) REFERENCES `desks` (`deskcode`) ON DELETE SET NULL ON UPDATE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- @@ -1841,6 +1858,7 @@ CREATE TABLE `reserves` ( -- information related to holds/reserves in Koha `biblionumber` int(11) NOT NULL default 0, -- foreign key from the biblio table defining which bib record this hold is on `constrainttype` varchar(1) default NULL, `branchcode` varchar(10) default NULL, -- foreign key from the branches table defining which branch the patron wishes to pick this hold up at + `deskcode` varchar(10) default NULL, -- foreign key from the desks table defining which desk the patron may pick this hold up from `notificationdate` date default NULL, -- currently unused `reminderdate` date default NULL, -- currently unused `cancellationdate` date default NULL, -- the date this hold was cancelled @@ -1860,10 +1878,12 @@ CREATE TABLE `reserves` ( -- information related to holds/reserves in Koha KEY `biblionumber` (`biblionumber`), KEY `itemnumber` (`itemnumber`), KEY `branchcode` (`branchcode`), + KEY `deskcode` (`deskcode`), CONSTRAINT `reserves_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `reserves_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `reserves_ibfk_3` FOREIGN KEY (`itemnumber`) REFERENCES `items` (`itemnumber`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `reserves_ibfk_4` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE + CONSTRAINT `reserves_ibfk_4` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `reserves_ibfk_5` FOREIGN KEY (`deskcode`) REFERENCES `desks` (`deskcode`) ON DELETE SET NULL ON UPDATE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc index e4caee8..66e4be7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc @@ -44,6 +44,18 @@ [% IF ( loggedinusername ) %] [% loggedinusername %] + [% IF ( LoginDeskcode ) %] + | + + [% LoginDeskname %] + [% LoginDeskcode %] + + [% ELSIF (HasDesk) %] + | + + NO DESK SET + + [% END %] | [% IF ( AutoLocation ) %] @@ -73,6 +85,9 @@ Set library [% END %] +
  • + Set desk +
  • [% IF EnableSearchHistory %]
  • Search history diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt index c85aa8e..eb56517 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt @@ -32,6 +32,8 @@
    Libraries and groups
    Define libraries and groups.
    +
    Desks
    +
    Define Desks.
    Item types
    Define item types used for circulation rules.
    Authorized values
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/desks.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/desks.tt new file mode 100644 index 0000000..ee8aa30 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/desks.tt @@ -0,0 +1,221 @@ +[% USE AuthorisedValues %] +[% USE Branches %] +[% INCLUDE 'doc-head-open.inc' %] +Koha › Administration › Desks [% IF ( add_form ) %]› + [% IF ( deskcode ) %] +Modify desk '[% deskcode %]' + [% ELSE %] +Add desk + [% END %] +[% END %] +[% IF ( delete_confirm ) %]› + Delete desk '[% deskcode %]'? +[% END %] +[% IF ( delete_confirmed ) %]› +Desk deleted +[% END %] + +[% INCLUDE 'doc-head-close.inc' %] + +[% INCLUDE 'datatables.inc' %] + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + + + +
    +
    +
    +
    + [% IF ( error ) %]$ +
    + [% IF ( CANT_ADD ) %] +

    Adding Desk [% deskcode %] failed

    + [% END %] + [% IF ( ALREADY_EXISTS ) %] +

    Adding Desk [% deskcode %] failed, it already exists

    + [% END %] + [% IF ( CANT_MODIFY ) %] +

    Modifying Desk [% deskcode %] failed

    + [% IF ( CANT_DELETE ) %] +

    Deleting Desk [% deskcode %] failed

    + [% END %] + [% END %] +
    +[% END %] +[% IF ( else ) %] + +[% END %] + + +[% IF ( add_form ) %] + [% IF ( deskcode ) %] +

    Modify desk

    + [% ELSE %] +

    Add desk

    + [% END %] +
    + + +
    +
      + [% IF ( desk.deskcode ) %] +
    1. + Desk code: + + [% desk.deskcode %] +
    2. + [% ELSE %] +
    3. + + + Required +
    4. + [% END %] +
    5. + + + Required +
    6. +
    7. + + + Required
    8. +
    9. + + +
    10. +
    +
    +
    + + Cancel +
    +
    +
    +[% END %] + + +[% IF ( delete_confirm ) %] +
    +

    Delete Desk '[% desk.deskcode %]'?

    +
    + + + + + + + + + +
    Desk[% desk.deskcode %]
    Name[% desk.deskname %]
    Description[% desk.deskdescription %]
    Branch[% desk.branchcode %]
    + +
    +
    + +
    +
    +[% END %] + + +[% IF ( else ) %] +

    Desks administration

    + [% IF ( deskloop ) %] + + + + + + + + + [% FOREACH deskloo IN deskloop %] + + + + + + + + [% END %] +
    Desk codeNameDescriptionBranchcodeAction
    + + [% deskloo.deskcode %] + + [% deskloo.deskname %][% deskloo.deskdescription %][% deskloo.branchcode %] + Edit + Delete +
    + [% ELSE %] +
    There are no desk defined
    + [% END %] +
    [% pagination_bar %]
    +[% END %] +
    +
    +
    +[% INCLUDE 'admin-menu.inc' %] +
    +
    +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/selectdesk.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/selectdesk.tt new file mode 100644 index 0000000..f49c68c --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/selectdesk.tt @@ -0,0 +1,50 @@ +[% INCLUDE 'doc-head-open.inc' %] +Koha › Circulation › Set library +[% INCLUDE 'doc-head-close.inc' %] + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'circ-search.inc' %] + + + +
    +
    +
    +
    +
    +
    + Set desk +
      +
    1. + +
    2. +
    +
    +
    + + Cancel +
    +
    + +
    +
    +
    +
    +
    +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt index 1d5faf4..31294ec 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt @@ -82,6 +82,9 @@ Title Patron Location + [% IF HasDesk %] + Desk + [% END %] Copy number Enumeration Action @@ -101,6 +104,9 @@ [% reserveloo.borrowermail %][% END %] [% Branches.GetName( reserveloo.homebranch ) %]
    [% reserveloo.itemcallnumber %] + [% IF HasDesk %] + [% reserveloo.deskname %] + [% END %] [% reserveloo.copynumber %] [% reserveloo.enumchron %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt index b5bc8d2..2e3e89f 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt @@ -566,7 +566,7 @@ [% IF ( RESERVE.wait ) %] [% IF ( RESERVE.atdestination ) %] [% IF ( RESERVE.found ) %] - Item waiting at [% RESERVE.wbrname %][% IF ( RESERVE.waitingdate ) %] since [% RESERVE.waitingdate | $KohaDates %][% END %] + Item waiting at [% RESERVE.wbrname %][% IF (RESERVE.wdkname) %], [% RESERVE.wdkname %][% END %][% IF ( RESERVE.waitingdate ) %], since [% RESERVE.waitingdate | $KohaDates %][% END %] [% ELSE %] Item waiting to be pulled from [% RESERVE.wbrname %] diff --git a/opac/opac-user.pl b/opac/opac-user.pl index d4fbbe3..35367e9 100755 --- a/opac/opac-user.pl +++ b/opac/opac-user.pl @@ -34,6 +34,7 @@ use C4::Biblio; use C4::Items; use C4::Letters; use C4::Branch; # GetBranches +use C4::Desks; use Koha::DateUtils; use Koha::Borrower::Debarments qw(IsDebarred); @@ -324,6 +325,12 @@ foreach my $res (@reserves) { $res->{'wbrcode'} = $res->{'branchcode'}; $res->{'itemnumber'} = $res->{'itemnumber'}; $res->{'wbrname'} = $branches->{$res->{'branchcode'}}->{'branchname'}; + if ($res->{'deskcode'}) { + my $desk = GetDesk($res->{'deskcode'}); + if ($desk) { + $res->{'wdkname'} = $desk->{'deskname'}; + } + } if($res->{'holdingbranch'} eq $res->{'wbrcode'}){ $res->{'atdestination'} = 1; } diff --git a/t/db_dependent/Desks.t b/t/db_dependent/Desks.t new file mode 100644 index 0000000..644fc0b --- /dev/null +++ b/t/db_dependent/Desks.t @@ -0,0 +1,70 @@ +#!/usr/bin/perl +# +# Copyright (C) 2015 BULAC +# +# 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 . + +use Modern::Perl; + +use Test::More tests => 17; + +BEGIN { + use_ok('C4::Branch'); + use_ok('C4::Desks'); +} + +my $deskcode = 'MON BUREAU'; +my $deskname = 'mon bureau'; +my $deskdescription = "Le beau bureau ici."; +my $branchcode = shift [keys GetBranches]; + +my $hrdesk = { + 'deskcode' => $deskcode, + 'deskname' => $deskname, + 'deskdescription' => $deskdescription, + 'branchcode' => $branchcode + }; + +ok(AddDesk($hrdesk) == 1, 'AddDesk creates desk.'); +ok(! defined AddDesk($hrdesk) + , 'AddDesk returns undef when desk already exists'); + +my $desk = GetDesk($deskcode); +ok (ref($desk) eq 'HASH', 'GetDesk returns hashref.'); +ok($desk->{'deskcode'} eq $deskcode, 'GetDesk returns desk code'); +ok($desk->{'deskname'} eq $deskname, 'GetDesk returns desk name'); +ok($desk->{'deskdescription'} eq $deskdescription, 'GetDesk returns desk description'); +ok($desk->{'branchcode'} eq $branchcode, 'GetDesk returns branchcode'); +ok(! defined GetDesk('this desk surely not exists'), + "GetDesk returns undef when desk doesn't exist"); + +my $modifieddesk = { + 'deskcode' => $deskcode, + 'deskname' => 'mon joli bureau', + 'deskdescription' => "Celui dans l'entrée", + 'branchcode' => $branchcode + }; +ok(ModDesk($modifieddesk) == 1, 'ModDesk modifies Desk'); +$modifieddesk->{'deskcode'} = 'this desk surely not exists'; +ok(ModDesk($modifieddesk) == 0, 'ModDesk returns 0 when deskcode is wrong'); + +my $desks = GetDesks(); +ok(ref($desks) eq 'ARRAY', 'GetDesks returns an array'); +ok(grep($deskcode, @$desks), 'GetDesks returns desk codes'); +my $emptydesksset = GetDesks("this branch sureley doesn't exist"); +ok(! @$emptydesksset , 'GetDesks returns [] when no desks are found'); + +ok(DelDesk($deskcode) == 1, 'DelDesk returns 1 when successfuly deleting desk'); +ok(DelDesk('this desk surely not exists'), + "DelDesk returns 0 when no desk were deleted"); -- 2.1.4