|
Lines 21-35
Link Here
|
| 21 |
|
21 |
|
| 22 |
# We're going to authenticate a self-check user. we'll add a flag to borrowers 'selfcheck' |
22 |
# We're going to authenticate a self-check user. we'll add a flag to borrowers 'selfcheck' |
| 23 |
# |
23 |
# |
| 24 |
# We're in a controlled environment; we trust the user. |
24 |
# We're not in a controlled environment; we never trust the user. |
| 25 |
# So the selfcheck station will accept a patronid and issue items to that borrower. |
|
|
| 26 |
# FIXME: NOT really a controlled environment... We're on the internet! |
| 27 |
# |
25 |
# |
| 28 |
# The checkout permission comes form the CGI cookie/session of a staff user. |
26 |
# The checkout permission comes form the CGI cookie/session of a staff user. |
| 29 |
# The patron is not really logging in here in the same way as they do on the |
27 |
# The patron is not really logging in here in the same way as they do on the |
| 30 |
# rest of the OPAC. So don't confuse loggedinuser with the patron user. |
28 |
# rest of the OPAC. So don't confuse loggedinuser with the patron user. |
| 31 |
# |
29 |
# The patron id/cardnumber is retrieved from the JWT |
| 32 |
# FIXME: inputfocus not really used in TMPL |
|
|
| 33 |
|
30 |
|
| 34 |
use Modern::Perl; |
31 |
use Modern::Perl; |
| 35 |
|
32 |
|
|
Lines 99-107
if (defined C4::Context->preference('AllowSelfCheckReturns')) {
Link Here
|
| 99 |
} |
96 |
} |
| 100 |
|
97 |
|
| 101 |
my $issuerid = $loggedinuser; |
98 |
my $issuerid = $loggedinuser; |
| 102 |
my ($op, $patronid, $patronlogin, $patronpw, $barcode, $confirmed, $newissues) = ( |
99 |
my ($op, $patronlogin, $patronpw, $barcode, $confirmed, $newissues) = ( |
| 103 |
$query->param("op") || '', |
100 |
$query->param("op") || '', |
| 104 |
$query->param("patronid") || '', |
|
|
| 105 |
$query->param("patronlogin")|| '', |
101 |
$query->param("patronlogin")|| '', |
| 106 |
$query->param("patronpw") || '', |
102 |
$query->param("patronpw") || '', |
| 107 |
$query->param("barcode") || '', |
103 |
$query->param("barcode") || '', |
|
Lines 109-144
my ($op, $patronid, $patronlogin, $patronpw, $barcode, $confirmed, $newissues) =
Link Here
|
| 109 |
$query->param("newissues") || '', |
105 |
$query->param("newissues") || '', |
| 110 |
); |
106 |
); |
| 111 |
|
107 |
|
|
|
108 |
my $jwt = $query->cookie('JWT'); |
| 109 |
if ($op eq "logout") { |
| 110 |
$template->param( loggedout => 1 ); |
| 111 |
$query->param( patronlogin => undef, patronpw => undef ); |
| 112 |
undef $jwt; |
| 113 |
} |
| 114 |
|
| 112 |
my @newissueslist = split /,/, $newissues; |
115 |
my @newissueslist = split /,/, $newissues; |
| 113 |
my $issuenoconfirm = 1; #don't need to confirm on issue. |
116 |
my $issuenoconfirm = 1; #don't need to confirm on issue. |
| 114 |
my $issuer = Koha::Patrons->find( $issuerid )->unblessed; |
117 |
my $issuer = Koha::Patrons->find( $issuerid )->unblessed; |
| 115 |
my $item = Koha::Items->find({ barcode => $barcode }); |
118 |
|
| 116 |
if (C4::Context->preference('SelfCheckoutByLogin') && !$patronid) { |
119 |
my $patronid = $jwt ? Koha::Token->new->decode_jwt({ token => $jwt }) : undef; |
| 117 |
my $dbh = C4::Context->dbh; |
120 |
unless ( $patronid ) { |
| 118 |
my $resval; |
121 |
if ( C4::Context->preference('SelfCheckoutByLogin') ) { |
| 119 |
($resval, $patronid) = checkpw($dbh, $patronlogin, $patronpw); |
122 |
my $dbh = C4::Context->dbh; |
|
|
123 |
( undef, $patronid ) = checkpw( $dbh, $patronlogin, $patronpw ); |
| 124 |
} |
| 125 |
else { # People should not do that unless they know what they are doing! |
| 126 |
# SelfCheckAllowByIPRanges MUST be configured |
| 127 |
$patronid = $query->param('patronid'); |
| 128 |
} |
| 129 |
$jwt = Koha::Token->new->generate_jwt({ id => $patronid }) if $patronid; |
| 120 |
} |
130 |
} |
| 121 |
|
131 |
|
| 122 |
my ( $borrower, $patron ); |
132 |
my $patron; |
| 123 |
if ( $patronid ) { |
133 |
if ( $patronid ) { |
| 124 |
$patron = Koha::Patrons->find( { cardnumber => $patronid } ); |
134 |
$patron = Koha::Patrons->find( { cardnumber => $patronid } ); |
| 125 |
$borrower = $patron->unblessed if $patron; |
|
|
| 126 |
} |
135 |
} |
| 127 |
|
136 |
|
| 128 |
my $branch = $issuer->{branchcode}; |
137 |
my $branch = $issuer->{branchcode}; |
| 129 |
my $confirm_required = 0; |
138 |
my $confirm_required = 0; |
| 130 |
my $return_only = 0; |
139 |
my $return_only = 0; |
| 131 |
#warn "issuer cardnumber: " . $issuer->{cardnumber}; |
|
|
| 132 |
#warn "patron cardnumber: " . $borrower->{cardnumber}; |
| 133 |
if ($op eq "logout") { |
140 |
if ($op eq "logout") { |
| 134 |
$template->param( loggedout => 1 ); |
141 |
$template->param( loggedout => 1 ); |
| 135 |
$query->param( patronid => undef, patronlogin => undef, patronpw => undef ); |
142 |
$query->param( patronid => undef, patronlogin => undef, patronpw => undef ); |
| 136 |
} |
143 |
} |
| 137 |
elsif ( $op eq "returnbook" && $allowselfcheckreturns ) { |
144 |
|
| 138 |
my ($doreturn) = AddReturn( $barcode, $branch ); |
145 |
if ( $op eq "returnbook" && $allowselfcheckreturns ) { |
|
|
146 |
|
| 147 |
# Patron cannot checkin an item they don't own |
| 148 |
my $item = Koha::Items->find( { barcode => $barcode } ); |
| 149 |
my $doreturn = $patron->checkouts->find( { itemnumber => $item->itemnumber} ) ? 1 : 0; |
| 150 |
|
| 151 |
if ( $doreturn ) { |
| 152 |
($doreturn) = AddReturn( $barcode, $branch ); |
| 153 |
} |
| 139 |
$template->param( returned => $doreturn ); |
154 |
$template->param( returned => $doreturn ); |
| 140 |
} |
155 |
} |
| 141 |
elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) { |
156 |
elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) { |
|
|
157 |
my $item = Koha::Items->find( { barcode => $barcode } ); |
| 142 |
my $impossible = {}; |
158 |
my $impossible = {}; |
| 143 |
my $needconfirm = {}; |
159 |
my $needconfirm = {}; |
| 144 |
( $impossible, $needconfirm ) = CanBookBeIssued( |
160 |
( $impossible, $needconfirm ) = CanBookBeIssued( |
|
Lines 159-165
elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) {
Link Here
|
| 159 |
} |
175 |
} |
| 160 |
} |
176 |
} |
| 161 |
|
177 |
|
| 162 |
#warn "confirm_required: " . $confirm_required ; |
|
|
| 163 |
if (scalar keys %$impossible) { |
178 |
if (scalar keys %$impossible) { |
| 164 |
|
179 |
|
| 165 |
my $issue_error = (keys %$impossible)[0]; # FIXME This is wrong, we assume only one error and keys are not ordered |
180 |
my $issue_error = (keys %$impossible)[0]; # FIXME This is wrong, we assume only one error and keys are not ordered |
|
Lines 174-180
elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) {
Link Here
|
| 174 |
if ($issue_error eq 'DEBT') { |
189 |
if ($issue_error eq 'DEBT') { |
| 175 |
$template->param(DEBT => $impossible->{DEBT}); |
190 |
$template->param(DEBT => $impossible->{DEBT}); |
| 176 |
} |
191 |
} |
| 177 |
#warn "issue_error: " . $issue_error ; |
|
|
| 178 |
if ( $issue_error eq "NO_MORE_RENEWALS" ) { |
192 |
if ( $issue_error eq "NO_MORE_RENEWALS" ) { |
| 179 |
$return_only = 1; |
193 |
$return_only = 1; |
| 180 |
$template->param( |
194 |
$template->param( |
|
Lines 184-193
elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) {
Link Here
|
| 184 |
} |
198 |
} |
| 185 |
} elsif ( $needconfirm->{RENEW_ISSUE} || $op eq 'renew' ) { |
199 |
} elsif ( $needconfirm->{RENEW_ISSUE} || $op eq 'renew' ) { |
| 186 |
if ($confirmed) { |
200 |
if ($confirmed) { |
| 187 |
#warn "renewing"; |
201 |
if ( $patron->checkouts->find( { itemnumber => $item->itemnumber } ) ) { |
| 188 |
AddRenewal( $borrower->{borrowernumber}, $item->itemnumber ); |
202 |
AddRenewal( $patron->borrowernumber, $item->itemnumber ); |
| 189 |
push @newissueslist, $barcode; |
203 |
push @newissueslist, $barcode; |
| 190 |
$template->param( renewed => 1 ); |
204 |
$template->param( renewed => 1 ); |
|
|
205 |
} else { |
| 206 |
$template->param( renewed => 0 ); |
| 207 |
} |
| 191 |
} else { |
208 |
} else { |
| 192 |
#warn "renew confirmation"; |
209 |
#warn "renew confirmation"; |
| 193 |
$template->param( |
210 |
$template->param( |
|
Lines 199-205
elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) {
Link Here
|
| 199 |
); |
216 |
); |
| 200 |
} |
217 |
} |
| 201 |
} elsif ( $confirm_required && !$confirmed ) { |
218 |
} elsif ( $confirm_required && !$confirmed ) { |
| 202 |
#warn "failed confirmation"; |
|
|
| 203 |
$template->param( |
219 |
$template->param( |
| 204 |
impossible => 1, |
220 |
impossible => 1, |
| 205 |
"circ_error_$issue_error" => 1, |
221 |
"circ_error_$issue_error" => 1, |
|
Lines 218-224
elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) {
Link Here
|
| 218 |
$hold_existed = Koha::Holds->search( |
234 |
$hold_existed = Koha::Holds->search( |
| 219 |
{ |
235 |
{ |
| 220 |
-and => { |
236 |
-and => { |
| 221 |
borrowernumber => $borrower->{borrowernumber}, |
237 |
borrowernumber => $patron->borrowernumber, |
| 222 |
-or => { |
238 |
-or => { |
| 223 |
biblionumber => $item->biblionumber, |
239 |
biblionumber => $item->biblionumber, |
| 224 |
itemnumber => $item->itemnumber |
240 |
itemnumber => $item->itemnumber |
|
Lines 228-234
elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) {
Link Here
|
| 228 |
)->count; |
244 |
)->count; |
| 229 |
} |
245 |
} |
| 230 |
|
246 |
|
| 231 |
AddIssue( $borrower, $barcode ); |
247 |
AddIssue( $patron->unblessed, $barcode ); |
| 232 |
$template->param( issued => 1 ); |
248 |
$template->param( issued => 1 ); |
| 233 |
push @newissueslist, $barcode; |
249 |
push @newissueslist, $barcode; |
| 234 |
|
250 |
|
|
Lines 239-245
elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) {
Link Here
|
| 239 |
# Note that this should not be needed but since we do not have proper exception handling here we do it this way |
255 |
# Note that this should not be needed but since we do not have proper exception handling here we do it this way |
| 240 |
patron_has_hold_fee => Koha::Account::Lines->search( |
256 |
patron_has_hold_fee => Koha::Account::Lines->search( |
| 241 |
{ |
257 |
{ |
| 242 |
borrowernumber => $borrower->{borrowernumber}, |
258 |
borrowernumber => $patron->borrowernumber, |
| 243 |
debit_type_code => 'RESERVE', |
259 |
debit_type_code => 'RESERVE', |
| 244 |
description => $item->biblio->title, |
260 |
description => $item->biblio->title, |
| 245 |
date => $dtf->format_date(dt_from_string) |
261 |
date => $dtf->format_date(dt_from_string) |
|
Lines 249-275
elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) {
Link Here
|
| 249 |
} |
265 |
} |
| 250 |
} else { |
266 |
} else { |
| 251 |
$confirm_required = 1; |
267 |
$confirm_required = 1; |
| 252 |
#warn "issue confirmation"; |
|
|
| 253 |
$template->param( |
268 |
$template->param( |
| 254 |
confirm => "Issuing title: " . $item->biblio->title, |
269 |
confirm => "Issuing title: " . $item->biblio->title, |
| 255 |
barcode => $barcode, |
270 |
barcode => $barcode, |
| 256 |
hide_main => 1, |
271 |
hide_main => 1, |
| 257 |
inputfocus => 'confirm', |
|
|
| 258 |
); |
272 |
); |
| 259 |
} |
273 |
} |
| 260 |
} |
274 |
} |
| 261 |
} # $op |
275 |
} # $op |
| 262 |
|
276 |
|
| 263 |
if ($borrower) { |
277 |
if ($patron) { |
| 264 |
# warn "issuer's branchcode: " . $issuer->{branchcode}; |
278 |
my $borrowername = sprintf "%s %s", ($patron->firstname || ''), ($patron->surname || ''); |
| 265 |
# warn "user's branchcode: " . $borrower->{branchcode}; |
|
|
| 266 |
my $borrowername = sprintf "%s %s", ($borrower->{firstname} || ''), ($borrower->{surname} || ''); |
| 267 |
my $pending_checkouts = $patron->pending_checkouts; |
279 |
my $pending_checkouts = $patron->pending_checkouts; |
| 268 |
my @checkouts; |
280 |
my @checkouts; |
| 269 |
while ( my $c = $pending_checkouts->next ) { |
281 |
while ( my $c = $pending_checkouts->next ) { |
| 270 |
my $checkout = $c->unblessed_all_relateds; |
282 |
my $checkout = $c->unblessed_all_relateds; |
| 271 |
my ($can_be_renewed, $renew_error) = CanBookBeRenewed( |
283 |
my ($can_be_renewed, $renew_error) = CanBookBeRenewed( |
| 272 |
$borrower->{borrowernumber}, |
284 |
$patron->borrowernumber, |
| 273 |
$checkout->{itemnumber}, |
285 |
$checkout->{itemnumber}, |
| 274 |
); |
286 |
); |
| 275 |
$checkout->{can_be_renewed} = $can_be_renewed; # In the future this will be $checkout->can_be_renewed |
287 |
$checkout->{can_be_renewed} = $can_be_renewed; # In the future this will be $checkout->can_be_renewed |
|
Lines 301-312
if ($borrower) {
Link Here
|
| 301 |
ISSUES => \@checkouts, |
313 |
ISSUES => \@checkouts, |
| 302 |
HOLDS => $holds, |
314 |
HOLDS => $holds, |
| 303 |
newissues => join(',',@newissueslist), |
315 |
newissues => join(',',@newissueslist), |
| 304 |
patronid => $patronid, |
|
|
| 305 |
patronlogin => $patronlogin, |
316 |
patronlogin => $patronlogin, |
| 306 |
patronpw => $patronpw, |
317 |
patronpw => $patronpw, |
| 307 |
waiting_holds_count => $waiting_holds_count, |
318 |
waiting_holds_count => $waiting_holds_count, |
| 308 |
noitemlinks => 1 , |
319 |
noitemlinks => 1 , |
| 309 |
borrowernumber => $borrower->{'borrowernumber'}, |
320 |
borrowernumber => $patron->borrowernumber, |
| 310 |
SuspendHoldsOpac => C4::Context->preference('SuspendHoldsOpac'), |
321 |
SuspendHoldsOpac => C4::Context->preference('SuspendHoldsOpac'), |
| 311 |
AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'), |
322 |
AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'), |
| 312 |
howpriority => $show_priority, |
323 |
howpriority => $show_priority, |
|
Lines 316-349
if ($borrower) {
Link Here
|
| 316 |
|
327 |
|
| 317 |
my $patron_messages = Koha::Patron::Messages->search( |
328 |
my $patron_messages = Koha::Patron::Messages->search( |
| 318 |
{ |
329 |
{ |
| 319 |
borrowernumber => $borrower->{'borrowernumber'}, |
330 |
borrowernumber => $patron->borrowernumber, |
| 320 |
message_type => 'B', |
331 |
message_type => 'B', |
| 321 |
} |
332 |
} |
| 322 |
); |
333 |
); |
| 323 |
$template->param( |
334 |
$template->param( |
| 324 |
patron_messages => $patron_messages, |
335 |
patron_messages => $patron_messages, |
| 325 |
opacnote => $borrower->{opacnote}, |
336 |
opacnote => $patron->opacnote, |
| 326 |
); |
337 |
); |
| 327 |
|
338 |
|
| 328 |
my $inputfocus = ($return_only == 1) ? 'returnbook' : |
|
|
| 329 |
($confirm_required == 1) ? 'confirm' : 'barcode' ; |
| 330 |
$template->param( |
339 |
$template->param( |
| 331 |
inputfocus => $inputfocus, |
|
|
| 332 |
nofines => 1, |
340 |
nofines => 1, |
| 333 |
|
341 |
|
| 334 |
); |
342 |
); |
| 335 |
if (C4::Context->preference('ShowPatronImageInWebBasedSelfCheck')) { |
343 |
if (C4::Context->preference('ShowPatronImageInWebBasedSelfCheck')) { |
| 336 |
my $patron_image = Koha::Patron::Images->find($borrower->{borrowernumber}); |
344 |
my $patron_image = $patron->image; |
| 337 |
$template->param( |
345 |
$template->param( |
| 338 |
display_patron_image => 1, |
346 |
display_patron_image => 1, |
| 339 |
csrf_token => Koha::Token->new->generate_csrf( { session_id => scalar $query->cookie('CGISESSID') . $borrower->{cardnumber}, id => $borrower->{userid}} ), |
347 |
csrf_token => Koha::Token->new->generate_csrf( { session_id => scalar $query->cookie('CGISESSID') . $patron->cardnumber, id => $patron->userid } ), |
| 340 |
) if $patron_image; |
348 |
) if $patron_image; |
| 341 |
} |
349 |
} |
| 342 |
} else { |
350 |
} else { |
| 343 |
$template->param( |
351 |
$template->param( |
| 344 |
patronid => $patronid, |
|
|
| 345 |
nouser => $patronid, |
352 |
nouser => $patronid, |
| 346 |
); |
353 |
); |
| 347 |
} |
354 |
} |
| 348 |
|
355 |
|
|
|
356 |
$cookie = $query->cookie( |
| 357 |
-name => 'JWT', |
| 358 |
-value => $jwt // '', |
| 359 |
-expires => $jwt ? '+1d' : '', |
| 360 |
-HttpOnly => 1, |
| 361 |
-secure => ( C4::Context->https_enabled() ? 1 : 0 ), |
| 362 |
); |
| 363 |
|
| 364 |
$template->param(patronid => $patronid); |
| 365 |
|
| 349 |
output_html_with_http_headers $query, $cookie, $template->output, undef, { force_no_caching => 1 }; |
366 |
output_html_with_http_headers $query, $cookie, $template->output, undef, { force_no_caching => 1 }; |