From 6a70c126d16aff00e278a2ae93e84f859d86be55 Mon Sep 17 00:00:00 2001 From: Aleisha Amohia Date: Mon, 28 Aug 2023 04:58:26 +0000 Subject: [PATCH] Bug 32256: Enable batch checkout using self-checkout This patch allows more than one item to be scanned and processed at once in Koha's self-checkout module. The items in the batch will still be handled one-by-one, so if any item in the batch requires confirmation (i.e. to be renewed or returned) or is impossible to check out, the process will stop at that item. Any items earlier in the list will be processed, but any items coming after in the list will be ignored. This feature uses the existing BatchCheckouts and BatchCheckoutsValidCategories system preferences to determine if batch checkouts should be allowed. To test: 1) Open the staff interface. Go to Koha Administration -> Global system preferences. Search for "BatchCheckouts". Confirm BatchCheckouts syspref is disabled, and no categories are selected for the BatchCheckoutsValidCategories syspref. 2) In another tab, open the OPAC self checkout (found out OPACBaseURL/cgi-bin/koha/sco/sco-main.pl) and log in 3) Confirm the self-checkout works as normal for checking out, returning or renewing one item at a time 4) Go back to the staff interface tab (you may need to log back in). Enable the BatchCheckouts syspref but leave the BatchCheckoutsValidCategories syspref empty. 5) Refresh the OPAC self checkout tab. The barcode input field will now be bigger to support a list of barcodes. Enter a list of barcodes separated by newlines and Submit. 6) Only the first barcode should be processed. This is because no categories are valid for BatchCheckouts. 7) Go back to the staff interface tab (you may need to log back in). Select at least your patron category for the BatchCheckoutsValidCategories syspref and Save. 8) Refresh the OPAC self checkout tab. Enter a list of barcodes separated by newlines and Submit. Confirm all valid items are checked out as expected. 9) Test with a few items that are notforloan or would not be valid checkouts. Confirm they are not checked out, but other valid items in the batch are checked out successfully. 10) Test with a batch where one of the items is already checked out to the patron. The batch should get blocked at this item as the self-checkout asks for confirmation. 11) Test with both renewing and returning of items that are already checked out to the patron. This will only work with one item at a time and later items in the list will be ignored. Sponsored-by: Koha-US Signed-off-by: David Nind Signed-off-by: Andrew Fuerste Henry Signed-off-by: Martin Renvoize Signed-off-by: Andrew Fuerste Henry Signed-off-by: Martin Renvoize Signed-off-by: Katrin Fischer --- .../bootstrap/en/modules/sco/sco-main.tt | 18 ++++--- opac/sco/sco-main.pl | 52 ++++++++++++++++--- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/sco/sco-main.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/sco/sco-main.tt index 7508a211b5..11692c9632 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/sco/sco-main.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/sco/sco-main.tt @@ -131,7 +131,7 @@

Please confirm the checkout:

[% IF ( confirm_renew_issue ) %] -

This item is already checked out to you.

+

This item is already checked out to you: [% confirm | html %] ([% barcode | html %])

[% END %] [% IF ( renew && Koha.Preference('SCOAllowCheckin') ) %] @@ -213,14 +213,16 @@ [% END %] [% IF ( issued ) %] + [% FOREACH barcode IN newissues.split(',') %]
-

Item checked out

+

Item checked out ([% barcode | html %])

+ [% END %] [% ELSIF ( renewed ) %]
-

Item renewed

+

Item renewed ([% barcode | html %])

[% ELSIF ( renewed == 0) %] @@ -235,7 +237,7 @@ [% ELSIF ( returned == 1 ) %]
-

Item checked in

+

Item checked in ([% barcode | html %])

[% END %] @@ -272,10 +274,14 @@
- +
- + [% IF Koha.Preference('BatchCheckouts') %] + + [% ELSE %] + + [% END %]
diff --git a/opac/sco/sco-main.pl b/opac/sco/sco-main.pl index a7fcb24d8f..55b4355f59 100755 --- a/opac/sco/sco-main.pl +++ b/opac/sco/sco-main.pl @@ -86,7 +86,7 @@ if (defined C4::Context->preference('SCOAllowCheckin')) { } my $issuerid = $loggedinuser; -my ( $op, $patronlogin, $patronpw, $barcode, $confirmed, $newissues, $load_checkouts ) = ( +my ( $op, $patronlogin, $patronpw, $barcodestr, $confirmed, $newissues, $load_checkouts ) = ( $query->param("op") || '', $query->param("patronlogin") || '', $query->param("patronpw") || '', @@ -104,7 +104,11 @@ if ($op eq "logout") { undef $jwt; } -$barcode = barcodedecode( $barcode ) if $barcode; +my $barcodes = []; +if ( $barcodestr ) { + push @$barcodes, split( /\s\n/, $barcodestr ); + $barcodes = [ map { $_ =~ /^\s*$/ ? () : barcodedecode( $_ ) } @$barcodes ]; +} my @newissueslist = split /,/, $newissues; my $issuenoconfirm = 1; #don't need to confirm on issue. @@ -134,10 +138,28 @@ my $branch = $issuer->{branchcode}; my $confirm_required = 0; my $return_only = 0; +if ( C4::Context->preference('BatchCheckouts') ) { + my @batch_category_codes = split ',', C4::Context->preference('BatchCheckoutsValidCategories'); + my $categorycode = $issuer->{categorycode}; + if ( $categorycode && grep { $_ eq $categorycode } @batch_category_codes ) { + # do nothing - logged in patron is allowed to do batch checkouts + } else { + # patron category not allowed to do batch checkouts, only allow first barcode + while ( scalar @$barcodes > 1 ) { + pop @$barcodes; + } + } +} else { + # batch checkouts not enabled, only allow first barcode + while ( scalar @$barcodes > 1 ) { + pop @$barcodes; + } +} + if ( $patron && $op eq "cud-returnbook" && $allowselfcheckreturns ) { my $success = 1; - + foreach my $barcode ( @$barcodes ) { my $item = Koha::Items->find( { barcode => $barcode } ); if ( $success && C4::Context->preference("CircConfirmItemParts") ) { if ( defined($item) @@ -157,10 +179,15 @@ if ( $patron && $op eq "cud-returnbook" && $allowselfcheckreturns ) { ($success) = AddReturn( $barcode, $branch ) } - $template->param( returned => $success ); + $template->param( + returned => $success, + barcode => $barcode + ); + } # foreach barcode in barcodes } -elsif ( $patron && ( $op eq 'cud-checkout' ) ) { +elsif ( $patron && ( $op eq 'cud-checkout' ) ) { + foreach my $barcode ( @$barcodes ) { my $item = Koha::Items->find( { barcode => $barcode } ); my $impossible = {}; my $needconfirm = {}; @@ -203,14 +230,16 @@ elsif ( $patron && ( $op eq 'cud-checkout' ) ) { barcode => $barcode, ); } + last; } elsif ( $needconfirm->{RENEW_ISSUE} ){ $template->param( renew => 1, barcode => $barcode, - confirm => 1, + confirm => $item->biblio->title, confirm_renew_issue => 1, hide_main => 1, ); + last; } elsif ( $confirm_required && !$confirmed ) { $template->param( impossible => 1, @@ -220,6 +249,7 @@ elsif ( $patron && ( $op eq 'cud-checkout' ) ) { if ($issue_error eq 'DEBT') { $template->param(DEBT => $needconfirm->{DEBT}); } + last; } else { if ( $confirmed || $issuenoconfirm ) { # we'll want to call getpatroninfo again to get updated issues. my ( $hold_existed, $item ); @@ -242,7 +272,7 @@ elsif ( $patron && ( $op eq 'cud-checkout' ) ) { my $new_issue = AddIssue( $patron, $barcode ); $template->param( issued => 1, new_issue => $new_issue ); - push @newissueslist, $barcode; + push @newissueslist, $barcode unless ( grep /^$barcode$/, @newissueslist ); if ( $hold_existed ) { my $dtf = Koha::Database->new->schema->storage->datetime_parser; @@ -268,9 +298,11 @@ elsif ( $patron && ( $op eq 'cud-checkout' ) ) { ); } } + } # foreach barcode in barcodes } # $op if ( $patron && ( $op eq 'cud-renew' ) ) { + foreach my $barcode ( @$barcodes ) { my $item = Koha::Items->find({ barcode => $barcode }); if ( $patron->checkouts->find( { itemnumber => $item->itemnumber } ) ) { @@ -284,11 +316,15 @@ if ( $patron && ( $op eq 'cud-renew' ) ) { } ); push @newissueslist, $barcode; - $template->param( renewed => 1 ); + $template->param( + renewed => 1, + barcode => $barcode + ); } } else { $template->param( renewed => 0 ); } + } # foreach barcode in barcodes } if ( $patron) { -- 2.39.5