From 03058827a4a5d8c27137c43aaf20078d1c26fcfc Mon Sep 17 00:00:00 2001 From: Chris Hall Date: Mon, 20 Feb 2012 10:07:13 +1300 Subject: [PATCH] Bug 6739 - expired patrons not blocked from opac actions Test Plan: 1) Apply patch 2) Run updatedatabase.pl 3) Pick a patron, note the patron's category 5) Issue an item to this patron 4) Edit that category, set "Block expired patrons" to "Block" 5) Verify the patron cannot renew or place holds in the opac 6) Edit the category again, set "Block expired patrons" to "Don't block" 7) Verify the patron *can* renew and place holds in the opac 8) Edit the category again, set "Block expired patrons" to "Follow system preference BlockExpiredPatronOpacActions" 9) Set the system preference BlockExpiredPatronOpacActions to "Block" 10) Verify the patron cannot renew or place holds in the opac 11) Set the system preference BlockExpiredPatronOpacActions to "Don't block" 12) Verify the patron *can* renew and place holds in the opac Signed-off-by: Kyle M Hall --- C4/Members.pm | 24 ++- admin/categorie.pl | 323 +++++++++++++------- installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/sysprefs.sql | 1 + installer/data/mysql/updatedatabase.pl | 17 + .../prog/en/modules/admin/categorie.tt | 8 + .../prog/en/modules/admin/preferences/opac.pref | 7 + .../prog/en/modules/admin/preferences/patrons.pref | 2 +- .../opac-tmpl/prog/en/modules/opac-reserve.tt | 3 + koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt | 11 + opac/opac-renew.pl | 78 +++--- opac/opac-reserve.pl | 11 + opac/opac-user.pl | 149 +++++----- 13 files changed, 406 insertions(+), 229 deletions(-) diff --git a/C4/Members.pm b/C4/Members.pm index 8042840..7dfb13b 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -325,11 +325,31 @@ sub GetMemberDetails { my $query; my $sth; if ($borrowernumber) { - $sth = $dbh->prepare("SELECT borrowers.*,category_type,categories.description,reservefee,enrolmentperiod FROM borrowers LEFT JOIN categories ON borrowers.categorycode=categories.categorycode WHERE borrowernumber=?"); + $sth = $dbh->prepare(" + SELECT borrowers.*, + category_type, + categories.description, + categories.BlockExpiredPatronOpacActions, + reservefee, + enrolmentperiod + FROM borrowers + LEFT JOIN categories ON borrowers.categorycode=categories.categorycode + WHERE borrowernumber = ? + "); $sth->execute($borrowernumber); } elsif ($cardnumber) { - $sth = $dbh->prepare("SELECT borrowers.*,category_type,categories.description,reservefee,enrolmentperiod FROM borrowers LEFT JOIN categories ON borrowers.categorycode=categories.categorycode WHERE cardnumber=?"); + $sth = $dbh->prepare(" + SELECT borrowers.*, + category_type, + categories.description, + categories.BlockExpiredPatronOpacActions, + reservefee, + enrolmentperiod + FROM borrowers + LEFT JOIN categories ON borrowers.categorycode = categories.categorycode + WHERE cardnumber = ? + "); $sth->execute($cardnumber); } else { diff --git a/admin/categorie.pl b/admin/categorie.pl index 952ef7a..2a006b3 100755 --- a/admin/categorie.pl +++ b/admin/categorie.pl @@ -46,42 +46,47 @@ use C4::Output; use C4::Dates; use C4::Form::MessagingPreferences; -sub StringSearch { - my ($searchstring,$type)=@_; - my $dbh = C4::Context->dbh; - $searchstring=~ s/\'/\\\'/g; - my @data=split(' ',$searchstring); - my $count=@data; - my $sth=$dbh->prepare("Select * from categories where (description like ?) order by category_type,description,categorycode"); - $sth->execute("$data[0]%"); - my @results; - while (my $data=$sth->fetchrow_hashref){ - push(@results,$data); - } - # $sth->execute; - $sth->finish; - return (scalar(@results),\@results); -} +sub StringSearch { + my ( $searchstring, $type ) = @_; + my $dbh = C4::Context->dbh; + $searchstring =~ s/\'/\\\'/g; + my @data = split( ' ', $searchstring ); + my $count = @data; + my $sth = $dbh->prepare("SELECT * FROM categories WHERE (description LIKE ?) ORDER BY category_type, description, categorycode"); + $sth->execute("$data[0]%"); + my @results; -my $input = new CGI; -my $searchfield=$input->param('description'); -my $script_name="/cgi-bin/koha/admin/categorie.pl"; -my $categorycode=$input->param('categorycode'); -my $op = $input->param('op'); + while ( my $data = $sth->fetchrow_hashref ) { + push( @results, $data ); + } -my ($template, $loggedinuser, $cookie) - = get_template_and_user({template_name => "admin/categorie.tmpl", - query => $input, - type => "intranet", - authnotrequired => 0, - flagsrequired => {parameters => 'parameters_remaining_permissions'}, - debug => 1, - }); + # $sth->execute; + $sth->finish; + return ( scalar(@results), \@results ); +} +my $input = new CGI; +my $searchfield = $input->param('description'); +my $script_name = "/cgi-bin/koha/admin/categorie.pl"; +my $categorycode = $input->param('categorycode'); +my $op = $input->param('op'); +my $block_expired = $input->param("block_expired"); -$template->param(script_name => $script_name, - categorycode => $categorycode, - searchfield => $searchfield); +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { template_name => "admin/categorie.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => { parameters => 'parameters_remaining_permissions' }, + debug => 1, + } +); + +$template->param( + script_name => $script_name, + categorycode => $categorycode, + searchfield => $searchfield +); ################## ADD_FORM ################################## @@ -94,10 +99,13 @@ if ($op eq 'add_form') { my @selected_branches; if ($categorycode) { my $dbh = C4::Context->dbh; - my $sth=$dbh->prepare("select categorycode,description,enrolmentperiod,enrolmentperioddate,upperagelimit,dateofbirthrequired,enrolmentfee,issuelimit,reservefee,hidelostitems,overduenoticerequired,category_type from categories where categorycode=?"); + my $sth=$dbh->prepare(" + SELECT * + FROM categories + WHERE categorycode = ? + "); $sth->execute($categorycode); - $data=$sth->fetchrow_hashref; - + $data = $sth->fetchrow_hashref; $sth = $dbh->prepare("SELECT b.branchcode, b.branchname FROM categories_branches AS cb, branches AS b WHERE cb.branchcode = b.branchcode AND cb.categorycode = ?"); $sth->execute( $categorycode ); while ( my $branch = $sth->fetchrow_hashref ) { @@ -119,22 +127,26 @@ if ($op eq 'add_form') { }; } - $template->param(description => $data->{'description'}, - enrolmentperiod => $data->{'enrolmentperiod'}, - enrolmentperioddate => C4::Dates::format_date($data->{'enrolmentperioddate'}), - upperagelimit => $data->{'upperagelimit'}, - dateofbirthrequired => $data->{'dateofbirthrequired'}, - enrolmentfee => sprintf("%.2f",$data->{'enrolmentfee'}), - overduenoticerequired => $data->{'overduenoticerequired'}, - issuelimit => $data->{'issuelimit'}, - reservefee => sprintf("%.2f",$data->{'reservefee'}), - hidelostitems => $data->{'hidelostitems'}, - category_type => $data->{'category_type'}, - SMSSendDriver => C4::Context->preference("SMSSendDriver"), - TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"), - "type_".$data->{'category_type'} => 1, - branches_loop => \@branches_loop, - ); + $template->param( + description => $data->{'description'}, + enrolmentperiod => $data->{'enrolmentperiod'}, + enrolmentperioddate => C4::Dates::format_date( $data->{'enrolmentperioddate'} ), + upperagelimit => $data->{'upperagelimit'}, + dateofbirthrequired => $data->{'dateofbirthrequired'}, + enrolmentfee => sprintf( "%.2f", $data->{'enrolmentfee'} ), + overduenoticerequired => $data->{'overduenoticerequired'}, + issuelimit => $data->{'issuelimit'}, + reservefee => sprintf( "%.2f", $data->{'reservefee'} ), + hidelostitems => $data->{'hidelostitems'}, + category_type => $data->{'category_type'}, + SMSSendDriver => C4::Context->preference("SMSSendDriver"), + TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"), + branches_loop => \@branches_loop, + SMSSendDriver => C4::Context->preference("SMSSendDriver"), + BlockExpiredPatronOpacActions => $data->{'BlockExpiredPatronOpacActions'}, + "type_" . $data->{'category_type'} => 1, + ); + if (C4::Context->preference('EnhancedMessagingPreferences')) { C4::Form::MessagingPreferences::set_form_values({ categorycode => $categorycode } , $template); } @@ -148,19 +160,47 @@ if ($op eq 'add_form') { if($input->param('enrolmentperioddate')){ $input->param('enrolmentperioddate' => C4::Dates::format_date_in_iso($input->param('enrolmentperioddate')) ); } - + if ($is_a_modif) { - my $sth=$dbh->prepare("UPDATE categories SET description=?,enrolmentperiod=?, enrolmentperioddate=?,upperagelimit=?,dateofbirthrequired=?,enrolmentfee=?,reservefee=?,hidelostitems=?,overduenoticerequired=?,category_type=? WHERE categorycode=?"); - $sth->execute(map { $input->param($_) } ('description','enrolmentperiod','enrolmentperioddate','upperagelimit','dateofbirthrequired','enrolmentfee','reservefee','hidelostitems','overduenoticerequired','category_type','categorycode')); + my $sth=$dbh->prepare(" + UPDATE categories + SET description=?, + enrolmentperiod=?, + enrolmentperioddate=?, + upperagelimit=?, + dateofbirthrequired=?, + enrolmentfee=?, + reservefee=?, + hidelostitems=?, + overduenoticerequired=?, + category_type=?, + BlockExpiredPatronOpacActions=? + WHERE categorycode=?" + ); + $sth->execute( + map { $input->param($_) } ( + 'description', + 'enrolmentperiod', + 'enrolmentperioddate', + 'upperagelimit', + 'dateofbirthrequired', + 'enrolmentfee', + 'reservefee', + 'hidelostitems', + 'overduenoticerequired', + 'category_type', + 'block_expired', + 'categorycode' + ) + ); my @branches = $input->param("branches"); if ( @branches ) { $sth = $dbh->prepare("DELETE FROM categories_branches WHERE categorycode = ?"); $sth->execute( $input->param( "categorycode" ) ); - $sth = $dbh->prepare( - "INSERT INTO categories_branches - ( categorycode, branchcode ) - VALUES ( ?, ? )" - ); + $sth = $dbh->prepare(" + INSERT INTO categories_branches ( categorycode, branchcode ) + VALUES ( ?, ? ) + "); for my $branchcode ( @branches ) { next if not $branchcode; $sth->bind_param( 1, $input->param( "categorycode" ) ); @@ -169,32 +209,65 @@ if ($op eq 'add_form') { } } $sth->finish; - } else { - my $sth=$dbh->prepare("INSERT INTO categories (categorycode,description,enrolmentperiod,enrolmentperioddate,upperagelimit,dateofbirthrequired,enrolmentfee,reservefee,hidelostitems,overduenoticerequired,category_type) values (?,?,?,?,?,?,?,?,?,?,?)"); - $sth->execute(map { $input->param($_) } ('categorycode','description','enrolmentperiod','enrolmentperioddate','upperagelimit','dateofbirthrequired','enrolmentfee','reservefee','hidelostitems','overduenoticerequired','category_type')); - $sth->finish; - } - if (C4::Context->preference('EnhancedMessagingPreferences')) { - C4::Form::MessagingPreferences::handle_form_action($input, - { categorycode => $input->param('categorycode') }, $template); + } else { + my $sth=$dbh->prepare(" + INSERT INTO categories ( + categorycode, + description, + enrolmentperiod, + enrolmentperioddate, + upperagelimit, + dateofbirthrequired, + enrolmentfee, + reservefee, + hidelostitems, + overduenoticerequired, + category_type, + BlockExpiredPatronOpacActions + ) + VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"); + $sth->execute( + map { $input->param($_) } ( + 'categorycode', + 'description', + 'enrolmentperiod', + 'enrolmentperioddate', + 'upperagelimit', + 'dateofbirthrequired', + 'enrolmentfee', + 'reservefee', + 'hidelostitems', + 'overduenoticerequired', + 'category_type', + 'block_expired' + ) + ); + $sth->finish; + } + if ( C4::Context->preference('EnhancedMessagingPreferences') ) { + C4::Form::MessagingPreferences::handle_form_action( $input, { categorycode => $input->param('categorycode') }, $template ); } print "Content-Type: text/html\n\n"; exit; - # END $OP eq ADD_VALIDATE +# END $OP eq ADD_VALIDATE ################## DELETE_CONFIRM ################################## # called by default form, used to confirm deletion of data in DB } elsif ($op eq 'delete_confirm') { $template->param(delete_confirm => 1); my $dbh = C4::Context->dbh; - my $sth=$dbh->prepare("select count(*) as total from borrowers where categorycode=?"); + my $sth=$dbh->prepare("SELECT count(*) AS total FROM borrowers WHERE categorycode = ?"); $sth->execute($categorycode); my $total = $sth->fetchrow_hashref; $sth->finish; $template->param(total => $total->{'total'}); - - my $sth2=$dbh->prepare("select categorycode,description,enrolmentperiod,enrolmentperioddate,upperagelimit,dateofbirthrequired,enrolmentfee,issuelimit,reservefee,hidelostitems,overduenoticerequired,category_type from categories where categorycode=?"); + + my $sth2 = $dbh->prepare(" + SELECT * + FROM categories + WHERE categorycode = ? + "); $sth2->execute($categorycode); my $data=$sth2->fetchrow_hashref; $sth2->finish; @@ -202,18 +275,20 @@ if ($op eq 'add_form') { $template->param(totalgtzero => 1); } - $template->param( description => $data->{'description'}, - enrolmentperiod => $data->{'enrolmentperiod'}, - enrolmentperioddate => C4::Dates::format_date($data->{'enrolmentperioddate'}), - upperagelimit => $data->{'upperagelimit'}, - dateofbirthrequired => $data->{'dateofbirthrequired'}, - enrolmentfee => sprintf("%.2f",$data->{'enrolmentfee'}), - overduenoticerequired => $data->{'overduenoticerequired'}, - issuelimit => $data->{'issuelimit'}, - reservefee => sprintf("%.2f",$data->{'reservefee'}), - hidelostitems => $data->{'hidelostitems'}, - category_type => $data->{'category_type'}, - ); + $template->param( + description => $data->{'description'}, + enrolmentperiod => $data->{'enrolmentperiod'}, + enrolmentperioddate => C4::Dates::format_date( $data->{'enrolmentperioddate'} ), + upperagelimit => $data->{'upperagelimit'}, + dateofbirthrequired => $data->{'dateofbirthrequired'}, + enrolmentfee => sprintf( "%.2f", $data->{'enrolmentfee'} ), + overduenoticerequired => $data->{'overduenoticerequired'}, + issuelimit => $data->{'issuelimit'}, + reservefee => sprintf( "%.2f", $data->{'reservefee'} ), + hidelostitems => $data->{'hidelostitems'}, + category_type => $data->{'category_type'}, + BlockExpiredPatronOpacActions => $data->{'BlockExpiredPatronOpacActions'}, + ); # END $OP eq DELETE_CONFIRM ################## DELETE_CONFIRMED ################################## # called by delete_confirm, used to effectively confirm deletion of data in DB @@ -229,51 +304,67 @@ if ($op eq 'add_form') { # END $OP eq DELETE_CONFIRMED } else { # DEFAULT - $template->param(else => 1); - my @loop; - my ($count,$results)=StringSearch($searchfield,'web'); + $template->param(else => 1); + my @loop; + my ($count,$results) = StringSearch($searchfield,'web'); + my $dbh = C4::Context->dbh; - my $sth = $dbh->prepare("SELECT b.branchcode, b.branchname FROM categories_branches AS cb, branches AS b WHERE cb.branchcode = b.branchcode AND cb.categorycode = ?"); - for (my $i=0; $i < $count; $i++){ + my $sth = $dbh->prepare(" + SELECT b.branchcode, + b.branchname + FROM categories_branches AS cb, + branches AS b + WHERE cb.branchcode = b.branchcode + AND cb.categorycode = ? + "); + + for (my $i=0; $i < $count; $i++){ $sth->execute( $results->[$i]{'categorycode'} ); + my @selected_branches; while ( my $branch = $sth->fetchrow_hashref ) { push @selected_branches, $branch; } - my %row = ( - categorycode => $results->[$i]{'categorycode'}, - description => $results->[$i]{'description'}, - enrolmentperiod => $results->[$i]{'enrolmentperiod'}, - enrolmentperioddate => C4::Dates::format_date($results->[$i]{'enrolmentperioddate'}), - upperagelimit => $results->[$i]{'upperagelimit'}, - dateofbirthrequired => $results->[$i]{'dateofbirthrequired'}, - enrolmentfee => sprintf("%.2f",$results->[$i]{'enrolmentfee'}), - overduenoticerequired => $results->[$i]{'overduenoticerequired'}, - issuelimit => $results->[$i]{'issuelimit'}, - reservefee => sprintf("%.2f",$results->[$i]{'reservefee'}), - hidelostitems => $results->[$i]{'hidelostitems'}, - category_type => $results->[$i]{'category_type'}, - "type_".$results->[$i]{'category_type'} => 1, - branches => \@selected_branches, + + my %row = ( + categorycode => $results->[$i]{'categorycode'}, + description => $results->[$i]{'description'}, + enrolmentperiod => $results->[$i]{'enrolmentperiod'}, + enrolmentperioddate => C4::Dates::format_date($results->[$i]{'enrolmentperioddate'}), + upperagelimit => $results->[$i]{'upperagelimit'}, + dateofbirthrequired => $results->[$i]{'dateofbirthrequired'}, + enrolmentfee => sprintf("%.2f",$results->[$i]{'enrolmentfee'}), + overduenoticerequired => $results->[$i]{'overduenoticerequired'}, + issuelimit => $results->[$i]{'issuelimit'}, + reservefee => sprintf("%.2f",$results->[$i]{'reservefee'}), + hidelostitems => $results->[$i]{'hidelostitems'}, + category_type => $results->[$i]{'category_type'}, + block_syspref => 1, + branches => \@selected_branches, + "type_".$results->[$i]{'category_type'} => 1, ); + if (C4::Context->preference('EnhancedMessagingPreferences')) { my $brief_prefs = _get_brief_messaging_prefs($results->[$i]{'categorycode'}); $row{messaging_prefs} = $brief_prefs if @$brief_prefs; } - push @loop, \%row; - } - $template->param(loop => \@loop); - # check that I (institution) and C (child) exists. otherwise => warning to the user - $sth=$dbh->prepare("select category_type from categories where category_type='C'"); - $sth->execute; - my ($categoryChild) = $sth->fetchrow; - $template->param(categoryChild => $categoryChild); - $sth=$dbh->prepare("select category_type from categories where category_type='I'"); - $sth->execute; - my ($categoryInstitution) = $sth->fetchrow; - $template->param(categoryInstitution => $categoryInstitution); - $sth->finish; + + push @loop, \%row; + } + + $template->param(loop => \@loop); + # check that I (institution) and C (child) exists. otherwise => warning to the user + + $sth = $dbh->prepare("select category_type from categories where category_type='C'"); + $sth->execute; + my ($categoryChild) = $sth->fetchrow; + $template->param(categoryChild => $categoryChild); + $sth = $dbh->prepare("select category_type from categories where category_type='I'"); + $sth->execute; + my ($categoryInstitution) = $sth->fetchrow; + $template->param(categoryInstitution => $categoryInstitution); + $sth->finish; } #---- END $OP eq DEFAULT output_html_with_http_headers $input, $cookie, $template->output; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index d004fe1..3ed7066 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -438,6 +438,7 @@ CREATE TABLE `categories` ( -- this table shows information related to Koha patr `reservefee` decimal(28,6) default NULL, -- cost to place holds `hidelostitems` tinyint(1) NOT NULL default '0', -- are lost items shown to this category (1 for yes, 0 for no) `category_type` varchar(1) NOT NULL default 'A', -- type of Koha patron (Adult, Child, Professional, Organizational, Statistical, Staff) + `BlockExpiredPatronOpacActions` tinyint(1) NOT NULL default '-1', -- wheither or not a patron of this categori can renew books or place holds once their card has expired. 0 means they can, 1 means they cannot, -1 means use syspref BLockExpiredPAtronOpacACtions PRIMARY KEY (`categorycode`), UNIQUE KEY `categorycode` (`categorycode`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index cad409c..2825d8b 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -418,3 +418,4 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES(' INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('Persona',0,'Use Mozilla Persona for login','','YesNo'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacItemLocation','callnum','Show the shelving location of items in the opac','callnum|ccode|location','Choice'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('TrackClicks','0','Track links clicked',NULL,'Integer'); +INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('BlockExpiredPatronOpacActions', 'yes', 'Set whether an expired patron can perform opac actions such as placing a hold or reserve, can be overridden on a per patron-type basis',NULL,'YesNo'); diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 041040a..39f321b 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -6476,6 +6476,23 @@ if ( CheckVersion($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.11.00.XXX"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do(" + INSERT INTO systempreferences (variable,value,explanation,options,type) + VALUES ( + 'BlockExpiredPatronOpacActions', + 'yes', + 'Set whether an expired patron can perform opac actions such as placing a hold or reserve, can be overridden on a per patron-type basis', + NULL, + 'YesNo' + ) + "); + $dbh->do("ALTER TABLE `categories` ADD COLUMN `BlockExpiredPatronOpacActions` TINYINT(1) DEFAULT 0 NOT NULL"); + print "Upgraded to $DBversion done (Bug 6739 - expired patrons not blocked from opac actions)\n"; + SetVersion ($DBversion); +} +=head1 FUNCTIONS =head1 FUNCTIONS diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categorie.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categorie.tt index e7e00d4..81e16ff 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categorie.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categorie.tt @@ -198,6 +198,14 @@ Select All if this category type must to be displayed all the time. Otherwise select librairies you want to associate with this value. +
  • + + Should patrons of this category be blocked from opac actions such as renew and reserve when their cards have expired. +
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref index 57df512..dc5c4a6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -493,6 +493,13 @@ OPAC: yes: Allow - opac users to share private lists with other patrons. This feature is not active yet but will be released soon + - + - pref: BlockExpiredPatronOpacActions + choices: + yes: "Block" + no: "Don't Block" + - expired patrons from opac actions such as placing a hold or renew, the setting for a patron category takes priority over this + Privacy: - - pref: AnonSuggestions diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref index 74d14af..fbd801a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref @@ -91,7 +91,7 @@ Patrons: class: integer - characters long. - - - Show a notice that a patron is about to expire + - Show a notice if the patron is about to expire or has expired - pref: NotifyBorrowerDeparture class: integer - days beforehand. diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt index 5788b38..55abab1 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt @@ -210,6 +210,9 @@ [% IF ( bad_data ) %]
    ERROR: Internal error: incomplete hold request.
    [% END %] + [% IF ( expired_patron ) %] +

    Sorry, you cannot place holds because your library card has expired.

    Please contact your librarian if you wish to renew your card

    + [% END %] [% ELSE %] [% IF ( none_available ) %]
    Sorry, none of these items can be placed on hold. diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt index 96f6e8d..7d0f003 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt @@ -96,8 +96,19 @@ $.tablesorter.addParser({
    Please note: Your card has expired. Please contact the library for more information.
    + [% ELSIF ( BORROWER_INF.warnexpired ) %] +
    + Please note: You card has expired as of [% BORROWER_INF.warnexpired %]. Please contact the library if you wish to renew your subscription. +
    [% END %] + [% IF ( RENEW_ERROR ) %] +
    + Please note: You're renew failed with the following error: [% RENEW_ERROR %] +
    + [% END %] + + [% IF ( patron_flagged ) %]
      diff --git a/opac/opac-renew.pl b/opac/opac-renew.pl index c699b35..39d7c03 100755 --- a/opac/opac-renew.pl +++ b/opac/opac-renew.pl @@ -29,50 +29,58 @@ use C4::Circulation; use C4::Auth; use C4::Items; use C4::Members; +use Date::Calc qw( Today Date_to_Days ); my $query = new CGI; my ( $template, $borrowernumber, $cookie ) = get_template_and_user( - { - template_name => "opac-user.tmpl", - query => $query, - type => "opac", - authnotrequired => 0, - flagsrequired => { borrow => 1 }, - debug => 1, - } + { + template_name => "opac-user.tmpl", + query => $query, + type => "opac", + authnotrequired => 0, + flagsrequired => { borrow => 1 }, + debug => 1, + } ); my @items = $query->param('item'); my $opacrenew = C4::Context->preference("OpacRenewalAllowed"); my $errorstring=''; -for my $itemnumber ( @items ) { - my ($status,$error) = CanBookBeRenewed( $borrowernumber, $itemnumber ); - if ( $status == 1 && $opacrenew == 1 ) { - my $renewalbranch = C4::Context->preference('OpacRenewalBranch'); - my $branchcode; - if ($renewalbranch eq 'itemhomebranch'){ - my $item = GetItem($itemnumber); - $branchcode=$item->{'homebranch'}; - } - elsif ($renewalbranch eq 'patronhomebranch'){ - my $borrower = GetMemberDetails($borrowernumber); - $branchcode = $borrower->{'branchcode'}; - } - elsif ($renewalbranch eq 'checkoutbranch'){ - my $issue = GetOpenIssue($itemnumber); - $branchcode = $issue->{'branchcode'}; - } - elsif ($renewalbranch eq 'NULL'){ - $branchcode=''; - } - else { - $branchcode='OPACRenew' - } - AddRenewal( $borrowernumber, $itemnumber, $branchcode); - } - else { - $errorstring .= $error ."|"; +my $member_details = GetMemberDetails($borrowernumber); +# BlockExpiredPatronOpacActions syspref 0 is false, 1 is true. BlockExpiredPatronOpacActions for categories (from GetMemberDetails) -1 means use syspref, 0 is false, 1 is true (where false means dont block, true means block) +if( ($member_details->{'BlockExpiredPatronOpacActions'} == -1 ? C4::Conext->preference('BlockExpiredPatronOpacActions') : $member_details->{'BlockExpiredPatronOpacActions'}) + && Date_to_Days( Today() ) > Date_to_Days( split /-/, $member_details->{'dateexpiry'} ) ){ + $errorstring='unable to renew as your card has expired'; +} else { + for my $itemnumber ( @items ) { + my ($status,$error) = CanBookBeRenewed( $borrowernumber, $itemnumber ); + if ( $status == 1 && $opacrenew == 1 ) { + my $renewalbranch = C4::Context->preference('OpacRenewalBranch'); + my $branchcode; + if ($renewalbranch eq 'itemhomebranch'){ + my $item = GetItem($itemnumber); + $branchcode=$item->{'homebranch'}; + } + elsif ($renewalbranch eq 'patronhomebranch'){ + my $borrower = GetMemberDetails($borrowernumber); + $branchcode = $borrower->{'branchcode'}; + } + elsif ($renewalbranch eq 'checkoutbranch'){ + my $issue = GetOpenIssue($itemnumber); + $branchcode = $issue->{'branchcode'}; + } + elsif ($renewalbranch eq 'NULL'){ + $branchcode=''; + } + else { + $branchcode='OPACRenew' + } + AddRenewal( $borrowernumber, $itemnumber, $branchcode); + } + else { + $errorstring .= $error ."|"; + } } } diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl index 07b4f76..5296f3c 100755 --- a/opac/opac-reserve.pl +++ b/opac/opac-reserve.pl @@ -35,6 +35,7 @@ use C4::Branch; # GetBranches use C4::Overdues; use C4::Debug; use Koha::DateUtils; +use Date::Calc qw/Today Date_to_Days/; # use Data::Dumper; my $MAXIMUM_NUMBER_OF_RESERVES = C4::Context->preference("maxreserves"); @@ -65,6 +66,16 @@ sub get_out { # get borrower information .... my ( $borr ) = GetMemberDetails( $borrowernumber ); +# check if this user can place a reserve, -1 means use sys pref, 0 means dont block, 1 means block +if( $borr->{'BlockExpiredPatronOpacActions'} == -1 ? C4::Context->preference("BlockExpiredPatronOpacActions") : $borr->{'BlockExpiredPatronOpacActions'} ) { + + if( Date_to_Days( Today() ) > Date_to_Days( split /-/, $borr->{'dateexpiry'} ) ){ + # cannot reserve, their card has expired and the rules set mean this is not allowed + $template->param( message=>1, expired_patron=>1 ); + get_out($query, $cookie, $template->output); + } +} + # Pass through any reserve charge if ($borr->{reservefee} > 0){ $template->param( RESERVE_CHARGE => sprintf("%.2f",$borr->{reservefee})); diff --git a/opac/opac-user.pl b/opac/opac-user.pl index f4273cb..92fc57b 100755 --- a/opac/opac-user.pl +++ b/opac/opac-user.pl @@ -12,9 +12,9 @@ # 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. +# 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 strict; @@ -65,10 +65,7 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( } ); -my $show_priority; -for ( C4::Context->preference("OPACShowHoldQueueDetails") ) { - m/priority/ and $show_priority = 1; -} +my $OPACDisplayRequestPriority = (C4::Context->preference("OPACDisplayRequestPriority")) ? 1 : 0; my $patronupdate = $query->param('patronupdate'); my $canrenew = 1; @@ -110,7 +107,6 @@ if ( $borr->{amountoutstanding} > $no_renewal_amt ) { $canrenew = 0; $template->param( renewal_blocked_fines => sprintf( '%.02f', $no_renewal_amt ), - renewal_blocked_fines_amountoutstanding => sprintf( '%.02f', $borr->{amountoutstanding} ), ); } @@ -125,19 +121,24 @@ my @bordat; $bordat[0] = $borr; # Warningdate is the date that the warning starts appearing -if ( $borr->{dateexpiry} && Date_to_Days( $today_year, $today_month, $today_day ) > Date_to_Days( $warning_year, $warning_month, $warning_day ) ) { - $borr->{'warnexpired'} = 1; -} -elsif ( $borr->{dateexpiry} && C4::Context->preference('NotifyBorrowerDeparture') && - Date_to_Days(Add_Delta_Days($warning_year, $warning_month, $warning_day,- C4::Context->preference('NotifyBorrowerDeparture'))) < - Date_to_Days( $today_year, $today_month, $today_day ) ) { +if ( $borr->{'dateexpiry'} && C4::Context->preference('NotifyBorrowerDeparture') ) { + my $days_to_expiry = Date_to_Days( $warning_year, $warning_month, $warning_day ) - Date_to_Days( $today_year, $today_month, $today_day ); + if ( $days_to_expiry < 0 ) { + + #borrower card has expired, warn the borrower + $borr->{'warnexpired'} = $borr->{'dateexpiry'}; + } elsif ( $days_to_expiry < C4::Context->preference('NotifyBorrowerDeparture') ) { + # borrower card soon to expire, warn the borrower $borr->{'warndeparture'} = $borr->{dateexpiry}; - if (C4::Context->preference('ReturnBeforeExpiry')){ + if ( C4::Context->preference('ReturnBeforeExpiry') ) { $borr->{'returnbeforeexpiry'} = 1; } + } } +# pass on any renew errors to the template for displaying +$template->param( RENEW_ERROR => $query->param('renew_error') ) if $query->param('renew_error'); $template->param( BORROWER_INFO => \@bordat, borrowernumber => $borrowernumber, @@ -145,6 +146,7 @@ $template->param( BORROWER_INFO => \@bordat, OPACMySummaryHTML => (C4::Context->preference("OPACMySummaryHTML")) ? 1 : 0, surname => $borr->{surname}, showname => $borr->{showname}, + ); #get issued items .... @@ -156,55 +158,53 @@ my @issuedat; my $itemtypes = GetItemTypes(); my $issues = GetPendingIssues($borrowernumber); if ($issues){ - foreach my $issue ( sort { $b->{date_due}->datetime() cmp $a->{date_due}->datetime() } @{$issues} ) { - # check for reserves - my ( $restype, $res, undef ) = CheckReserves( $issue->{'itemnumber'} ); - if ( $restype ) { - $issue->{'reserved'} = 1; - } - - my ( $total , $accts, $numaccts) = GetMemberAccountRecords( $borrowernumber ); - my $charges = 0; - foreach my $ac (@$accts) { - if ( $ac->{'itemnumber'} == $issue->{'itemnumber'} ) { - $charges += $ac->{'amountoutstanding'} - if $ac->{'accounttype'} eq 'F'; - $charges += $ac->{'amountoutstanding'} - if $ac->{'accounttype'} eq 'FU'; - $charges += $ac->{'amountoutstanding'} - if $ac->{'accounttype'} eq 'L'; - } - } - $issue->{'charges'} = $charges; - - # check if item is renewable - my ($status,$renewerror) = CanBookBeRenewed( $borrowernumber, $issue->{'itemnumber'} ); - ($issue->{'renewcount'},$issue->{'renewsallowed'},$issue->{'renewsleft'}) = GetRenewCount($borrowernumber, $issue->{'itemnumber'}); + foreach my $issue ( sort { $b->{date_due}->datetime() cmp $a->{date_due}->datetime() } @{$issues} ) { + # check for reserves + my ( $restype, $res, undef ) = CheckReserves( $issue->{'itemnumber'} ); + if ( $restype ) { + $issue->{'reserved'} = 1; + } + + my ( $total , $accts, $numaccts) = GetMemberAccountRecords( $borrowernumber ); + my $charges = 0; + foreach my $ac (@$accts) { + if ( $ac->{'itemnumber'} == $issue->{'itemnumber'} ) { + $charges += $ac->{'amountoutstanding'} + if $ac->{'accounttype'} eq 'F'; + $charges += $ac->{'amountoutstanding'} + if $ac->{'accounttype'} eq 'L'; + } + } + $issue->{'charges'} = $charges; + + # check if item is renewable + my ($status,$renewerror) = CanBookBeRenewed( $borrowernumber, $issue->{'itemnumber'} ); + ($issue->{'renewcount'},$issue->{'renewsallowed'},$issue->{'renewsleft'}) = GetRenewCount($borrowernumber, $issue->{'itemnumber'}); if($status && C4::Context->preference("OpacRenewalAllowed")){ $issue->{'status'} = $status; } - $issue->{'too_many'} = 1 if $renewerror and $renewerror eq 'too_many'; - $issue->{'on_reserve'} = 1 if $renewerror and $renewerror eq 'on_reserve'; - - if ( $issue->{'overdue'} ) { - push @overdues, $issue; - $overdues_count++; - $issue->{'overdue'} = 1; - } - else { - $issue->{'issued'} = 1; - } - # imageurl: - my $itemtype = $issue->{'itemtype'}; - if ( $itemtype ) { - $issue->{'imageurl'} = getitemtypeimagelocation( 'opac', $itemtypes->{$itemtype}->{'imageurl'} ); - $issue->{'description'} = $itemtypes->{$itemtype}->{'description'}; - } - push @issuedat, $issue; - $count++; - - my $isbn = GetNormalizedISBN($issue->{'isbn'}); - $issue->{normalized_isbn} = $isbn; + $issue->{'too_many'} = 1 if $renewerror and $renewerror eq 'too_many'; + $issue->{'on_reserve'} = 1 if $renewerror and $renewerror eq 'on_reserve'; + + if ( $issue->{'overdue'} ) { + push @overdues, $issue; + $overdues_count++; + $issue->{'overdue'} = 1; + } + else { + $issue->{'issued'} = 1; + } + # imageurl: + my $itemtype = $issue->{'itemtype'}; + if ( $itemtype ) { + $issue->{'imageurl'} = getitemtypeimagelocation( 'opac', $itemtypes->{$itemtype}->{'imageurl'} ); + $issue->{'description'} = $itemtypes->{$itemtype}->{'description'}; + } + push @issuedat, $issue; + $count++; + + my $isbn = GetNormalizedISBN($issue->{'isbn'}); + $issue->{normalized_isbn} = $isbn; # My Summary HTML if (my $my_summary_html = C4::Context->preference('OPACMySummaryHTML')){ @@ -216,7 +216,7 @@ if ($issues){ $issue->{biblionumber} ? $my_summary_html =~ s/{BIBLIONUMBER}/$issue->{biblionumber}/g : $my_summary_html =~ s/{BIBLIONUMBER}//g; $issue->{MySummaryHTML} = $my_summary_html; } - } + } } $template->param( ISSUES => \@issuedat ); $template->param( issues_count => $count ); @@ -256,13 +256,13 @@ foreach my $res (@reserves) { if ( $res->{'expirationdate'} eq '0000-00-00' ) { $res->{'expirationdate'} = ''; } - + $res->{'waiting'} = 1 if $res->{'found'} eq 'W'; $res->{'branch'} = $branches->{ $res->{'branchcode'} }->{'branchname'}; my $biblioData = GetBiblioData($res->{'biblionumber'}); $res->{'reserves_title'} = $biblioData->{'title'}; - if ($show_priority) { - $res->{'priority'} ||= ''; + if ($OPACDisplayRequestPriority) { + $res->{'priority'} = '' if $res->{'priority'} eq '0'; } $res->{'suspend_until'} = C4::Dates->new( $res->{'suspend_until'}, "iso")->output("syspref") if ( $res->{'suspend_until'} ); } @@ -272,7 +272,7 @@ foreach my $res (@reserves) { $template->param( RESERVES => \@reserves ); $template->param( reserves_count => $#reserves+1 ); -$template->param( showpriority=>$show_priority ); +$template->param( showpriority=>1 ) if $OPACDisplayRequestPriority; my @waiting; my $wcount = 0; @@ -288,7 +288,7 @@ foreach my $res (@reserves) { if ( ( $res->{'found'} eq 'W' ) ) { my $item = $res->{'itemnumber'}; $item = GetBiblioFromItemNumber($item,undef); - $res->{'wait'}= 1; + $res->{'wait'}= 1; $res->{'holdingbranch'}=$item->{'holdingbranch'}; $res->{'biblionumber'}=$item->{'biblionumber'}; $res->{'barcode'} = $item->{'barcode'}; @@ -314,7 +314,7 @@ foreach my $res (@reserves) { # can be cancelled #$res->{'cancelable'} = 1 if ($res->{'wait'} && $res->{'atdestination'} && $res->{'found'} ne "1"); $res->{'cancelable'} = 1 if ($res->{wait} and not $res->{found}) or (not $res->{wait} and not $res->{intransit}); - + } $template->param( WAITING => \@waiting ); @@ -338,12 +338,12 @@ if (C4::Context->preference('BakerTaylorEnabled')) { if (C4::Context->preference("OPACAmazonCoverImages") or C4::Context->preference("GoogleJackets") or C4::Context->preference("BakerTaylorEnabled") or - C4::Context->preference("SyndeticsCoverImages")) { + C4::Context->preference("SyndeticsCoverImages")) { $template->param(JacketImages=>1); } if ( GetMessagesCount( $borrowernumber, 'B' ) ) { - $template->param( bor_messages => 1 ); + $template->param( bor_messages => 1 ); } if ( $borr->{'opacnote'} ) { @@ -354,17 +354,16 @@ if ( $borr->{'opacnote'} ) { } $template->param( - bor_messages_loop => GetMessages( $borrowernumber, 'B', 'NONE' ), + bor_messages_loop => GetMessages( $borrowernumber, 'B', 'NONE' ), waiting_count => $wcount, patronupdate => $patronupdate, OpacRenewalAllowed => C4::Context->preference("OpacRenewalAllowed"), userview => 1, + dateformat => C4::Context->preference("dateformat"), ); -$template->param( - SuspendHoldsOpac => C4::Context->preference('SuspendHoldsOpac'), - AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'), -); +$template->param( DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar() ); +$template->param( AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds') ); output_html_with_http_headers $query, $cookie, $template->output; -- 1.7.2.5