Bugzilla – Attachment 194759 Details for
Bug 26355
Allow patrons to self-renew through the OPAC
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 26355: Update the OPAC templates to support the Vue island
Bug-26355-Update-the-OPAC-templates-to-support-the.patch (text/plain), 44.85 KB, created by
Andrew Fuerste-Henry
on 2026-03-06 16:03:05 UTC
(
hide
)
Description:
Bug 26355: Update the OPAC templates to support the Vue island
Filename:
MIME Type:
Creator:
Andrew Fuerste-Henry
Created:
2026-03-06 16:03:05 UTC
Size:
44.85 KB
patch
obsolete
>From a93fea415c8b90b0b5fb63d456bd56bf9bbad96d Mon Sep 17 00:00:00 2001 >From: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> >Date: Thu, 19 Feb 2026 13:32:24 +0000 >Subject: [PATCH] Bug 26355: Update the OPAC templates to support the Vue > island > >Signed-off-by: Christopher Brannon <cbrannon@cdalibrary.org> >Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> >--- > .../bootstrap/en/modules/opac-memberentry.tt | 64 +- > .../bootstrap/en/modules/opac-user.tt | 41 +- > opac/opac-memberentry.pl | 23 +- > opac/opac-user.pl | 687 +++++++++--------- > 4 files changed, 450 insertions(+), 365 deletions(-) > >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt >index f47c30acbbd..7952726052b 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt >@@ -92,6 +92,9 @@ > [% IF nochanges %] > <div class="alert alert-error">No changes were made.</div> > [% END %] >+ [% IF self_renewal %] >+ <div class="alert alert-info">Please verify your details to proceed with your self-renewal.</div> >+ [% END %] > [% END %] > > [% IF empty_mandatory_fields %] >@@ -241,7 +244,11 @@ > > > [% END %] > >- <form method="post" action="/cgi-bin/koha/opac-memberentry.pl" id="memberentry-form" autocomplete="off"> >+ <form >+ method="post" >+ [% IF (self_renewal) %]action="/api/v1/public/patrons/[% logged_in_user.borrowernumber | uri %]/self_renewal" id="self-renewal-form"[% ELSE %]action="/cgi-bin/koha/opac-memberentry.pl" id="memberentry-form"[% END %] >+ autocomplete="off" >+ > > [% INCLUDE 'csrf-token.inc' %] > > [% FOREACH field = ['streetnumber' 'streettype' 'cardnumber' 'branchcode' 'categorycode' 'title' 'surname' 'firstname' 'preferred_name' 'middle_name' 'dateofbirth' 'initials' 'pronouns' 'othernames' 'address' 'address2' 'city' 'state' 'zipcode' 'country' 'phone' 'phonepro' 'mobile' 'email' 'emailpro' 'fax' 'B_streettype' 'B_streetnumber' 'B_address' 'B_address2' 'B_city' 'B_state' 'B_zipcode' 'B_country' 'B_phone' 'B_email' 'contactnote' 'altcontactsurname' 'altcontactfirstname' 'altcontactaddress1' 'altcontactaddress2' 'altcontactaddress3' 'altcontactstate' 'altcontactzipcode' 'altcontactcountry' 'altcontactphone' 'password' 'lang' ] %] >@@ -1362,7 +1369,11 @@ > [% IF OPACPatronDetails %] > <fieldset class="action"> > <input type="hidden" name="op" value="cud-update" /> >- <input type="submit" class="btn btn-primary" value="Submit update request" /> >+ [% IF (self_renewal) %] >+ <input type="submit" class="btn btn-primary" value="Submit renewal request" /> >+ [% ELSE %] >+ <input type="submit" class="btn btn-primary" value="Submit update request" /> >+ [% END %] > </fieldset> > [% END %] > [% ELSE %] >@@ -1391,16 +1402,23 @@ > [% INCLUDE 'calendar.inc' %] > <script> > $(document).ready(function() { >+ let formName >+ [% IF (self_renewal) %] >+ formName = 'self-renewal-form' >+ [% ELSE %] >+ formName = 'memberentry-form' >+ [% END %] >+ > [% IF op == 'edit' && !OPACPatronDetails %] >- $("#memberentry-form :input").attr('readonly', true); >+ $("#" + formName + " :input").attr('readonly', true); > $("#borrower_branchcode").attr('disabled',true); > $("#borrower_title").attr('disabled',true); >- $('#memberentry-form :radio').attr('disabled',true); >+ $('#' + formName + ' :radio').attr('disabled',true); > $('span.required').remove(); > $('label.required').removeClass('required'); > [% END %] > >- $("#memberentry-form").validate({ >+ $("#" + formName).validate({ > rules: { > borrower_email: { > email: true >@@ -1430,8 +1448,40 @@ > return false; > } > else { >- form.beenSubmitted = true; >- form.submit(); >+ if(formName === 'self-renewal-form') { >+ const formValues = $(form).serializeArray() >+ const renewalBody = formValues.reduce((body, curr, i) => { >+ if(curr.name.includes("borrower")) { >+ const fieldName = curr.name.replace("borrower_", "") >+ body[fieldName] = curr.value >+ } >+ if(curr.name === "patron_attribute_code") { >+ const matchingValue = formValues[i + 1].value >+ body.extended_attributes.push({code: curr.value, attribute: matchingValue}) >+ } >+ return body >+ }, {extended_attributes: []}) >+ const options = { >+ url: $(form).attr('action'), >+ method: $(form).attr('method').toUpperCase(), >+ contentType: 'application/json', >+ data: JSON.stringify({patron: renewalBody}) >+ }; >+ $.ajax(options) >+ .then(function(result) { >+ let newLocation = "/cgi-bin/koha/opac-user.pl?self_renewal_success=" + result.expiry_date >+ if(result.confirmation_sent) { >+ newLocation += "&confirmation_sent=1" >+ } >+ document.location = newLocation >+ }) >+ .fail(function(err) { >+ document.location = "/cgi-bin/koha/opac-user.pl?self_renewal_success=0"; >+ }); >+ } else { >+ form.beenSubmitted = true; >+ form.submit(); >+ } > } > } > }); >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 bafc9bf9691..be184a3a99d 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >@@ -1,4 +1,5 @@ > [% USE raw %] >+[% USE To %] > [% USE Asset %] > [% USE Koha %] > [% USE KohaDates %] >@@ -126,18 +127,41 @@ > </div> > [% END %] > >- [% IF ( borrower.warndeparture ) %] >+ [% IF ( borrower.warndeparture) %] > <div class="alert alert-warning" id="warndeparture"> >- <strong>Please note:</strong><span> Your library card will expire on <span id="warndeparture_date">[% borrower.warndeparture | $KohaDates %]</span>. Please contact the library for more information.</span> >+ <strong>Please note:</strong >+ ><span> >+ Your library card will expire on <span id="warndeparture_date">[% borrower.warndeparture | $KohaDates %]</span>. >+ [% IF ( !self_renewal_available) %]Please contact the library for more information.[% END %]</span >+ > > [% IF ( borrower.returnbeforeexpiry ) %]<span id="warndeparture_returnbeforeexpiry"> Also note that you must return all checked out items before your library card expires.</span>[% END %] > </div> > [% END %] >- > [% IF ( borrower.warnexpired ) %] > <div class="alert alert-warning" id="warnexpired"> > <strong>Please note: </strong><span>Your account has expired as of [% borrower.warnexpired | $KohaDates %]. Please contact the library if you wish to renew your account.</span> > </div> > [% END %] >+ [% IF ( self_renewal_available && !self_renewal_alert ) %] >+ <div class="alert alert-info" id="self_renewal_available"> >+ [% IF ( self_renewal_available ) %] >+ <span> You are eligible for self-renewal. <a href="#patronSelfRenewal" data-bs-toggle="modal">Please click here to renew your account.</a></span> >+ [% END %] >+ </div> >+ [% END %] >+ [% IF ( self_renewal_success ) %] >+ <div class="alert alert-success" id="self_renewal_success"> >+ <span>Your account has been successfully renewed until [% self_renewal_success | $KohaDates %].</span> >+ [% IF ( self_renewal_confirmation_sent ) %] >+ <span>You should receive a confirmation shortly.</span> >+ [% END %] >+ </div> >+ [% END %] >+ [% IF ( self_renewal_alert ) %] >+ <div class="alert alert-warning" id="self_renewal_alert"> >+ <span>[% self_renewal_alert | html %]</span> >+ </div> >+ [% END %] > > [% IF ( RENEW_ERROR ) %] > <div class="alert alert-warning"> >@@ -1010,6 +1034,17 @@ > </main> > <!-- /#main --> > >+[% IF ( self_renewal_available ) %] >+ <patron-self-renewal patron="[% borrowernumber | html %]"></patron-self-renewal> >+[% END %] >+ >+[% SET islands = Asset.js("js/vue/dist/islands.esm.js").match('(src="([^"]+)")').1 %] >+<script src="[% islands | $raw %]" type="module"> >+</script> >+<script type="module"> >+ import { hydrate } from "[% islands | $raw %]"; >+ hydrate(); >+</script> > [%# hold suspend modal form %] > <div id="suspendHoldModal" class="modal" tabindex="-1" role="dialog" aria-labelledby="suspendModalLabel" aria-hidden="true" data-focus="false"> > <div class="modal-dialog"> >diff --git a/opac/opac-memberentry.pl b/opac/opac-memberentry.pl >index 1daa2daf2c0..011f3f2fbe3 100755 >--- a/opac/opac-memberentry.pl >+++ b/opac/opac-memberentry.pl >@@ -354,22 +354,8 @@ if ( $op eq 'cud-create' ) { > $borrower_changes{borrowernumber} = $borrowernumber; > $borrower_changes{extended_attributes} = to_json($extended_attributes_changes); > >- Koha::Patron::Modifications->search( { borrowernumber => $borrowernumber } )->delete; >- >- $borrower_changes{verification_token} = q{}; # prevent warn Missing value for PK column >- my $m = Koha::Patron::Modification->new( \%borrower_changes )->store(); >- >- #Automatically approve patron profile changes if set in syspref >- >- if ( C4::Context->preference('AutoApprovePatronProfileSettings') ) { >- >- # Need to get the object from database, otherwise it is not complete enough to allow deletion >- # when approval has been performed. >- my $tmp_m = Koha::Patron::Modifications->find( { borrowernumber => $borrowernumber } ); >- $tmp_m->approve() if $tmp_m; >- } >- > my $patron = Koha::Patrons->find($borrowernumber); >+ $patron->request_modification( \%borrower_changes ); > $template->param( borrower => $patron->unblessed ); > } else { > my $patron = Koha::Patrons->find($borrowernumber); >@@ -385,9 +371,12 @@ if ( $op eq 'cud-create' ) { > my $patron = Koha::Patrons->find($borrowernumber); > my $borrower = $patron->unblessed; > >+ my $self_renewal = $cgi->param('self_renewal') || 0; >+ > $template->param( >- borrower => $borrower, >- hidden => GetHiddenFields( $mandatory, 'edit' ), >+ borrower => $borrower, >+ hidden => GetHiddenFields( $mandatory, 'edit' ), >+ self_renewal => $self_renewal > ); > > if ( C4::Context->preference('OPACpatronimages') ) { >diff --git a/opac/opac-user.pl b/opac/opac-user.pl >index 3f1bc9f3d9f..e59321ef8cf 100755 >--- a/opac/opac-user.pl >+++ b/opac/opac-user.pl >@@ -16,410 +16,417 @@ > # You should have received a copy of the GNU General Public License > # along with Koha; if not, see <https://www.gnu.org/licenses>. > >-use Modern::Perl; >+ use Modern::Perl; > >-use CGI qw ( -utf8 ); >-use URI; >+ use CGI qw ( -utf8 ); >+ use URI; > >-use C4::Auth qw( get_template_and_user ); >-use C4::Koha qw( >- getitemtypeimagelocation >- GetNormalizedISBN >- GetNormalizedUPC >- GetNormalizedOCLCNumber >-); >-use C4::Circulation qw( CanBookBeRenewed GetRenewCount GetIssuingCharges ); >-use C4::External::BakerTaylor qw( image_url link_url ); >-use C4::Reserves qw( GetReserveStatus ); >-use C4::Members; >-use C4::Output qw( output_html_with_http_headers ); >-use Koha::Account::Lines; >-use Koha::Biblios; >-use Koha::Libraries; >-use Koha::DateUtils qw( output_pref ); >-use Koha::Holds; >-use Koha::Database; >-use Koha::ItemTypes; >-use Koha::Patron::Attribute::Types; >-use Koha::Patrons; >-use Koha::Patron::Messages; >-use Koha::Patron::Discharge; >-use Koha::Patrons; >-use Koha::Ratings; >-use Koha::Recalls; >- >-use constant ATTRIBUTE_SHOW_BARCODE => 'SHOW_BCODE'; >- >-use Scalar::Util qw( looks_like_number ); >-use Date::Calc qw( Date_to_Days Today ); >- >-my $query = CGI->new; >- >-my $op = $query->param('op') || q{}; >+ use C4::Auth qw( get_template_and_user ); >+ use C4::Koha qw( >+ getitemtypeimagelocation >+ GetNormalizedISBN >+ GetNormalizedUPC >+ GetNormalizedOCLCNumber >+ ); >+ use C4::Circulation qw( CanBookBeRenewed GetRenewCount GetIssuingCharges ); >+ use C4::External::BakerTaylor qw( image_url link_url ); >+ use C4::Reserves qw( GetReserveStatus ); >+ use C4::Members; >+ use C4::Output qw( output_html_with_http_headers ); >+ use Koha::Account::Lines; >+ use Koha::Biblios; >+ use Koha::Libraries; >+ use Koha::DateUtils qw( output_pref ); >+ use Koha::Holds; >+ use Koha::Database; >+ use Koha::ItemTypes; >+ use Koha::Patron::Attribute::Types; >+ use Koha::Patrons; >+ use Koha::Patron::Messages; >+ use Koha::Patron::Discharge; >+ use Koha::Patrons; >+ use Koha::Ratings; >+ use Koha::Recalls; >+ >+ use constant ATTRIBUTE_SHOW_BARCODE => 'SHOW_BCODE'; >+ >+ use Scalar::Util qw( looks_like_number ); >+ use Date::Calc qw( Date_to_Days Today ); >+ >+ my $query = CGI->new; >+ >+ my $op = $query->param('op') || q{}; > > # CAS single logout handling > # Will print header and exit >-if ( C4::Context->preference('casAuthentication') ) { >- require C4::Auth_with_cas; >- C4::Auth_with_cas::logout_if_required($query); >-} >- >-my ( $template, $borrowernumber, $cookie ) = get_template_and_user( >- { >- template_name => "opac-user.tt", >- query => $query, >- type => "opac", >+ if ( C4::Context->preference('casAuthentication') ) { >+ require C4::Auth_with_cas; >+ C4::Auth_with_cas::logout_if_required($query); > } >-); > >-my %renewed = map { $_ => 1 } split( ':', $query->param('renewed') || '' ); >+ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( >+ { >+ template_name => "opac-user.tt", >+ query => $query, >+ type => "opac", >+ } >+ ); >+ >+ my %renewed = map { $_ => 1 } split( ':', $query->param('renewed') || '' ); > >-my $show_priority; >-for ( C4::Context->preference("OPACShowHoldQueueDetails") ) { >- m/priority/ and $show_priority = 1; >-} >+ my $show_priority; >+ for ( C4::Context->preference("OPACShowHoldQueueDetails") ) { >+ m/priority/ and $show_priority = 1; >+ } > >-my $patronupdate = $query->param('patronupdate'); >-my $canrenew = 1; >+ my $patronupdate = $query->param('patronupdate'); >+ my $canrenew = 1; > >-$template->param( shibbolethAuthentication => C4::Context->config('useshibboleth') ); >+ $template->param( shibbolethAuthentication => C4::Context->config('useshibboleth') ); > > # get borrower information .... >-my $patron = Koha::Patrons->find($borrowernumber); >- >-if ( $op eq 'cud-update_arc' && C4::Context->preference("AllowPatronToControlAutorenewal") ) { >- my $autorenew_checkouts = $query->param('borrower_autorenew_checkouts'); >- $patron->autorenew_checkouts($autorenew_checkouts)->store() if defined $autorenew_checkouts; >-} >+ my $patron = Koha::Patrons->find($borrowernumber); > >-my $borr = $patron->unblessed; >+ if ( $op eq 'cud-update_arc' && C4::Context->preference("AllowPatronToControlAutorenewal") ) { >+ my $autorenew_checkouts = $query->param('borrower_autorenew_checkouts'); >+ $patron->autorenew_checkouts($autorenew_checkouts)->store() if defined $autorenew_checkouts; >+ } > >-my ( $today_year, $today_month, $today_day ) = Today(); >-my ( $warning_year, $warning_month, $warning_day ) = split /-/, $borr->{'dateexpiry'}; >+ my $borr = $patron->unblessed; > >-my $debar = Koha::Patrons->find($borrowernumber)->is_debarred; >-my $userdebarred; >+ my ( $today_year, $today_month, $today_day ) = Today(); >+ my ( $warning_year, $warning_month, $warning_day ) = split /-/, $borr->{'dateexpiry'}; > >-if ($debar) { >- $userdebarred = 1; >- $template->param( 'userdebarred' => $userdebarred ); >- if ( $debar ne "9999-12-31" ) { >- $borr->{'userdebarreddate'} = $debar; >- } >+ my $debar = Koha::Patrons->find($borrowernumber)->is_debarred; >+ my $userdebarred; > >- # FIXME looks like $available is not needed >- # If a user is discharged they have a validated discharge available >- my $available = Koha::Patron::Discharge::count( >- { >- borrowernumber => $borrowernumber, >- validated => 1, >+ if ($debar) { >+ $userdebarred = 1; >+ $template->param( 'userdebarred' => $userdebarred ); >+ if ( $debar ne "9999-12-31" ) { >+ $borr->{'userdebarreddate'} = $debar; > } >- ); >- $template->param( 'discharge_available' => $available >- && Koha::Patron::Discharge::is_discharged( { borrowernumber => $borrowernumber } ) ); >-} > >-if ( $userdebarred || $borr->{'gonenoaddress'} || $borr->{'lost'} ) { >- $borr->{'flagged'} = 1; >- $canrenew = 0; >-} >+ # FIXME looks like $available is not needed >+ # If a user is discharged they have a validated discharge available >+ my $available = Koha::Patron::Discharge::count( >+ { >+ borrowernumber => $borrowernumber, >+ validated => 1, >+ } >+ ); >+ $template->param( 'discharge_available' => $available >+ && Koha::Patron::Discharge::is_discharged( { borrowernumber => $borrowernumber } ) ); >+ } > >-my $amountoutstanding = $patron->account->balance; >-my $no_renewal_amt = C4::Context->preference('OPACFineNoRenewals'); >-$no_renewal_amt = undef unless looks_like_number($no_renewal_amt); >-my $amountoutstandingfornewal = >- C4::Context->preference("OPACFineNoRenewalsIncludeCredits") >- ? $amountoutstanding >- : $patron->account->outstanding_debits->total_outstanding; >- >-if ( C4::Context->preference('OpacRenewalAllowed') >- && defined($no_renewal_amt) >- && $amountoutstandingfornewal > $no_renewal_amt ) >-{ >- $borr->{'flagged'} = 1; >- $canrenew = 0; >- $template->param( >- renewal_blocked_fines => $no_renewal_amt, >- renewal_blocked_fines_amountoutstanding => $amountoutstandingfornewal, >- ); >-} >+ if ( $userdebarred || $borr->{'gonenoaddress'} || $borr->{'lost'} ) { >+ $borr->{'flagged'} = 1; >+ $canrenew = 0; >+ } > >-my $maxoutstanding = C4::Context->preference('maxoutstanding'); >-if ( $amountoutstanding && ( $amountoutstanding > $maxoutstanding ) ) { >- $borr->{blockedonfines} = 1; >-} >+ my $amountoutstanding = $patron->account->balance; >+ my $no_renewal_amt = C4::Context->preference('OPACFineNoRenewals'); >+ $no_renewal_amt = undef unless looks_like_number($no_renewal_amt); >+ my $amountoutstandingfornewal = >+ C4::Context->preference("OPACFineNoRenewalsIncludeCredits") >+ ? $amountoutstanding >+ : $patron->account->outstanding_debits->total_outstanding; >+ >+ if ( C4::Context->preference('OpacRenewalAllowed') >+ && defined($no_renewal_amt) >+ && $amountoutstandingfornewal > $no_renewal_amt ) >+ { >+ $borr->{'flagged'} = 1; >+ $canrenew = 0; >+ $template->param( >+ renewal_blocked_fines => $no_renewal_amt, >+ renewal_blocked_fines_amountoutstanding => $amountoutstandingfornewal, >+ ); >+ } >+ >+ my $maxoutstanding = C4::Context->preference('maxoutstanding'); >+ if ( $amountoutstanding && ( $amountoutstanding > $maxoutstanding ) ) { >+ $borr->{blockedonfines} = 1; >+ } > > # Warningdate is the date that the warning starts appearing >-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; >+ 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; >+ } > } > } >-} > >-my $saving_display = C4::Context->preference('OPACShowSavings'); >-if ( $saving_display =~ /user/ ) { >- $template->param( savings => $patron->get_savings ); >-} >+ my $saving_display = C4::Context->preference('OPACShowSavings'); >+ if ( $saving_display =~ /user/ ) { >+ $template->param( savings => $patron->get_savings ); >+ } > > # pass on any renew errors to the template for displaying >-my $renew_error = $query->param('renew_error'); >- >-$template->param( >- amountoutstanding => $amountoutstanding, >- borrowernumber => $borrowernumber, >- patron_flagged => $borr->{flagged}, >- surname => $borr->{surname}, >- RENEW_ERROR => $renew_error, >- borrower => $borr, >-); >+ my $renew_error = $query->param('renew_error'); >+ >+ $template->param( >+ amountoutstanding => $amountoutstanding, >+ borrowernumber => $borrowernumber, >+ patron_flagged => $borr->{flagged}, >+ surname => $borr->{surname}, >+ RENEW_ERROR => $renew_error, >+ borrower => $borr, >+ ); > > #get issued items .... > >-my $count = 0; >-my $overdues_count = 0; >-my @overdues; >-my @issuedat; >-my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; >-my $pending_checkouts = $patron->pending_checkouts->search( >- {}, >- { >- order_by => [ { -desc => 'date_due' }, { -asc => 'issue_id' } ], >- prefetch => 'item' >- } >-); >-my $are_renewable_items = 0; >-if ( $pending_checkouts->count ) { # Useless test >- while ( my $c = $pending_checkouts->next ) { >- my $issue = $c->unblessed_all_relateds; >- >- # check for reserves >- my $restype = GetReserveStatus( $issue->{'itemnumber'} ); >- if ($restype) { >- $issue->{'reserved'} = 1; >+ my $count = 0; >+ my $overdues_count = 0; >+ my @overdues; >+ my @issuedat; >+ my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; >+ my $pending_checkouts = $patron->pending_checkouts->search( >+ {}, >+ { >+ order_by => [ { -desc => 'date_due' }, { -asc => 'issue_id' } ], >+ prefetch => 'item' > } >+ ); >+ my $are_renewable_items = 0; >+ if ( $pending_checkouts->count ) { # Useless test >+ while ( my $c = $pending_checkouts->next ) { >+ my $issue = $c->unblessed_all_relateds; >+ >+ # check for reserves >+ my $restype = GetReserveStatus( $issue->{'itemnumber'} ); >+ if ($restype) { >+ $issue->{'reserved'} = 1; >+ } > >- # Must be moved in a module if reused >- my $charges = Koha::Account::Lines->search( >- { >- borrowernumber => $patron->borrowernumber, >- amountoutstanding => { '>' => 0 }, >- debit_type_code => [ 'OVERDUE', 'LOST' ], >- itemnumber => $issue->{itemnumber} >- }, >- ); >- $issue->{charges} = $charges->total_outstanding; >+ # Must be moved in a module if reused >+ my $charges = Koha::Account::Lines->search( >+ { >+ borrowernumber => $patron->borrowernumber, >+ amountoutstanding => { '>' => 0 }, >+ debit_type_code => [ 'OVERDUE', 'LOST' ], >+ itemnumber => $issue->{itemnumber} >+ }, >+ ); >+ $issue->{charges} = $charges->total_outstanding; > >- my $rental_fines = Koha::Account::Lines->search( >- { >- borrowernumber => $patron->borrowernumber, >- amountoutstanding => { '>' => 0 }, >- debit_type_code => { 'LIKE' => 'RENT_%' }, >- itemnumber => $issue->{itemnumber} >+ my $rental_fines = Koha::Account::Lines->search( >+ { >+ borrowernumber => $patron->borrowernumber, >+ amountoutstanding => { '>' => 0 }, >+ debit_type_code => { 'LIKE' => 'RENT_%' }, >+ itemnumber => $issue->{itemnumber} >+ } >+ ); >+ $issue->{rentalfines} = $rental_fines->total_outstanding; >+ >+ # check if item is renewable >+ my ( $status, $renewerror, $info ) = CanBookBeRenewed( $patron, $c ); >+ ( >+ $issue->{'renewcount'}, >+ $issue->{'renewsallowed'}, >+ $issue->{'renewsleft'}, >+ $issue->{'unseencount'}, >+ $issue->{'unseenallowed'}, >+ $issue->{'unseenleft'} >+ ) = GetRenewCount( $patron, $c->item ); >+ ( $issue->{'renewalfee'}, $issue->{'renewalitemtype'} ) = >+ GetIssuingCharges( $issue->{'itemnumber'}, $borrowernumber ); >+ $issue->{itemtype_object} = Koha::ItemTypes->find( $c->item->effective_itemtype ); >+ if ( $status && C4::Context->preference("OpacRenewalAllowed") ) { >+ $are_renewable_items = 1; >+ $issue->{'status'} = $status; > } >- ); >- $issue->{rentalfines} = $rental_fines->total_outstanding; >- >- # check if item is renewable >- my ( $status, $renewerror, $info ) = CanBookBeRenewed( $patron, $c ); >- ( >- $issue->{'renewcount'}, >- $issue->{'renewsallowed'}, >- $issue->{'renewsleft'}, >- $issue->{'unseencount'}, >- $issue->{'unseenallowed'}, >- $issue->{'unseenleft'} >- ) = GetRenewCount( $patron, $c->item ); >- ( $issue->{'renewalfee'}, $issue->{'renewalitemtype'} ) = >- GetIssuingCharges( $issue->{'itemnumber'}, $borrowernumber ); >- $issue->{itemtype_object} = Koha::ItemTypes->find( $c->item->effective_itemtype ); >- if ( $status && C4::Context->preference("OpacRenewalAllowed") ) { >- $are_renewable_items = 1; >- $issue->{'status'} = $status; >- } > >- $issue->{'renewed'} = $renewed{ $issue->{'itemnumber'} }; >- >- if ($renewerror) { >- $issue->{'too_many'} = 1 if $renewerror eq 'too_many'; >- $issue->{'too_unseen'} = 1 if $renewerror eq 'too_unseen'; >- $issue->{'on_reserve'} = 1 if $renewerror eq 'on_reserve'; >- $issue->{'norenew_overdue'} = 1 if $renewerror eq 'overdue'; >- $issue->{'auto_renew'} = 1 if $renewerror eq 'auto_renew'; >- $issue->{'auto_too_soon'} = 1 if $renewerror eq 'auto_too_soon'; >- $issue->{'auto_too_late'} = 1 if $renewerror eq 'auto_too_late'; >- $issue->{'auto_too_much_oweing'} = 1 if $renewerror eq 'auto_too_much_oweing'; >- $issue->{'item_denied_renewal'} = 1 if $renewerror eq 'item_denied_renewal'; >- $issue->{'item_issued_to_other_patron'} = 1 if $renewerror eq 'item_issued_to_other_patron'; >- >- if ( $renewerror eq 'too_soon' ) { >- $issue->{'too_soon'} = 1; >- $issue->{'soonestrenewdate'} = $info->{soonest_renew_date}; >+ $issue->{'renewed'} = $renewed{ $issue->{'itemnumber'} }; >+ >+ if ($renewerror) { >+ $issue->{'too_many'} = 1 if $renewerror eq 'too_many'; >+ $issue->{'too_unseen'} = 1 if $renewerror eq 'too_unseen'; >+ $issue->{'on_reserve'} = 1 if $renewerror eq 'on_reserve'; >+ $issue->{'norenew_overdue'} = 1 if $renewerror eq 'overdue'; >+ $issue->{'auto_renew'} = 1 if $renewerror eq 'auto_renew'; >+ $issue->{'auto_too_soon'} = 1 if $renewerror eq 'auto_too_soon'; >+ $issue->{'auto_too_late'} = 1 if $renewerror eq 'auto_too_late'; >+ $issue->{'auto_too_much_oweing'} = 1 if $renewerror eq 'auto_too_much_oweing'; >+ $issue->{'item_denied_renewal'} = 1 if $renewerror eq 'item_denied_renewal'; >+ $issue->{'item_issued_to_other_patron'} = 1 if $renewerror eq 'item_issued_to_other_patron'; >+ >+ if ( $renewerror eq 'too_soon' ) { >+ $issue->{'too_soon'} = 1; >+ $issue->{'soonestrenewdate'} = $info->{soonest_renew_date}; >+ } > } >- } > >- if ( $c->is_overdue ) { >- push @overdues, $issue; >- $overdues_count++; >- $issue->{'overdue'} = 1; >- } else { >- $issue->{'issued'} = 1; >- } >+ if ( $c->is_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'}; >- } >+ # imageurl: >+ my $itemtype = $issue->{'itemtype'}; >+ if ($itemtype) { >+ $issue->{'imageurl'} = getitemtypeimagelocation( 'opac', $itemtypes->{$itemtype}->{'imageurl'} ); >+ $issue->{'description'} = $itemtypes->{$itemtype}->{'description'}; >+ } > >- if ( C4::Context->preference('OpacStarRatings') eq 'all' ) { >- my $ratings = Koha::Ratings->search( { biblionumber => $issue->{biblionumber} } ); >- $issue->{ratings} = $ratings; >- $issue->{my_rating} = >- $borrowernumber ? $ratings->search( { borrowernumber => $borrowernumber } )->next : undef; >- } >+ if ( C4::Context->preference('OpacStarRatings') eq 'all' ) { >+ my $ratings = Koha::Ratings->search( { biblionumber => $issue->{biblionumber} } ); >+ $issue->{ratings} = $ratings; >+ $issue->{my_rating} = >+ $borrowernumber ? $ratings->search( { borrowernumber => $borrowernumber } )->next : undef; >+ } > >- my $biblio_object = Koha::Biblios->find( $issue->{biblionumber} ); >- $issue->{biblio_object} = $biblio_object; >- push @issuedat, $issue; >- $count++; >+ my $biblio_object = Koha::Biblios->find( $issue->{biblionumber} ); >+ $issue->{biblio_object} = $biblio_object; >+ push @issuedat, $issue; >+ $count++; > >- my $isbn = GetNormalizedISBN( $issue->{'isbn'} ); >- $issue->{normalized_isbn} = $isbn; >+ my $isbn = GetNormalizedISBN( $issue->{'isbn'} ); >+ $issue->{normalized_isbn} = $isbn; > >- if ( C4::Context->preference('BakerTaylorEnabled') >- || C4::Context->preference('SyndeticsEnabled') >- || C4::Context->preference('SyndeticsCoverImages') ) >- { >- my $marcrecord = $biblio_object->metadata_record( >- { >- embed_items => 1, >- interface => 'opac', >- patron => $patron >- } >- ); >- $issue->{normalized_upc} = GetNormalizedUPC( $marcrecord, C4::Context->preference('marcflavour') ); >- $issue->{normalized_oclc} = GetNormalizedOCLCNumber( $marcrecord, C4::Context->preference('marcflavour') ); >- } >+ if ( C4::Context->preference('BakerTaylorEnabled') >+ || C4::Context->preference('SyndeticsEnabled') >+ || C4::Context->preference('SyndeticsCoverImages') ) >+ { >+ my $marcrecord = $biblio_object->metadata_record( >+ { >+ embed_items => 1, >+ interface => 'opac', >+ patron => $patron >+ } >+ ); >+ $issue->{normalized_upc} = GetNormalizedUPC( $marcrecord, C4::Context->preference('marcflavour') ); >+ $issue->{normalized_oclc} = GetNormalizedOCLCNumber( $marcrecord, C4::Context->preference('marcflavour') ); >+ } > >- if ( C4::Context->preference('UseRecalls') ) { >- my $maybe_recalls = Koha::Recalls->search( >- { biblio_id => $issue->{biblionumber}, item_id => [ undef, $issue->{itemnumber} ], completed => 0 } ); >- while ( my $recall = $maybe_recalls->next ) { >- if ( $recall->checkout and $recall->checkout->issue_id == $issue->{issue_id} ) { >- $issue->{recall} = 1; >- last; >+ if ( C4::Context->preference('UseRecalls') ) { >+ my $maybe_recalls = Koha::Recalls->search( >+ { biblio_id => $issue->{biblionumber}, item_id => [ undef, $issue->{itemnumber} ], completed => 0 } ); >+ while ( my $recall = $maybe_recalls->next ) { >+ if ( $recall->checkout and $recall->checkout->issue_id == $issue->{issue_id} ) { >+ $issue->{recall} = 1; >+ last; >+ } > } > } > } > } >-} >-my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing'); >-$canrenew = 0 if ( $overduesblockrenewing ne 'allow' and $overdues_count == $count ) || !$are_renewable_items; >- >-$template->param( ISSUES => \@issuedat ); >-$template->param( issues_count => $count ); >-$template->param( canrenew => $canrenew ); >-$template->param( OVERDUES => \@overdues ); >-$template->param( overdues_count => $overdues_count ); >- >-my $show_barcode = Koha::Patron::Attribute::Types->search( # FIXME we should not need this search >- { code => ATTRIBUTE_SHOW_BARCODE } >-)->count; >-if ($show_barcode) { >- my $patron_show_barcode = $patron->get_extended_attribute(ATTRIBUTE_SHOW_BARCODE); >- undef $show_barcode if $patron_show_barcode and not $patron_show_barcode->attribute; >-} >-$template->param( show_barcode => 1 ) if $show_barcode; >+ my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing'); >+ $canrenew = 0 if ( $overduesblockrenewing ne 'allow' and $overdues_count == $count ) || !$are_renewable_items; >+ >+ $template->param( ISSUES => \@issuedat ); >+ $template->param( issues_count => $count ); >+ $template->param( canrenew => $canrenew ); >+ $template->param( OVERDUES => \@overdues ); >+ $template->param( overdues_count => $overdues_count ); >+ >+ my $show_barcode = Koha::Patron::Attribute::Types->search( # FIXME we should not need this search >+ { code => ATTRIBUTE_SHOW_BARCODE } >+ )->count; >+ if ($show_barcode) { >+ my $patron_show_barcode = $patron->get_extended_attribute(ATTRIBUTE_SHOW_BARCODE); >+ undef $show_barcode if $patron_show_barcode and not $patron_show_barcode->attribute; >+ } >+ $template->param( show_barcode => 1 ) if $show_barcode; > > # now the reserved items.... >-my $reserves = $patron->holds->filter_out_has_cancellation_requests; >- >-$template->param( >- RESERVES => $reserves, >- reserves_count => $reserves->count_holds, >- showpriority => $show_priority, >-); >+ my $reserves = $patron->holds->filter_out_has_cancellation_requests; > >-if ( C4::Context->preference('UseRecalls') ) { >- my $recalls = Koha::Recalls->search( { patron_id => $borrowernumber, completed => 0 } ); >- $template->param( RECALLS => $recalls ); >-} >- >-if ( C4::Context->preference('BakerTaylorEnabled') ) { > $template->param( >- BakerTaylorEnabled => 1, >- BakerTaylorImageURL => &image_url(), >- BakerTaylorLinkURL => &link_url(), >- BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'), >+ RESERVES => $reserves, >+ reserves_count => $reserves->count_holds, >+ showpriority => $show_priority, > ); >-} > >-if ( C4::Context->preference("OPACAmazonCoverImages") >- or C4::Context->preference("GoogleJackets") >- or C4::Context->preference("BakerTaylorEnabled") >- or C4::Context->preference("SyndeticsCoverImages") >- or ( C4::Context->preference('OPACCustomCoverImages') and C4::Context->preference('CustomCoverImagesURL') ) ) >-{ >- $template->param( JacketImages => 1 ); >-} >+ if ( C4::Context->preference('UseRecalls') ) { >+ my $recalls = Koha::Recalls->search( { patron_id => $borrowernumber, completed => 0 } ); >+ $template->param( RECALLS => $recalls ); >+ } > >-$template->param( >- overdrive_error => scalar $query->param('overdrive_error') || undef, >- overdrive_tab => scalar $query->param('overdrive_tab') || 0, >-); >+ if ( C4::Context->preference('BakerTaylorEnabled') ) { >+ $template->param( >+ BakerTaylorEnabled => 1, >+ BakerTaylorImageURL => &image_url(), >+ BakerTaylorLinkURL => &link_url(), >+ BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'), >+ ); >+ } > >-my $patron_messages = Koha::Patron::Messages->search( >+ if ( C4::Context->preference("OPACAmazonCoverImages") >+ or C4::Context->preference("GoogleJackets") >+ or C4::Context->preference("BakerTaylorEnabled") >+ or C4::Context->preference("SyndeticsCoverImages") >+ or ( C4::Context->preference('OPACCustomCoverImages') and C4::Context->preference('CustomCoverImagesURL') ) ) > { >- borrowernumber => $borrowernumber, >- message_type => 'B', >+ $template->param( JacketImages => 1 ); > } >-); > >-if ( C4::Context->preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') >- || C4::Context->preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') ) >-{ >- my @relatives; >+ $template->param( >+ overdrive_error => scalar $query->param('overdrive_error') || undef, >+ overdrive_tab => scalar $query->param('overdrive_tab') || 0, >+ ); >+ >+ my $patron_messages = Koha::Patron::Messages->search( >+ { >+ borrowernumber => $borrowernumber, >+ message_type => 'B', >+ } >+ ); > >- # Filter out guarantees that don't want guarantor to see checkouts >- foreach my $gr ( $patron->guarantee_relationships->as_list ) { >- my $g = $gr->guarantee; >- push( @relatives, $g ) if $g->privacy_guarantor_checkouts; >+ if ( C4::Context->preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') >+ || C4::Context->preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') ) >+ { >+ my @relatives; >+ >+ # Filter out guarantees that don't want guarantor to see checkouts >+ foreach my $gr ( $patron->guarantee_relationships->as_list ) { >+ my $g = $gr->guarantee; >+ push( @relatives, $g ) if $g->privacy_guarantor_checkouts; >+ } >+ $template->param( relatives => \@relatives ); > } >- $template->param( relatives => \@relatives ); >-} > >-if ( C4::Context->preference('AllowPatronToSetFinesVisibilityForGuarantor') >- || C4::Context->preference('AllowStaffToSetFinesVisibilityForGuarantor') ) >-{ >- my @relatives_with_fines; >+ if ( C4::Context->preference('AllowPatronToSetFinesVisibilityForGuarantor') >+ || C4::Context->preference('AllowStaffToSetFinesVisibilityForGuarantor') ) >+ { >+ my @relatives_with_fines; > >- # Filter out guarantees that don't want guarantor to see checkouts >- foreach my $gr ( $patron->guarantee_relationships->as_list ) { >- my $g = $gr->guarantee; >- push( @relatives_with_fines, $g ) if $g->privacy_guarantor_fines; >+ # Filter out guarantees that don't want guarantor to see checkouts >+ foreach my $gr ( $patron->guarantee_relationships->as_list ) { >+ my $g = $gr->guarantee; >+ push( @relatives_with_fines, $g ) if $g->privacy_guarantor_fines; >+ } >+ $template->param( relatives_with_fines => \@relatives_with_fines ); > } >- $template->param( relatives_with_fines => \@relatives_with_fines ); >-} > >-if ( C4::Context->preference("ArticleRequests") ) { >- $template->param( >- current_article_requests => [ $patron->article_requests->filter_by_current->as_list ], >- ); >-} >+ if ( C4::Context->preference("ArticleRequests") ) { >+ $template->param( >+ current_article_requests => [ $patron->article_requests->filter_by_current->as_list ], >+ ); >+ } >+ >+ my $self_renewal_available = $patron->is_eligible_for_self_renewal(); >+ my $self_renewal_alert; >+ my $self_renewal_success = $query->param('self_renewal_success'); >+ $self_renewal_alert = $patron->category->self_renewal_failure_message >+ if defined $self_renewal_success && !$self_renewal_success; >+ my $self_renewal_confirmation_sent = $query->param('confirmation_sent'); > >-$template->param( >+ $template->param( > patron_messages => $patron_messages, > opacnote => $borr->{opacnote}, > patronupdate => $patronupdate, >@@ -430,6 +437,10 @@ $template->param( > AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'), > OpacHoldNotes => C4::Context->preference('OpacHoldNotes'), > failed_holds => scalar $query->param('failed_holds'), >+ self_renewal_available => $self_renewal_available, >+ self_renewal_success => $self_renewal_success, >+ self_renewal_alert => $self_renewal_alert, >+ self_renewal_confirmation_sent => $self_renewal_confirmation_sent, > ); > > # if not an empty string this indicates to return >-- >2.39.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 26355
:
191781
|
191782
|
191783
|
191784
|
191785
|
191786
|
191787
|
191788
|
191789
|
192440
|
192441
|
192442
|
192443
|
192444
|
192445
|
192446
|
192447
|
192448
|
193065
|
193066
|
193067
|
193068
|
193069
|
193070
|
193071
|
193072
|
193073
|
193074
|
193249
|
193250
|
193251
|
193252
|
193253
|
193521
|
193522
|
193523
|
193524
|
193525
|
193526
|
193527
|
193528
|
193529
|
193581
|
193635
|
193654
|
193699
|
193756
|
193757
|
193758
|
193759
|
193760
|
193761
|
193762
|
193763
|
193764
|
193765
|
193921
|
194435
|
194464
|
194465
|
194466
|
194467
|
194468
|
194469
|
194470
|
194471
|
194472
|
194473
|
194474
|
194753
|
194754
|
194755
|
194756
|
194757
|
194758
| 194759 |
194760
|
194761
|
194763
|
194764
|
194765
|
194780