From 5398c7b23fe57e94128cb454e12d72afe290d8b2 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=UTF-8 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 --- 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 e37e646596..43d8e65f00 100644 --- a/Koha/Account.pm +++ b/Koha/Account.pm @@ -36,6 +36,7 @@ use Koha::Account::DebitTypes; use Koha::Exceptions; use Koha::Exceptions::Account; use Koha::Plugins; +use Koha::Patron::Debarments; =head1 NAME @@ -102,6 +103,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 06812c0bfa..5e43e4322d 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) { @@ -61,13 +63,15 @@ if ( $op eq 'add_form') { my $dupe = Koha::Patron::Restriction::Types->find({ display_text => $display_text }); - if ($dupe) { + if ($dupe && $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' }; } @@ -81,7 +85,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 0a2855af88..4afe008a43 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 %] @@ -172,6 +198,8 @@ Code Label Default + Lift after payment? + Fee limit Actions @@ -187,6 +215,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.20.1