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 }; |