From 974c5f4fd14ee01bab8badaa2972f9e7b60a8061 Mon Sep 17 00:00:00 2001 From: emilyrose Date: Tue, 26 Sep 2023 08:44:24 -0400 Subject: [PATCH] Bug 9762: Log circulation overrides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch allows you to save commands that have been overridden by someone. The patch has been updated but is not yet completed. Tests 10, 13, 14, and 17 are still not functional. Tests 15 and 16 need to be fixed as they do not display the barcode. All other tests should be functional. To test: --After each step, a message will be displayed in the action_logs table and in Tools > Log viewer -- Circulation -- Checking out 1) Check out an item that is age-restricted (AgeRestrictionOverride syspref) 2) Check out an item that has a “not for loan” status (AllowNotForLoanOverride syspref) 3) Check out an item that has a “lost” status (IssueLostItem syspref) 4) Check out an item to a patron who has reached the checkout limit (AllowTooManyOverride syspref) 5) Check out an item to a patron who is not allowed to borrow this item type 6) Check out an item to a patron who has unpaid fines (AllFinesNeedOverride and/or AllowFineOverride + noissuescharge sysprefs) 7) Check out an item on hold for someone else 8) Check out an item on hold ready for pickup by someone else 9) Check out an item already checked out to someone else (AutoReturnCheckedOutItems syspref) 10) Check out to a patron who has restrictions Circulation -- Checking in 11) Ignore a hold upon check in 12) Ignore a hold and transfer upon check in Circulation – Renewing 13) Renew an item on hold for someone else (AllowRenewalOnHoldOverride syspref) 14) Renew an item that has reached the maximum number of renewals (AllowRenewalLimitOverride syspref) Holds 15) Place a hold for a patron who is not allowed to place this item type on hold (AllowHoldPolicyOverride syspref) 16) Place a hold for a patron who has reached the maximum number of holds 17) Place an item-level hold when rules dictate that this is not allowed (In circulation rules put "On shelf holds allowed" to "If any unavailable") --- C4/Circulation.pm | 187 +++++++++++++++++++++++++++++++++++++++++--- circ/circulation.pl | 95 ++++++++++++++-------- circ/renew.pl | 55 ++++++++++++- circ/returns.pl | 29 ++++++- reserve/request.pl | 66 ++++++++++++++-- svc/renew | 58 +++++++++++++- 6 files changed, 438 insertions(+), 52 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index d41c5f7615..8a8c951f2b 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -22,6 +22,7 @@ use Modern::Perl; use DateTime; use POSIX qw( floor ); use Encode; +use JSON; use C4::Context; use C4::Stats qw( UpdateStats ); @@ -317,6 +318,21 @@ A recall for this item was found, and the item needs to be transferred to the re =cut +my $query = CGI->new; + +my $stickyduedate = $query->param('stickyduedate'); +my $duedatespec = $query->param('duedatespec'); +my $restoreduedatespec = $query->param('restoreduedatespec') || $duedatespec; +if ( $restoreduedatespec && $restoreduedatespec eq "highholds_empty" ) { + undef $restoreduedatespec; +} +my $issueconfirmed = $query->param('issueconfirmed'); +my $cancelreserve = $query->param('cancelreserve'); +my $cancel_recall = $query->param('cancel_recall'); +my $recall_id = $query->param('recall_id'); +my $debt_confirmed = $query->param('debt_confirmed') || 0; # Don't show the debt error dialog twice +my $charges = $query->param('charges') || q{}; + sub transferbook { my $params = shift; my $tbr = $params->{to_branch}; @@ -801,9 +817,22 @@ sub CanBookBeIssued { my $circ_library = Koha::Libraries->find( _GetCircControlBranch($item_object, $patron) ); my $now = dt_from_string(); + my $message; + my @message; + $duedate ||= CalcDateDue( $now, $effective_itemtype, $circ_library->branchcode, $patron ); + if (DateTime->compare($duedate,$now) == -1 ) { # duedate cannot be before now $needsconfirmation{INVALID_DATE} = $duedate; + if ($issueconfirmed) { + if ($message) { + $message = "$message + sticky due date is invalid or due date in the past"; + } else { + $message = "sticky due date is invalid or due date in the past"; + } + push( @message, "sticky due date is invalid or due date in the past" ); + } + } my $fees = Koha::Charges::Fees->new( @@ -848,6 +877,14 @@ sub CanBookBeIssued { } if ( $patron->is_debarred ) { $issuingimpossible{DEBARRED} = 1; + if ($issueconfirmed) { + if ($message) { + $message = "$message + borrower is restricted"; + } else { + $message = "borrower is restricted"; + } + push( @message, "borrower is restricted" ); + } } if ( $patron->is_expired ) { @@ -914,10 +951,26 @@ sub CanBookBeIssued { else { if ( $non_issues_charges > $amountlimit && $allowfineoverride ) { $needsconfirmation{DEBT} = $non_issues_charges; + if ($issueconfirmed) { + if ($message) { + $message = "$message + borrower had amend"; + } else { + $message = "borrower had amend"; + } + push( @message, "borrower had amend" ); + } } elsif ( $non_issues_charges > $amountlimit && !$allowfineoverride) { $issuingimpossible{DEBT} = $non_issues_charges; } elsif ( $non_issues_charges > 0 && $allfinesneedoverride ) { $needsconfirmation{DEBT} = $non_issues_charges; + if ($issueconfirmed) { + if ($message) { + $message = "$message + borrower had amend"; + } else { + $message = "borrower had amend"; + } + push( @message, "borrower had amend" ); + } } } @@ -994,13 +1047,20 @@ sub CanBookBeIssued { } else { if ( C4::Context->preference('AutoReturnCheckedOutItems') ) { $alerts{RETURNED_FROM_ANOTHER} = { patron => $patron }; - } - else { + } else { $needsconfirmation{ISSUED_TO_ANOTHER} = 1; $needsconfirmation{issued_firstname} = $patron->firstname; $needsconfirmation{issued_surname} = $patron->surname; $needsconfirmation{issued_cardnumber} = $patron->cardnumber; $needsconfirmation{issued_borrowernumber} = $patron->borrowernumber; + if ($issueconfirmed) { + if ($message) { + $message = "$message + item is checked out for someone else "; + } else { + $message = "item is checked out for someone else"; + } + push( @message, "item is checked out for someone else" ); + } } } } @@ -1024,6 +1084,14 @@ sub CanBookBeIssued { $needsconfirmation{current_loan_count} = $toomany->{count}; $needsconfirmation{max_loans_allowed} = $toomany->{max_allowed}; $needsconfirmation{circulation_rule_TOO_MANY} = $toomany->{circulation_rule}; + if ($issueconfirmed) { + if ($message) { + $message = "$message + too many checkout"; + } else { + $message = "too many checkout"; + } + push( @message, "too many checkout" ); + } } else { $issuingimpossible{TOO_MANY} = $toomany->{reason}; $issuingimpossible{current_loan_count} = $toomany->{count}; @@ -1051,6 +1119,14 @@ sub CanBookBeIssued { }else{ $needsconfirmation{NOT_FOR_LOAN_FORCING} = 1; $needsconfirmation{item_notforloan} = $item_object->notforloan; + if ($issueconfirmed) { + if ($message) { + $message = "$message + item not for loan"; + } else { + $message = "item not for loan"; + } + push( @message, "item not for loan" ); + } } } else { @@ -1097,6 +1173,14 @@ sub CanBookBeIssued { my $code = $av->count ? $av->next->lib : ''; $needsconfirmation{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'confirm' ); $alerts{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'alert' ); + if ($issueconfirmed) { + if ($message) { + $message = "$message + item lost"; + } else { + $message = "item lost"; + } + push( @message, "item lost" ); + } } if ( C4::Context->preference("IndependentBranches") ) { my $userenv = C4::Context->userenv; @@ -1193,6 +1277,15 @@ sub CanBookBeIssued { $needsconfirmation{'resbranchcode'} = $res->{branchcode}; $needsconfirmation{'reswaitingdate'} = $res->{'waitingdate'}; $needsconfirmation{'reserve_id'} = $res->{reserve_id}; + if ($issueconfirmed) { + if ($message) { + $message = + "$message + item is on reserve and waiting, but has been reserved by some other patron."; + } else { + $message = "item is on reserve and waiting, but has been reserved by some other patron."; + } + push( @message, "item is on reserve and waiting, but has been reserved by some other patron" ); + } } elsif ( $restype eq "Reserved" ) { # The item is on reserve for someone else. @@ -1204,6 +1297,14 @@ sub CanBookBeIssued { $needsconfirmation{'resbranchcode'} = $res->{branchcode}; $needsconfirmation{'resreservedate'} = $res->{reservedate}; $needsconfirmation{'reserve_id'} = $res->{reserve_id}; + if ($issueconfirmed) { + if ($message) { + $message = "$message + item is on reserve for someone else"; + } else { + $message = "item is on reserve for someone else"; + } + push( @message, "item is on reserve for someone else" ); + } } elsif ( $restype eq "Transferred" ) { # The item is determined hold being transferred for someone else. @@ -1215,6 +1316,14 @@ sub CanBookBeIssued { $needsconfirmation{'resbranchcode'} = $res->{branchcode}; $needsconfirmation{'resreservedate'} = $res->{reservedate}; $needsconfirmation{'reserve_id'} = $res->{reserve_id}; + if ($issueconfirmed) { + if ($message) { + $message = "$message + item is determined hold being transferred for someone else"; + } else { + $message = "item is determined hold being transferred for someone else"; + } + push( @message, "item is determined hold being transferred for someone else" ); + } } elsif ( $restype eq "Processing" ) { # The item is determined hold being processed for someone else. @@ -1226,6 +1335,14 @@ sub CanBookBeIssued { $needsconfirmation{'resbranchcode'} = $res->{branchcode}; $needsconfirmation{'resreservedate'} = $res->{reservedate}; $needsconfirmation{'reserve_id'} = $res->{reserve_id}; + if ($issueconfirmed) { + if ($message) { + $message = "$message + item is determined hold being processed for someone else"; + } else { + $message = "item is determined hold being processed for someone else"; + } + push( @message, "item is determined hold being processed for someone else" ); + } } } } @@ -1269,6 +1386,12 @@ sub CanBookBeIssued { if ( $daysToAgeRestriction && $daysToAgeRestriction > 0 ) { if ( C4::Context->preference('AgeRestrictionOverride') ) { $needsconfirmation{AGE_RESTRICTION} = "$agerestriction"; + if ($message) { + $message = "$message + age restriction"; + } else { + $message = "age restriction"; + } + push( @message, "age restriction" ); } else { $issuingimpossible{AGE_RESTRICTION} = "$agerestriction"; @@ -1325,10 +1448,40 @@ sub CanBookBeIssued { } } + my $borrower = $patron; + my $user = C4::Context->userenv->{number}; + my $branchcode = C4::Context->userenv->{branch}; + my $item = Koha::Items->find( { barcode => $barcode } ); + my $itemnumber = $item->itemnumber; + + # action, cardnumber, barcode, date, heure, user, branche + if ($issueconfirmed) { + + my $infos = ( + { + message => \@message, + borrowernumber => $borrower->borrowernumber, + barcode => $barcode, + manager_id => $user, + branchcode => $branchcode, + } + ); + + my $json_infos = JSON->new->utf8->pretty->encode($infos); + $json_infos =~ s/"/'/g; + + logaction( + "CIRCULATION", "ISSUE", + $borrower->{'borrowernumber'}, + $json_infos, + ) if C4::Context->preference("IssueLog"); + } + + return ( \%issuingimpossible, \%needsconfirmation, \%alerts, \%messages, ); } -=head2 CanBookBeReturned +=head2 CanBookBeReturnedcd ($returnallowed, $message) = CanBookBeReturned($item, $branch) @@ -2343,9 +2496,9 @@ sub AddReturn { if ( $transfer->tobranch eq $branch ) { $transfer->receive; $messages->{'TransferArrived'} = $transfer->frombranch; + # validTransfer=1 allows us returning the item back if the reserve is cancelled - $validTransfer = 1 - if defined $transfer->reason && $transfer->reason eq 'Reserve'; + $validTransfer = 1 if $transfer->reason eq 'Reserve'; } else { $messages->{'WrongTransfer'} = $transfer->tobranch; @@ -3053,6 +3206,22 @@ sub CanBookBeRenewed { return ( 0, "on_reserve" ) if ( $item->current_holds->search( { non_priority => 0 } )->count ); + my $issuing_rule = Koha::CirculationRules->get_effective_rules( + { + categorycode => $patron->categorycode, + itemtype => $item->effective_itemtype, + branchcode => $branchcode, + rules => [ + 'renewalsallowed', + 'lengthunit', + 'unseen_renewals_allowed' + ] + } + ); + + return ( 0, "too_many" ) + if not $issuing_rule->{renewalsallowed} + or $issuing_rule->{renewalsallowed} <= $issue->renewals_count; my ( $status, $matched_reserve, $possible_holds ) = CheckReserves($item); my @fillable_holds = (); @@ -3181,8 +3350,7 @@ fallback to a true value C<$automatic> is a boolean flag indicating the renewal was triggered automatically and not by a person ( librarian or patron ) -C<$skip_record_index> is an optional boolean flag to indicate whether queuing the search indexing -should be skipped for this renewal. +C<$skip_record_index> is an optional boolean flag to indicate whether queuing the search indexing should be skipped for this renewal. =cut @@ -3384,9 +3552,10 @@ sub AddRenewal { }); }); - unless( $skip_record_index ){ + unless ($skip_record_index) { + # We index now, after the transaction is committed - my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX }); + my $indexer = Koha::SearchEngine::Indexer->new( { index => $Koha::SearchEngine::BIBLIOS_INDEX } ); $indexer->index_records( $item_object->biblionumber, "specialUpdate", "biblioserver" ); } diff --git a/circ/circulation.pl b/circ/circulation.pl index d1fe834df3..4f0c5b8f80 100755 --- a/circ/circulation.pl +++ b/circ/circulation.pl @@ -38,7 +38,8 @@ use C4::Circulation qw( barcodedecode CanBookBeIssued AddIssue AddReturn ); use C4::Members; use C4::Biblio qw( TransformMarcToKoha ); use C4::Search qw( new_record_from_zebra ); -use C4::Reserves qw( ModReserveAffect ); +use C4::Reserves; +use C4::Log qw( logaction ); use Koha::Holds; use C4::Context; use CGI::Session; @@ -239,7 +240,7 @@ if ( @$barcodes == 0 && $charges eq 'yes' ) { # STEP 2 : FIND BORROWER # if there is a list of find borrowers.... # -my $message; + if ($findborrower) { Koha::Plugins->call( 'patron_barcode_transform', \$findborrower ); my $patron = Koha::Patrons->find( { cardnumber => $findborrower } ); @@ -313,6 +314,9 @@ if ($patron) { # STEP 3 : ISSUING # # +my $message; +my @message; + if (@$barcodes && $op eq 'cud-checkout') { my $checkout_infos; for my $barcode ( @$barcodes ) { @@ -450,39 +454,68 @@ if (@$barcodes && $op eq 'cud-checkout') { } } } - unless ($confirm_required) { - my $switch_onsite_checkout = exists $messages->{ONSITE_CHECKOUT_WILL_BE_SWITCHED}; - if ( C4::Context->preference('UseRecalls') && !$recall_id ) { - my $recall = Koha::Recalls->find( + unless ($confirm_required) { + my $switch_onsite_checkout = exists $messages->{ONSITE_CHECKOUT_WILL_BE_SWITCHED}; + if ( C4::Context->preference('UseRecalls') && !$recall_id ) { + my $recall = Koha::Recalls->find( + { + biblio_id => $item->biblionumber, + item_id => [ undef, $item->itemnumber ], + status => [ 'requested', 'waiting' ], + completed => 0, + patron_id => $patron->borrowernumber, + } + ); + $recall_id = ( $recall and $recall->id ) ? $recall->id : undef; + + } + + # If booked (alerts or confirmation) update datedue to end of booking + if ( my $booked = $needsconfirmation->{BOOKED_EARLY} // $alerts->{BOOKED} ) { + $datedue = $booked->end_date; + } + my $issue = AddIssue( + $patron, $barcode, $datedue, + $cancelreserve, + undef, undef, { - biblio_id => $item->biblionumber, - item_id => [ undef, $item->itemnumber ], - status => [ 'requested', 'waiting' ], - completed => 0, - patron_id => $patron->borrowernumber, + onsite_checkout => $onsite_checkout, auto_renew => $session->param('auto_renew'), + switch_onsite_checkout => $switch_onsite_checkout, cancel_recall => $cancel_recall, + recall_id => $recall_id, } ); - $recall_id = ( $recall and $recall->id ) ? $recall->id : undef; - } - - # If booked (alerts or confirmation) update datedue to end of booking - if ( my $booked = $needsconfirmation->{BOOKED_EARLY} // $alerts->{BOOKED} ) { - $datedue = $booked->end_date; - } - my $issue = AddIssue( - $patron, $barcode, $datedue, - $cancelreserve, - undef, undef, - { - onsite_checkout => $onsite_checkout, auto_renew => $session->param('auto_renew'), - switch_onsite_checkout => $switch_onsite_checkout, cancel_recall => $cancel_recall, - recall_id => $recall_id, + $template_params->{issue} = $issue; + + my $borrower = $patron; + my $borrowernumber = $patron->borrowernumber; + my $user = C4::Context->userenv->{number}; + my $branchcode = C4::Context->userenv->{branch}; + $message = "Restriction overridden temporarily"; + @message = ("Restriction overridden temporarily"); + + if ($issueconfirmed) { + my $infos = ( + { + message => \@message, + borrowernumber => $borrowernumber, + barcode => $barcode, + manager_id => $user, + branchcode => $branchcode, + } + ); + + my $json_infos = JSON->new->utf8->pretty->encode($infos); + $json_infos =~ s/"/'/g; + + logaction( + "CIRCULATION", "ISSUE", + $borrower->{'borrowernumber'}, + $json_infos, + ) if C4::Context->preference("IssueLog"); } - ); - $template_params->{issue} = $issue; - $session->clear('auto_renew'); - $inprocess = 1; - } + $session->clear('auto_renew'); + $inprocess = 1; + } } if ($needsconfirmation->{RESERVE_WAITING} or $needsconfirmation->{RESERVED} or $needsconfirmation->{TRANSFERRED} or $needsconfirmation->{PROCESSING}){ diff --git a/circ/renew.pl b/circ/renew.pl index 52b38ddb8c..e786914bbe 100755 --- a/circ/renew.pl +++ b/circ/renew.pl @@ -24,6 +24,7 @@ use C4::Context; use C4::Auth qw( get_template_and_user ); use C4::Output qw( output_html_with_http_headers ); use C4::Circulation qw( barcodedecode CanBookBeRenewed GetLatestAutoRenewDate AddRenewal ); +use C4::Log qw( logaction ); use Koha::DateUtils qw( dt_from_string ); use Koha::Database; use Koha::BiblioFrameworks; @@ -64,8 +65,14 @@ if ($op eq 'cud-renew' && $barcode) { if ($checkout) { $patron = $checkout->patron; - - if ( ( $patron->is_debarred || q{} ) lt dt_from_string()->ymd() ) { + my $borrower = $patron; + my $borrowernumber = $borrower->borrowernumber; + my $user = C4::Context->userenv->{number}; + my $branchcode = C4::Context->userenv->{branch}; + my $message; + my @message; + + if ( ( $borrower->debarred() || q{} ) lt dt_from_string()->ymd() ) { my $can_renew; my $info; ( $can_renew, $error, $info ) = @@ -75,6 +82,28 @@ if ($op eq 'cud-renew' && $barcode) { if ($override_holds) { $can_renew = 1; $error = undef; + + $message = "Override Renew hold for another"; + @message = ("Override Renew hold for another"); + + my $infos = ( + { + message => \@message, + borrowernumber => $borrowernumber, + barcode => $barcode, + manager_id => $user, + branchcode => $branchcode, + } + ); + + my $json_infos = JSON->new->utf8->pretty->encode($infos); + $json_infos =~ s/"/'/g; + + logaction( + "CIRCULATION", "RENEWAL", + $borrower->{'borrowernumber'}, + $json_infos, + ) if C4::Context->preference("RenewalLog"); } else { $can_renew = 0; @@ -107,6 +136,28 @@ if ($op eq 'cud-renew' && $barcode) { } ); $template->param( date_due => $date_due ); + + $message = "Override limit Renew"; + @message = ("Override limit Renew"); + + my $infos = ( + { + message => \@message, + borrowernumber => $borrowernumber, + barcode => $barcode, + manager_id => $user, + branchcode => $branchcode, + } + ); + + my $json_infos = JSON->new->utf8->pretty->encode($infos); + $json_infos =~ s/"/'/g; + + logaction( + "CIRCULATION", "RENEWAL", + $borrower->{'borrowernumber'}, + $json_infos, + ) if C4::Context->preference("RenewalLog"); } } else { diff --git a/circ/returns.pl b/circ/returns.pl index 5b119e3726..2b0c0c4335 100755 --- a/circ/returns.pl +++ b/circ/returns.pl @@ -43,6 +43,7 @@ use C4::Members; use C4::Output qw( output_html_with_http_headers ); use C4::Reserves qw( ModReserve ModReserveAffect GetOtherReserves ); use C4::RotatingCollections; +use C4::Log qw( logaction ); use Koha::AuthorisedValues; use Koha::BiblioFrameworks; use Koha::Calendar; @@ -179,6 +180,32 @@ if ( $query->param('reserve_id') && $op eq 'cud-affect_reserve') { diffbranch => 1, ); } +} else { + my $message = "return an element that is reserved"; + my @message = ("return an element that is reserved"); + my $user = C4::Context->userenv->{number}; + my $branchcode = C4::Context->userenv->{branch}; + my $barcode = $query->param('barcode'); + + my $infos = ( + { + message => \@message, + + #'card number' => $cardnumber, + barcode => $barcode, + manager_id => $user, + branchcode => $branchcode, + } + ); + + my $json_infos = JSON->new->utf8->pretty->encode($infos); + $json_infos =~ s/"/'/g; + + logaction( + "CIRCULATION", "RETURN", + $session, + $json_infos, + ) if C4::Context->preference("ReturnLog"); } if ( $query->param('recall_id') && $op eq 'cud-affect_recall' ) { @@ -432,7 +459,7 @@ if ($barcode && $op eq 'cud-checkin') { } # Mark missing bundle items as lost and report unexpected items - if ( $item && $item->is_bundle && $query->param('confirm_items_bundle_return') && !$query->param('do_not_verify_items_bundle_contents') ) { + if ( $item && $item->is_bundle && $query->param('confirm_items_bundle_return') ) { my $BundleLostValue = C4::Context->preference('BundleLostValue'); my $barcodes = $query->param('verify-items-bundle-contents-barcodes'); my @barcodes = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes ); diff --git a/reserve/request.pl b/reserve/request.pl index 6989485f0b..5a233b8227 100755 --- a/reserve/request.pl +++ b/reserve/request.pl @@ -27,6 +27,7 @@ script to place reserves/requests =cut use Modern::Perl; +use Data::Dumper; use CGI qw ( -utf8 ); use List::MoreUtils qw( uniq ); @@ -40,6 +41,7 @@ use C4::Serials qw( CountSubscriptionFromBiblionumber ); use C4::Circulation qw( _GetCircControlBranch GetBranchItemRule ); use Koha::DateUtils qw( dt_from_string ); use C4::Search qw( enabled_staff_search_views ); +use C4::Log qw( logaction ); use Koha::Biblios; use Koha::Checkouts; @@ -509,7 +511,7 @@ if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) && !$exceeded_maxreserves && $can_item_be_reserved eq 'OK' && IsAvailableForItemLevelRequest($item_object, $patron, undef) - ) || C4::Context->preference('AllowHoldPolicyOverride') + ) #|| C4::Context->preference('AllowHoldPolicyOverride') # If AllowHoldPolicyOverride is set, it overrides EVERY restriction # not just branch item rules ) @@ -524,17 +526,67 @@ if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) my $default_pickup_location = $pickup_locations->search({ branchcode => $default_pickup_branch })->next; $item->{default_pickup_location} = $default_pickup_location; } - elsif ( C4::Context->preference('AllowHoldPolicyOverride') ){ - $num_items_available++; - $item->{override} = 1; - my $default_pickup_location = $pickup_locations->search({ branchcode => $default_pickup_branch })->next; - $item->{default_pickup_location} = $default_pickup_location; - } else { $item->{available} = 0; $item->{not_holdable} = "no_valid_pickup_location"; } + push( @available_itemtypes, $item->{itype} ); + } elsif ( C4::Context->preference('AllowHoldPolicyOverride') ) { + + # If AllowHoldPolicyOverride is set, it should override EVERY restriction, not just branch item rules + # with the exception of itemAlreadyOnHold because, you know, the item is already on hold + if ( $can_item_be_reserved ne 'itemAlreadyOnHold' ) { + + # Send the pickup locations count to the UI, the pickup locations will be pulled using the API + my @pickup_locations = $item_object->pickup_locations( { patron => $patron } )->as_list; + $item->{pickup_locations_count} = scalar @pickup_locations; + + if (@pickup_locations) { + $num_items_available++; + $item->{override} = 1; + + my $default_pickup_location; + + ($default_pickup_location) = + grep { $_->branchcode eq $default_pickup_branch } @pickup_locations; + + $item->{default_pickup_location} = $default_pickup_location; + } else { + $item->{available} = 0; + $item->{not_holdable} = "no_valid_pickup_location"; + } + } else { + $num_alreadyheld++; + } + + my $borrower = $patron; + my $borrowernumber = $patron->borrowernumber; + my $user = C4::Context->userenv->{number}; + my $branchcode = C4::Context->userenv->{branch}; + my $message = "Override limitation of hold"; + my @message = ("Override limitation of hold"); + my $barcode = $item->{barcode}; + + my $infos = ( + { + message => \@message, + borrowernumber => $borrowernumber, + barcode => $barcode, + manager_id => $user, + branchcode => $branchcode, + } + ); + + my $json_infos = JSON->new->utf8->pretty->encode($infos); + $json_infos =~ s/"/'/g; + + logaction( + "HOLD", "ISSUE", + $borrower->{'borrowernumber'}, + $json_infos, + ) if C4::Context->preference("IssueLog"); + push( @available_itemtypes, $item->{itype} ); } else { # If none of the conditions hold true, then neither override nor available is set and the item cannot be checked diff --git a/svc/renew b/svc/renew index eca18e647f..5761f2e56f 100755 --- a/svc/renew +++ b/svc/renew @@ -26,6 +26,7 @@ use Try::Tiny; use C4::Circulation qw( AddRenewal CanBookBeRenewed ); use C4::Context; use C4::Auth qw(check_cookie_auth); +use C4::Log qw( logaction ); use Koha::DateUtils qw(output_pref dt_from_string); @@ -52,6 +53,10 @@ my $date_due; if ( $input->param('date_due') ) { $date_due = dt_from_string( scalar $input->param('date_due') ); } +my $borrower = Koha::Patrons->find($borrowernumber); +my $user = C4::Context->userenv->{'number'}; +my $message; +my @message; my $data; $data->{itemnumber} = $itemnumber; @@ -65,9 +70,58 @@ my $item = Koha::Items->find($itemnumber); CanBookBeRenewed( $patron, $item->checkout, $override_limit ); # If we're allowing reserved items to be renewed... -if ( $data->{error} && $data->{error} eq 'on_reserve' && C4::Context->preference('AllowRenewalOnHoldOverride')) { +if ( $data->{error} && $data->{error} eq 'on_reserve' && C4::Context->preference('AllowRenewalOnHoldOverride') ) { $data->{renew_okay} = 1; - $data->{error} = undef; + $data->{error} = undef; + + $message = "Override Renew hold for another"; + @message = ("Override Renew hold for another"); + + my $infos = ( + { + message => \@message, + borrowernumber => $borrowernumber, + barcode => $item->barcode, + manager_id => $user, + branchcode => $branchcode, + } + ); + + my $json_infos = JSON->new->utf8->pretty->encode($infos); + $json_infos =~ s/"/'/g; + + logaction( + "CIRCULATION", "RENEWAL", + $borrower->{'borrowernumber'}, + $json_infos, + ) if C4::Context->preference("IssueLog"); +} + +if ( $data->{error} && $data->{error} eq 'too_many' && C4::Context->preference('AllowRenewalLimitOverride') ) { + $data->{renew_okay} = 1; + $data->{error} = undef; + + $message = "Override limit Renew"; + @message = ("Override limit Renew"); + + my $infos = ( + { + message => \@message, + borrowernumber => $borrowernumber, + barcode => $item->barcode, + manager_id => $user, + branchcode => $branchcode, + } + ); + + my $json_infos = JSON->new->utf8->pretty->encode($infos); + $json_infos =~ s/"/'/g; + + logaction( + "CIRCULATION", "RENEWAL", + $borrower->{'borrowernumber'}, + $json_infos, + ) if C4::Context->preference("IssueLog"); } if ( $data->{renew_okay} || ( $seen && $data->{error} eq 'too_unseen') ) { -- 2.34.1