Koha/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
Aleisha Amohia db095c3a7b 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

== TEST PLAN FOR RECALLS ==

ADMINISTRATION

1. Apply all patches
2. Run database updates, update schema files and confirm everything applies cleanly
3. Run tests and confirm everything passes:
t/db_dependent/Koha/Recall.t
t/db_dependent/Koha/Recalls.t
t/db_dependent/Stats.t
t/db_dependent/Circulation/CalcFine.t
t/db_dependent/Koha/Item.t
t/db_dependent/Koha/Biblio.t
t/db_dependent/Koha/Patron.t
t/db_dependent/XSLT.t
t/db_dependent/Search.t
t/db_dependent/Holds.t
t/db_dependent/Circulation/transferbook.t
t/db_dependent/Circulation.t

4. Go to Administration -> system preferences. Find the UseRecalls system preference. It should be DISABLED. Confirm RecallsMaxPickUpDelay is set to 7 by default.
5. Go to Administration -> circulation rules. Confirm there are no recalls circulation rules showing.
6. Test a few circulation flows: checking out, placing a reserve, checking in, fulfilling a reserve, etc. Confirm everything works as normal.

7. Go to Administration -> system preferences. Enable the UseRecalls system preference.
8. Go to Administration -> circulation rules. Set the following rules:
Recalls allowed (count) = 0
Recalls per record (count) = 0
On shelf recalls allowed ( If any unavailable / If all unavailable ) = If any unavailable
Recall due date interval (days) = 3
Recall overdue fine amount = (something different to your normal fine amount)
Recall pickup period (days) = 1

Throughout your testing, try with different combinations of these rules and itemtype / branchcode / categorycode. Also try with null values. Keep the circulation rules open in another tab so you can refer to and update these easily. You should also have at least one other tab open for the staff client, and a third tab open for the OPAC, for ease of testing.

9. Go to your account -> More -> Set permissions. Confirm the recalls permission is checked.
10. Set up a test user with OPAC login details (Borrower A). This could also be your own user, as long as you have OPAC login access.
11. Set up a test record (Biblio A) with at least two items (Item A and Item B) of the same item type (or an item type with the same recall circ rules).

PLACING A RECALL

12. Log in to the OPAC as Borrower A. Do a catalogue search with a term that will return multiple results, including Biblio A.
13. Click on Biblio A.
14. Notice there is a 'Place recall' button on the sidebar menu. Click this button. There will be a message saying that there are no items to recall - this is because all items are available.

15. Check out Item A to another borrower (Borrower B).
16. Refresh the 'Place recall' page. You will still NOT be able to place a recall - this is because Recalls allowed = 0 and Recalls per record = 0.

17. Edit the circulation rules to have the following values:
Recalls allowed (count) = 1
Recalls per record (count) = 1
18. Refresh the 'Place recall' page. You will now see the form to place a recall.

BIBLIO-LEVEL RECALL, NO TRANSFER

19. Place a biblio-level recall.
Pickup location: Branch A, the set branch when you are logged into the staff client
Recall not needed after (expiration date): whatever you want
Select 'recall next available item'
Click confirm
20. Confirm the recall is placed successfully. Confirm that the new due date displayed is correctly calculated to be today's date, plus 3 days (taken from the 'recall due date interval' circ rule)
21. In the staff client, look at Borrower B's account, and go to their Notices tab. Confirm they have received a 'Notification to return recalled item' notice.
22. Look at Borrower B's checkouts table. Notice the due date for their checkout has been adjusted, and there is now a note to say that the item was recalled and the due date adjusted.
23. Log in to the OPAC as Borrower B and go to your summary tab. Notice there is a note under their checkout to say the item had been recalled.

24. Log out of the OPAC and log back in as Borrower A.
25. Go to your summary tab. Confirm there is a Recalls tab with a count of 1.
26. Cancel the recall using the button. Confirm it cancels and the Recalls tab disappears.

27. Do a catalogue search with a term that will return multiple results, including Biblio A.
28. When the results load, notice there is a 'Place recall' button next to the 'Place hold' button. Click this 'Place recall' button.
29. Notice you are redirected straight to the form to place a recall.
30. Place a biblio-level recall again, following the steps in Step 19.

31. Go to your recalls history tab. Notice your first cancelled recall shows here.
32. Cancel the recall you just created, using the button. Confirm it cancels and you are redirected to your summary tab.

33. In the staff client, enable the UseCourseReserves system preference.
34. Go to the main menu, click Course Reserves.
35. Add a new course. (You may also have to define an authorised value for DEPARTMENT.)
36. Add Item A as a reserve to this course.

37. View Course Reserves in the OPAC. Click the course you just created.
38. Notice the reserve has a Recall button underneath it's 'Checked out' status. Click this button.
39. Place a biblio-level recall again, following the steps in Step 19.

40. Click the 'Place recall' link in the breadcrumbs.
41. Notice there is a message saying that you have reached the max number of recalls on this record. This is because Recalls allowed = 1 and Recalls per record = 1.
42. Edit the circulation rules to have the following values:
Recalls allowed (count) = 10
Recalls per record (count) = 5
43. Refresh the 'Place recall' page. You will now see the form to place a recall.

44. Create another test record (Biblio B) with at least one item (Item C).
45. Find this record on the OPAC and place a biblio-level recall again, following the steps in Step 19.

46. In the staff client, go to Circulation -> Old recalls. You should be able to see your two cancelled recalls.
47. Go to Circulation -> Recalls queue. Your current recalls should show here.
48. Use the 'Select all' checkbox to select all recalls.
49. Cancel the recalls using the 'Cancel selected recalls' button.

50. Go to the OPAC and place a biblio-level recall on Biblio A again, following the steps in Step 19.

51. In the staff client, check in Item A, which should still be checked out to Borrower B.
52. A box should pop-up asking you to confirm Borrower A's recall. Click ignore.
53. Click the link to go view Biblio A's details in the catalogue.
54. Click the recalls tab. Notice Borrower A's recall is displayed, and shows it is still Requested (has not been confirmed waiting).

55. Check in Item A again. This time, confirm the recall as waiting using the "Confirm recall" button.
56. Go to Borrower A's Notices tab. Confirm there is a notice "Recalled item awaiting pickup".
57. Go to Borrower A's checkouts. Notice there is a recalls tab. Confirm the recall is showing as "Ready for pickup".
58. Click the 'Actions' dropdown. Click the "Revert waiting" button. The page should show a message that the waiting status has been reverted, without reloading.

59. This time, check in Item B. The recall confirmation box should show again, because this a biblio-level recall that any recallable item under Biblio A can fill. Click the "Print slip and confirm" button.
60. Check the slip that is generated. Confirm it contains Borrower A's correct details, and the details of the recall are correct.
61. Go to Circulation -> Recalls awaiting pickup. Confirm the recall is now waiting and shows in this list.
(You could also try this with Item B having a different item type to Item A, and circ rules not allowing Item B's item type to have recalls. When checking in Item A, it should not trigger the recall box).

62. Go to Borrower A's checkouts. Check out Item B.
63. Confirm the checkout is successful and the recall is removed from the Recalls tab.
64. Go to Circulation -> Old recalls. The fulfilled recall should show.

65. Check in Item B.

BIBLIO-LEVEL RECALL, TRANSFER REQUIRED

66. Check out Item A to Borrower B.
67. Log in to the OPAC as Borrower A.
68. Find Biblio A and place a biblio-level recall.
Pickup location: Branch B, a different branch from your logged in branch. This recall will require a transfer.
Recall not needed after (expiration date): whatever you want
Select 'recall next available item'
Click confirm

69. In the staff client, check in Item A at Branch A. Notice the box that pops up shows that a transfer is required.
70. Click "confirm recall and transfer" and confirm the transfer.
71. Go to your account and click the Recalls tab.
72. Confirm the recall status now shows the item is in transit to Branch B.
73. In the drop-down top-right of your window, select 'Set library'.
74. Set your library to Branch B.

75. Go to Circulation -> Transfers to receive. Notice that the recall is showing here.
76. Click 'Cancel transfer'.
77. Go to Circulation -> Recalls queue
78. Confirm the recall status has been reverted to Requested.

79. Set your library back to Branch A.
80. Check in Item A and trigger the transfer.
81. Set your library back to Branch B.

82. Check in Item A at Branch B.
83. When the 'Recall found' box pops up, click Ignore.
84. Go to Circulation -> Recalls to pull. The recall should show here, with a button to "Cancel recall and return to: Branch A"
85. Click the button to cancel the recall.

86. Repeat Steps 66-70.
87. Check in Item A at Branch B. Confirm the recall as waiting.
88. Check out Item A to Borrower A to fulfill the recall.

89. Set your library back to Branch A and check in Item A.

ITEM-LEVEL RECALL, NO TRANSFER

90. Go to Administration -> circulation rules. Set the following rules:
On shelf recalls allowed ( If any unavailable / If all unavailable ) = If all unavailable

91. Check out Item A to Borrower B.
92. Log in to the OPAC as Borrower A and go to Biblio A.
93. Click the 'Place recall' button. Confirm there is a message that there are no items to recall. This is because On shelf recalls allowed = If all unavailable, and there is still one item (Item B) available.
94. In the staff client, edit Item B to have a withdrawn, item lost or not for loan status.
95. Refresh the 'Place recall' page. Confirm you can now see the form to place a recall.

96. Place an item-level recall.
Pickup location: Branch A.
Recall not needed after (expiration date): whatever you want
Select 'recall a specific item'
Item B will not be selectable, and Item A should be selected by default.
Click confirm

97. In the staff client, edit Item B and remove the lost or missing status.
98. Check in Item B. Confirm the recall box does not pop up, because it cannot fill the item-level recall.
99. Check in Item A. Confirm the recall as waiting.
100. Go to Circulation -> Recalls awaiting pickup
101. Expire the recall. Confirm it expires as expected.

ITEM-LEVEL RECALL, TRANSFER REQUIRED

102. Repeat steps 91 to 95.
103. Place an item-level recall.
Pickup location: Branch B, we will require a transfer.
Recall not needed after (expiration date): whatever you want
Select 'recall a specific item'
Item B will not be selectable, and Item A should be selected by default.
Click confirm
104. In the staff client, check in Item A. Confirm the recall and trigger the transfer.
105. Set your library to Branch B and check in Item A.
106. Confirm the recall as waiting.
107. Check out Item A to Borrower A and fulfill the recall.

108. Set your library back to Branch A and check in Item A.

CRONJOBS: EXPIRING RECALL

109. Check out Item A to Borrower B.
110. Log in to the OPAC as Borrower A. Place a recall (any level) on Biblio A.
111. In your terminal, enter mysql and edit the expiration date of your recall to be before today
UPDATE recalls SET expirationdate = NOW()-2 WHERE recall_id = X;
112. Run the expiry cronjob from within your shell
perl misc/cronjobs/recalls/expire_recalls.pl
113. Go to Borrower A's account and go to the Recalls history tab
114. Confirm the recall has been expired because the current date surpassed the specified expiration date

115. Check out Item A to Borrower B.
116. Log in to the OPAC as Borrower A. Place a recall (any level) on Biblio A.
117. In the staff client, check in Item A and confirm the recall as waiting.
118. In your terminal, enter mysql and edit the waiting date of your recall to be before today
UPDATE recalls SET waitingdate = NOW() - interval 5 day WHERE recall_id = X;
119. Run the expiry cronjob from within your shell
perl misc/cronjobs/recalls/expire_recalls.pl
120. Go to Borrower A's account and go to the Recalls history tab
121. Confirm the recall has been expired because the recall had been waiting for more days than the Recall pickup period

122. Go to Administration -> circulation rules. Set the following rules:
Recall pickup period (days) = 0
123. Set the RecallsMaxPickUpDelay system preference = 1.
124. Check out Item A to Borrower B.
125. Log in to the OPAC as Borrower A. Place a recall (any level) on Biblio A.
126. In the staff client, check in Item A and confirm the recall as waiting.
127. In your terminal, enter mysql and edit the waiting date of your recall to be before today
UPDATE recalls SET waitingdate = NOW()-2 WHERE recall_id = X;
128. Run the expiry cronjob from within your shell
perl misc/cronjobs/recalls/expire_recalls.pl
129. Go to Borrower A's account and go to the Recalls history tab
130. Confirm the recall has been expired because the recall had been waiting for more days than the RecallsMaxPickUpDelay syspref

CRONJOBS: OVERDUE RECALL

131. Check out Item A to Borrower B
132. Log in to the OPAC as Borrower A. Place a recall (any level) on Biblio A.
133. In your terminal, enter mysql and edit the due date of the checkout to Borrower B to be before today
UPDATE issues SET date_due = NOW()-2 WHERE issue_id = X;
134. Run the overdue cronjob from within your shell
perl misc/cronjobs/recall/overdue_recalls.pl
135. Go to Circulation -> Overdue recalls
136. Confirm your recall is showing here now as the recall has been marked Overdue

CIRCULATION

137. Check in Item A.
138. When the recall box pops up, click Ignore.
139. Check out Item A to Borrower B. You should see a yellow confirmation box, saying that another borrower has recalled the item you are trying to check out.
140. Click "No don't check out" and confirm the item isn't checked out and the recall remains.
141. Repeat Step 139.
142. Click "Yes check out" and confirm the item is checked out and the recall remains.
143. When Borrower B's checkout table loads, confirm that you cannot renew or check in the item from the Checkouts table because there is a 'Recalled' link which takes you to the recalls tab for that biblio.
144. Repeat Steps 137-139.
145. Select "Cancel recall" and click "Yes check out" and confirm the item is checked out and the recall has been cancelled.
146. Log in to the OPAC as Borrower A. Place a recall (any level) on Biblio A.
147. Check in Item A. Confirm the recall as waiting.
148. Check out Item A to Borrower B. You should see a yellow confirmation box, saying that that another borrower has recalled the item that you are trying to check out.
149. Select "Revert waiting status" and click "Yes check out" and confirm the item is checked out and the recall status has reverted to requested.

OTHER
150. In your terminal, enter mysql and edit the due date of the checkout to Borrower B to be before today
UPDATE issues SET date_due = NOW()-2 WHERE issue_id = X;
151. Go to Borrower A's recalls and click the Actions dropdown.
152. Click "Mark as overdue" and confirm the recall is marked as overdue manually.

153. Go to Tools -> Log Viewer. Check only the Recalls module, and leave all other parameters, and click Submit.
154. Confirm all of the recalls actions that have been made are correctly logged.

Note: recalls messaging preferences are introduced in Bug 23781.
The recall feature is fully documented at: https://wiki.koha-community.org/wiki/Catalyst_IT_Recalls

Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>
2022-03-14 22:45:51 -10:00

1656 lines
96 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[% USE raw %]
[% USE To %]
[% USE Asset %]
[% USE JSON.Escape %]
[% USE Koha %]
[% USE Biblio %]
[% USE KohaDates %]
[% USE Branches %]
[% USE Categories %]
[% USE ItemTypes %]
[% USE AuthorisedValues %]
[% USE Price %]
[% USE TablesSettings %]
[% PROCESS 'i18n.inc' %]
[% SET footerjs = 1 %]
[% INCLUDE 'doc-head-open.inc' %]
[% UNLESS ( multi_hold ) %]
<title>Place a hold on [% INCLUDE 'biblio-title-head.inc' %] &rsaquo; Holds &rsaquo; Circulation &rsaquo; Koha</title>
[% ELSE %]
<title>Confirm holds &rsaquo; Holds &rsaquo; Circulation &rsaquo; Koha</title>
[% END %]
[% INCLUDE 'doc-head-close.inc' %]
[% Asset.css("css/holds.css") | $raw %]
</head>
<body id="circ_request" class="catalog">
[% INCLUDE 'header.inc' %]
[% INCLUDE 'circ-search.inc' %]
[% UNLESS ( multi_hold ) %]
<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="/cgi-bin/koha/mainpage.pl">Home</a>
</li>
<li>
<a href="/cgi-bin/koha/catalogue/search.pl">Catalog</a>
</li>
<li>
[% INCLUDE 'biblio-title.inc' link =1 %]
</li>
<li>
<a href="#" aria-current="page">
Place a hold
</a>
</li>
</ol>
</nav>
[% ELSE %]
<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="/cgi-bin/koha/mainpage.pl">Home</a>
</li>
<li>
<a href="/cgi-bin/koha/catalogue/search.pl">Catalog</a>
</li>
<li>
[% IF ( patron ) %]
<a href="#" aria-current="page">
Place holds
</a>
[% ELSE %]
[% IF clubcount %]
<a href="#" aria-current="page">
Search patrons or clubs
</a>
[% ELSE %]
<a href="#" aria-current="page">
Search patrons
</a>
[% END %]
[% END %]
</li>
</ol>
</nav>
[% END # UNLESS multi_hold %]
<div class="main container-fluid">
<div class="row">
[% IF ( multi_hold || nobiblio ) # No sidebar menu when placing multiple holds or biblio not found %]
<div class="col-md-10 col-md-offset-1">
[% ELSE %]
<div class="col-sm-10 col-sm-push-2">
[% END %]
<main>
[% IF ( nobiblio ) %]
<div class="dialog alert">
[%IF (multi_hold) %]
<strong>Cannot place hold:</strong> one or more records don't exist.
[% ELSE %]
<strong>Cannot place hold:</strong> this record doesn't exist.
[% END %]
</div>
[% END %]
[% IF ( noitems ) %]
<div class="dialog alert">
[%IF (multi_hold) %]
<strong>Cannot place hold:</strong> one or more records without items attached.
[% ELSE %]
<strong>Cannot place hold:</strong> this record has no items attached.
[% END %]
</div>
[% END %]
[% IF ( messagetransfert ) %]
<div class="dialog message">
<h2>Hold found for ([% nextreservtitle | html %]), please transfer</h2>
<p>Hold placed by : <strong> [% nextreservsurname | html %] [% nextreservfirstname | html %]</strong> at : <strong> [% branchname | html %] </strong>, Please transfer this item.
</p>
<form name="cancelReservewithtransfert" action="branchreserves.pl" method="post">
<input type="submit" class="button" />
</form>
</div>
[% END %]
[% UNLESS ( multi_hold ) %]
<h1>Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %] by [% biblio.author | html %][% END %]</h1>
[% ELSE %]
<h1>
[% IF ( patron ) %]
Place holds
[% ELSE %]
[% IF clubcount %]
Search patrons or clubs
[% ELSE %]
Search patrons
[% END %]
[% END %]
</h1>
[% END %]
[% UNLESS club OR patron OR patron.borrowernumber OR noitems OR nobiblio %]
[% IF ( messageborrower ) %]
<div class="dialog alert">
<h3>Patron not found</h3>
<p>No patron with this name, please, try another</p>
</div>
[% END %]
[% IF ( messageclub ) %]
<div class="dialog alert">
<h3>Club not found</h3>
<p>No club with this name, please, try another</p>
</div>
[% END %]
<fieldset class="brief">
[% UNLESS multi_hold %]
[% IF clubcount %]
<label>Search patrons or clubs</label>
[% ELSE %]
<label>Search patrons</label>
[% END %]
[% END %]
<div id="circ_holds_select" class="toptabs">
<ul>
<li><a href="#holds_patronsearch_pane">Patrons</a></li>
[% IF clubcount %]
<li><a href="#holds_clubsearch_pane">Clubs</a></li>
[% END %]
</ul>
<div id="holds_patronsearch_pane">
<form id="holds_patronsearch" method="get">
<div class="hint">Enter patron card number or partial name:</div>
<input type="text" size="40" id="patron" class="focus" autocomplete="off" />
<input type="submit" value="Search" />
[% FOREACH biblionumber IN biblionumbers %]
<input type="hidden" name="biblionumber" value="[% biblionumber | html %]"/>
[% END %]
</form> <!-- /#holds_patronsearch -->
<table id="table_borrowers" class="selections-table" style="display: none;">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Card number</th>
<th>Date of birth</th>
<th>Category</th>
<th>Library</th>
<th>Primary phone</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
[% IF clubcount %]
<div id="holds_clubsearch_pane">
<form id="holds_clubsearch" action="request.pl" method="post">
<div class="hint">Enter club ID or partial name:</div>
<input type="text" size="40" id="club" class="focus" name="findclub" autocomplete="off" />
<input type="submit" value="Search" />
[% FOREACH biblionumber IN biblionumbers %]
<input type="hidden" name="biblionumber" value="[% biblionumber | html %]"/>
[% END %]
</form> <!-- /#holds_patronsearch -->
[% IF clubs %]
[% INCLUDE 'clubs-table.inc' destination = "holds" %]
[% END %]
</div>
[% END %]
</div>
</fieldset>
[% ELSIF club %]
<div class="dialog alert hide clubalert">
</div>
<fieldset class="rows">
<legend>Hold details</legend>
<form action="/api/v1/clubs/[% club.id | html %]/holds" method="post" name="form" id="club-request-form">
[% IF ( multi_hold ) %]
<input type="hidden" name="bad_bibs" id="bad_bibs" value=""/>
<input type="hidden" name="request" value="any"/>
[% FOREACH biblioloo IN biblioloop %]
<input type="hidden" name="title_[% biblioloo.biblionumber | html %]" value="[% biblioloo.title | html %]"/>
<input type="hidden" name="rank_[% biblioloo.biblionumber | html %]" value="[% biblioloo.rank | html %]"/>
[% END %]
[% ELSE %]
<input type="hidden" name="title" value="[% biblio.title | html %]" />
<input type="hidden" name="rank-request" value="[% fixedRank | html %]" />
[% END # /IF multi_hold %]
<ol>
<li>
<span class="label">Club: </span> [% club.name | html %]
</li>
<li>
<span class="label">Description: </span> [% club.description | html %]
</li>
<li>
<label for="pickup">Pickup at:</label>
<select name="pickup" id="pickup_club">
[% PROCESS options_for_libraries libraries => Branches.all({ selected => club.branchcode, search_params => { pickup_location => 1 } }) %]
</select>
</li>
<li>
<label for="default_patron_home">Pickup at patron's home library when possible:</label>
<input type="checkbox" id="default_patron_home" name="default_patron_home"/>
</li>
</ol>
<h2 style="padding: 0 1em;">Members</h2>
<ol>
[% FOREACH member IN members %]
[% SET patron = member.patron %]
<li style="padding: 0.5em 1em;">
<div><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %] ([% patron.cardnumber | html %])</a></div>
[% IF member.exceeded_maxreserves %]
<div>
<i class="fa fa-error"></i>
<strong>Too many holds: </strong> Patron can only place a maximum of [% maxreserves | html %] total holds.
</div>
[% END %]
[% IF ( patron.is_expired ) %]
<div>
<i class="fa fa-warning"></i>
<strong>Account has expired</strong>
</div>
[% END %]
[% IF patron.is_debarred %]
<div>
<i class="fa fa-warning"></i>
<strong>Patron has restrictions</strong>
</div>
[% END %]
[% IF member.amount_outstanding && Koha.Preference('maxoutstanding') && member.amount_outstanding > Koha.Preference('maxoutstanding') %]
<div>
<i class="fa fa-warning"></i>
<strong>Patron has outstanding fines: [% member.amount_outstanding | $Price %]</strong>
</div>
[% END %]
[% IF ( member.diffbranch ) %]
<div>
<i class="fa fa-warning"></i>
<strong>Pickup library is different.</strong> Patron's home library: ([% Branches.GetName(patron.branchcode) | html %] / [% patron.branchcode | html %] )
</div>
[% END %]
</li>
[% END %]
[% UNLESS ( multi_hold ) %]
<fieldset class="action">
<input type="submit" value="Place hold" />
</fieldset>
[% ELSE %]
<table id="requesttitles">
<tr>
<th>&nbsp;</th>
<th>Title</th>
[% UNLESS Koha.Preference('item-level_itypes') %]
<th>Item type</th>
[% END %]
<th>Priority</th>
<th>Information</th>
</tr>
[% FOREACH biblioloo IN biblioloop %]
[% IF ( biblioloo.warn ) %]
<tr class="onissue">
[% ELSE %]
<tr>
[% END %]
<td>
[% UNLESS ( biblioloo.warn ) %]
<input class="multi_hold_item_checkbox" type="checkbox" checked="checked" title="[% biblioloo.biblionumber | html %]"/>
</td>
[% END %]
<td>
<ul>
<li>
<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]">[% biblioloo.title | html %]</a>
[% IF biblioloo.author %] by [% biblioloo.author | html %][% END %]
</li>
[% IF ( biblioloo.publicationyear ) %]
<li>
<span class="label">Publication year:</span> [% biblioloo.publicationyear | html %]
</li>
[% END %]
</ul>
[% IF ( biblioloo.warn ) %]
<span class="not_holdable" title="[% biblioloo.biblionumber | html %]"></span>
[% END %]
</td>
[% UNLESS Koha.Preference('item-level_itypes') %]
<td>
<img src="[% biblioloo.itemtype.image_location| html %]" alt="[% biblioloo.itemtype.translated_description | html %]" title="[% biblioloo.itemtype.translated_description | html %]" />
</td>
[% END %]
<td>[% biblioloo.rank | html %]</td>
<td>
[% IF ( biblioloo.checked_previously ) %]
<span>Patron has previously checked out this title</span><br/>
[% END %]
[% IF ( biblioloo.alreadyres ) %]
<ul>
[% ELSE %]
[% IF ( biblioloo.none_avail || biblioloo.noitems ) %]
<ul>
[% END %]
[% END %]
[% IF ( biblioloo.alreadyres ) %]
<li>
<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %]</a>
<strong>already has a hold</strong> on this item
</li>
[% END %]
[% IF ( biblioloo.none_avail || biblioloo.noitems ) %]
<li> <strong>No items are available</strong> to be placed on hold</li>
[% END %]
[% IF ( biblioloo.alreadyres ) %]
</ul>
[% ELSE %]
[% IF ( biblioloo.none_avail || biblioloo.noitems ) %]
</ul>
[% END %]
[% END %]
</td>
</tr>
[% END # /FOREACH biblioloo %]
</table> <!-- /#requesttitles -->
[% END %]
</form>
</fieldset>
[% ELSIF NOT ( noitems || nobiblio ) # /UNLESS patron %]
[% IF ( checked_previously && !multi_hold ) %]
<div class="dialog alert">
<ul>
<li>Patron has previously checked out this title</li>
</ul>
</div>
[% END %]
[% IF ( no_reserves_allowed || exceeded_maxreserves || exceeded_holds_per_record || alreadyreserved || none_available || alreadypossession || ageRestricted || recall ) %]
<div class="dialog alert">
[% UNLESS ( multi_hold ) %]
<h3>Cannot place hold</h3>
<ul>
[% IF ( no_reserves_allowed ) %]
<li><strong>No holds allowed: </strong> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %] </a> cannot place a hold on any of these items.</li>
[% ELSIF ( exceeded_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> can only place a maximum of [% maxreserves | html %] total holds.</li>
[% ELSIF ( exceeded_holds_per_record ) %]
<li><strong>Too many holds for this record: </strong> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %] </a> can only place a maximum of [% max_holds_for_record | html %] hold(s) on this record.</li>
[% ELSIF ( alreadypossession ) %]
<li> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %]</a> <strong>is already in possession</strong> of one item.</li>
[% ELSIF ( alreadyreserved ) %]
<li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %]</a> <strong>already has a hold</strong> on this item.</li>
[% ELSIF ( ageRestricted ) %]
<li><strong>Age restricted</strong></li>
[% ELSIF ( none_available ) %]
<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 %]
<h3>Cannot place hold on some items</h3>
[% IF (no_reserves_allowed ) %]
<li><strong>No holds allowed: </strong> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %] </a> cannot place holds on some of these title's items.</li>
[% ELSIF ( exceeded_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> can place [% new_reserves_allowed | html %] of the requested [% new_reserves_count | html %] holds for a maximum of [% maxreserves | html %] total holds.</li>
[% ELSIF ( exceeded_holds_per_record ) %]
[% FOREACH biblioloo IN biblioloop %]
[% IF (biblioloo.tooManyHoldsForThisRecord) %]
<li><strong>Too many holds for <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]"> [% biblioloo.title | html %]</a>: </strong> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | html %]">[% patron.firstname | html %] [% patron.surname | html %] </a> can only place a maximum of [% max_holds_for_record | html %] hold(s) on this record.</li>
[% END %]
[% END %]
[% END # /IF exceeded_maxreserves %]
[% END # /UNLESS multi_hold %]
</div>
[% END # /IF ( exceeded_maxreserves || ... %]
[% IF ( patron.is_expired || diffbranch || patron.is_debarred || ( amount_outstanding && Koha.Preference('maxoutstanding') && amount_outstanding > Koha.Preference('maxoutstanding') ) ) %]
<div class="dialog message">
<ul>
[% IF ( patron.is_expired ) %]
<li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %]</a>: <strong>Account has expired</strong></li>
[% END %]
[% IF patron.is_debarred %]
<li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]#reldebarments">[% patron.firstname | html %] [% patron.surname | html %]</a>: <strong>Patron has restrictions</strong></li>
[% END %]
[% IF amount_outstanding && Koha.Preference('maxoutstanding') && amount_outstanding > Koha.Preference('maxoutstanding') %]
<li><a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %]</a>: <strong>Patron has outstanding fines: [% amount_outstanding | $Price %]</strong></li>
[% END %]
[% IF ( diffbranch ) %]
<li> <strong>Pickup library is different. </strong>Patron: <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %]</a> Patron's home library: ([% Branches.GetName(patron.branchcode) | html %] / [% patron.branchcode | html %] )</li>
[% END %]
</ul> <!-- /.dialog.message -->
</div>
[% END # /IF patron.is_expired || diffbranch ... %]
[% IF ( messageborrower ) %]
<div class="dialog alert">
<h3>Patron not found:</h3>
<p>Name or barcode not found. Please try an other </p>
</div>
[% END %]
<div class="dialog alert hide holdalert">
</div>
<fieldset class="rows">
<legend>Hold details</legend>
<form action="placerequest.pl" method="post" name="form" id="hold-request-form">
<input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]" />
<input type="hidden" name="type" value="str8" />
[% FOREACH biblionumber IN biblionumbers %]
<input type="hidden" name="biblionumber" value="[% biblionumber | html %]"/>
[% END %]
[% IF ( multi_hold ) %]
<input type="hidden" name="multi_holds" id="multi_holds" value="1" />
<input type="hidden" name="bad_bibs" id="bad_bibs" value=""/>
<input type="hidden" name="request" value="any"/>
[% FOREACH biblioloo IN biblioloop %]
<input type="hidden" name="title_[% biblioloo.biblionumber | html %]" value="[% biblioloo.title | html %]"/>
<input type="hidden" name="rank_[% biblioloo.biblionumber | html %]" value="[% biblioloo.rank | html %]"/>
[% END %]
[% ELSE %]
<input type="hidden" name="title" value="[% biblio.title | html %]" />
<input type="hidden" name="rank-request" value="[% fixedRank | html %]" />
[% END # /IF multi_hold %]
<ol>
<li>
<span class="label">Patron:</span>
[% IF ( patron.borrowernumber ) %]
<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %] ([% patron.cardnumber | html %])</a>
[% ELSE %]
Not defined yet
[% END %]
</li>
[% UNLESS ( multi_hold ) %]
<li>
<span class="label">Estimated priority:</span>
<strong>[% fixedRank | html %]</strong>
</li>
[% END %]
<li>
<label for="holdnotes">Notes:</label>
<textarea id="holdnotes" name="notes" cols="30" rows="1"></textarea>
</li>
<li>
<label for="pickup">Pickup at:</label>
[% UNLESS ( multi_hold ) %]
<select name="pickup" id="pickup"
data-biblio-id="[% biblio.biblionumber | html %]"
data-patron-id="[% patron.borrowernumber | html %]"
data-pickup-location-source="biblio">
[% PROCESS options_for_libraries libraries => Branches.pickup_locations({ search_params => { biblio => biblionumber, patron => patron }, selected => pickup }) %]
[% ELSE %]
<select name="pickup" id="pickup_multi" data-patron-id="[% patron.borrowernumber | html %]">
<option value="" selected="selected"></option>
[% FOREACH pickup_location IN multi_pickup_locations %]
<option value="[% pickup_location.branchcode | html %]">[% pickup_location.branchname | html %]</option>
[% END %]
[% END %]
</select>
</li>
[% UNLESS ( multi_hold ) %]
[% IF Koha.Preference('AllowHoldItemTypeSelection') %]
<li>
<label for="itemtype">Request specific item type:</label>
<select name="itemtype" id="itemtype">
<option value="">Any item type</option>
[%- FOREACH itemtype IN available_itemtypes %]
<option value="[% itemtype | html %]">[% ItemTypes.GetDescription( itemtype ) | html %]</option>
[%- END %]
</select>
</li>
[% END %]
[% END # /UNLESS multi_hold %]
[% IF ( reserve_in_future ) %]
<li>
<label for="from">Hold starts on date:</label>
<input id="reserve_date" name="reserve_date" id="from" size="10" type="text" data-date_to="expiration_date" class="flatpickr" data-flatpickr-futuredate="true" />
</li>
[% END %]
<li>
<label for="to">Hold expires on date:</label>
<input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
</li>
[% UNLESS ( multi_hold ) %]
<li>
<label for="requestany">Hold next available item </label>
[% IF force_hold_level == 'item' %]
<input type="checkbox" id="requestany" name="request" disabled="true" />
[% ELSIF force_hold_level == 'record' %]
<input type="checkbox" id="requestany" checked="checked" value="Any" disabled="true"/>
<input type="hidden" name="request" value="Any"/>
[% ELSE %]
<input type="checkbox" id="requestany" name="request" checked="checked" value="Any" />
[% END %]
<input type="hidden" name="alreadyreserved" value="[% alreadyreserved | html %]" />
</li>
[% IF remaining_holds_for_record > 1 %]
<li>
<label for="holds_to_place_count">Holds to place (count)</label>
<input type="text" inputmode="numeric" pattern="[0-9]*" id="holds_to_place_count" name="holds_to_place_count" maxlength="[% remaining_holds_for_record | html %]" value="1" />
</li>
[% ELSE %]
<input type="hidden" name="holds_to_place_count" value="1" />
[% END %]
[% END # /UNLESS multi_hold %]
<li id="non_priority_list_item">
<label for="non_priority">Non priority hold:</label>
<input name="non_priority" id="non_priority" type="checkbox" />
<span class="hint">A non priority hold doesn't prevent a current checkout from renewing</span>
</li>
</ol>
[% UNLESS ( multi_hold ) %]
<fieldset class="action">
[% IF ( patron.borrowernumber ) %]
[% IF ( override_required ) %]
<button type="submit" class="btn btn-default warning"><i class="fa fa-exclamation-triangle "></i> Place hold</button>
[% ELSIF ( none_available ) %]
<button type="submit" disabled="disabled" class="btn btn-default btn-disabled">Place hold</button>
[% ELSE %]
<button type="submit" class="btn btn-default">Place hold</button>
[% END %]
[% END %]
</fieldset>
[% biblio = biblioloop.0 %]
<ol>
[% UNLESS Koha.Preference('item-level_itypes') %]
<li>
<span class="label">Item typeX:</span>
[% biblio.itemtype.translated_description | html %]
</li>
[% END %]
[% IF ( biblio.biblioitem.publicationyear ) %]
<li>
<span class="label">Publication year:</span>
[% biblio.biblioitem.publicationyear | $KohaDates %]
</li>
[% END %]
</ol>
<h2 style="padding: 0 1em;">
Place a hold on a specific item
[% IF force_hold_level == 'item' %]
<span class="error"><em>(Required)</em></span>
[% END %]
</h2>
<table id="requestspecific">
<thead>
<tr>
<th>Hold</th>
[% IF Koha.Preference('item-level_itypes') %]
<th>Item type</th>
[% END %]
<th>Barcode</th>
<th>Home library</th>
<th>Last location</th>
[% IF itemdata_ccode %]
<th>Collection</th>
[% END %]
<th>Call number</th>
<th>Copy number</th>
[% IF itemdata_enumchron %]
<th>Vol no.</th>
[% END %]
<th>Information</th>
<th>Allowed pickup locations</th>
</tr>
</thead>
<tbody>
[% SET selected = 0 %]
[% FOREACH itemloo IN biblio.itemloop %]
[% UNLESS ( itemloo.hide ) %]
<tr class="[% itemloo.backgroundcolor | html %]">
<td>
[% IF force_hold_level == 'record' # Patron has placed a record level hold previously for this record %]
<span class="error">
<i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
Hold must be record level
</span>
[% ELSIF ( itemloo.available ) %]
<input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" />
[% ELSIF ( itemloo.override ) %]
<input type="radio" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber | html %]" />
<i class="fa fa-exclamation-triangle fa-lg" style="color:gold" title="Requires override of hold policy"/></i>
[% ELSE %]
<span class="error">
<i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
[% IF itemloo.not_holdable %]
[% IF itemloo.not_holdable == 'damaged' %]
Item damaged
[% ELSIF itemloo.not_holdable == 'ageRestricted' %]
Age restricted
[% ELSIF itemloo.not_holdable == 'tooManyHoldsForThisRecord' %]
Exceeded max holds per record
[% ELSIF itemloo.not_holdable == 'tooManyReservesToday' %]
Daily hold limit reached for patron
[% ELSIF itemloo.not_holdable == 'tooManyReserves' %]
Too many holds
[% ELSIF itemloo.not_holdable == 'notReservable' %]
Not holdable
[% ELSIF itemloo.not_holdable == 'cannotReserveFromOtherBranches' %]
Patron is from different library
[% ELSIF itemloo.not_holdable == 'branchNotInHoldGroup' %]
Cannot place hold from patron's library
[% ELSIF itemloo.not_holdable == 'itemAlreadyOnHold' %]
Patron already has hold for this item
[% ELSIF itemloo.not_holdable == 'cannotBeTransferred' %]
Cannot be transferred to pickup library
[% ELSIF itemloo.not_holdable == 'pickupNotInHoldGroup' %]
Only pickup locations within the same hold group are allowed
[% ELSIF itemloo.not_holdable == 'noReservesAllowed' %]
No reserves are allowed on this item
[% ELSIF itemloo.not_holdable == 'libraryNotPickupLocation' %]
Library is not a pickup location
[% ELSIF itemloo.not_holdable == 'no_valid_pickup_location' %]
No valid pickup location
[% ELSE %]
[% itemloo.not_holdable | html %]
[% END %]
[% END %]
</span>
[% END # /IF force_hold_level %]
</td>
[% IF Koha.Preference('item-level_itypes') %]
<td>
[% UNLESS ( noItemTypeImages ) %]
[% IF ( itemloo.itemtype.image_location) %]<img src="[% itemloo.itemtype.image_location | html %]" alt="" /> <br /> [% END %]
[% END %]
[% itemloo.itemtype.translated_description | html %]
</td>
[% END %]
<td>
[% itemloo.barcode | html %]
</td>
<td>
[% Branches.GetName( itemloo.homebranch ) | html %]
</td>
<td>
[% Branches.GetName( itemloo.holdingbranch ) | html %]
</td>
[% IF itemdata_ccode %]
<td>
[% IF ( itemloo.ccode ) %][% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => itemloo.ccode ) | html %][% END %]
</td>
[% END %]
<td>
[% itemloo.itemcallnumber | html %]
</td>
<td>
[% IF ( itemloo.copynumber ) %][% itemloo.copynumber | html %][% ELSE %]&nbsp;[% END %]
</td>
[% IF itemdata_enumchron %]
<td>
[% itemloo.enumchron | html %]
</td>
[% END %]
[% IF ( itemloo.onloan ) %]
<td data-order="[% itemloo.date_due | html %]">
<span class="checkedout">Due [% itemloo.date_due | $KohaDates as_due_date => 1 %]</span>
[% ELSE %]
<td>
[% IF ( itemloo.transfertwhen ) %]
In transit from [% Branches.GetName( itemloo.transfertfrom ) | html %],
to [% Branches.GetName( itemloo.transfertto ) | html %], since [% itemloo.transfertwhen | html %]
[% END %]
[% END %]
[% IF ( itemloo.reservedate ) %]
[% IF ( itemloo.nocancel ) %]
Can't be cancelled when item is in transit
[% ELSE %]
[% IF ( itemloo.waitingdate ) %]Waiting[% ELSE %]On hold[% END %]
[% IF ( itemloo.canreservefromotherbranches ) %]
for <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% itemloo.ReservedFor.borrowernumber | uri %]">[% itemloo.ReservedFor.firstname | html %] [% itemloo.ReservedFor.surname | html %]</a>
[% END %]
[% IF ( itemloo.waitingdate ) %]at[% ELSE %]expected at[% END %]
[% Branches.GetName( itemloo.ExpectedAtLibrary ) | html %] since
[% IF ( itemloo.waitingdate ) %]
[% itemloo.waitingdate | $KohaDates %]
[% ELSE %]
[% IF ( itemloo.reservedate ) %]
[% itemloo.reservedate | html %]
[% END %]
[% END %].
<a class="info cancel-hold" href="modrequest.pl?CancelBiblioNumber=[% itemloo.biblionumber | html %]&amp;CancelBorrowerNumber=[% itemloo.ReservedFor.borrowernumber | html %]&amp;CancelItemnumber=[% itemloo.itemnumber | html %]">Cancel hold</a>
[% END # /IF itemloo.nocancel %]
[% ELSE %]
Not on hold
[% END # /IF itemloo.reservedate %]
[% IF itemloo.item_level_holds == "N" %]
<br/>Item level hold not allowed from OPAC
[% ELSIF itemloo.item_level_holds == "F" %]
<br/>Item level hold forced from OPAC
[% END %]
[% IF ( itemloo.itemlost ) %]
<span class="lost">[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.itemlost', authorised_value => itemloo.itemlost ) | html %]</span>
[% END %]
[% IF ( itemloo.damaged ) %]
<span class="dmg">[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.damaged', authorised_value => itemloo.damaged ) | html %]</span>
[% END %]
[% IF ( itemloo.withdrawn ) %]
<span class="wdn">[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.withdrawn', authorised_value => itemloo.withdrawn ) | html %]</span>
[% END %]
[% IF ( itemloo.notforloan ) %]
<span class="nfl">Not for loan ([% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.notforloan', authorised_value => itemloo.notforloan ) | html %])</span>
[% END %]
</td>
<td>
[% IF (itemloo.pickup_locations_count > 0) %]
<select name="item_pickup_[% itemloo.itemnumber | html %]" class="pickup_locations" style="width:100%;"
data-item-id="[% itemloo.itemnumber | html %]"
data-patron-id="[% patron.borrowernumber | html %]"
data-pickup-location-source="item">
[% IF (itemloo.default_pickup_location) %]
<option value="[% itemloo.default_pickup_location.branchcode | html %]" selected="selected">[% itemloo.default_pickup_location.branchname | html %]</option>
[% END %]
</select>
[% END %]
</td>
</tr>
[% END # / UNLESS itemloo.hide %]
[% END # /FOREACH itemloo %]
</tbody>
</table> <!-- /#requestspecific -->
[% IF hiddencount %]
<form>
<p class="hiddencount">
<a href="request.pl?biblionumber=[% biblio.biblionumber | uri %]&amp;borrowernumber=[% borrowernumber | uri %]&amp;showallitems=1">Show all items ([% biblio.hiddencount | html %] hidden)</a>
</p>
</form>
[% END # /IF hiddencount %]
[% ELSE # /UNLESS multi_hold %]
<table id="requesttitles">
<tr>
<th>&nbsp;</th>
<th>Title</th>
[% UNLESS Koha.Preference('item-level_itypes') %]
<th>Item type</th>
[% END %]
<th>Priority</th>
<th>Information</th>
<th>Pickup location</th>
</tr>
[% FOREACH biblioloo IN biblioloop %]
[% IF ( biblioloo.warn ) %]
<tr class="onissue">
[% ELSE %]
<tr>
[% END %]
<td>
[% UNLESS ( biblioloo.warn ) %]
<input class="multi_hold_item_checkbox" type="checkbox" checked="checked" title="[% biblioloo.biblionumber | html %]"/>
</td>
[% END %]
<td>
<ul>
<li>
<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]">[% biblioloo.title | html %]</a>
[% IF biblioloo.author %] by [% biblioloo.author | html %][% END %]
</li>
[% IF ( biblioloo.publicationyear ) %]
<li>
<span class="label">Publication year:</span> [% biblioloo.publicationyear | html %]
</li>
[% END %]
</ul>
[% IF ( biblioloo.warn ) %]
<span class="not_holdable" title="[% biblioloo.biblionumber | html %]"></span>
[% END %]
</td>
[% UNLESS Koha.Preference('item-level_itypes') %]
<td>
<img src="[% biblioloo.itemtype.image_location | html %]" alt="[% biblioloo.itemtype.translated_description | html %]" title="[% biblioloo.itemtype.translated_description | html %]" />
</td>
[% END %]
<td>[% biblioloo.rank | html %]</td>
<td>
[% IF ( biblioloo.checked_previously ) %]
<span>Patron has previously checked out this title</span><br/>
[% END %]
[% IF ( biblioloo.alreadyres ) %]
<ul>
[% ELSE %]
[% IF ( biblioloo.none_avail || biblioloo.noitems ) %]
<ul>
[% END %]
[% END %]
[% IF ( biblioloo.alreadyres ) %]
<li>
<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %]</a>
<strong>already has a hold</strong> on this item
</li>
[% END %]
[% IF ( biblioloo.none_avail || biblioloo.noitems ) %]
<li> <strong>No items are available</strong> to be placed on hold</li>
[% END %]
[% IF ( biblioloo.alreadyres ) %]
</ul>
[% ELSE %]
[% IF ( biblioloo.none_avail || biblioloo.noitems ) %]
</ul>
[% END %]
[% END %]
</td>
<td>
[% UNLESS ( biblioloo.none_avail || biblioloo.noitems ) %]
<select name="pickup_[% biblioloo.biblionumber | html %]"
class="multi_pickup_select"
data-biblio-id="[% biblioloo.biblionumber | html %]"
data-patron-id="[% patron.borrowernumber | html %]"
data-pickup-locations='[% biblioloo.pickup_locations_codes.json | $raw %]'>
<option value=""></option>
[% FOREACH pickup_location IN biblioloo.pickup_locations %]
<option value="[% pickup_location.branchcode | html %]">[% pickup_location.branchname | html %]</option>
[% END %]
</select>
[% END %]
</td>
</tr>
[% END # /FOREACH biblioloo %]
</table> <!-- /#requesttitles -->
[% END # /UNLESS multi_hold %]
<fieldset class="action">
[% IF ( patron AND patron.borrowernumber ) %]
[% IF ( override_required ) %]
<button type="submit" class="btn btn-default warning"><i class="fa fa-exclamation-triangle "></i> Place holds</button>
[% ELSIF ( none_available ) %]
<button class="btn btn-default" type="submit">Place holds</button>
[% ELSE %]
[% IF ( multi_hold ) %]
<button type="submit" class="btn btn-default" id="multi_hold_submit">Place holds</button>
[% ELSE %]
<button type="submit" class="btn btn-default">Place hold</button>
[% END %]
[% END %]
[% END # /IF patron %]
</fieldset> <!-- /.action -->
</form> <!-- /#hold-request-form -->
</fieldset> <!-- /.rows -->
[% END %]
[% UNLESS ( patron ) %]
[% UNLESS borrowers %]
[% SET hold_count = Biblio.HoldsCount( biblio.biblionumber ) | html %]
[% IF hold_count %]
<label for ="always_show_holds">Always show holds</label>
[% IF always_show_holds == 'DONT' %]
<input type="checkbox" name="always_show_holds" id="always_show_holds" value="DO">
[% UNLESS reserveloop %]
<a class="btn btn-default" value="Show holds" id="show_holds_now" href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% biblio.biblionumber | uri %]&show_holds_now=1">Show holds ([% hold_count | html %])</a>
[% END %]
[% ELSE %]
<input type="checkbox" name="always_show_holds" value="DO" id="always_show_holds" checked="checked">
[% END %]
[% END %]
[% END %]
[% IF ( reserveloop ) %]
<form id="existing_holds" name="T[% time | html %]" action="modrequest.pl" method="post" style="display:block">
[% IF ( multi_hold ) %]
[% FOREACH biblionumber IN biblionumbers %]
<input type="hidden" name="biblionumber" value="[% biblionumber | html %]"/>
[% END %]
[% END %]
[% IF enqueued %]
<div class="dialog message">
<p>The job has been enqueued! It will be processed as soon as possible.</p>
<p><a href="/cgi-bin/koha/admin/background_jobs.pl?op=view&id=[% job_id | uri %]" title="View detail of the enqueued job">View detail of the enqueued job</a></p>
</div>
[% END %]
<h2>Existing holds</h2>
<div id="toolbar" class="btn-toolbar">
<input type="submit" name="submit" value="Update hold(s)" /> <button class="cancel_selected_holds" data-bulk="true"></button>
<fieldset id="cancellation-reason-fieldset" class="action">
[% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %]
[% IF hold_cancellation %]
<label for="cancellation-reason">Cancellation reason: </label>
<select class="cancellation-reason" name="cancellation-reason" id="cancellation-reason">
<option value="">No reason given</option>
[% FOREACH reason IN hold_cancellation %]
<option value="[% reason.authorised_value | html %]">[% reason.lib | html %]</option>
[% END %]
</select>
[% END %]
</fieldset>
</div>
[% FOREACH biblioloo IN biblioloop %]
[% IF ( biblioloo.reserveloop ) %]
<div class="hold_title" id="hold_title_[% biblioloo.biblionumber | html %]">
[% IF ( multi_hold ) %]
<h3>
<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]">
[% biblioloo.title | html %]
</a> <span class="number_box"><span>[% biblioloo.reserveloop.size | html %] [% tn('Hold', 'Holds', biblioloo.reserveloop.size) | $raw %]</span></span>
</h3>
[% END %]
[% IF Koha.Preference('HoldsSplitQueue') == 'branch' %]
[% SET branchcodes = [] %]
[% FOREACH h IN biblioloo.reserveloop %]
[% branchcodes.push( h.branchcode ) %]
[% END %]
[% branchcodes = branchcodes.unique %]
[% IF ( branchcodes.empty ) %]
<div class="note">
There are no holds on this title.
</div>
[% ELSE %]
[% FOREACH b IN branchcodes.sort %]
[% SET holds_by_branch = [] %]
[% FOREACH h IN biblioloo.reserveloop %]
[% IF h.branchcode == b %]
[% holds_by_branch.push( h ) %]
[% END %]
[% END %]
<div class="holds_by_library">
<h4>[% Branches.GetName( b ) | html %]</h4>
[% INCLUDE holds_table.inc holds=holds_by_branch %]
</div>
[% END # /FOREACh b %]
[% END # /IF ( branchcodes.empty ) %]
[% ELSIF Koha.Preference('HoldsSplitQueue') == 'itemtype' %]
[% SET itemtypes = [] %]
[% FOREACH h IN biblioloo.reserveloop %]
[% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
[% itemtypes.push( hold_itemtype ) %]
[% END %]
[% itemtypes = itemtypes.unique %]
[% IF ( itemtypes.empty ) %]
<div class="note">
There are no holds on this title.
</div>
[% ELSE %]
[% FOREACH i IN itemtypes.sort %]
[% SET holds_by_itemtype = [] %]
[% FOREACH h IN biblioloo.reserveloop %]
[% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
[% IF hold_itemtype == i %]
[% holds_by_itemtype.push( h ) %]
[% END %]
[% END %]
<div class="holds_by_itemtype">
[% IF i %]
<h4>[% ItemTypes.GetDescription( i ) | html %]</h4>
[% ELSE %]
<h4>Any item type</h4>
[% END %]
[% INCLUDE holds_table.inc holds=holds_by_itemtype %]
</div>
[% END # /FOREACH i %]
[% END # /IF ( itemtypes.empty ) %]
[% ELSIF Koha.Preference('HoldsSplitQueue') == 'branch_itemtype' %]
[% SET branchcodes = [] %]
[% FOREACH h IN biblioloo.reserveloop %]
[% branchcodes.push( h.branchcode ) %]
[% END %]
[% branchcodes = branchcodes.unique %]
[% IF ( branchcodes.empty ) %]
<div class="note">
There are no holds on this title.
</div>
[% ELSE %]
[% FOREACH b IN branchcodes.sort %]
<div class="holds_by_library">
<h4 class="library_holds">[% Branches.GetName( b ) | html %]</h4>
[% SET holds_by_branch = [] %]
[% FOREACH h IN biblioloo.reserveloop %]
[% IF h.branchcode == b %]
[% holds_by_branch.push( h ) %]
[% END %]
[% END %]
[% SET itemtypes = [] %]
[% FOREACH h IN holds_by_branch %]
[% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
[% itemtypes.push( hold_itemtype ) %]
[% END %]
[% itemtypes = itemtypes.unique %]
[% FOREACH i IN itemtypes.sort %]
<div class="holds_by_itemtype">
<h5 class="itemtype_holds">
[% IF i %]
[% ItemTypes.GetDescription( i ) | html %]
[% ELSE %]
Any item type
[% END %]
</h5>
[% SET holds_by_itemtype = [] %]
[% FOREACH h IN holds_by_branch %]
[% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
[% IF hold_itemtype == i %]
[% holds_by_itemtype.push( h ) %]
[% END %]
[% END %]
[% INCLUDE holds_table.inc holds=holds_by_itemtype %]
</div> <!-- /.holds_by_itemtype -->
[% END %]
</div> <!-- /.holds_by_library -->
[% END # /FOREACH b %]
[% END # /IF ( branchcodes.empty ) %]
[% ELSE %]
[% IF ( biblioloo.reserveloop.size ) %]
[% INCLUDE holds_table.inc holds=biblioloo.reserveloop %]
[% ELSE %]
<div class="note">
There are no holds on this title.
</div>
[% END %]
[% END # /IF HoldsSplitQueue %]
</div> <!-- /hold_title -->
[% END # /IF biblioloo.reserveloop %]
[% END # FOREACH biblioloo %]
</form> <!-- /#existing_holds -->
[% END # IF reserveloop %]
[% END # UNLESS patron %]
</main>
[% IF ( multi_hold || nobiblio ) # No sidebar menu when placing multiple holds or biblio not found %]
</div> <!-- /.col-md-10.col-md-offset-1 -->
[% ELSE %]
</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 -->
[% END %]
</div> <!-- /.row -->
<div id="cancelModal" class="modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
<h3>Confirm deletion</h3>
</div>
<div class="modal-body">
<p>Are you sure you want to cancel this hold?</p>
<fieldset class="action">
[% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %]
[% IF hold_cancellation %]
<label for="cancellation-reason">Cancellation reason: </label>
<select class="cancellation-reason" name="modal-cancellation-reason" id="modal-cancellation-reason">
<option value="">No reason given</option>
[% FOREACH reason IN hold_cancellation %]
<option value="[% reason.authorised_value | html %]">[% reason.lib | html %]</option>
[% END %]
</select>
[% END %]
</fieldset>
</div>
<div class="modal-footer">
<button id="cancelModalConfirmBtn" type="button" class="btn btn-danger">Confirm cancellation</button>
<a href="#" data-dismiss="modal">Cancel</a>
</div>
</div>
</div>
</div>
[% MACRO jsinclude BLOCK %]
[% INCLUDE 'datatables.inc' %]
[% INCLUDE 'calendar.inc' %]
[% INCLUDE 'columns_settings.inc' %]
[% Asset.js("lib/hc-sticky.js") | $raw %]
[% INCLUDE 'select2.inc' %]
[% Asset.js("js/holds.js") | $raw%]
<script>
var Sticky;
var biblionumbers = [[% biblionumbers.join(', ') | $raw %]];
var borrowernumber = "[% patron.borrowernumber | $raw %]";
var patron_homebranch = "[% To.json( Branches.GetName( patron.branchcode ) ) | $raw %]";
var override_items = {[% FOREACH biblio IN biblioloop %][% FOREACH itemloo IN biblio.itemloop %][% IF ( itemloo.override ) %]
[% itemloo.itemnumber | html %]: {
homebranch: "[% To.json( Branches.GetName( itemloo.homebranch ) ) | $raw %]",
holdallowed: "[% itemloo.holdallowed | html %]"
},
[% END %][% END %][% END %]
};
var ERROR_MAP = {
damaged: _("Item damaged"),
ageRestricted: _("Age restricted"),
tooManyHoldsForThisRecord: _("Exceeded max holds per record"),
tooManyReservesToday: _("Daily hold limit reached for patron"),
tooManyReserves: _("Too many holds"),
notReservable: _("Not holdable"),
noReservesAllowed: _("No reserves allowed"),
cannotReserveFromOtherBranches: _("Patron is from different library"),
itemAlreadyOnHold: _("Patron already has hold for this item"),
cannotBeTransferred: _("Cannot be transferred to pickup library"),
pickupNotInHoldGroup: _("Only pickup locations within the same hold group are allowed")
}
var MSG_CANCEL_SELECTED = _("Cancel selected (%s)");
columns_settings_borrowers_table = [% TablesSettings.GetColumns( 'circ', 'circulation', 'table_borrowers', 'json' ) | $raw %];
$.fn.select2.defaults.set("width", "100%" );
$.fn.select2.defaults.set("dropdownAutoWidth", true );
$(document).ready(function() {
$('#cancellation-reason-fieldset').hide();
$('.rank-request').on('change', function() {
if ( $(".rank-request option:selected[value='del']").length ) {
$('#cancellation-reason-fieldset').show();
} else {
$('#cancellation-reason-fieldset').hide();
}
});
[% SET active = clubs ? 1 : 0 %]
$('#circ_holds_select').tabs({
active: [% active | $raw %],
activate: function(){
$(this).find("input.focus").focus();
},
create: function(){
$(this).find("input.focus").focus();
}
});
function ToggleHoldsToPlace() {
if ( $("#requestany").prop('checked') ) {
$("#holds_to_place_count").prop('disabled', false);
} else {
$("#holds_to_place_count").prop('disabled', true);
}
}
ToggleHoldsToPlace();
$("#requestany").on('change', function(){
ToggleHoldsToPlace();
});
[% IF Koha.Preference('UseBranchTransferLimits') %]
$("#pickup").on('change', function(){
var pickup = $("#pickup").val();
var url = "?pickup=" + pickup;
url += "&borrowernumber=" + borrowernumber;
url += "&biblionumber=" + biblionumbers[0];
window.location.replace(url);
});
[% END %]
var my_table = $("#requestspecific").dataTable($.extend(true, {}, dataTablesDefaults, {
'bPaginate': false,
"sDom": '<"top pager"ilf>t',
}));
//Override fieldset styling for dataTables search box
$("div.top.pager").css("margin-left","1em");
$(".dataTables_filter label").css({
"width":"auto",
"margin-right":"0em"
});
$("#club-request-form").on("submit", function() {
let $t = $(this);
$('.clubalert, .holdalert').addClass('hide');
const data = {
pickup_library_id: $('select[name="pickup"]').val()
};
if($('input[name="checkitem"]:checked').length)
data.item_id = $('input[name="checkitem"]:checked').val();
if($('input[name="borrowernumber"]').length)
data.patron_id = $('input[name="borrowernumber"]').val();
if($('textarea[name="notes"]').length)
data.notes = $('textarea[name="notes"]').val()||null;
if($('input[name="itemtype"]').length) {
data.item_type = $('input[name="itemtype"]').val()||null;
}
if($('input[name="default_patron_home"]:checked').length) {
data.default_patron_home = 1;
}
const count = $('input[name="holds_to_place_count"]').length?$('input[name="holds_to_place_count"]').val():1;
var newloc = 'request.pl?';
biblionumbers.forEach(function (biblionumber) {
newloc += '&biblionumber=' + biblionumber;
});
biblionumbers.forEach(function(biblionumber) {
data.biblio_id = biblionumber;
let options = {
url: $t.attr('action'),
method: $t.attr('method').toUpperCase(),
contentType: 'application/json',
data: JSON.stringify(data)
};
for(let i = 0; i < count; i++) {
$.ajax(options)
.then(function(result) {
document.location = newloc;
})
.fail(function(err) {
var message = err.responseJSON.error;
var match = err.responseJSON.error.match(/Reason: (\w+)\s*$/);
if(match && ERROR_MAP[match[1]]) {
message = '<div><strong>'+_("Cannot place hold")+'</strong></div><div>'+ERROR_MAP[match[1]]+'</div>'
}
$('.clubalert, .holdalert').removeClass('hide').html(message);
});
}
});
return false;
});
[% UNLESS ( multi_hold ) %]
$("#hold-request-form").on("submit", function(){
return check($(this));
});
[% ELSE %]
$("#hold-request-form").on("submit", function(){
return checkMultiHold();
});
[% END %]
$(".pickup_location_dropdown").each( function () {
$(this).pickup_locations_dropdown();
});
$("#pickup_multi").select2({
width: '30%',
allowClear: true
});
$('.multi_pickup_select').select2({
width: '100%',
allowClear: true
});
$("#pickup_multi").on("change", function() {
var selection = $(this).val();
if ( selection != '' ) {
$(".multi_pickup_select").each(function() {
var valid_pickup_locations = $(this).data('pickup-locations');
if ( valid_pickup_locations.includes(selection) ) {
$(this).val(selection);
$(this).trigger("change");
}
});
}
});
$("#pickup").each( function () {
$(this).pickup_locations_dropdown();
});
$(".pickup_locations").each(function () {
$(this).pickup_locations_dropdown();
});
});
function check( table ) {
var msg = "";
if ( $("#requestany").attr("checked") !== "checked" ) {
// requestany not selected, go through the item-specific cases
if ( $('input[type="radio"]:checked').length > 0 ) {
// got item-specific hold requests in the form!
// verify they have a pickup location selected
if (table.find('input[type="radio"]:checked')
.closest('tr')
.find(".pickup_locations").val() === null) {
msg = _("- Please select a pickup location for the item" + "\n")
}
}
else {
msg = (_("- Please select an item to place a hold") + "\n");
}
}
if (msg == "") {
$('#hold-request-form').preventDoubleFormSubmit();
return(true);
} else {
alert(msg);
return(false);
}
}
function checkMultiHold() {
var selected_bibs = $(".multi_hold_item_checkbox:checked");
if ( selected_bibs.length > 0 ) {
// there are biblios selected in the form!
// verify they have a pickup location selected
var pickup_not_set = 0;
selected_bibs.each(function() {
if ( $(this).closest('tr').find(".multi_pickup_select").val() === "" ) {
pickup_not_set++;
}
else {
var bibnum = $(this).attr("title");
}
});
if ( pickup_not_set > 0 ) {
alert( _("Please make sure all selected titles have a pickup location set" + "\n") );
return false;
}
}
else {
alert( _("Please select at least one title" + "\n") );
return false;
}
var badSpans = $(".not_holdable");
var badBibs = "";
$(badSpans).each(function() {
var bibnum = $(this).attr("title");
badBibs += bibnum + "/";
});
$("#bad_bibs").val(badBibs);
$('#hold-request-form').preventDoubleFormSubmit();
return true;
}
$(document).ready(function() {
$("#always_show_holds").change(function(){
if( $(this).prop('checked') ){
document.cookie = 'always_show_holds=DO';
} else {
document.cookie = 'always_show_holds=DONT';
}
});
$("input.needsoverride").click(function() { // This must be before the radio button/checkbox switch logic
var itemnumber = this.value;
var msg = '';
switch (override_items[itemnumber].holdallowed) {
case "not_allowed": msg = _("This item normally cannot be put on hold."); break;
case "from_home_library": msg = _("This item normally cannot be put on hold except for patrons from %s.").format(override_items[itemnumber].homebranch); break;
}
msg += "\n\n" + _("Place hold on this item?");
return confirm(msg);
});
$("button.warning").click(function() {
return confirm( _("None of these items can normally be put on hold for this patron.") + "\n\n" + _("Place hold?") );
});
$("#requestany").click(function() {
if(this.checked){
$("input[name=checkitem]").each(function() {
$(this).prop("checked", false);
});
}
});
$("input[name=checkitem]").click(function() {
onechecked = 0;
$("input[name=checkitem]").each(function() {
if(this.checked){
onechecked = 1;
}
});
if(onechecked == 1){
$("#requestany").prop("checked", false);
$("#holds_to_place_count").prop('disabled', true);
} else {
$("#requestany").prop("checked",true);
$("#holds_to_place_count").prop('disabled', false);
}
});
var prev_rank_request;
$("select[name=rank-request]").on("focus", function() {
prev_rank_request = $(this).val();
var row = $(this).parents("tr:first");
}).change(function() {
var row = $(this).parents("tr:first");
var value = parseInt($(this).val());
var found_holds = $("select[name='rank-request'][disabled='disabled']").length ; //Count how many are found
if( !isNaN(value) ) { //If moved to 'del'
var after = row.parent().find("tr:nth-child("+(value+1+found_holds )+")"); //Go to the row 1 after the new value (and skip found holds)
if (prev_rank_request > value) {
row.insertBefore(after);
} else {
row.insertAfter(after);
}
}
var next_priority = 1;
$("select[name=rank-request]").each(function () {
if( isNaN( $(this).val() ) ){ return true; } //Don't reset found or del holds
$(this).val(next_priority);
next_priority++;
});
});
$(".clear-date").on("click",function(e){
e.preventDefault();
var fieldID = this.id.replace("clear-date-","");
$("#" + fieldID).val("");
});
// Confirm cancellation of hold
let cancel_link;
$(".cancel-hold").on("click",function(e) {
e.preventDefault;
cancel_link = $(this);
$('#cancelModal').modal();
return false;
});
$("#cancelModalConfirmBtn").on("click",function(e) {
let link;
if(cancel_link.data('bulk')) {
[% SET data_url = 'biblionumber=' _ biblionumbers.join('&biblionumber=') %]
link = `request.pl?[% data_url | url %]&amp;action=cancelBulk&amp;ids=${$('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id')).join(',')}`;
} else {
let borrowernumber = cancel_link.data('borrowernumber');
let biblionumber = cancel_link.data('biblionumber');
let reserve_id = cancel_link.data('id');
link = `request.pl?action=cancel&amp;borrowernumber=${ borrowernumber }&amp;biblionumber=${ biblionumber }&amp;reserve_id=${ reserve_id }`;
}
let reason = $("#modal-cancellation-reason").val();
if ( reason ) {
link += "&amp;cancellation-reason=" + reason
}
window.location.href = link;
return false;
});
Sticky = $("#toolbar");
Sticky.hcSticky({
stickTo: "#existing_holds",
stickyClass: "floating"
});
if(!localStorage.selectedHolds || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
localStorage.selectedHolds = [];
}
$('.holds_table .select_hold').each(function() {
if(localStorage.selectedHolds.includes($(this).data('id'))) {
$(this).prop('checked', true);
}
});
$('.holds_table .select_hold_all').each(function() {
var table = $(this).parents('.holds_table');
var count = $('.select_hold:not(:checked)', table).length;
$('.select_hold_all', table).prop('checked', !count);
});
$('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
$('.holds_table .select_hold_all').click(function() {
var table = $(this).parents('.holds_table');
var count = $('.select_hold:checked', table).length;
$('.select_hold', table).prop('checked', !count);
$(this).prop('checked', !count);
$('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id'));
});
$('.holds_table .select_hold').click(function() {
var table = $(this).parents('.holds_table');
var count = $('.select_hold:not(:checked)', table).length;
$('.select_hold_all', table).prop('checked', !count);
$('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id'));
});
$('.cancel_selected_holds').click(function(e) {
e.preventDefault();
if($('.holds_table .select_hold:checked').length) {
cancel_link = $(this);
delete localStorage.selectedHolds;
$('#cancelModal').modal();
}
return false;
});
[% FOREACH biblionumber IN biblionumbers %]
[% SET url_biblio_params = url_biblio_params _ "&amp;biblionumber=" _ biblionumber | uri %]
[% END %]
[% IF multi_hold %]
[% SET url_biblio_params = url_biblio_params _ "&amp;multi_hold=1" %]
[% END %]
search = 0;
dtMemberResults = KohaTable("table_borrowers", {
'bServerSide': true,
'sAjaxSource': "/cgi-bin/koha/svc/members/search",
'fnServerData': function(sSource, aoData, fnCallback) {
if ( ! search ) {
return;
}
aoData.push({
'name': 'searchmember',
'value': $("#patron").val()
},{
'name': 'template_path',
'value': 'reserve/tables/members_results.tt',
});
$.ajax({
'dataType': 'json',
'type': 'POST',
'url': sSource,
'data': aoData,
'success': function(json){
// redirect if there is only 1 result.
if ( json.iTotalDisplayRecords == 1 ) {
var borrowernumber = json.aaData[0].borrowernumber;
document.location.href = '/cgi-bin/koha/reserve/request.pl?borrowernumber=' + borrowernumber + "[% url_biblio_params | $raw %]"
return false;
}
fnCallback(json);
}
});
},
'fnDrawCallback': function (oSettings) {
var data = this.fnGetData();
$.each($(this).find("tbody tr"), function(index, tr) {
let url = '/cgi-bin/koha/reserve/request.pl?borrowernumber=' + data[index].borrowernumber + "[% url_biblio_params | $raw %]"
$(tr).off('click').on('click', function() {
document.location.href = url;
}).addClass('clickable');
$(tr).find("a.patron_preview").attr('href', url);
});
},
'aoColumns':[
{ 'mDataProp': 'dt_name' },
{ 'mDataProp': 'dt_address' },
{ 'mDataProp': 'dt_cardnumber' },
{ 'mDataProp': 'dt_dateofbirth' },
{ 'mDataProp': 'dt_category' },
{ 'mDataProp': 'dt_branch' },
{ 'mDataProp': 'dt_phone' },
],
'bFilter': false,
'bAutoWidth': false,
'sPaginationType': 'full_numbers',
"bProcessing": true
}, columns_settings_borrowers_table );
$("#table_borrowers_wrapper").hide();
function filter() {
search = 1;
$("#table_borrowers").show();
$("#table_borrowers_wrapper").show();
dtMemberResults.fnDraw();
return false;
}
$("#holds_patronsearch").on("submit", filter);
});
$('.printholdslip').click(function(){
var reserve_id = $(this).attr('data-reserve_id');
window.open("/cgi-bin/koha/circ/hold-transfer-slip.pl?reserve_id=" + reserve_id);
return false;
})
</script>
[% END %]
[% INCLUDE 'intranet-bottom.inc' %]