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 {
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");
my ($template, $loggedinuser, $cookie)
= get_template_and_user({template_name => "admin/categorie.tmpl",
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;
TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"),
"type_".$data->{'category_type'} => 1,
branches_loop => \@branches_loop,
+ BlockExpiredPatronOpacActions => $data->{'BlockExpiredPatronOpacActions'},
);
if (C4::Context->preference('EnhancedMessagingPreferences')) {
C4::Form::MessagingPreferences::set_form_values({ categorycode => $categorycode } , $template);
}
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->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;
- }
+ } 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);
$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;
reservefee => sprintf("%.2f",$data->{'reservefee'} || 0),
hidelostitems => $data->{'hidelostitems'},
category_type => $data->{'category_type'},
+ BlockExpiredPatronOpacActions => $data->{'BlockExpiredPatronOpacActions'},
);
# END $OP eq DELETE_CONFIRM
################## DELETE_CONFIRMED ##################################
`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;
('BasketConfirmations','1','always ask for confirmation.|do not ask for confirmation.','When closing or reopening a basket,','Choice'),
('BiblioAddsAuthorities','0',NULL,'If ON, adding a new biblio will check for an existing authority record and create one on the fly if one doesn\'t exist','YesNo'),
('BiblioDefaultView','normal','normal|marc|isbd','Choose the default detail view in the catalog; choose between normal, marc or isbd','Choice'),
+('BlockExpiredPatronOpacActions','yes',NULL,'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','YesNo'),
('BlockReturnOfWithdrawnItems','1','0','If enabled, items that are marked as withdrawn cannot be returned.','YesNo'),
('BorrowerMandatoryField','surname|cardnumber',NULL,'Choose the mandatory fields for a patron\'s account','free'),
('borrowerRelationship','father|mother','','Define valid relationships between a guarantor & a guarantee (separated by | or ,)','free'),
$dbh->do("INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES('WhenLostForgiveFine','0',NULL,'If ON, Forgives the fines on an item when it is lost.','YesNo')");
$dbh->do("INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES('WhenLostChargeReplacementFee','1',NULL,'If ON, Charge the replacement price when a patron loses an item.','YesNo')");
print "Upgrade to $DBversion done (Bug 7639: system preferences to forgive fines on lost items)\n";
+ SetVersion($DBversion);
+}
+
+
+$DBversion = "3.13.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);
}
<span>Select All if this category type must to be displayed all the time. Otherwise select librairies you want to associate with this value.
</span>
</li>
+ <li><label for="block_expired">Block expired patrons</label>
+ <select name="block_expired" id="block_expired">
+ <option value="-1" [% IF ( BlockExpiredPatronOpacActions == -1 ) %] selected="selected" [% END %]> Follow system preference BlockExpiredPatronOpacActions </option>
+ <option value="1" [% IF ( BlockExpiredPatronOpacActions == 1 ) %] selected="selected" [% END %]> Block </option>
+ <option value="0" [% IF ( BlockExpiredPatronOpacActions == 0 ) %] selected="selected" [% END %]> Don't block </option>
+ </select>
+ Should patrons of this category be blocked from opac actions such as renew and reserve when their cards have expired.
+ </li>
</ol>
</fieldset>
no: "Don't allow"
yes: Allow
- opac users to share private lists with other patrons.
+ -
+ - 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:
-
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.
[% IF ( bad_data ) %]
<div id="bad_data" class="dialog alert">ERROR: Internal error: incomplete hold request.</div>
[% END %]
+ [% IF ( expired_patron ) %]
+ <div id="expired_patron" class="dialog alert"><p><strong>Sorry</strong>, you cannot place holds because your library card has expired.<p><p>Please contact your librarian if you wish to renew your card</p></div>
+ [% END %]
[% ELSE %]
[% IF ( none_available ) %]
<div id="none_available" class="dialog alert"><strong>Sorry</strong>, none of these items can be placed on hold.
<div class="dialog alert" id="warnexpired">
<strong>Please note:</strong><span> Your card has expired. Please contact the library for more information.</span>
</div>
+ [% ELSIF ( BORROWER_INF.warnexpired ) %]
+ <div class="dialog alert">
+ <string>Please note:</string><span> You card has expired as of [% BORROWER_INF.warnexpired %]. Please contact the library if you wish to renew your subscription.</span>
+ </div>
+ [% END %]
+
+ [% IF ( RENEW_ERROR ) %]
+ <div class="dialog alert">
+ <string>Please note:</string><span> You're renew failed with the following error: [% RENEW_ERROR %]</span>
+ </div>
[% END %]
[% IF ( patron_flagged ) %]
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(
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 ."|";
+ }
}
}
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");
# 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}));
}
);
-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;
$canrenew = 0;
$template->param(
renewal_blocked_fines => sprintf( '%.02f', $no_renewal_amt ),
- renewal_blocked_fines_amountoutstanding => sprintf( '%.02f', $borr->{amountoutstanding} ),
);
}
$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')){
$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,
if ($issues){
foreach my $issue ( sort { $b->{date_due}->datetime() cmp $a->{date_due}->datetime() } @{$issues} ) {
# check for reserves
- my $restype = GetReserveStatus( $issue->{'itemnumber'} );
+ my ( $restype, $res, undef ) = CheckReserves( $issue->{'itemnumber'} );
if ( $restype ) {
$issue->{'reserved'} = 1;
}
$charges += $ac->{'amountoutstanding'}
if $ac->{'accounttype'} eq 'F';
$charges += $ac->{'amountoutstanding'}
- if $ac->{'accounttype'} eq 'FU';
- $charges += $ac->{'amountoutstanding'}
if $ac->{'accounttype'} eq 'L';
}
}
$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'} );
}
$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;
patronupdate => $patronupdate,
OpacRenewalAllowed => C4::Context->preference("OpacRenewalAllowed"),
userview => 1,
+ dateformat => C4::Context->preference("dateformat"),
);
$template->param(