Bugzilla – Attachment 104920 Details for
Bug 19532
Recalls for Koha
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 19532: Recalls on intranet
Bug-19532-Recalls-on-intranet.patch (text/plain), 130.43 KB, created by
Aleisha Amohia
on 2020-05-15 06:31:46 UTC
(
hide
)
Description:
Bug 19532: Recalls on intranet
Filename:
MIME Type:
Creator:
Aleisha Amohia
Created:
2020-05-15 06:31:46 UTC
Size:
130.43 KB
patch
obsolete
>From 743851ac42b6ebad32d0614686229e0caae42823 Mon Sep 17 00:00:00 2001 >From: Aleisha Amohia <aleishaamohia@hotmail.com> >Date: Mon, 11 May 2020 23:52:09 +0000 >Subject: [PATCH] Bug 19532: Recalls on intranet > >See recalls on Intranet >- old recalls (all inactive recalls) >- recalls queue (all active recalls) - cancel, expire, revert waiting status, multiple cancel, mark overdue >- recalls to pull (available but not yet waiting) - cancel >- recalls awaiting pickup (awaiting pickup, awaiting pickup more than RecallMaxPickUpDelay days) - expire, revert waiting status >- overdue recalls (overdue to be returned) - cancel, multiple cancel >- biblio recalls tab (all active recalls relevant to this bib) - cancel, expire, revert waiting status, mark overdue >- patron recalls tab (all active recalls relevant to this patron) - cancel, expire, revert waiting status, mark overdue >- patron recalls history tab (all recalls relevant to this patron) - cancel, expire, revert waiting status, mark overdue >- log viewer > >and the general circulation of recalls >--- > catalogue/detail.pl | 6 + > circ/circulation.pl | 10 +- > circ/returns.pl | 71 ++++++++ > circ/transferstoreceive.pl | 7 + > .../prog/en/includes/biblio-view-menu.inc | 3 + > .../intranet-tmpl/prog/en/includes/circ-menu.inc | 3 + > .../intranet-tmpl/prog/en/includes/circ-nav.inc | 8 + > .../prog/en/includes/patron-title.inc | 1 + > .../intranet-tmpl/prog/en/includes/recalls.inc | 131 +++++++++++++ > .../intranet-tmpl/prog/en/includes/strings.inc | 1 + > .../prog/en/modules/catalogue/detail.tt | 13 +- > .../prog/en/modules/catalogue/results.tt | 6 + > .../prog/en/modules/cataloguing/addbooks.tt | 1 + > .../prog/en/modules/circ/circulation-home.tt | 12 ++ > .../prog/en/modules/circ/circulation.tt | 47 ++++- > .../prog/en/modules/circ/printslip.tt | 2 + > .../intranet-tmpl/prog/en/modules/circ/renew.tt | 3 + > .../intranet-tmpl/prog/en/modules/circ/returns.tt | 202 +++++++++++++++++++++ > .../prog/en/modules/circ/transferstoreceive.tt | 2 + > .../prog/en/modules/members/moremember.tt | 15 ++ > .../prog/en/modules/members/recallshistory.tt | 48 +++++ > .../prog/en/modules/recalls/recalls_old_queue.tt | 56 ++++++ > .../prog/en/modules/recalls/recalls_overdue.tt | 67 +++++++ > .../prog/en/modules/recalls/recalls_queue.tt | 67 +++++++ > .../prog/en/modules/recalls/recalls_to_pull.tt | 175 ++++++++++++++++++ > .../prog/en/modules/recalls/recalls_waiting.tt | 181 ++++++++++++++++++ > .../prog/en/modules/recalls/request.tt | 63 +++++++ > .../prog/en/modules/reserve/request.tt | 4 +- > .../intranet-tmpl/prog/en/modules/tools/viewlog.tt | 14 +- > koha-tmpl/intranet-tmpl/prog/js/checkouts.js | 15 +- > koha-tmpl/intranet-tmpl/prog/js/recalls.js | 147 +++++++++++++++ > members/moremember.pl | 2 + > members/recallshistory.pl | 47 +++++ > recalls/recall_pickup_slip.pl | 74 ++++++++ > recalls/recalls_old_queue.pl | 47 +++++ > recalls/recalls_overdue.pl | 61 +++++++ > recalls/recalls_queue.pl | 57 ++++++ > recalls/recalls_to_pull.pl | 126 +++++++++++++ > recalls/recalls_waiting.pl | 76 ++++++++ > recalls/request.pl | 65 +++++++ > reserve/request.pl | 4 + > svc/checkouts | 21 +++ > svc/recall | 79 ++++++++ > tools/letter.pl | 2 +- > tools/viewlog.pl | 10 + > 45 files changed, 2043 insertions(+), 9 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/recalls.inc > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/recallshistory.tt > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_old_queue.tt > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_overdue.tt > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_queue.tt > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_to_pull.tt > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_waiting.tt > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/recalls/request.tt > create mode 100644 koha-tmpl/intranet-tmpl/prog/js/recalls.js > create mode 100755 members/recallshistory.pl > create mode 100755 recalls/recall_pickup_slip.pl > create mode 100755 recalls/recalls_old_queue.pl > create mode 100755 recalls/recalls_overdue.pl > create mode 100755 recalls/recalls_queue.pl > create mode 100755 recalls/recalls_to_pull.pl > create mode 100755 recalls/recalls_waiting.pl > create mode 100755 recalls/request.pl > create mode 100755 svc/recall > >diff --git a/catalogue/detail.pl b/catalogue/detail.pl >index c968e33dc99..5a564286f3c 100755 >--- a/catalogue/detail.pl >+++ b/catalogue/detail.pl >@@ -395,6 +395,12 @@ foreach my $item (@items) { > } > } > >+ my $recall = Koha::Recalls->find({ itemnumber => $item->{itemnumber}, old => undef }); >+ if ( defined $recall ) { >+ $item->{recalled} = 1; >+ $item->{recall} = $recall; >+ } >+ > if ($currentbranch and C4::Context->preference('SeparateHoldings')) { > if ($itembranchcode and $itembranchcode eq $currentbranch) { > push @itemloop, $item; >diff --git a/circ/circulation.pl b/circ/circulation.pl >index 81c3bcdf561..3965130f9f5 100755 >--- a/circ/circulation.pl >+++ b/circ/circulation.pl >@@ -178,6 +178,8 @@ if ( $restoreduedatespec && $restoreduedatespec eq "highholds_empty" ) { > } > my $issueconfirmed = $query->param('issueconfirmed'); > my $cancelreserve = $query->param('cancelreserve'); >+my $cancel_recall = $query->param('cancel_recall'); >+my $recall_id = $query->param('recall_id'); > my $debt_confirmed = $query->param('debt_confirmed') || 0; # Don't show the debt error dialog twice > my $charges = $query->param('charges') || q{}; > >@@ -410,7 +412,11 @@ if (@$barcodes) { > } > unless($confirm_required) { > my $switch_onsite_checkout = exists $messages->{ONSITE_CHECKOUT_WILL_BE_SWITCHED}; >- my $issue = AddIssue( $patron->unblessed, $barcode, $datedue, $cancelreserve, undef, undef, { onsite_checkout => $onsite_checkout, auto_renew => $session->param('auto_renew'), switch_onsite_checkout => $switch_onsite_checkout, } ); >+ my $recall = Koha::Recalls->find({ borrowernumber => $patron->borrowernumber, itemnumber => $item->itemnumber, old => undef }); >+ if ( $recall and !$recall_id ){ >+ $recall_id = $recall->recall_id; >+ } >+ my $issue = AddIssue( $patron->unblessed, $barcode, $datedue, $cancelreserve, undef, undef, { onsite_checkout => $onsite_checkout, auto_renew => $session->param('auto_renew'), switch_onsite_checkout => $switch_onsite_checkout, cancel_recall => $cancel_recall, recall_id => $recall_id, } ); > $template_params->{issue} = $issue; > $session->clear('auto_renew'); > $inprocess = 1; >@@ -456,6 +462,8 @@ if ($patron) { > $template->param( > holds_count => $holds->count(), > WaitingHolds => $waiting_holds, >+ recalls => $patron->recalls, >+ specific_patron => 1, > ); > } > >diff --git a/circ/returns.pl b/circ/returns.pl >index 8044262551a..9a68b111928 100755 >--- a/circ/returns.pl >+++ b/circ/returns.pl >@@ -83,6 +83,15 @@ if ( $query->param('print_slip') ) { > ); > } > >+# print a recall slip >+if ( $query->param('recall_slip') ) { >+ $template->param( >+ recall_slip => 1, >+ recall_id => scalar $query->param('recall_id'), >+ ); >+} >+ >+ > ##################### > #Global vars > my $userenv = C4::Context->userenv; >@@ -178,6 +187,24 @@ if ( $query->param('reserve_id') ) { > } > } > >+if ( $query->param('recall_id') ) { >+ my $recall = Koha::Recalls->find( scalar $query->param('recall_id') ); >+ my $barcode = $query->param('barcode'); >+ my $return_branch = $query->param('returnbranch'); >+ >+ my $expirationdate = $recall->calc_expirationdate; >+ my $item; >+ if ( !$recall->item_level_recall ) { >+ $item = Koha::Items->find({ barcode => $barcode }); >+ } >+ >+ if ( $recall->branchcode ne $return_branch ) { >+ $recall->start_transfer({ item => $item }); >+ } else { >+ $recall->set_waiting({ item => $item }); >+ } >+} >+ > my $borrower; > my $returned = 0; > my $messages; >@@ -236,6 +263,10 @@ if ($dotransfer){ > if ($canceltransfer){ > $itemnumber=$query->param('itemnumber'); > DeleteTransfer($itemnumber); >+ my $recall_transfer_deleted = Koha::Recalls->find({ itemnumber => $itemnumber, status => 'T' }); >+ if ( defined $recall_transfer_deleted ) { >+ $recall_transfer_deleted->revert_transfer; >+ } > if($dest eq "ttr"){ > print $query->redirect("/cgi-bin/koha/circ/transferstoreceive.pl"); > exit; >@@ -353,6 +384,7 @@ $template->param( inputloop => \@inputloop ); > my $found = 0; > my $waiting = 0; > my $reserved = 0; >+my $recalled = 0; > > # new op dev : we check if the document must be returned to his homebranch directly, > # if the document is transferred, we have warning message . >@@ -469,6 +501,39 @@ if ( $messages->{'ResFound'}) { > ); > } > >+if ( $messages->{RecallFound} ) { >+ my $recall = $messages->{RecallFound}; >+ if ( dt_from_string( $recall->timestamp ) == dt_from_string ) { >+ # we just updated this recall >+ $template->param( recall => $recall ); >+ } else { >+ my $transfertodo = $messages->{RecallNeedsTransfer}; >+ $template->param( >+ found => 1, >+ recall => $recall, >+ recalled => $recall->waiting ? 0 : 1, >+ transfertodo => $transfertodo, >+ waitingrecall => $recall->waiting ? 1 : 0, >+ ); >+ } >+} >+ >+if ( $messages->{TransferredRecall} ) { >+ my $recall = $messages->{TransferredRecall}; >+ >+ # confirm transfer has arrived at the branch >+ my $transfer = Koha::Item::Transfers->search({ datearrived => { '!=' => undef }, itemnumber => $recall->itemnumber }, { order_by => { -desc => 'datearrived' } })->next; >+ >+ # if transfer has completed, show popup to confirm as waiting >+ if ( defined $transfer and $transfer->tobranch eq $recall->branchcode ) { >+ $template->param( >+ found => 1, >+ recall => $recall, >+ recalled => 1, >+ ); >+ } >+} >+ > # Error Messages > my @errmsgloop; > foreach my $code ( keys %$messages ) { >@@ -541,6 +606,12 @@ foreach my $code ( keys %$messages ) { > } > elsif ( $code eq 'ReturnClaims' ) { > $template->param( ReturnClaims => $messages->{ReturnClaims} ); >+ } elsif ( $code eq 'RecallFound' ) { >+ ; >+ } elsif ( $code eq 'RecallNeedsTransfer' ) { >+ ; >+ } elsif ( $code eq 'TransferredRecall' ) { >+ ; > } else { > die "Unknown error code $code"; # note we need all the (empty) elsif's above, or we die. > # This forces the issue of staying in sync w/ Circulation.pm >diff --git a/circ/transferstoreceive.pl b/circ/transferstoreceive.pl >index b9123f6c017..33055d3812f 100755 >--- a/circ/transferstoreceive.pl >+++ b/circ/transferstoreceive.pl >@@ -117,6 +117,13 @@ while ( my $library = $libraries->next ) { > if ( my $first_hold = $holds->next ) { > $getransf{patron} = Koha::Patrons->find( $first_hold->borrowernumber ); > } >+ >+ # check for a recall for this transfer >+ my $recall = $item->recall; >+ if ( defined $recall ) { >+ $getransf{recall} = $recall; >+ } >+ > push( @transferloop, \%getransf ); > } > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc >index 2080b07707d..4ef1173213f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc >@@ -41,5 +41,8 @@ > <a href="/cgi-bin/koha/catalogue/issuehistory.pl?biblionumber=[% biblio_object_id | url %]" >Checkout history</a></li> > [% IF ( CAN_user_tools_view_system_logs ) %][% IF ( logview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/tools/viewlog.pl?do_it=1&modules=CATALOGUING&action=MODIFY&object=[% biblio_object_id | url %]&object_type=biblio">Modification log</a> </li>[% END %] > [% IF ( CAN_user_stockrotation_manage_rota_items && Koha.Preference('StockRotation') ) %][% IF ( stockrotationview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/catalogue/stockrotation.pl?biblionumber=[% biblio_object_id | uri %]">Rota</a> </li>[% END %] >+ [% IF ( Koha.Preference('UseRecalls') && CAN_user_recalls ) %] >+ [% IF ( recallsview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/recalls/request.pl?biblionumber=[% biblio_object_id | url %]">Recalls ([% Biblio.RecallsCount( biblio_object_id ) | html %])</a></li> >+ [% END %] > </ul> > </div> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc >index d665e811045..8f5d996c936 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc >@@ -139,6 +139,9 @@ > [% IF Koha.Preference('ILLModule') && CAN_user_ill %] > [% IF illview %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/ill-requests.pl?borrowernumber=[% patron.borrowernumber | uri %]">ILL requests history</a></li> > [% END %] >+ [% IF Koha.Preference('UseRecalls') && CAN_user_recalls %] >+ [% IF recallsview %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/recallshistory.pl?borrowernumber=[% patron.borrowernumber | uri %]">Recalls history</a></li> >+ [% END %] > </ul></div> > > <!-- Modal --> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-nav.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-nav.inc >index 979871a0b99..535ba7be900 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-nav.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-nav.inc >@@ -39,6 +39,14 @@ > [% IF Koha.Preference('OnSiteCheckouts') %] > <li><a href="/cgi-bin/koha/circ/on-site_checkouts.pl">Pending on-site checkouts</a></li> > [% END %] >+ >+ [% IF Koha.Preference('UseRecalls') and CAN_user_recalls %] >+ <li><a href="/cgi-bin/koha/recalls/recalls_queue.pl" title="All active recalls">Recalls queue</a></li> >+ <li><a href="/cgi-bin/koha/recalls/recalls_to_pull.pl" title="Recalls that could be filled but have not been set waiting">Recalls to pull</a></li> >+ <li><a href="/cgi-bin/koha/recalls/recalls_overdue.pl" title="Recalled items that are overdue to be returned">Overdue recalls</a></li> >+ <li><a href="/cgi-bin/koha/recalls/recalls_waiting.pl" title="Recalled items awaiting pickup">Recalls awaiting pickup</a></li> >+ <li><a href="/cgi-bin/koha/recalls/recalls_old_queue.pl" title="Inactive recalls">Old recalls</a></li> >+ [% END %] > </ul> > > </div> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-title.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/patron-title.inc >index d5dcd7d0f0e..3daee1ce7e1 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-title.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/patron-title.inc >@@ -53,6 +53,7 @@ > [%- END -%] > [%- IF hide_patron_infos_if_needed AND ( display_patron_name OR display_cardnumber ) -%] > [%- IF link_to == 'circulation_reserves' %]<a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% data.borrowernumber | uri %]#reserves"> >+ [%- ELSIF link_to == 'circulation_recalls' %]<a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% data.borrowernumber | uri %]#recalls"> > [%- ELSE %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% data.borrowernumber | uri %]"> > [%- END -%] > [%- END -%] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/recalls.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/recalls.inc >new file mode 100644 >index 00000000000..2f43e9fb879 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/recalls.inc >@@ -0,0 +1,131 @@ >+<div id="recalls"> >+[% IF recalls.count %] >+ <table id="recalls-table"> >+ <thead> >+ <tr> >+ [% IF checkboxes %]<th class="recall-checkbox nosort"> </th>[% END %] >+ <th class="recall-title anti-the">Title</th> >+ [% UNLESS specific_patron %]<th class="recall-patron">Requested by</th>[% END %] >+ <th class="recall-date">Placed on</th> >+ <th class="recall-expiry">Expires on</th> >+ <th class="recall-branch">Pickup location</th> >+ <th class="recall-status">Status</th> >+ [% UNLESS viewing_old %]<th class="recall-duedate">Due date</th>[% END %] >+ [% UNLESS viewing_old %]<th class="recall-actions nosort"> </th>[% END %] >+ </tr> >+ </thead> >+ >+ <tbody> >+ [% FOREACH recall IN recalls %] >+ [% IF recall.old %]<tr class="old">[% ELSE %]<tr>[% END %] >+ >+ [% IF checkboxes %] >+ <td class="recall-checkbox"> >+ [% IF recall.old %] >+ >+ [% ELSE %] >+ <input type="checkbox" value="[% recall.recall_id | html %]" name="recall_ids"> >+ [% END %] >+ </td> >+ [% END %] >+ >+ <td class="recall-title"> >+ <b><a class="recall-title" href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% recall.biblionumber | html %]"> >+ [% recall.biblio.title | html %] >+ [% FOREACH s IN recall.biblio.subtitle %] >+ [% s | html %] >+ [% END %] >+ </a></b> >+ [% IF recall.item %][% recall.item.barcode | html %][% END %] >+ [% recall.biblio.author | html %] >+ </td> >+ >+ [% UNLESS specific_patron %] >+ <td class="recall-patron"> >+ <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% recall.borrowernumber | uri %]">[% recall.patron.firstname | html %] [% recall.patron.surname | html %] ([% recall.patron.cardnumber | html %])</a> >+ </td> >+ [% END %] >+ >+ <td class="recall-date"> >+ [% recall.recalldate | $KohaDates %] >+ </td> >+ >+ <td class="recall-expiry"> >+ [% IF ( recall.expirationdate ) %] >+ [% recall.expirationdate | $KohaDates %] >+ [% ELSIF ( !recall.old ) %] >+ Never expires >+ [% ELSE %] >+ - >+ [% END %] >+ </td> >+ >+ <td class="recall-branch"> >+ [% recall.library.branchname | html %] >+ </td> >+ >+ <td class="recall-status"> >+ [% IF ( recall.in_transit ) %] >+ In transit to [% recall.library.branchname | html %] >+ [% ELSIF ( recall.waiting ) %] >+ Ready for pickup >+ [% ELSIF ( recall.expired ) %] >+ Expired on [% recall.expirationdate | $KohaDates %] >+ [% ELSIF ( recall.cancelled ) %] >+ Cancelled on [% recall.cancellationdate | $KohaDates %] >+ [% ELSIF ( recall.overdue ) %] >+ Overdue to be returned >+ [% ELSIF ( recall.finished ) %] >+ Fulfilled >+ [% ELSE %] >+ Requested >+ [% END %] >+ </td> >+ >+ [% UNLESS viewing_old %] >+ <td class="recall-duedate"> >+ [% IF recall.requested and recall.checkout %] >+ Due to be returned by [% recall.checkout.date_due | $KohaDates %] >+ [% ELSIF recall.waiting and RECALL.expirationdate %] >+ Pick up by [% RECALL.expirationdate | $KohaDates %] >+ [% ELSE %] >+ - >+ [% END %] >+ </td> >+ [% END %] >+ >+ [% UNLESS viewing_old %] >+ <td class="recall-cancel actions"> >+ [% IF recall.old %] >+ >+ [% ELSE %] >+ <div class="btn-group"> >+ <a class="btn btn-sm dropdown-toggle" data-toggle="dropdown" href="#"> Actions <span class="caret"></span></a> >+ <ul class="dropdown-menu"> >+ [% IF ( recall.requested or recall.overdue ) %] >+ <li><a class="cancel_recall" data-id="[% recall.recall_id | html %]" data-action="cancel"><i class="fa fa-times"></i> Cancel</a></li> >+ [% IF ( recall.should_be_overdue ) %] >+ <li><a class="overdue_recall" data-id="[% recall.recall_id | html %]" data-action="overdue"><i class="fa fa-hourglass-end"></i> Mark as overdue</a></li> >+ [% END %] >+ [% ELSIF ( recall.waiting ) %] >+ <li><a class="revert_recall" data-id="[% recall.recall_id | html %]" data-action="revert"><i class="fa fa-undo"></i> Revert waiting</a></li> >+ <li><a class="expire_recall" data-id="[% recall.recall_id | html %]" data-action="expire"><i class="fa fa-times"></i> Expire</a></li> >+ [% END %] >+ </ul> >+ </div> >+ [% END %] >+ </td> >+ [% END %] >+ >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ [% ELSE %] >+ [% IF patron.borrowernumber %] >+ <div class="dialog message">Patron has no recalls.</div> >+ [% ELSE %] >+ <div class="dialog message">There are no recalls to show.</div> >+ [% END %] >+ [% END %] >+</div> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc >index 26aed467659..e55d106e4d3 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc >@@ -57,5 +57,6 @@ > var BROWSER_RETURN_TO_SEARCH = _("Results"); > var BROWSER_PREVIOUS = _("Previous"); > var BROWSER_NEXT = _("Next"); >+ var RECALLED = _("Recalled"); > </script> > <!-- / strings.inc --> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >index 95af8c679cb..1432675f6bf 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >@@ -391,14 +391,22 @@ Note that permanent location is a code, and location may be an authval. > There is an item level hold on this item (priority = [% hold.priority | html %]). > [% END %] > [% END %] >- [% UNLESS ( item.itemnotforloan || item.notforloan_per_itemtype || item.onloan || item.itemlost || item.withdrawn || item.damaged || item.transfertwhen || hold ) %] >+ >+ [% IF item.recalled %] >+ [% IF item.recall.waitingdate %] >+ Waiting at [% Branches.GetName( item.recall.branchcode ) | html %] since [% item.recall.waitingdate | $KohaDates %] >+ [% ELSE %] >+ Item recalled by <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% item.recall.borrowernumber | uri %]">[% item.recall.patron.firstname | html %] [% item.recall.patron.surname | html %] ([% item.recall.patron.cardnumber | html %])</a> on [% item.recall.recalldate | $KohaDates %] >+ [% END %] >+ [% END %] >+ >+ [% UNLESS ( item.itemnotforloan || item.notforloan_per_itemtype || item.onloan || item.itemlost || item.withdrawn || item.damaged || item.transfertwhen || hold || item.recalled ) %] > Available > [% END %] > > [% IF ( item.restricted ) %] > <span class="restricted">([% item.restrictedvalue | html %])</span> > [% END %] >- > </td> > <td class="datelastseen"><span title="[% item.datelastseen | html %]">[% item.datelastseen | $KohaDates %]</span></td> > <td class="dateaccessioned"><span title="[% item.dateaccessioned | html %]">[% item.dateaccessioned | $KohaDates %]</span></td> >@@ -895,6 +903,7 @@ Note that permanent location is a code, and location may be an authval. > [% MACRO jsinclude BLOCK %] > [% INCLUDE 'catalog-strings.inc' %] > [% Asset.js("js/catalog.js") | $raw %] >+ [% Asset.js("js/recalls.js") | $raw %] > [% Asset.js("js/coce.js") | $raw %] > <script> > var interface = "[% interface | html %]"; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt >index 220d7de5ea2..09d7cc36a7f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt >@@ -487,6 +487,9 @@ > Holds ([% Biblio.HoldsCount( SEARCH_RESULT.biblionumber ) | html %]) > [% END %] > [% END # /IF SEARCH_RESULT.norequests %] >+ [% IF Koha.Preference('UseRecalls') and CAN_user_recalls %] >+ | <a id="recall_[% SEARCH_RESULT.biblionumber | html %]" href="/cgi-bin/koha/recalls/request.pl?biblionumber=[% SEARCH_RESULT.biblionumber | html %]">Recalls ([% Biblio.RecallsCount( SEARCH_RESULT.biblionumber ) | html %])</a> >+ [% END %] > > [% IF Koha.Preference('intranetbookbag') == 1 %] > [% IF ( SEARCH_RESULT.incart ) %] >@@ -622,6 +625,9 @@ > [% IF ( other_items_loo.intransit ) %] > (In transit) > [% END %] >+ [% IF ( other_items_loo.recalled ) %] >+ (Recalled) >+ [% END %] > [% IF ( other_items_loo.onhold ) %] > (On hold) > [% END %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbooks.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbooks.tt >index 57fa62ba358..e0f70c994b7 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbooks.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbooks.tt >@@ -120,6 +120,7 @@ > [% IF ( resultsloo.itemlostcount ) %] Lost ([% resultsloo.itemlostcount | html %])<br />[% END %] > [% IF ( resultsloo.orderedcount ) %] On order ([% resultsloo.orderedcount | html %])<br/>[% END %] > [% IF ( resultsloo.notforloancount ) %] Not for loan ([% resultsloo.notforloancount | html %])[% END %] >+ [% IF ( resultsloo.recalledcount ) %] Waiting to fill recall ([% resultsloo.recalled | html %])[% END %] > [% IF ( resultsloo.onholdcount ) %] Waiting on hold ([% resultsloo.onholdcount | html %])[% END %] > </span> > </td> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt >index fbabec67457..429a595367b 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt >@@ -70,6 +70,18 @@ > <a class="circ-button" href="/cgi-bin/koha/circ/reserveratios.pl"><i class="fa fa-line-chart"></i> Hold ratios</a> > </li> > </ul> >+ >+ [% IF Koha.Preference('UseRecalls') and CAN_user_recalls %] >+ <h3>Recalls</h3> >+ >+ <ul class="buttons-list"> >+ <li><a class="circ-button" href="/cgi-bin/koha/recalls/recalls_queue.pl" title="All active recalls"><i class="fa fa-tasks"></i> Recalls queue</a></li> >+ <li><a class="circ-button" href="/cgi-bin/koha/recalls/recalls_to_pull.pl" title="Recalls that could be filled but have not been set waiting"><i class="fa fa-hand-grab-o"></i> Recalls to pull</a></li> >+ <li><a class="circ-button" href="/cgi-bin/koha/recalls/recalls_overdue.pl" title="Recalled items that are overdue to be returned"><i class="fa fa-clock-o"></i> Overdue recalls</a></li> >+ <li><a class="circ-button" href="/cgi-bin/koha/recalls/recalls_waiting.pl" title="Recalled items awaiting pickup"><i class="fa fa-calendar"></i> Recalls awaiting pickup</a></li> >+ <li><a class="circ-button" href="/cgi-bin/koha/recalls/recalls_old_queue.pl" title="Inactive recalls"><i class="fa fa-tasks"></i> Old recalls</a></li> >+ </ul> >+ [% END %] > </div> > > <!-- Add the extra clearfix for only the required viewport --> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >index b8ec599508c..753b34a72e8 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >@@ -196,6 +196,15 @@ > [% END %] > </li> > [% END %] >+ >+ [% IF RECALLED %] >+ [% IF RECALLED.waiting %] >+ <li>Item <i>[% RECALLED.biblio.title | html %]</i> ([% RECALLED.item.barcode | html %]) has been waiting for <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% RECALLED.borrowernumber | uri %]">[% RECALLED.patron.firstname | html %] [% RECALLED.patron.surname | html %]</a> ([% RECALLED.patron.cardnumber | html %]) at [% Branches.GetName( RECALLED.branchcode ) | html %] since [% RECALLED.waitingdate | $KohaDates %]</li> >+ [% ELSIF RECALLED.requested or RECALLED.overdue %] >+ <li>Item <i>[% RECALLED.biblio.title | html %]</i> [% IF RECALLED.item %]([% RECALLED.item.barcode | html %])[% END %] has been recalled by <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% RECALLED.borrowernumber | uri %]">[% RECALLED.patron.firstname | html %] [% RECALLED.patron.surname | html %]</a> ([% RECALLED.patron.cardnumber | html %]) at [% Branches.GetName( RECALLED.branchcode ) | html %] since [% RECALLED.recalldate | $KohaDates %]</li> >+ [% END %] >+ [% END %] >+ > </ul> > > [% IF CAN_user_circulate_force_checkout or HIGHHOLDS %] >@@ -227,6 +236,21 @@ > </p> > [% END %] > >+ [% IF ( RECALLED ) %] >+ <p> >+ <label for="cancelrecall">Cancel recall</label> >+ <input type="radio" value="cancel" name="cancel_recall" id="cancelrecall" /> >+ <input type="hidden" value="[% RECALLED.recall_id | html %]" name="recall_id" /> >+ </p> >+ [% IF RECALLED.waiting %] >+ <p> >+ <label for="revertrecall">Revert waiting status</label> >+ <input type="radio" value="revert" name="cancel_recall" id="revertrecall" checked="checked"/> >+ <input type="hidden" value="[% RECALLED.recall_id | html %]" name="recall_id" /> >+ </p> >+ [% END %] >+ [% END %] >+ > <input type="hidden" name="barcode" value="[% barcode | html %]" /> > <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]" /> > <input type="hidden" name="issueconfirmed" value="1" /> >@@ -277,6 +301,12 @@ > </form> > [% END %] > >+ [% IF ( RECALLED ) %] >+ <form method="get" action="/cgi-bin/koha/circ/circulation.pl"> >+ <button class="print" type="submit" onclick="Dopop('/cgi-bin/koha/recalls/recall_pickup_slip.pl?recall_id=[% RECALLED.recall_id | html %]');this.form.submit();"><i class="fa fa-print"></i> Don't check out and print slip (P)</button> >+ </form> >+ [% END %] >+ > <form method="get" action="/cgi-bin/koha/circ/circulation.pl"> > [% IF (forceallow) %]<input type="hidden" name="forceallow" value="1">[% END %] > <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]" /> >@@ -294,7 +324,7 @@ > [% END %] > </form> > >- [% IF ( RESERVED || ISSUED_TO_ANOTHER ) && (CAN_user_reserveforothers_place_holds ) %] >+ [% IF ( RESERVED || ISSUED_TO_ANOTHER || RECALLED ) && (CAN_user_reserveforothers_place_holds ) %] > [% UNLESS noissues %] > <button type="submit" onclick="window.location.href='/cgi-bin/koha/reserve/request.pl?biblionumber=[% itembiblionumber | html %]&borrowernumber=[% patron.borrowernumber | html %]'"><i class="fa fa-sticky-note-o"></i> Cancel checkout and place a hold for [% INCLUDE 'patron-title.inc' %]</button> > [% END %] >@@ -900,6 +930,14 @@ > </a> > </li> > [% END %] >+ >+ [% IF Koha.Preference('UseRecalls') %] >+ <li> >+ <a href="#recalls" id="recalls-tab"> >+ [% recalls.count | html %] Recalls >+ </a> >+ </li> >+ [% END %] > </ul> > > <!-- SUMMARY : TODAY & PREVIOUS ISSUES --> >@@ -914,6 +952,12 @@ > </div> <!-- /#clubs-tab --> > [% END %] > >+ [% IF Koha.Preference('UseRecalls') %] >+ <div id="recalls"> >+ [% INCLUDE 'recalls.inc' %] >+ </div> >+ [% END %] >+ > [% INCLUDE borrower_debarments.inc %] > > <div id="reserves"> >@@ -1154,6 +1198,7 @@ > </script> > [% INCLUDE 'str/members-menu.inc' %] > [% Asset.js("js/members-menu.js") | $raw %] >+ [% Asset.js("js/recalls.js") | $raw %] > [% END %] > > [% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt >index 78f74fd4c10..bc053f873b9 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt >@@ -8,6 +8,8 @@ > <title>Koha › Circulation › Transfers print receipt</title> > [% ELSIF ( caller == 'members' ) %] > <title>Koha › Patrons › Print receipt for [% borrowernumber | html %]</title> >+[% ELSIF ( caller == 'recall' ) %] >+<title>Koha › Circulation › Recall print receipt</title> > [% ELSIF ( title ) %][%# FIXME title is never defined %] > <title>Koha › Patrons › [% title | html %]</title> > [% END %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt >index 608ed5c84d7..c3638f340b4 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt >@@ -137,6 +137,9 @@ > [% ELSIF error == "onsite_checkout" %] > <p>Item cannot be renewed because it's an onsite checkout</p> > >+ [% ELSIF error == 'recalled' %] >+ <p>This item has been recalled.</p> >+ > [% ELSE %] > > [% error | html %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt >index bcde1e90cb8..4c2c76ab2de 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt >@@ -655,6 +655,199 @@ > </div> <!-- /.modal-dialog --> > </div> <!-- /#hold-found2 --> > [% END #/IF reserved %] >+ >+ [% IF ( recalled ) %] >+ <!-- recalled --> >+ <div id="recalled" class="modal fade audio-alert-action block"> >+ <div class="modal-dialog"> >+ <div class="modal-content"> >+ <form method="post" action="/cgi-bin/koha/circ/returns.pl" class="confirm"> >+ >+ <div class="modal-header"> >+ <h3> >+ Recall found: >+ <br/> >+ <a href="/cgi-bin/koha/catalogue/detail.pl?type=intra&biblionumber=[% recall.biblionumber | uri %]">[% recall.biblio.title | html %]</a> >+ [% IF recall.item %] >+ <div class="recall-found-barcode"> >+ (<a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% recall.biblionumber | uri %]&itemnumber=[% recall.itemnumber | uri %]">[% recall.item.barcode | html %]</a>) >+ </div> >+ [% END %] >+ </h3> >+ </div> >+ >+ <div class="modal-body"> >+ [% IF ( recall.recallnotes ) %] >+ <h4>Notes:</h4> >+ <p>[% recall.recallnotes | html %]</p> >+ <hr /> >+ [% END %] >+ <h5>Recall placed by:</h5> >+ <ul> >+ <li> >+ [% INCLUDE 'patron-title.inc' patron=recall.patron hide_patron_infos_if_needed=1 invert_name=1 link_to="circulation_recalls" %] >+ <span class="patron-category"> - [% recall.patron.category.description | html %]</span> >+ </li> >+ >+ [% INCLUDE display_holdpatron_address patron=recall.patron %] >+ >+ [% IF ( recall.patron.phone ) %] >+ <li>[% recall.patron.phone | html %]</li> >+ [% END %] >+ >+ [% IF ( recall.patron.email ) %] >+ <li> >+ [% IF ( transfertodo ) %] >+ [% recall.patron.email | html %] >+ [% ELSE %] >+ <a id="boremail" href="mailto:[% recall.patron.email | html %]">[% recall.patron.email | html %]</a> >+ [% END %] >+ </li> >+ [% END %] >+ >+ [% UNLESS ( transfertodo) %] >+ [% INCLUDE display_bormessagepref %] >+ [% END %] >+ >+ [% IF ( recall.patron.is_debarred ) %] >+ <li class="error">Patron is RESTRICTED</li> >+ [% END %] >+ >+ [% IF ( recall.patron.gonenoaddress ) %] >+ <li class="error">Patron's address is in doubt</li> >+ [% END %] >+ </ul> >+ [% IF ( transfertodo ) %] >+ <h4><strong>Transfer to:</strong> [% Branches.GetName( recall.branchcode ) | html %]</h4> >+ [% ELSE %] >+ <h4><strong>Recall at</strong> [% Branches.GetName( recall.branchcode ) | html %]</h4> >+ [% END %] >+ >+ <input type="hidden" name="recall_id" value="[% recall.recall_id | html %]"> >+ <input type="hidden" name="barcode" value="[% itembarcode | html %]"> >+ <input type="hidden" name="returnbranch" value="[% Branches.GetLoggedInBranchcode | html %]"> >+ <input type="hidden" name="recall_slip" value="0"> >+ >+ </div> >+ >+ <div class="modal-footer"> >+ [% IF ( transfertodo ) %] >+ <button type="submit" class="btn btn-default approve"> >+ <i class="fa fa-check"></i> Confirm recall and transfer >+ </button> >+ <button type="button" class="btn btn-default print-recall"> >+ <i class="fa fa-print"></i> Print slip, transfer, and confirm >+ </button> >+ [% ELSE %] >+ <button type="submit" class="btn btn-default approve"> >+ <i class="fa fa-check"></i> Confirm recall >+ </button> >+ <button type="button" class="btn btn-default print-recall"> >+ <i class="fa fa-print"></i> Print slip and confirm >+ </button> >+ [% END %] >+ >+ <button data-dismiss="modal" aria-hidden="true" type="submit" class="btn btn-default deny"> >+ <i class="fa fa-times"></i> Ignore >+ </button> >+ </div> <!-- /.modal-footer --> >+ </form> <!-- /.confirm --> >+ </div> <!-- /.modal-content --> >+ </div> <!-- /.modal-dialog --> >+ </div> <!-- /#recalled --> >+ [% END #/IF recalled %] >+ >+ [% IF ( waitingrecall ) %] >+ <!-- recalled --> >+ <div id="recalledwaiting" class="modal fade audio-alert-action block"> >+ <div class="modal-dialog"> >+ <div class="modal-content"> >+ <form method="post" action="/cgi-bin/koha/circ/returns.pl" class="confirm"> >+ >+ <div class="modal-header"> >+ <h3> >+ Recall found (item is already waiting): >+ <br/> >+ <a href="/cgi-bin/koha/catalogue/detail.pl?type=intra&biblionumber=[% recall.biblionumber | uri %]">[% recall.biblio.title | html %]</a> >+ [% IF recall.item %] >+ <div class="recall-found-barcode"> >+ (<a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% recall.biblionumber | uri %]&itemnumber=[% recall.itemnumber | uri %]">[% recall.item.barcode | html %]</a>) >+ </div> >+ [% END %] >+ </h3> >+ </div> >+ >+ <div class="modal-body"> >+ [% IF ( recall.recallnotes ) %] >+ <h4>Notes:</h4> >+ <p>[% recall.recallnotes | html %]</p> >+ <hr /> >+ [% END %] >+ <h5>Recall placed by:</h5> >+ <ul> >+ <li> >+ [% INCLUDE 'patron-title.inc' patron=recall.patron hide_patron_infos_if_needed=1 invert_name=1 link_to="circulation_recalls" %] >+ <span class="patron-category"> - [% recall.patron.category.description | html %]</span> >+ </li> >+ >+ [% INCLUDE display_holdpatron_address patron=recall.patron %] >+ >+ [% IF ( recall.patron.phone ) %] >+ <li>[% recall.patron.phone | html %]</li> >+ [% END %] >+ >+ [% IF ( recall.patron.email ) %] >+ <li> >+ [% IF ( transfertodo ) %] >+ [% recall.patron.email | html %] >+ [% ELSE %] >+ <a id="boremail" href="mailto:[% recall.patron.email | html %]">[% recall.patron.email | html %]</a> >+ [% END %] >+ </li> >+ [% END %] >+ >+ [% UNLESS ( transfertodo) %] >+ [% INCLUDE display_bormessagepref %] >+ [% END %] >+ >+ [% IF ( recall.patron.is_debarred ) %] >+ <li class="error">Patron is RESTRICTED</li> >+ [% END %] >+ >+ [% IF ( recall.patron.gonenoaddress ) %] >+ <li class="error">Patron's address is in doubt</li> >+ [% END %] >+ </ul> >+ [% IF ( transfertodo ) %] >+ <h4><strong>Transfer to:</strong> [% Branches.GetName( recall.branchcode ) | html %]</h4> >+ [% ELSE %] >+ <h4><strong>Wait for pickup at</strong> [% Branches.GetName( recall.branchcode ) | html %]</h4> >+ [% END %] >+ >+ <input type="hidden" name="recall_id" value="[% recall.recall_id | html %]"> >+ <input type="hidden" name="barcode" value="[% itembarcode | html %]"> >+ <input type="hidden" name="returnbranch" value="[% Branches.GetLoggedInBranchcode | html %]"> >+ <input type="hidden" name="recall_slip" value="0"> >+ >+ </div> >+ >+ <div class="modal-footer"> >+ <button type="submit" class="btn btn-default approve"> >+ <i class="fa fa-check"></i> Confirm recall >+ </button> >+ <button type="button" class="btn btn-default print-recall"> >+ <i class="fa fa-print"></i> Print slip and confirm >+ </button> >+ >+ <button data-dismiss="modal" aria-hidden="true" type="submit" class="btn btn-default deny"> >+ <i class="fa fa-times"></i> Ignore >+ </button> >+ </div> <!-- /.modal-footer --> >+ </form> <!-- /.confirm --> >+ </div> <!-- /.modal-content --> >+ </div> <!-- /.modal-dialog --> >+ </div> <!-- /#recalledwaiting--> >+ [% END #/IF recalledwaiting %] > [% END # /IF found %] > > <div class="static_checkin_messages"> >@@ -936,6 +1129,10 @@ > Dopop('hold-transfer-slip.pl?borrowernumber=[% borrowernumber | uri %]&biblionumber=[% biblionumber | uri %]&itemnumber=[% itemnumber | uri %]'); > [% END %] > >+ [% IF recall_slip %] >+ Dopop('/cgi-bin/koha/recalls/recall_pickup_slip.pl?recall_id=[% recall.recall_id | uri %]'); >+ [% END %] >+ > var columns_settings = [% ColumnsSettings.GetColumns( 'circ', 'returns', 'checkedintable', 'json' ) | $raw %] > var returns_table = KohaTable("checkedintable", { > "bFilter":false, >@@ -1042,6 +1239,11 @@ > this.form.submit(); > }); > >+ $('.print-recall').on("click",function(e){ >+ this.form.recall_slip.value = 1; >+ this.form.submit(); >+ }); >+ > $('.cancel-hold').on("click",function(e){ > this.form.cancel_reserve.value = 1; > this.form.submit(); >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/transferstoreceive.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/transferstoreceive.tt >index f0c3d4ffdfd..dde27299316 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/transferstoreceive.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/transferstoreceive.tt >@@ -68,6 +68,8 @@ > [% reser.patron.first_valid_email_address | html %] > </a> > [% END %] >+ [% ELSIF ( reser.recall ) %] >+ Recall requested by <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% reser.recall.borrowernumber | uri %]">[% reser.recall.patron.surname | html %][% IF reser.recall.patron.firstname %], [% reser.recall.patron.firstname | html %][% END %] ([% reser.recall.patron.cardnumber | html %])</a> > [% ELSE %] > <p>None</p> > [% END %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >index a6016d68d1b..c6d5687dca6 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >@@ -771,6 +771,14 @@ > </a> > </li> > [% END %] >+ >+ [% IF Koha.Preference('UseRecalls') %] >+ <li> >+ <a href="#recalls" id="recalls-tab"> >+ [% recalls.count | html %] Recalls >+ </a> >+ </li> >+ [% END %] > </ul> > > [% INCLUDE "checkouts-table.inc" %] >@@ -793,6 +801,12 @@ > </div> > [% END %] > >+ [% IF Koha.Preference('UseRecalls') %] >+ <div id="recalls"> >+ [% INCLUDE 'recalls.inc' %] >+ </div> >+ [% END %] >+ > [% INCLUDE borrower_debarments.inc %] > > [% IF ( CAN_user_circulate_circulate_remaining_permissions ) %] >@@ -910,6 +924,7 @@ > [% Asset.js("js/holds.js") | $raw %] > [% INCLUDE 'str/members-menu.inc' %] > [% Asset.js("js/members-menu.js") | $raw %] >+ [% Asset.js("js/recalls.js") | $raw %] > [% Asset.js("js/messaging-preference-form.js") | $raw %] > <script> > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/recallshistory.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/recallshistory.tt >new file mode 100644 >index 00000000000..b1f3c622330 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/recallshistory.tt >@@ -0,0 +1,48 @@ >+[% USE raw %] >+[% USE KohaDates %] >+[% USE Koha %] >+[% USE Asset %] >+[% SET footerjs = 1 %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Recalls history for [% INCLUDE 'patron-title.inc' %]</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+ >+<body id="recalls_history" class="pat"> >+ [% INCLUDE 'header.inc' %] >+ [% INCLUDE 'patron-search.inc' %] >+ >+ <div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> › >+ <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a> › >+ Recalls history for [% INCLUDE 'patron-title.inc' %] >+ </div> >+ <div class="main container-fluid"> >+ <div class="row"> >+ <div class="col-sm-10 col-sm-push-2"> >+ <main> >+ [% INCLUDE 'members-toolbar.inc' %] >+ <h1>Recalls history</h1> >+ [% IF Koha.Preference('UseRecalls') %] >+ <input type="checkbox" id="hide_old" name="hide_old" checked="checked"> >+ <label for="hide_old">Show old recalls</label> >+ [% INCLUDE 'recalls.inc' %] >+ [% ELSE %] >+ <div class="dialog message">Recalls have not been enabled. Enable the <a href="/cgi-bin/koha/admin/preferences.pl?tab=circulation">UseRecalls</a> system preference to use recalls.</div> >+ [% END %] >+ </main> >+ </div> >+ <div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'circ-menu.inc' %] >+ </aside> >+ </div> >+ </div> >+ >+[% MACRO jsinclude BLOCK %] >+ [% INCLUDE 'datatables.inc' %] >+ [% INCLUDE 'columns_settings.inc' %] >+ [% Asset.js("js/recalls.js") | $raw %] >+[% END %] >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_old_queue.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_old_queue.tt >new file mode 100644 >index 00000000000..e645bb78751 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_old_queue.tt >@@ -0,0 +1,56 @@ >+[% USE raw %] >+[% USE Koha %] >+[% USE KohaDates %] >+[% USE Asset %] >+[% SET footerjs = 1 %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Circulation › Old recalls</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+<body id="circ_recalls_old_queue" class="circ"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> >+ › <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a> >+ › <a href="/cgi-bin/koha/recalls/recalls_old_queue.pl">Old recalls</a> >+</div> >+ >+<div class="main container-fluid"> >+ <div class="row"> >+ [% IF Koha.Preference('CircSidebar') %] >+ <div class="col-sm-10 col-sm-push-2"> >+ [% ELSE %] >+ <div class="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2"> >+ [% END %] >+ <main> >+ >+ <h1>Old recalls</h1> >+ [% IF Koha.Preference('UseRecalls') %] >+ [% INCLUDE 'recalls.inc' %] >+ [% ELSE %] >+ <div class="dialog message">Recalls have not been enabled. Enable the <a href="/cgi-bin/koha/admin/preferences.pl?tab=circulation">UseRecalls</a> system preference to use recalls.</div> >+ [% END %] >+ >+ </main> >+ </div> <!-- /.col-etc --> >+ >+ [% IF Koha.Preference('CircSidebar') %] >+ <div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'circ-nav.inc' %] >+ </aside> >+ </div> <!-- /.col-sm-2.col-sm-pull-10 --> >+ [% END %] >+ >+ </div> <!-- /.row --> >+</div> >+ >+[% MACRO jsinclude BLOCK %] >+ [% INCLUDE 'datatables.inc' %] >+ [% INCLUDE 'columns_settings.inc' %] >+ [% Asset.js("js/recalls.js") | $raw %] >+[% END %] >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_overdue.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_overdue.tt >new file mode 100644 >index 00000000000..86c3a982071 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_overdue.tt >@@ -0,0 +1,67 @@ >+[% USE raw %] >+[% USE Koha %] >+[% USE KohaDates %] >+[% USE Asset %] >+[% SET footerjs = 1 %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Circulation › Overdue recalls</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+<body id="circ_overdue_recalls" class="circ"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> >+ › <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a> >+ › <a href="/cgi-bin/koha/recalls/recalls_overdue.pl">Overdue recalls</a> >+</div> >+ >+<div class="main container-fluid"> >+ <div class="row"> >+ [% IF Koha.Preference('CircSidebar') %] >+ <div class="col-sm-10 col-sm-push-2"> >+ [% ELSE %] >+ <div class="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2"> >+ [% END %] >+ <main> >+ >+ <h1>Overdue recalls</h1> >+ [% IF Koha.Preference('UseRecalls') %] >+ [% IF recalls.count %] >+ <form method="post" action="/cgi-bin/koha/recalls/recalls_overdue.pl"> >+ <input type="hidden" name="op" value="cancel_multiple_recalls"> >+ <input type="checkbox" id="select_all"> <span id="select_all_text">Select all</span> >+ [% INCLUDE 'recalls.inc' %] >+ <fieldset class="action"> >+ <button type="submit" id="cancel_selected" class="btn btn-default btn-sm">Cancel selected recalls</button> >+ </fieldset> >+ </form> >+ [% ELSE %] >+ <div class="dialog message">There are no recalls to show.</div> >+ [% END %] >+ [% ELSE %] >+ <div class="dialog message">Recalls have not been enabled. Enable the <a href="/cgi-bin/koha/admin/preferences.pl?tab=circulation">UseRecalls</a> system preference to use recalls.</div> >+ [% END %] >+ >+ </main> >+ </div> <!-- /.col-etc --> >+ >+ [% IF Koha.Preference('CircSidebar') %] >+ <div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'circ-nav.inc' %] >+ </aside> >+ </div> <!-- /.col-sm-2.col-sm-pull-10 --> >+ [% END %] >+ >+ </div> <!-- /.row --> >+</div> >+ >+[% MACRO jsinclude BLOCK %] >+ [% INCLUDE 'columns_settings.inc' %] >+ [% INCLUDE 'datatables.inc' %] >+ [% Asset.js("js/recalls.js") | $raw %] >+[% END %] >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_queue.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_queue.tt >new file mode 100644 >index 00000000000..e3caa919a3a >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_queue.tt >@@ -0,0 +1,67 @@ >+[% USE raw %] >+[% USE Koha %] >+[% USE KohaDates %] >+[% USE Asset %] >+[% SET footerjs = 1 %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Circulation › Recalls queue</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+<body id="circ_recalls_queue" class="circ"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> >+ › <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a> >+ › <a href="/cgi-bin/koha/recalls/recalls_queue.pl">Recalls queue</a> >+</div> >+ >+<div class="main container-fluid"> >+ <div class="row"> >+ [% IF Koha.Preference('CircSidebar') %] >+ <div class="col-sm-10 col-sm-push-2"> >+ [% ELSE %] >+ <div class="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2"> >+ [% END %] >+ <main> >+ >+ <h1>Recalls queue</h1> >+ [% IF Koha.Preference('UseRecalls') %] >+ [% IF recalls.count %] >+ <form method="post" action="/cgi-bin/koha/recalls/recalls_queue.pl"> >+ <input type="hidden" name="op" value="cancel_multiple_recalls"> >+ <input type="checkbox" id="select_all"> <span id="select_all_text">Select all</span> >+ [% INCLUDE 'recalls.inc' %] >+ <fieldset class="action"> >+ <button type="submit" id="cancel_selected" class="btn btn-default btn-sm">Cancel selected recalls</button> >+ </fieldset> >+ </form> >+ [% ELSE %] >+ <div class="dialog message">There are no recalls to show.</div> >+ [% END %] >+ [% ELSE %] >+ <div class="dialog message">Recalls have not been enabled. Enable the <a href="/cgi-bin/koha/admin/preferences.pl?tab=circulation">UseRecalls</a> system preference to use recalls.</div> >+ [% END %] >+ >+ </main> >+ </div> <!-- /.col-etc --> >+ >+ [% IF Koha.Preference('CircSidebar') %] >+ <div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'circ-nav.inc' %] >+ </aside> >+ </div> <!-- /.col-sm-2.col-sm-pull-10 --> >+ [% END %] >+ >+ </div> <!-- /.row --> >+</div> >+ >+[% MACRO jsinclude BLOCK %] >+ [% INCLUDE 'datatables.inc' %] >+ [% INCLUDE 'columns_settings.inc' %] >+ [% Asset.js("js/recalls.js") | $raw %] >+[% END %] >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_to_pull.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_to_pull.tt >new file mode 100644 >index 00000000000..c97efd65a8d >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_to_pull.tt >@@ -0,0 +1,175 @@ >+[% USE raw %] >+[% USE Koha %] >+[% USE KohaDates %] >+[% USE AuthorisedValues %] >+[% USE Branches %] >+[% USE ItemTypes %] >+[% USE Asset %] >+[% SET footerjs = 1 %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Circulation › Recalls to pull</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+<body id="circ_recalls_to_pull" class="circ"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> >+ › <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a> >+ › <a href="/cgi-bin/koha/recalls/recalls_to_pull.pl">Recalls to pull</a> >+</div> >+ >+<div class="main container-fluid"> >+ <div class="row"> >+ [% IF Koha.Preference('CircSidebar') %] >+ <div class="col-sm-10 col-sm-push-2"> >+ [% ELSE %] >+ <div class="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2"> >+ [% END %] >+ <main> >+ >+ <h1>Recalls to pull</h1> >+ The following recalls could be fulfilled by available items. >+ >+ [% IF Koha.Preference('UseRecalls') %] >+ <div id="recalls"> >+ [% IF recalls %] >+ <table id="recalls-table"> >+ <thead> >+ <tr> >+ <th class="recall-topull">Pull this many items</th> >+ <th class="recall-items">Items available</th> >+ <th class="recall-patrons">Patrons with recalls</th> >+ <th class="recall-firstpatron">First patron</th> >+ <th class="recall-title anti-the">Title</th> >+ <th class="recall-libraries">Libraries</th> >+ <th class="recall-callnumbers">Available call numbers</th> >+ <th class="recall-copynumbers">Available copy numbers</th> >+ <th class="recall-enumeration">Available enumeration</th> >+ <th class="recall-itemtypes">Available item types</th> >+ <th class="recall-locations">Available locations</th> >+ <th class="recall-date title-string">Earliest recall date</th> >+ <th class="recall-action nosort"> </th> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH recall IN recalls %] >+ <tr> >+ <td class="recall-topull"><b>[% recall.pull_count | html %]</b></td> >+ <td class="recall-items">[% recall.items_count | html %]</td> >+ <td class="recall-patrons">[% recall.patrons_count | html %]</td> >+ <td class="recall-firstpatron"><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% recall.first_recall.borrowernumber | uri %]">[% recall.first_recall.patron.firstname | html %] [% recall.first_recall.patron.surname | html %]</a></td> >+ <td class="recall-title"> >+ [% INCLUDE 'biblio-default-view.inc' biblionumber=recall.first_recall.biblio.biblionumber %] >+ [% INCLUDE 'biblio-title.inc' biblio=recall.first_recall.biblio %] >+ [% IF recall.first_recall.biblio.author %] by [% recall.first_recall.biblio.author | html %][% END %] >+ </td> >+ <td class="recall-libraries"> >+ <ul> >+ [% FOREACH library IN recall.libraries %] >+ <li>[% Branches.GetName( library ) | html %]</li> >+ [% END %] >+ </ul> >+ </td> >+ <td class="recall-callnumbers"> >+ <ul> >+ [% FOREACH callnumber IN recall.callnumbers %] >+ <li>[% callnumber | html %]</li> >+ [% END %] >+ </ul> >+ </td> >+ <td class="recall-copynumbers"> >+ <ul> >+ [% FOREACH copyno IN recall.copynumbers %] >+ <li>[% copyno | html %]</li> >+ [% END %] >+ </ul> >+ </td> >+ <td class="recall-enumeration"> >+ <ul> >+ [% FOREACH enumchron IN recall.enumchrons %] >+ <li>[% enumchron | html %]</li> >+ [% END %] >+ </ul> >+ </td> >+ <td class="recall-itemtypes"> >+ <ul> >+ [% FOREACH itemtype IN recall.itemtypes %] >+ <li>[% ItemTypes.GetDescription( itemtype ) | html %]</li> >+ [% END %] >+ </ul> >+ </td> >+ <td class="recall-locations"> >+ <ul> >+ [% FOREACH loc IN recall.locations %] >+ <li>[% AuthorisedValues.GetByCode('LOC', loc) | html %]</li> >+ [% END %] >+ </ul> >+ </td> >+ <td class="recall-date"> >+ <span title="[% recall.first_recall.recalldate | html %]">[% recall.first_recall.recalldate | $KohaDates %] in [% recall.first_recall.library.branchname | html %]</span> >+ </td> >+ <td class="recall-action"> >+ <form action="/cgi-bin/koha/recalls/recalls_to_pull.pl" method="post"> >+ <input type="hidden" name="recall_id" value="[% recall.first_recall.recall_id | html %]"> >+ <input type="hidden" name="op" value="cancel"> >+ [% IF recall.first_recall.in_transit %] >+ <button type="submit" class="btn btn-default cancelreturn"><i class="fa fa-times"></i> Cancel recall and return to: [% recall.first_recall.item.homebranch | html %]</button> >+ [% ELSE %] >+ <button type="submit" class="btn btn-default cancel"><i class="fa fa-times"></i> Cancel recall</button> >+ [% END %] >+ </form> >+ </td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ [% ELSE %] >+ <div class="dialog message">There are no recalls to pull.</div> >+ [% END %] >+ </div> >+ [% ELSE %] >+ <div class="dialog message">Recalls have not been enabled. Enable the <a href="/cgi-bin/koha/admin/preferences.pl?tab=circulation">UseRecalls</a> system preference to use recalls.</div> >+ [% END %] >+ >+ </main> >+ </div> <!-- /.col-etc --> >+ >+ [% IF Koha.Preference('CircSidebar') %] >+ <div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'circ-nav.inc' %] >+ </aside> >+ </div> <!-- /.col-sm-2.col-sm-pull-10 --> >+ [% END %] >+ >+ </div> <!-- /.row --> >+</div> >+ >+[% MACRO jsinclude BLOCK %] >+ [% INCLUDE 'datatables.inc' %] >+ [% INCLUDE 'columns_settings.inc' %] >+ <script> >+ $(document).ready(function(){ >+ $("#recalls-table").dataTable($.extend(true, {}, dataTablesDefaults, { >+ "aoColumnDefs": [ >+ { 'bSortable': false, 'aTargets': [ 'nosort' ] }, >+ { "sType": "title-string", "aTargets" : [ "title-string" ] }, >+ { "sType": "anti-the", "aTargets": [ "anti-the" ] } >+ ], >+ "sPaginationType": "full_numbers" >+ })); >+ >+ $(".cancelreturn").click(function(){ >+ return confirmDelete(_("Are you sure you want to remove this recall and return the item to it's home library?")); >+ }); >+ >+ $(".cancel").click(function(){ >+ return confirmDelete(_("Are you sure you want to remove this recall?")); >+ }); >+ }); >+ </script> >+[% END %] >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_waiting.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_waiting.tt >new file mode 100644 >index 00000000000..d7b40e2dc15 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/recalls_waiting.tt >@@ -0,0 +1,181 @@ >+[% USE raw %] >+[% USE Koha %] >+[% USE KohaDates %] >+[% USE Asset %] >+[% SET footerjs = 1 %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Circulation › Recalls awaiting pickup</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+<body id="circ_recalls_awaiting_pickup" class="circ"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> >+ › <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a> >+ › <a href="/cgi-bin/koha/recalls/recalls_waiting.pl">Recalls awaiting pickup</a> >+</div> >+ >+<div class="main container-fluid"> >+ <div class="row"> >+ [% IF Koha.Preference('CircSidebar') %] >+ <div class="col-sm-10 col-sm-push-2"> >+ [% ELSE %] >+ <div class="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2"> >+ [% END %] >+ <main> >+ <h1>Recalls awaiting pickup</h1> >+ >+ [% IF Koha.Preference('UseRecalls') %] >+ >+ <div id="results" class="toptabs"> >+ >+ <ul> >+ <li><a href="#recallswaiting">Recalls waiting: [% recalls.count | html %]</a></li> >+ <li><a href="#recallsover">Recalls waiting over [% Koha.Preference('RecallsMaxPickUpDelay') | html %] days: [% over.count | html %]</a></li> >+ </ul> >+ >+ <div id="recallswaiting"> >+ [% IF ( recalls ) %] >+ <table id="recallswaiting-table"> >+ <thead><tr> >+ <th class="recall-waitingdate title-string">Available since</th> >+ <th class="recall-title anti-the">Title</th> >+ <th class="recall-patron">Requested by</th> >+ <th class="recall-library">Pickup location</th> >+ <th class="recall-action nosort"> </th> >+ </tr></thead> >+ <tbody> >+ [% FOREACH recall IN recalls %]<tr> >+ <td class="recall-waitingdate">[% recall.waitingdate | $KohaDates %]</td> >+ <td class="recall-title"> >+ <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% recall.biblionumber | uri %]"> >+ [% recall.biblio.title | html %] >+ [% FOREACH s IN recall.biblio.subtitle %] >+ [% s | html %] >+ [% END %] >+ </a> >+ [% recall.biblio.author | html %] >+ <br><i>Barcode: [% recall.item.barcode | html %]</i> >+ </td> >+ <td class="recall-patron"> >+ <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% recall.borrowernumber | uri %]">[% recall.patron.firstname | html %] [% recall.patron.surname | html %]</a> >+ [% IF ( recall.patron.phone ) %]<br />[% recall.patron.phone | html %][% END %] >+ [% IF ( recall.patron.email ) %]<br /><a href="mailto:[% recall.patron.email | uri %]?subject=Recall waiting: [% recall.biblio.title | uri %]">[% recall.patron.email | html %]</a>[% END %] >+ </td> >+ <td class="recall-library">[% recall.library.branchname | html %]</td> >+ <td class="recall-action actions"> >+ <form action="/cgi-bin/koha/recalls/recalls_waiting.pl" method="post"> >+ <input type="hidden" name="recall_id" value="[% recall.recall_id | html %]"> >+ <input type="hidden" name="op" value="modify"> >+ <fieldset class="action"> >+ <input type="submit" name="revert" class="revert_recall" value="Revert waiting status"> >+ <input type="submit" name="expire" class="expire_recall" value="Expire recall"> >+ </fieldset> >+ </form> >+ </td> >+ </tr>[% END %] >+ </tbody> >+ </table> >+ [% ELSE %] >+ <div class="dialog message">There are no recalls to show.</div> >+ [% END %] >+ </div> <!-- recallswaiting --> >+ >+ <div id="recallsover"> >+ [% IF ( over.size ) %] >+ [% IF ( Koha.Preference('RecallsMaxPickUpDelay') ) %]<p>Recalls listed here have been awaiting pickup for more than [% Koha.Preference('RecallsMaxPickUpDelay') | html %] days.</p>[% END %] >+ <table id="recallsover-table"> >+ <thead><tr> >+ <th class="recall-waitingdate title-string">Available since</th> >+ <th class="recall-title anti-the">Title</th> >+ <th class="recall-patron">Requested by</th> >+ <th class="recall-library">Pickup location</th> >+ <th class="recall-action nosort"> </th> >+ </tr></thead> >+ <tbody> >+ [% FOREACH recall IN over %]<tr> >+ <td class="recall-waitingdate">[% recall.waitingdate | $KohaDates %]</td> >+ <td class="recall-title"> >+ <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% recall.biblionumber | uri %]"> >+ [% recall.biblio.title | html %] >+ [% FOREACH s IN recall.biblio.subtitles %] >+ [% s | html %] >+ [% END %] >+ [% recall.item.enumchron | html %] >+ </a> >+ [% recall.biblio.author | html %] >+ <br><i>Barcode: [% recall.item.barcode | html %]</i> >+ </td> >+ <td class="recall-patron"> >+ <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% recall.borrowernumber | uri %]">[% recall.patron.firstname | html %] [% recall.patron.surname | html %]</a> >+ [% IF ( recall.patron.phone ) %]<br />[% recall.patron.phone | html %][% END %] >+ [% IF ( recall.patron.email ) %]<br /><a href="mailto:[% recall.patron.email | uri %]?subject=Recall waiting: [% recall.biblio.title | uri %]">[% recall.patron.email | html %]</a>[% END %] >+ </td> >+ <td class="recall-library">[% recall.library.branchname | html %]</td> >+ <td class="recall-action actions"> >+ <form action="/cgi-bin/koha/recalls/recalls_waiting.pl" method="post"> >+ <input type="hidden" name="recall_id" value="[% recall.recall_id | html %]"> >+ <input type="hidden" name="op" value="modify"> >+ <fieldset class="action"> >+ <input type="submit" name="revert" class="revert_recall" value="Revert waiting status"> >+ <input type="submit" name="expire" class="expire_recall" value="Expire recall"> >+ </fieldset> >+ </form> >+ </td> >+ </tr>[% END %] >+ </tbody> >+ </table> >+ [% ELSE %] >+ <div class="dialog message">There are no recalls to show.</div> >+ [% END %] >+ </div> <!-- recallsover --> >+ >+ </div> <!-- results--> >+ >+ [% ELSE %] >+ <div class="dialog message">Recalls have not been enabled. Enable the <a href="/cgi-bin/koha/admin/preferences.pl?tab=circulation">UseRecalls</a> system preference to use recalls.</div> >+ [% END %] <!-- Koha.Preference('UseRecalls') --> >+ >+ </main> >+ </div> <!-- /.col-etc --> >+ >+ [% IF Koha.Preference('CircSidebar') %] >+ <div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'circ-nav.inc' %] >+ </aside> >+ </div> <!-- /.col-sm-2.col-sm-pull-10 --> >+ [% END %] >+ >+ </div> <!-- /.row --> >+</div> >+ >+[% MACRO jsinclude BLOCK %] >+ [% INCLUDE 'datatables.inc' %] >+ [% INCLUDE 'columns_settings.inc' %] >+ <script type="text/javascript"> >+ $(document).ready(function() { >+ $('#results').tabs(); >+ >+ $("#recallswaiting-table, #recallsover-table").dataTable($.extend(true, {}, dataTablesDefaults, { >+ "autoWidth": false, >+ "aoColumnDefs": [ >+ { 'bSortable': false, 'aTargets': [ 'nosort' ] }, >+ ], >+ "sPaginationType": "full_numbers" >+ })); >+ >+ $(".revert_recall").click(function(e) { >+ return confirmDelete(_("Are you sure you want to revert this recall's status from Waiting?")); >+ }); >+ >+ $(".expire_recall").click(function(e) { >+ return confirmDelete(_("Are you sure you want to remove this recall?")); >+ }); >+ }); >+ </script> >+[% END %] >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/request.tt >new file mode 100644 >index 00000000000..c085368bb38 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/request.tt >@@ -0,0 +1,63 @@ >+[% USE raw %] >+[% USE Asset %] >+[% USE Koha %] >+[% USE KohaDates %] >+[% SET footerjs = 1 %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Circulation › Recalls › Confirm recalls</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+<body id="recalls-request" class="catalog"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'circ-search.inc' %] >+ >+<div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> › >+ <a href="/cgi-bin/koha/catalogue/search.pl">Catalog</a> › >+ <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblio.biblionumber | uri %]">[% biblio.title | html %]</a> › >+ Confirm recalls on [% biblio.title | html %] >+</div> >+ >+<div class="main container-fluid"> >+<div class="row"> >+<div class="col-sm-10 col-sm-push-2"> >+<main> >+ >+ <h1>Existing recalls</h1> >+ >+ [% IF Koha.Preference('UseRecalls') %] >+ [% IF recalls.count %] >+ <form method="post" action="/cgi-bin/koha/recalls/request.pl"> >+ <input type="hidden" name="op" value="cancel_multiple_recalls"> >+ <input type="checkbox" id="select_all"> <span id="select_all_text">Select all</span> >+ [% INCLUDE 'recalls.inc' %] >+ <fieldset class="action"> >+ <button type="submit" id="cancel_selected" class="btn btn-default btn-sm">Cancel selected recalls</button> >+ </fieldset> >+ </form> >+ [% ELSE %] >+ <div class="dialog message">No recalls have been made.</div> >+ [% END %] >+ [% ELSE %] >+ <div class="dialog message">Recalls have not been enabled. Enable the <a href="/cgi-bin/koha/admin/preferences.pl?tab=circulation">UseRecalls</a> system preference to use recalls.</div> >+ [% END %] >+ >+</main> >+</div> <!-- /.col-sm-10.col-sm-push-2 --> >+ >+<div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'biblio-view-menu.inc' %] >+ </aside> >+</div> <!-- .col-sm-2.col-sm-pull-10 --> >+ >+</div> <!-- /.row --> >+</div> <!-- /.main.container-fluid --> >+ >+[% MACRO jsinclude BLOCK %] >+ [% Asset.js("js/recalls.js") | $raw %] >+ [% INCLUDE 'datatables.inc' %] >+ [% INCLUDE 'columns_settings.inc' %] >+[% END %] >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >index 2f5f0ebdb70..9a29d634c67 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >@@ -296,7 +296,7 @@ > </div> > [% END %] > >- [% IF ( exceeded_maxreserves || exceeded_holds_per_record || alreadyreserved || none_available || alreadypossession || ageRestricted ) %] >+ [% IF ( exceeded_maxreserves || exceeded_holds_per_record || alreadyreserved || none_available || alreadypossession || ageRestricted || recall ) %] > <div class="dialog alert"> > > [% UNLESS ( multi_hold ) %] >@@ -316,6 +316,8 @@ > <li> <strong>No items are available</strong> to be placed on hold.</li> > [% ELSIF ( maxreserves ) %] > <li><strong>Too many holds: </strong> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %] </a> has too many holds.</li> >+ [% ELSIF ( recall ) %] >+ <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %]</a> has <strong>already placed a recall</strong> on this item.</li> > [% END # /IF exceeded_maxreserves %] > </ul> > [% ELSE # UNLESS multi_hold %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt >index 259d36d32bd..963875ea994 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt >@@ -53,6 +53,7 @@ fieldset.rows label.viewlog { > [% CASE 'SYSTEMPREFERENCE' %]System prefs > [% CASE 'CRONJOBS' %]Cron jobs > [% CASE 'REPORTS' %]Reports >+[% CASE 'RECALLS' %]Recalls > [% CASE %][% module | html %] > [% END %] > [% END %] >@@ -75,6 +76,9 @@ fieldset.rows label.viewlog { > [% CASE 'DELCIRCMESSAGE' %]Delete circulation message > [% CASE 'STATUS_CHANGE' %]Change ILL request status > [% CASE 'Run' %]Run >+[% CASE 'FULFILL' %]Fulfill >+[% CASE 'OVERDUE' %]Overdue >+[% CASE 'EXPIRE' %]Expire > [% CASE %][% action | html %] > [% END %] > [% END %] >@@ -124,7 +128,7 @@ fieldset.rows label.viewlog { > [% ELSE %] > <label for="moduleALL" class="viewlog"><input type="checkbox" id="moduleALL" name="modules" value=""> All</label> > [% END %] >- [% FOREACH modx IN [ 'AUTH' 'CATALOGUING' 'AUTHORITIES' 'MEMBERS' 'ACQUISITIONS' 'SERIAL' 'HOLDS' 'ILL' 'CIRCULATION' 'LETTER' 'FINES' 'SYSTEMPREFERENCE' 'CRONJOBS', 'REPORTS' ] %] >+ [% FOREACH modx IN [ 'AUTH' 'CATALOGUING' 'AUTHORITIES' 'MEMBERS' 'ACQUISITIONS' 'SERIAL' 'HOLDS' 'ILL' 'CIRCULATION' 'LETTER' 'FINES' 'SYSTEMPREFERENCE' 'CRONJOBS' 'REPORTS' 'RECALLS' ] %] > [% IF modules.grep(modx).size %] > <label for="module[% modx | html %]" class="viewlog"><input type="checkbox" id="module[% modx | html %]" name="modules" value="[% modx | html %]" checked="checked"> [% PROCESS translate_log_module module=modx %]</label> > [% ELSE %] >@@ -146,7 +150,7 @@ fieldset.rows label.viewlog { > <label for="actionALL" class="viewlog"><input type="checkbox" id="actionALL" name="actions" value=""> All</label> > [% END %] > >- [% FOREACH actx IN [ 'ADD' 'DELETE' 'MODIFY' 'ISSUE' 'RETURN' 'RENEW' 'CREATE' 'CANCEL' 'SUSPEND' 'RESUME' 'ADDCIRCMESSAGE' 'DELCIRCMESSAGE' 'STATUS_CHANGE' 'CHANGE PASS' 'Run' ] %] >+ [% FOREACH actx IN [ 'ADD' 'DELETE' 'MODIFY' 'ISSUE' 'RETURN' 'RENEW' 'CREATE' 'CANCEL' 'SUSPEND' 'RESUME' 'ADDCIRCMESSAGE' 'DELCIRCMESSAGE' 'STATUS_CHANGE' 'CHANGE PASS' 'Run' 'OVERDUE' 'EXPIRE' 'FULFILL' ] %] > [% IF actions.grep(actx).size %] > <label for="action[% actx | html %]" class="viewlog"><input type="checkbox" id="action[% actx | html %]" name="actions" value="[% actx | html %]" checked="checked"> [% PROCESS translate_log_action action=actx %]</label> > [% ELSE %] >@@ -264,6 +268,12 @@ fieldset.rows label.viewlog { > [% ELSE %] > [% loopro.object | html %] > [% END %] >+ [% ELSIF ( loopro.module == 'RECALLS' ) %] >+ [% IF loopro.recall.item_level_recall %] >+ Item-level recall on <a href="/cgi-bin/koha/catalogue/moredetail.pl?item=[% loopro.recall.itemnumber | uri %]&biblionumber=[% loopro.recall.biblionumber | uri %]&bi=[% loopro.recall.item.biblioitemnumber | uri %]">item</a> >+ [% ELSE %] >+ Biblio-level recall on <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% loopro.recall.biblionumber | uri %]">biblio</a> >+ [% END %] > [% ELSE %] > [% IF ( loopro.module == 'SERIAL' ) %] > <a href="/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=[% loopro.object | uri %]">Subscription [% loopro.object | html %] </a> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/checkouts.js b/koha-tmpl/intranet-tmpl/prog/js/checkouts.js >index 1b9b4a213d6..3b183461ec8 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/checkouts.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/checkouts.js >@@ -331,6 +331,10 @@ $(document).ready(function() { > onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>"; > } > >+ if ( oObj.recalled == 1 ) { >+ title += " - <span class='circ-hlt item-recalled'>This item has been recalled and the due date updated.</span>"; >+ } >+ > title += " " > + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=" > + oObj.biblionumber >@@ -419,6 +423,13 @@ $(document).ready(function() { > > if ( oObj.can_renew ) { > // Do nothing >+ } else if ( oObj.can_renew_error == "recalled" ) { >+ msg += "<span>" >+ + "<a href='/cgi-bin/koha/recalls/request.pl?biblionumber=" + oObj.biblionumber + "'>" + RECALLED + "</a>" >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed-recalled"; > } else if ( oObj.can_renew_error == "on_reserve" ) { > msg += "<span>" > + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>" >@@ -541,7 +552,9 @@ $(document).ready(function() { > "bSortable": false, > "bVisible": AllowCirculate ? true : false, > "mDataProp": function ( oObj ) { >- if ( oObj.can_renew_error == "on_reserve" ) { >+ if ( oObj.can_renew_error == "recalled" ) { >+ return "<a href='/cgi-bin/koha/recalls/request.pl?biblionumber=" + oObj.biblionumber + "'>" + RECALLED + "</a>"; >+ } else if ( oObj.can_renew_error == "on_reserve" ) { > return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"; > } else { > return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>"; >diff --git a/koha-tmpl/intranet-tmpl/prog/js/recalls.js b/koha-tmpl/intranet-tmpl/prog/js/recalls.js >new file mode 100644 >index 00000000000..ee637de5827 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/js/recalls.js >@@ -0,0 +1,147 @@ >+$(document).ready(function() { >+ >+ $(".cancel_recall").click(function(e){ >+ if (confirmDelete(_("Are you sure you want to remove this recall?"))){ >+ var $self = $(this); >+ var $recall_id = $(this).data('id'); >+ var $action = $(this).data('action'); >+ var ajaxData = { >+ 'recall_id': $recall_id, >+ 'action' : $action, >+ }; >+ >+ $.ajax({ >+ url: '/cgi-bin/koha/svc/recall', >+ type: 'POST', >+ dataType: 'json', >+ data: ajaxData, >+ }) >+ .done(function(data) { >+ var message = ""; >+ if(data.success == 0) { >+ message = _("The recall may have already been cancelled. Please refresh the page."); >+ } else { >+ message = _("Cancelled"); >+ } >+ $self.parent().parent().parent().parent().html(message); >+ }); >+ } >+ }); >+ >+ $(".expire_recall").click(function(e){ >+ if (confirmDelete(_("Are you sure you want to expire this recall?"))){ >+ var $self = $(this); >+ var $recall_id = $(this).data('id'); >+ var $action = $(this).data('action'); >+ var ajaxData = { >+ 'recall_id': $recall_id, >+ 'action' : $action, >+ }; >+ >+ $.ajax({ >+ url: '/cgi-bin/koha/svc/recall', >+ type: 'POST', >+ dataType: 'json', >+ data: ajaxData, >+ }) >+ .done(function(data) { >+ var message = ""; >+ if(data.success == 0) { >+ message = _("The recall may have already been expired. Please refresh the page."); >+ } else { >+ message = _("Expired"); >+ } >+ $self.parent().parent().parent().parent().html(message); >+ }); >+ } >+ }); >+ >+ $(".revert_recall").click(function(e){ >+ if (confirmDelete(_("Are you sure you want to revert the waiting status of this recall?"))){ >+ var $self = $(this); >+ var $recall_id = $(this).data('id'); >+ var $action = $(this).data('action'); >+ var ajaxData = { >+ 'recall_id': $recall_id, >+ 'action' : $action, >+ }; >+ >+ $.ajax({ >+ url: '/cgi-bin/koha/svc/recall', >+ type: 'POST', >+ dataType: 'json', >+ data: ajaxData, >+ }) >+ .done(function(data) { >+ var message = ""; >+ if(data.success == 0) { >+ message = _("The recall waiting status may have already been reverted. Please refresh the page."); >+ } else { >+ message = _("Status updated"); >+ } >+ $self.parent().parent().parent().parent().html(message); >+ }); >+ } >+ }); >+ >+ $(".overdue_recall").click(function(e){ >+ if (confirmDelete(_("Are you sure you want to mark this recall as overdue?"))){ >+ var $self = $(this); >+ var $recall_id = $(this).data('id'); >+ var $action = $(this).data('action'); >+ var ajaxData = { >+ 'recall_id': $recall_id, >+ 'action' : $action, >+ }; >+ >+ $.ajax({ >+ url: '/cgi-bin/koha/svc/recall', >+ type: 'POST', >+ dataType: 'json', >+ data: ajaxData, >+ }) >+ .done(function(data) { >+ var message = ""; >+ if(data.success == 0) { >+ message = _("The recall may have already been marked as overdue. Please refresh the page."); >+ } else { >+ message = _("Marked overdue"); >+ } >+ $self.parent().parent().parent().parent().html(message); >+ }); >+ } >+ }); >+ >+ $("#recalls-table").dataTable($.extend(true, {}, dataTablesDefaults, { >+ "aoColumnDefs": [ >+ { 'bSortable': false, 'aTargets': [ 'nosort' ] }, >+ { "sType": "title-string", "aTargets" : [ "title-string" ] }, >+ { "sType": "anti-the", "aTargets": [ "anti-the" ] } >+ ], >+ "sPaginationType": "full_numbers" >+ })); >+ >+ $("#cancel_selected").click(function(e){ >+ if ($("input[name='recall_ids']:checked").length > 0){ >+ return confirmDelete(_("Are you sure you want to remove the selected recall(s)?")); >+ } else { >+ alert(_("Please make a selection.")); >+ } >+ }); >+ >+ $("#select_all").click(function(){ >+ if ($("#select_all").prop("checked")){ >+ $("input[name='recall_ids']").prop("checked", true); >+ } else { >+ $("input[name='recall_ids']").prop("checked", false); >+ } >+ }); >+ >+ $("#hide_old").click(function(){ >+ if ($("#hide_old").prop("checked")){ >+ $(".old").show(); >+ } else { >+ $(".old").hide(); >+ } >+ }); >+}); >diff --git a/members/moremember.pl b/members/moremember.pl >index 656ee35a939..9e8ad05d7e0 100755 >--- a/members/moremember.pl >+++ b/members/moremember.pl >@@ -210,6 +210,8 @@ $template->param( > relatives_issues_count => $relatives_issues_count, > relatives_borrowernumbers => \@relatives, > logged_in_user => $logged_in_user, >+ recalls => $patron->recalls, >+ specific_patron => 1, > ); > > output_html_with_http_headers $input, $cookie, $template->output; >diff --git a/members/recallshistory.pl b/members/recallshistory.pl >new file mode 100755 >index 00000000000..175f15945e4 >--- /dev/null >+++ b/members/recallshistory.pl >@@ -0,0 +1,47 @@ >+#!/usr/bin/perl >+ >+# Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz> >+# >+# This file is part of Koha. >+ >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+ >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw ( -utf8 ); >+use C4::Auth; >+use C4::Output; >+ >+my $input = CGI->new; >+my ($template, $loggedinuser, $cookie)= get_template_and_user( >+ { >+ template_name => "members/recallshistory.tt", >+ query => $input, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { recalls => 1 }, >+ debug => 1, >+ } >+); >+ >+my $borrowernumber = $input->param('borrowernumber'); >+my $recalls = Koha::Recalls->search({ borrowernumber => $borrowernumber }, { order_by => { '-desc' => 'recalldate' } }); >+my $patron = Koha::Patrons->find( $borrowernumber ); >+ >+$template->param( >+ patron => $patron, >+ recalls => $recalls, >+ recallsview => 1, >+ specific_patron => 1, >+); >+ >+output_html_with_http_headers $input, $cookie, $template->output; >diff --git a/recalls/recall_pickup_slip.pl b/recalls/recall_pickup_slip.pl >new file mode 100755 >index 00000000000..7a130871f20 >--- /dev/null >+++ b/recalls/recall_pickup_slip.pl >@@ -0,0 +1,74 @@ >+#!/usr/bin/perl >+ >+# Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz> >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw ( -utf8 ); >+use C4::Context; >+use C4::Output; >+use C4::Auth; >+ >+my $input = new CGI; >+ >+my ( $template, $loggedinuser, $cookie ) = get_template_and_user( >+ { >+ template_name => "circ/printslip.tt", >+ query => $input, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { circulate => "circulate_remaining_permissions" }, >+ } >+); >+ >+my $recallid = $input->param('recall_id'); >+my $recall = Koha::Recalls->find($recallid); >+ >+my $itemnumber; >+if ( $recall->itemnumber ){ >+ $itemnumber = $recall->itemnumber; >+} else { >+ $itemnumber = $recall->checkout->itemnumber; >+} >+ >+# Print slip to inform library staff of details of recall requester, so the item can be put aside for requester >+my $letter = C4::Letters::GetPreparedLetter( >+ module => 'circulation', >+ letter_code => 'RECALL_REQUESTER_DET', >+ message_transport_type => 'print', >+ tables => { >+ 'branches' => $recall->branchcode, >+ 'borrowers' => $recall->borrowernumber, >+ 'biblio' => $recall->biblionumber, >+ 'items' => $itemnumber, >+ 'recalls' => $recall->recall_id, >+ } >+); >+ >+my ($slip, $is_html); >+if ($letter) { >+ $slip = $letter->{content}; >+ $is_html = $letter->{is_html}; >+} >+ >+$template->param( >+ slip => $slip, >+ plain => !$is_html, >+ caller => 'recall', >+); >+ >+output_html_with_http_headers $input, $cookie, $template->output; >diff --git a/recalls/recalls_old_queue.pl b/recalls/recalls_old_queue.pl >new file mode 100755 >index 00000000000..161dcd41a1b >--- /dev/null >+++ b/recalls/recalls_old_queue.pl >@@ -0,0 +1,47 @@ >+#!/usr/bin/perl >+ >+# Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz> >+# >+# This file is part of Koha. >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw ( -utf8 ); >+use C4::Auth; >+use C4::Output; >+use Koha::BiblioFrameworks; >+ >+my $query = new CGI; >+my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( >+ { >+ template_name => "recalls/recalls_old_queue.tt", >+ query => $query, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { recalls => "manage_recalls" }, >+ debug => 1, >+ } >+); >+ >+my $recalls = Koha::Recalls->search({ old => 1 }); >+$template->param( >+ recalls => $recalls, >+ viewing_old => 1 >+); >+ >+# Checking if there is a Fast Cataloging Framework >+$template->param( fast_cataloging => 1 ) if Koha::BiblioFrameworks->find( 'FA' ); >+ >+# writing the template >+output_html_with_http_headers $query, $cookie, $template->output; >diff --git a/recalls/recalls_overdue.pl b/recalls/recalls_overdue.pl >new file mode 100755 >index 00000000000..91c1e6973db >--- /dev/null >+++ b/recalls/recalls_overdue.pl >@@ -0,0 +1,61 @@ >+#!/usr/bin/perl >+ >+# Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz> >+# >+# This file is part of Koha. >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw ( -utf8 ); >+use C4::Auth; >+use C4::Output; >+use Koha::BiblioFrameworks; >+use Koha::DateUtils; >+ >+my $query = new CGI; >+my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( >+ { >+ template_name => "recalls/recalls_overdue.tt", >+ query => $query, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { recalls => "manage_recalls" }, >+ debug => 1, >+ } >+); >+ >+my $op = $query->param('op') || 'list'; >+my @recall_ids = $query->multi_param('recall_ids'); >+ >+if ( $op eq 'cancel_multiple_recalls' ) { >+ foreach my $id ( @recall_ids ) { >+ Koha::Recalls->find( $id )->set_cancelled; >+ } >+ $op = 'list' >+} >+ >+if ( $op eq 'list' ) { >+ my $recalls = Koha::Recalls->search({ status => 'O' }); >+ # will be set as Overdue by the misc/cronjobs/recall/overdue_recalls.pl cronjob >+ $template->param( >+ recalls => $recalls, >+ checkboxes => 1, >+ ); >+} >+ >+# Checking if there is a Fast Cataloging Framework >+$template->param( fast_cataloging => 1 ) if Koha::BiblioFrameworks->find( 'FA' ); >+ >+# writing the template >+output_html_with_http_headers $query, $cookie, $template->output; >diff --git a/recalls/recalls_queue.pl b/recalls/recalls_queue.pl >new file mode 100755 >index 00000000000..0d820592a0f >--- /dev/null >+++ b/recalls/recalls_queue.pl >@@ -0,0 +1,57 @@ >+#!/usr/bin/perl >+ >+# Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz> >+# >+# This file is part of Koha. >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw ( -utf8 ); >+use C4::Auth; >+use C4::Output; >+use Koha::BiblioFrameworks; >+ >+my $query = new CGI; >+my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( >+ { >+ template_name => "recalls/recalls_queue.tt", >+ query => $query, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { recalls => 'manage_recalls' }, >+ debug => 1, >+ } >+); >+ >+my $op = $query->param('op') || 'list'; >+my @recall_ids = $query->multi_param('recall_ids'); >+if ( $op eq 'cancel_multiple_recalls' ) { >+ foreach my $id ( @recall_ids ) { >+ Koha::Recalls->find( $id )->set_cancelled; >+ } >+ $op = 'list' >+} >+elsif ( $op eq 'list' ) { >+ my $recalls = Koha::Recalls->search({ old => undef }); >+ $template->param( >+ recalls => $recalls, >+ checkboxes => 1, >+ ); >+} >+ >+# Checking if there is a Fast Cataloging Framework >+$template->param( fast_cataloging => 1 ) if Koha::BiblioFrameworks->find( 'FA' ); >+ >+# writing the template >+output_html_with_http_headers $query, $cookie, $template->output; >diff --git a/recalls/recalls_to_pull.pl b/recalls/recalls_to_pull.pl >new file mode 100755 >index 00000000000..8582de14604 >--- /dev/null >+++ b/recalls/recalls_to_pull.pl >@@ -0,0 +1,126 @@ >+#!/usr/bin/perl >+ >+# Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz> >+# >+# This file is part of Koha. >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw ( -utf8 ); >+use C4::Auth; >+use C4::Output; >+use Koha::BiblioFrameworks; >+ >+my $query = new CGI; >+my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( >+ { >+ template_name => "recalls/recalls_to_pull.tt", >+ query => $query, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { recalls => 'manage_recalls' }, >+ debug => 1, >+ } >+); >+ >+my $op = $query->param('op') || 'list'; >+my $recall_id = $query->param('recall_id'); >+if ( $op eq 'cancel' ) { >+ my $recall = Koha::Recalls->find( $recall_id ); >+ if ( $recall->in_transit ) { >+ C4::Items::ModItemTransfer( $recall->item->itemnumber, $recall->item->holdingbranch, $recall->item->homebranch, 'CancelRecall' ); >+ } >+ $recall->set_cancelled; >+ $op = 'list'; >+} >+ >+if ( $op eq 'list' ) { >+ my @recalls = Koha::Recalls->search({ status => [ 'R','O','T' ] }); >+ my @pull_list; >+ my %seen_bib; >+ foreach my $recall ( @recalls ) { >+ if ( $seen_bib{$recall->biblionumber} ){ >+ # we've already looked at the recalls on this biblio >+ next; >+ } else { >+ # this is an unseen biblio >+ $seen_bib{$recall->biblionumber}++; >+ >+ # get recall data about this biblio >+ my @this_bib_recalls = Koha::Recalls->search({ biblionumber => $recall->biblionumber, status => [ 'R','O','T' ] }, { order_by => { -asc => 'recalldate' } }); >+ my $recalls_count = scalar @this_bib_recalls; >+ my @unique_patrons = do { my %seen; grep { !$seen{$_->borrowernumber}++ } @this_bib_recalls }; >+ my $patrons_count = scalar @unique_patrons; >+ my $first_recall = $this_bib_recalls[0]; >+ >+ my $items_count = 0; >+ my @callnumbers; >+ my @copynumbers; >+ my @enumchrons; >+ my @itemtypes; >+ my @locations; >+ my @libraries; >+ >+ my @items = Koha::Items->search({ biblionumber => $recall->biblionumber }); >+ foreach my $item ( @items ) { >+ if ( $item->can_be_waiting_recall and !$item->checkout ) { >+ # if item can be pulled to fulfill recall, collect item data >+ $items_count++; >+ push( @callnumbers, $item->itemcallnumber ) if ( $item->itemcallnumber ); >+ push( @copynumbers, $item->copynumber ) if ( $item->copynumber ); >+ push( @enumchrons, $item->enumchron ) if ( $item->enumchron ); >+ push( @itemtypes, $item->effective_itemtype ) if ( $item->effective_itemtype ); >+ push( @locations, $item->location ) if ( $item->location ); >+ push( @libraries, $item->holdingbranch ) if ( $item->holdingbranch ); >+ } >+ } >+ >+ if ( $items_count > 0 ) { >+ # don't push data if there are no items available for this recall >+ >+ # get unique values >+ my @unique_callnumbers = do { my %seen; grep { !$seen{$_}++ } @callnumbers }; >+ my @unique_copynumbers = do { my %seen; grep { !$seen{$_}++ } @copynumbers }; >+ my @unique_enumchrons = do { my %seen; grep { !$seen{$_}++ } @enumchrons }; >+ my @unique_itemtypes = do { my %seen; grep { !$seen{$_}++ } @itemtypes }; >+ my @unique_locations = do { my %seen; grep { !$seen{$_}++ } @locations }; >+ my @unique_libraries = do { my %seen; grep { !$seen{$_}++ } @libraries }; >+ >+ push( @pull_list, { >+ biblio => $recall->biblio, >+ items_count => $items_count, >+ recalls_count => $recalls_count, >+ patrons_count => $patrons_count, >+ pull_count => $items_count <= $recalls_count ? $items_count : $recalls_count, >+ first_recall => $first_recall, >+ callnumbers => \@unique_callnumbers, >+ copynumbers => \@unique_copynumbers, >+ enumchrons => \@unique_enumchrons, >+ itemtypes => \@unique_itemtypes, >+ locations => \@unique_locations, >+ libraries => \@unique_libraries, >+ }); >+ } >+ } >+ } >+ $template->param( >+ recalls => \@pull_list, >+ ); >+} >+ >+# Checking if there is a Fast Cataloging Framework >+$template->param( fast_cataloging => 1 ) if Koha::BiblioFrameworks->find( 'FA' ); >+ >+# writing the template >+output_html_with_http_headers $query, $cookie, $template->output; >diff --git a/recalls/recalls_waiting.pl b/recalls/recalls_waiting.pl >new file mode 100755 >index 00000000000..4026fee1dc1 >--- /dev/null >+++ b/recalls/recalls_waiting.pl >@@ -0,0 +1,76 @@ >+#!/usr/bin/perl >+ >+# Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz> >+# >+# This file is part of Koha. >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw ( -utf8 ); >+use C4::Auth; >+use C4::Output; >+use Koha::Recalls; >+use Koha::BiblioFrameworks; >+use Koha::DateUtils; >+use Koha::Patrons; >+ >+my $query = new CGI; >+my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( >+ { >+ template_name => "recalls/recalls_waiting.tt", >+ query => $query, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { recalls => "manage_recalls" }, >+ debug => 1, >+ } >+); >+ >+my $op = $query->param('op') || 'list'; >+ >+if ( $op eq 'modify' ) { >+ my $expire = $query->param('expire') || ''; >+ my $revert = $query->param('revert') || ''; >+ my $recall_id = $query->param('recall_id'); >+ if ( $expire ) { >+ Koha::Recalls->find( $recall_id )->set_expired({ interface => 'INTRANET' }); >+ } elsif ( $revert ) { >+ Koha::Recalls->find( $recall_id )->revert_waiting; >+ } >+ $op = 'list'; >+} >+ >+if ( $op eq 'list' ) { >+ my @recalls = Koha::Recalls->search({ status => 'W' }); >+ my $borrower = Koha::Patrons->find( $loggedinuser ); >+ my @over; >+ my $maxdelay = C4::Context->preference('RecallsMaxPickUpDelay') || 7; >+ my $today = dt_from_string(); >+ foreach my $r ( @recalls ){ >+ my $lastwaitingday = dt_from_string( $r->waitingdate )->add( days => $maxdelay ); >+ if ( $today > $lastwaitingday ){ >+ push @over, $r; >+ } >+ } >+ $template->param( >+ recalls => \@recalls, >+ over => \@over, >+ ); >+} >+ >+# Checking if there is a Fast Cataloging Framework >+$template->param( fast_cataloging => 1 ) if Koha::BiblioFrameworks->find( 'FA' ); >+ >+# writing the template >+output_html_with_http_headers $query, $cookie, $template->output; >diff --git a/recalls/request.pl b/recalls/request.pl >new file mode 100755 >index 00000000000..59a4b4555b0 >--- /dev/null >+++ b/recalls/request.pl >@@ -0,0 +1,65 @@ >+#!/usr/bin/perl >+ >+# Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz> >+# >+# This file is part of Koha. >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw ( -utf8 ); >+use C4::Auth; >+use C4::Output; >+use C4::Search; >+use Koha::Recalls; >+use Koha::Biblios; >+ >+my $input = CGI->new; >+my ($template, $loggedinuser, $cookie)= get_template_and_user( >+ { >+ template_name => "recalls/request.tt", >+ query => $input, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { recalls => "manage_recalls" }, >+ debug => 1, >+ } >+); >+ >+my $op = $input->param('op') || 'list'; >+my @recall_ids = $input->multi_param('recall_ids'); >+my $biblionumber = $input->param('biblionumber'); >+my $recalls = Koha::Recalls->search({ biblionumber => $biblionumber, old => undef }); >+my $biblio = Koha::Biblios->find( $biblionumber ); >+ >+if ( $op eq 'cancel_multiple_recalls' ) { >+ foreach my $id ( @recall_ids ) { >+ Koha::Recalls->find( $id )->set_cancelled; >+ } >+ $op = 'list' >+} >+ >+if ( $op eq 'list' ) { >+ $recalls = Koha::Recalls->search({ biblionumber => $biblionumber, old => undef }); >+ $biblio = Koha::Biblios->find( $biblionumber ); >+} >+ >+$template->param( >+ recalls => $recalls, >+ recallsview => 1, >+ biblio => $biblio, >+ checkboxes => 1, >+ C4::Search::enabled_staff_search_views, >+); >+ >+output_html_with_http_headers $input, $cookie, $template->output; >diff --git a/reserve/request.pl b/reserve/request.pl >index 61f853d0857..356909f9e35 100755 >--- a/reserve/request.pl >+++ b/reserve/request.pl >@@ -314,6 +314,10 @@ foreach my $biblionumber (@biblionumbers) { > $template->param( $canReserve->{status} => 1 ); > $biblioloopiter{ $canReserve->{status} } = 1; > } >+ elsif ( $canReserve->{status} eq 'recall' ) { >+ $template->param( $canReserve->{status} => 1 ); >+ $biblioloopiter{ $canReserve->{status} } = 1; >+ } > else { > $biblioloopiter{ $canReserve->{status} } = 1; > } >diff --git a/svc/checkouts b/svc/checkouts >index fa470b3a2a3..cd42e3b48c6 100755 >--- a/svc/checkouts >+++ b/svc/checkouts >@@ -187,6 +187,26 @@ while ( my $c = $sth->fetchrow_hashref() ) { > $damaged = $av->count ? $av->next->lib : ''; > } > my @subtitles = split(/ \| /, $c->{'subtitle'} // '' ); >+ >+ my $item = Koha::Items->find( $c->{itemnumber} ); >+ my $recalled = 0; >+ my $recall = $item->check_recalls if $item->can_be_waiting_recall; >+ if ( defined $recall ) { >+ if ( $recall->item_level_recall ) { >+ if ( $recall->itemnumber == $c->{itemnumber} ) { >+ # item-level recall on this item >+ $recalled = 1; >+ } else { >+ $recalled = 0; >+ } >+ } else { >+ # biblio-level recall, but don't want to mark recalled if the recall has been allocated a different item >+ if ( !$recall->waiting ) { >+ $recalled = 1; >+ } >+ } >+ } >+ > my $checkout = { > DT_RowId => $c->{itemnumber} . '-' . $c->{borrowernumber}, > title => $c->{title}, >@@ -254,6 +274,7 @@ while ( my $c = $sth->fetchrow_hashref() ) { > cardnumber => $c->{cardnumber}, > }, > issued_today => !$c->{not_issued_today}, >+ recalled => $recalled, > }; > > if ( $c->{not_issued_today} ) { >diff --git a/svc/recall b/svc/recall >new file mode 100755 >index 00000000000..85e1a477d41 >--- /dev/null >+++ b/svc/recall >@@ -0,0 +1,79 @@ >+#!/usr/bin/perl >+ >+# Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz> >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use CGI; >+use JSON qw(encode_json); >+ >+use C4::Context; >+use C4::Auth qw(check_cookie_auth); >+use C4::Output qw(output_with_http_headers); >+use C4::Circulation qw(AddReturn); >+use Koha::Recalls; >+ >+my $input = new CGI; >+my $json = encode_json({ success => 0 }); >+ >+my ( $auth_status, $sessionID ) = check_cookie_auth( $input->cookie('CGISESSID'), { recall => 'manage_recalls' } ); >+ >+if ( $auth_status ne "ok" ) { >+ print $input->header(-type => 'text/plain', -status => '403 Forbidden'); >+ exit 0; >+} >+ >+my $recall_id = $input->param('recall_id'); >+my $recall = Koha::Recalls->find( $recall_id ); >+unless ( $recall ) { >+ my $json = encode_json({ success => 0 }); >+ output_with_http_headers( $input, undef, $json, "json" ); >+ exit; >+} >+ >+my $op = $input->param('action'); >+ >+if ( $op eq 'cancel' ) { >+ # cancel recall >+ $recall->set_cancelled; >+ if ( $recall->cancelled ){ >+ $json = encode_json({ success => 1 }); >+ } >+ >+} elsif ( $op eq 'expire' ) { >+ # expire recall >+ $recall->set_expired({ interface => 'INTRANET' }); >+ if ( $recall->expired ){ >+ $json = encode_json({ success => 1 }); >+ } >+ >+} elsif ( $op eq 'revert' ) { >+ # revert recall waiting status >+ $recall->revert_waiting; >+ if ( $recall->requested ){ >+ $json = encode_json({ success => 1 }); >+ } >+ >+} elsif ( $op eq 'overdue' ) { >+ # mark recall as overdue >+ $recall->set_overdue({ interface => 'INTRANET' }); >+ if ( $recall->overdue ){ >+ $json = encode_json({ success => 1 }); >+ } >+} >+ >+output_with_http_headers( $input, undef, $json, "json" ); >diff --git a/tools/letter.pl b/tools/letter.pl >index 6044243c090..e95746e1e21 100755 >--- a/tools/letter.pl >+++ b/tools/letter.pl >@@ -248,7 +248,7 @@ sub add_form { > {value => 'items.fine', text => 'items.fine'}, > add_fields('borrowers'); > if ($module eq 'circulation') { >- push @{$field_selection}, add_fields('opac_news'); >+ push @{$field_selection}, add_fields('opac_news', 'recalls'); > > } > >diff --git a/tools/viewlog.pl b/tools/viewlog.pl >index 2ccd472f0e5..3377c561a99 100755 >--- a/tools/viewlog.pl >+++ b/tools/viewlog.pl >@@ -188,6 +188,16 @@ if ($do_it) { > } > } > } >+ >+ # get recall information >+ if ( $log->module eq "RECALLS" ) { >+ if ( $log->object ) { >+ my $recall = Koha::Recalls->find( $log->object ); >+ if ( $recall && $output eq 'screen' ) { >+ $result->{recall} = $recall; >+ } >+ } >+ } > push @data, $result; > } > if ( $output eq "screen" ) { >-- >2.11.0
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 19532
:
68569
|
68570
|
68571
|
68572
|
68642
|
68643
|
68644
|
68645
|
68653
|
69100
|
69102
|
69147
|
69148
|
69149
|
69170
|
69172
|
69221
|
69222
|
69223
|
69322
|
69353
|
69354
|
69405
|
69409
|
69410
|
69411
|
69841
|
69872
|
69873
|
69874
|
69875
|
69876
|
69877
|
69878
|
69879
|
69880
|
69881
|
69882
|
69883
|
69884
|
69885
|
69886
|
69887
|
69888
|
69889
|
69890
|
69986
|
70093
|
71409
|
71574
|
71575
|
71576
|
71577
|
71578
|
71579
|
71580
|
71581
|
71582
|
71583
|
71584
|
71585
|
71586
|
71587
|
71588
|
71589
|
71590
|
71591
|
71592
|
72244
|
72311
|
72312
|
72313
|
72314
|
72315
|
72316
|
72317
|
72318
|
72319
|
72320
|
72321
|
72322
|
72323
|
72324
|
72325
|
72326
|
72327
|
72328
|
72329
|
72330
|
72331
|
72332
|
72333
|
72334
|
72335
|
72336
|
72337
|
72338
|
72527
|
76817
|
76818
|
76819
|
76820
|
76821
|
76822
|
76823
|
76824
|
76825
|
76826
|
76827
|
76828
|
76829
|
76830
|
76831
|
76832
|
76833
|
76834
|
76835
|
76836
|
76837
|
76838
|
76839
|
76840
|
76841
|
76842
|
76843
|
76844
|
76845
|
76846
|
76847
|
77177
|
77178
|
77179
|
78755
|
78757
|
78759
|
78761
|
78763
|
78765
|
78766
|
78768
|
78770
|
78772
|
78773
|
78774
|
78775
|
78776
|
78777
|
78778
|
78780
|
78782
|
78785
|
78787
|
78789
|
78790
|
78792
|
78794
|
78797
|
78800
|
78801
|
78802
|
78803
|
78804
|
78805
|
78806
|
78807
|
78808
|
80763
|
80764
|
80765
|
80766
|
80767
|
80768
|
80769
|
80770
|
80771
|
80772
|
80773
|
80774
|
80775
|
80776
|
80777
|
80778
|
80779
|
80780
|
80781
|
80782
|
80783
|
80784
|
80785
|
80786
|
80787
|
80788
|
80789
|
80793
|
80878
|
81204
|
81205
|
81206
|
81207
|
81208
|
81209
|
81210
|
81211
|
81212
|
81213
|
81214
|
81215
|
81216
|
81217
|
81218
|
81219
|
81220
|
81221
|
81222
|
81223
|
81224
|
81225
|
81226
|
81227
|
81228
|
81229
|
81230
|
81231
|
81232
|
81233
|
81234
|
81235
|
81236
|
81237
|
81238
|
81239
|
81240
|
81241
|
81242
|
81243
|
81244
|
81245
|
81246
|
81247
|
81547
|
81548
|
81549
|
81550
|
81551
|
81552
|
81553
|
81554
|
81555
|
81556
|
81557
|
81558
|
81559
|
81560
|
81561
|
81562
|
81563
|
81564
|
81565
|
81566
|
81567
|
81568
|
81569
|
81583
|
81584
|
81585
|
81586
|
81587
|
81588
|
81595
|
81618
|
81652
|
81653
|
81654
|
81655
|
81656
|
81657
|
81658
|
81659
|
81660
|
81661
|
81662
|
81663
|
81664
|
81665
|
81666
|
81667
|
81668
|
81669
|
81670
|
81671
|
81672
|
81673
|
81674
|
81675
|
81676
|
81677
|
81678
|
81679
|
81680
|
81681
|
81682
|
81683
|
103887
|
103888
|
103890
|
103899
|
103900
|
103901
|
103999
|
104000
|
104001
|
104002
|
104005
|
104006
|
104007
|
104066
|
104067
|
104068
|
104069
|
104070
|
104071
|
104246
|
104247
|
104248
|
104249
|
104250
|
104322
|
104323
|
104324
|
104325
|
104326
|
104327
|
104328
|
104329
|
104330
|
104331
|
104332
|
104333
|
104334
|
104335
|
104336
|
104391
|
104392
|
104393
|
104394
|
104395
|
104396
|
104397
|
104398
|
104474
|
104475
|
104476
|
104477
|
104478
|
104479
|
104480
|
104481
|
104545
|
104546
|
104547
|
104548
|
104549
|
104550
|
104551
|
104552
|
104646
|
104647
|
104648
|
104649
|
104650
|
104651
|
104652
|
104653
|
104722
|
104723
|
104724
|
104725
|
104726
|
104727
|
104728
|
104729
|
104806
|
104807
|
104808
|
104809
|
104810
|
104811
|
104812
|
104813
|
104814
|
104815
|
104816
|
104817
|
104818
|
104819
|
104820
|
104821
|
104863
|
104864
|
104865
|
104866
|
104867
|
104868
|
104869
|
104870
|
104902
|
104903
|
104904
|
104905
|
104906
|
104907
|
104908
|
104909
|
104910
|
104913
|
104914
|
104915
|
104916
|
104917
|
104918
|
104919
|
104920
|
104988
|
104989
|
104990
|
104991
|
104992
|
106268
|
106269
|
106371
|
106372
|
106373
|
106374
|
106375
|
106376
|
106377
|
106378
|
106810
|
106811
|
106812
|
106813
|
106814
|
106815
|
106816
|
106817
|
106857
|
107198
|
107199
|
107200
|
107201
|
107202
|
107203
|
107204
|
107205
|
107807
|
107808
|
107809
|
107810
|
107811
|
107812
|
107813
|
107814
|
107918
|
107919
|
107920
|
107921
|
107922
|
107923
|
107924
|
107925
|
108222
|
108223
|
108224
|
108225
|
108226
|
108227
|
108228
|
108229
|
108980
|
108981
|
108982
|
109306
|
109307
|
109308
|
109309
|
109310
|
109311
|
109312
|
109313
|
109314
|
109315
|
109316
|
109317
|
109318
|
109463
|
109464
|
109465
|
109466
|
109467
|
109468
|
109469
|
109775
|
109776
|
109777
|
109778
|
109779
|
109780
|
109781
|
109782
|
109783
|
109784
|
109785
|
111199
|
111200
|
111201
|
111202
|
111203
|
111204
|
111205
|
111206
|
112316
|
112317
|
112321
|
112322
|
112323
|
112324
|
112325
|
112326
|
112346
|
112472
|
112491
|
112540
|
112612
|
112613
|
112614
|
112615
|
112616
|
112617
|
112618
|
112619
|
112620
|
112621
|
112622
|
113195
|
113196
|
113197
|
113198
|
113199
|
113200
|
113201
|
113202
|
113203
|
113204
|
113205
|
113286
|
113287
|
113288
|
113289
|
113290
|
113291
|
113292
|
113293
|
113294
|
113295
|
113296
|
113297
|
113298
|
113335
|
113351
|
113352
|
113353
|
113354
|
113355
|
113356
|
113357
|
113358
|
113359
|
113361
|
113362
|
113363
|
113364
|
113365
|
113430
|
113431
|
113432
|
113433
|
113434
|
113435
|
113436
|
113437
|
113438
|
113439
|
113440
|
113441
|
113442
|
113443
|
113444
|
113445
|
116121
|
116122
|
116123
|
116124
|
116125
|
116126
|
116127
|
116128
|
116129
|
116130
|
116131
|
116132
|
116133
|
116134
|
118267
|
118268
|
118269
|
118270
|
118271
|
118272
|
118273
|
118274
|
118275
|
118276
|
118277
|
118278
|
118279
|
118280
|
122993
|
122994
|
122995
|
122996
|
122997
|
122998
|
122999
|
123000
|
123001
|
123002
|
123003
|
123004
|
123005
|
126244
|
126245
|
126246
|
126247
|
126248
|
126249
|
126250
|
126251
|
126252
|
126253
|
126254
|
126255
|
126256
|
126257
|
126453
|
126454
|
126455
|
126456
|
126457
|
126458
|
126459
|
126460
|
126469
|
126470
|
126565
|
126566
|
126568
|
126569
|
126570
|
126571
|
126572
|
126573
|
126574
|
126575
|
126576
|
126577
|
126578
|
126579
|
126580
|
129305
|
129306
|
129307
|
129308
|
129309
|
129310
|
129311
|
129312
|
129313
|
129314
|
129315
|
129316
|
129317
|
129318
|
129319
|
130641
|
130642
|
130643
|
130644
|
130645
|
130646
|
130647
|
130648
|
130649
|
130650
|
130651
|
130652
|
130653
|
130654
|
130655
|
130656
|
131108
|
131156
|
131157
|
131158
|
131159
|
131160
|
131193
|
131213
|
131257
|
131260
|
131261
|
131262
|
131263
|
131264
|
131265
|
131266
|
131267
|
131268
|
131269
|
131270
|
131271
|
131272
|
131273
|
131274
|
131275
|
131276
|
131277
|
131278
|
131279
|
131280
|
131281
|
131282
|
131330
|
131629
|
131630
|
131631
|
131664
|
131665
|
131666
|
131701
|
132332