From 335f68eb51679fd58b25cf5a563c0cb7b2237dfa Mon Sep 17 00:00:00 2001 From: Emmi Takkinen Date: Thu, 22 Sep 2022 12:19:03 +0300 Subject: [PATCH] Bug 16223: Add ability to define liftable restrictions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Some libraries debar Patrons at the end of the year for having unpaid fines, like in Bug 15157. Currently librarians have to manually remove this type of debarments after Patron has paid his/her fines. This patch adds ability to create restrictions which are lifted after patron pays ceratain amount of fines. To test: 1. Apply this patch. 2. Restart your services if needed. 3. Navigate to page restrictions.pl. => Note that table has two new colums in it, "Lift after payment?" and "Fee limit". 4. Add new restriction which has "Lift after payment?" set as Yes and fee limit as 5. 5. Create fees for a patron so they exceed fee limit e.g. 10 6. Add restriction made in step 2. for the patron 7. Pay patrons fees partially so that they go under fee limit => Note that patrons restriction should now be lifted. Also prove t/db_dependent/Patron/Borrower_Debarments.t. Sponsored-by: Koha-Suomi Oy Signed-off-by: Anneli Österman Signed-off-by: Martin Renvoize Signed-off-by: Marcel de Rooy Signed-off-by: Tomas Cohen Arazi --- Koha/Account.pm | 3 + Koha/Patron/Debarments.pm | 38 ++++++++++ admin/restrictions.pl | 10 ++- .../prog/en/modules/admin/restrictions.tt | 34 +++++++++ .../intranet-tmpl/prog/js/restrictiontypes.js | 3 +- t/db_dependent/Patron/Borrower_Debarments.t | 76 ++++++++++++++++++- 6 files changed, 160 insertions(+), 4 deletions(-) diff --git a/Koha/Account.pm b/Koha/Account.pm index ad08a6df4b..b6bd357b16 100644 --- a/Koha/Account.pm +++ b/Koha/Account.pm @@ -39,6 +39,7 @@ use Koha::Account::DebitTypes; use Koha::Exceptions; use Koha::Exceptions::Account; use Koha::Plugins; +use Koha::Patron::Debarments; =head1 NAME @@ -117,6 +118,8 @@ sub pay { } ); + Koha::Patron::Debarments::del_restrictions_after_payment({ borrowernumber => $self->{patron_id} }); + # NOTE: Pay historically always applied as much credit as it could to all # existing outstanding debits, whether passed specific debits or otherwise. if ( $payment->amountoutstanding ) { diff --git a/Koha/Patron/Debarments.pm b/Koha/Patron/Debarments.pm index 60c3f5504e..ca6e27c2ee 100644 --- a/Koha/Patron/Debarments.pm +++ b/Koha/Patron/Debarments.pm @@ -21,6 +21,8 @@ use Modern::Perl; use C4::Context; +use Koha::Patron::Restriction::Types; + our ( @ISA, @EXPORT_OK ); BEGIN { @@ -270,6 +272,42 @@ sub UpdateBorrowerDebarmentFlags { return $dbh->do( "UPDATE borrowers SET debarred = ?, debarredcomment = ? WHERE borrowernumber = ?", {}, ( $expiration, $comment, $borrowernumber ) ); } +=head2 del_restrictions_after_payment + +my $success = del_restrictions_after_payment({ + borrowernumber => $borrowernumber, +}); + +Deletes any restrictions from patron by following the rules +defined in "Patron restrictions". + +=cut + +sub del_restrictions_after_payment { + my ($params) = @_; + + my $borrowernumber = $params->{'borrowernumber'}; + return unless ( $borrowernumber ); + + my $patron_restrictions = GetDebarments( { borrowernumber => $borrowernumber } ); + return unless ( $patron_restrictions ); + + my $patron = Koha::Patrons->find( $borrowernumber ); + return unless ( $patron ); + + my $lines = Koha::Account::Lines->search({ borrowernumber => $borrowernumber }); + my $total_due = $lines->total_outstanding; + + foreach my $patron_restriction (@{ $patron_restrictions }){ + my $restriction = Koha::Patron::Restriction::Types->find({ + code => $patron_restriction->{type} + }); + if($restriction->lift_after_payment && $total_due <= $restriction->fee_limit){ + DelDebarment($patron_restriction->{'borrower_debarment_id'}); + } + } +} + =head2 _GetBorrowernumberByDebarmentId my $borrowernumber = _GetBorrowernumberByDebarmentId( $borrower_debarment_id ); diff --git a/admin/restrictions.pl b/admin/restrictions.pl index ab0c384212..a1a0bc1bdf 100755 --- a/admin/restrictions.pl +++ b/admin/restrictions.pl @@ -54,6 +54,8 @@ if ( $op eq 'add_form') { } elsif ( $op eq 'add_validate' ) { my $display_text = $input->param('display_text'); + my $lift_after_payment = $input->param('lift_after_payment'); + my $fee_limit = $input->param('fee_limit'); my $is_a_modif = $input->param("is_a_modif"); if ($is_a_modif) { @@ -64,13 +66,15 @@ if ( $op eq 'add_form') { display_text => $display_text, } ); - if ($dupe->count) { + if ($dupe->count && $dupe->unblessed->{code} ne $code) { push @messages, { type => 'error', code => 'duplicate_display_text' }; } else { my $restriction = Koha::Patron::Restriction::Types->find($code); $restriction->display_text($display_text); + $restriction->lift_after_payment($lift_after_payment); + $restriction->fee_limit($fee_limit); $restriction->store; push @messages, { type => 'message', code => 'update_success' }; } @@ -84,7 +88,9 @@ if ( $op eq 'add_form') { } else { my $restriction = Koha::Patron::Restriction::Type->new({ code => $code, - display_text => $display_text + display_text => $display_text, + lift_after_payment => $lift_after_payment, + fee_limit => $fee_limit }); $restriction->store; push @messages, { type => 'message', code => 'add_success' }; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/restrictions.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/restrictions.tt index dd530d964f..0acd70ca68 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/restrictions.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/restrictions.tt @@ -113,6 +113,19 @@ Required +
  • + + + Required +
  • +
  • + + + Required +
  • [% ELSE %]
  • @@ -124,6 +137,19 @@ Required
  • +
  • + + + Required +
  • +
  • + + + Required +
  • [% END %] @@ -166,6 +192,8 @@ Code Label Default + Lift after payment? + Fee limit Actions @@ -181,6 +209,12 @@ [% IF restriction.is_default %]Yes[% END %] + + [% IF restriction.lift_after_payment %]Yes[% END %] + + + [% IF restriction.fee_limit %][% restriction.fee_limit %][% END %] + Edit [% IF !restriction.is_system && !restriction.is_default %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/restrictiontypes.js b/koha-tmpl/intranet-tmpl/prog/js/restrictiontypes.js index d1a4e5383e..3f8d4f7728 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/restrictiontypes.js +++ b/koha-tmpl/intranet-tmpl/prog/js/restrictiontypes.js @@ -9,7 +9,8 @@ jQuery.validator.addMethod( "restrictionDisplayText", function(value){ var ex = Object.values(existing).map(function(el) { return el.toLowerCase(); }); - return (value.length > 0 && ex.indexOf(value.toLowerCase()) > -1) ? + var code = $('input[name="code"]').val(); + return (value.length > 0 && ex.indexOf(value.toLowerCase()) > -1) && existing[code] != value ? false : true; }, MSG_DUPLICATE_DISPLAY_TEXT); diff --git a/t/db_dependent/Patron/Borrower_Debarments.t b/t/db_dependent/Patron/Borrower_Debarments.t index 562281e3d3..86fe952f2b 100755 --- a/t/db_dependent/Patron/Borrower_Debarments.t +++ b/t/db_dependent/Patron/Borrower_Debarments.t @@ -5,10 +5,11 @@ use Modern::Perl; use C4::Context; use Koha::Database; use Koha::Patrons; +use Koha::Account; use t::lib::TestBuilder; -use Test::More tests => 34; +use Test::More tests => 38; use_ok('Koha::Patron::Debarments'); @@ -221,3 +222,76 @@ is( Koha::Patrons->find($borrowernumber3)->debarred, $debarreddate2, 'Koha::Patron->merge_with() transfers well debarred' ); is( Koha::Patrons->find($borrowernumber3)->debarredcomment, $debarredcomment2, 'Koha::Patron->merge_with() transfers well debarredcomment' ); + +# Test removing debartments after payment +$builder->build( + { + source => 'RestrictionType', + value => { + code => 'TEST', + display_text => 'This is a test.', + is_system => 0, + is_default => 0, + lift_after_payment => 1, + fee_limit => 5 + } + } +); + +$builder->build( + { + source => 'RestrictionType', + value => { + code => 'TEST2', + display_text => 'This too is a test.', + is_system => 0, + is_default => 0, + lift_after_payment => 1, + fee_limit => 0 + } + } +); + +my $borrowernumber4 = Koha::Patron->new( + { + firstname => 'First', + surname => 'Sur', + categorycode => $patron_category->{categorycode}, + branchcode => $library->{branchcode}, + } +)->store->borrowernumber; + +my $account = Koha::Account->new({ patron_id => $borrowernumber4 }); +my $line1 = $account->add_debit({ type => 'ACCOUNT', amount => 10, interface => 'commandline' }); + +Koha::Patron::Debarments::AddDebarment( + { + borrowernumber => $borrowernumber4, + expiration => '9999-06-10', + type => 'TEST', + comment => 'Test delete' + } +); + +Koha::Patron::Debarments::AddDebarment( + { + borrowernumber => $borrowernumber4, + expiration => '9999-10-10', + type => 'TEST2', + comment => 'Test delete again', + } +); + +$debarments = Koha::Patron::Debarments::GetDebarments({ borrowernumber => $borrowernumber4 }); + +is( @$debarments, 2, "GetDebarments returns 2 debarments before payment" ); + +$account->pay({amount => 5}); + +$debarments = Koha::Patron::Debarments::GetDebarments({ borrowernumber => $borrowernumber4 }); +is( @$debarments, 1, "GetDebarments returns 1 debarment after paying half of the fee" ); +is( @$debarments[0]->{type}, "TEST2", "Debarment left has type value 'TEST2'" ); + +$account->pay({amount => 5}); +$debarments = Koha::Patron::Debarments::GetDebarments({ borrowernumber => $borrowernumber4 }); +is( @$debarments, 0, "GetDebarments returns 0 debarments after paying all fees" ); -- 2.39.5