From 3695df4d89e86ec7d2518904b604b06e48001c0c Mon Sep 17 00:00:00 2001 From: Agustin Moyano Date: Thu, 22 Apr 2021 19:29:37 -0300 Subject: [PATCH] Bug 27946: Add article request fee feature This patch adds the ability to charge a fee for article scan requests. To test: 1. apply patches 2. updatedatabase 3. restart_all 4. enable ArticleRequest in preferences 5. grab a patron category and set a fee for article requests 6. grab a patron of that category (patron a) and another fron different category (patron b) 7. place an article request for both patrons SUCCESS => only for patron a, a warning is displayed saying a fee will be charged 8. check the account for both patrons SUCCESS => only for patron a there is a debit of type ARTICLE_REQUEST 9. cancel the article request for patron a SUCCESS => the debit for patron a gets canceled 10. repeat step 7 only for patron a 11. change article request fee for the patron a's category 12. repeat step 10 13. check account for patron a SUCCESS => there are 2 debits with different amount of typ ARTICLE_REQUEST 14. cancel only one article request SUCCESS => only the corresponding debit gets canceled 15. prove t/db_dependent/ArticleRequests.t Signed-off-by: Marcel de Rooy --- Koha/ArticleRequest.pm | 48 +++++ admin/categories.pl | 187 +++++++++--------- .../prog/en/modules/admin/categories.tt | 22 ++- .../prog/en/modules/circ/request-article.tt | 7 +- .../en/modules/opac-request-article.tt | 7 + 5 files changed, 180 insertions(+), 91 deletions(-) diff --git a/Koha/ArticleRequest.pm b/Koha/ArticleRequest.pm index 05b0e32542..692e70318c 100644 --- a/Koha/ArticleRequest.pm +++ b/Koha/ArticleRequest.pm @@ -26,6 +26,8 @@ use Koha::Biblios; use Koha::Items; use Koha::Libraries; use Koha::DateUtils qw( dt_from_string ); +use C4::Context; +use Koha::Account::Lines; use base qw(Koha::Object); @@ -47,6 +49,19 @@ sub open { my ($self) = @_; $self->status(Koha::ArticleRequest::Status::Pending); + if(C4::Context->preference('ArticleRequests') && $self->borrower->category->article_request_fee) { + my $debit_line = $self->borrower->account->add_debit( + { + amount => $self->borrower->category->article_request_fee, + user_id => C4::Context->userenv ? C4::Context->userenv->{'number'} : undef, + interface => C4::Context->interface, + library_id => C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef, + type => 'ARTICLE_REQUEST', + item_id => $self->itemnumber + } + ); + $self->debit_line_id($debit_line->id); + } $self->SUPER::store(); $self->notify(); return $self; @@ -87,6 +102,39 @@ sub cancel { $self->status(Koha::ArticleRequest::Status::Canceled); $self->notes($notes) if $notes; + if ( $self->debit_line_id ) { + my $line = Koha::Account::Lines->find( $self->debit_line_id ); + if ( $line->amount != $line->amountoutstanding ) { + $self->borrower->account->add_credit( + { + amount => $line->amount, + user_id => C4::Context->userenv + ? C4::Context->userenv->{'number'} + : undef, + interface => C4::Context->interface, + library_id => C4::Context->userenv + ? C4::Context->userenv->{'branch'} + : undef, + type => 'CREDIT', + description => 'Article request cancelled', + item_id => $self->itemnumber + } + ); + } + else { + $line->cancel( + { + branch => C4::Context->userenv + ? C4::Context->userenv->{'branch'} + : undef, + staff_id => C4::Context->userenv + ? C4::Context->userenv->{'number'} + : undef, + } + ) unless $line->status && $line->status eq 'CANCELLED'; + } + } + $self->store(); $self->notify(); return $self; diff --git a/admin/categories.pl b/admin/categories.pl index 368960f9cd..7aba61990e 100755 --- a/admin/categories.pl +++ b/admin/categories.pl @@ -46,18 +46,7 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( } ); -if ( $op eq 'add_form' ) { - - $template->param( - category => scalar Koha::Patron::Categories->find($categorycode), - ); - - if ( C4::Context->preference('EnhancedMessagingPreferences') ) { - C4::Form::MessagingPreferences::set_form_values( - { categorycode => $categorycode }, $template ); - } -} -elsif ( $op eq 'add_validate' ) { +if ( $op eq 'add_validate' ) { my $categorycode = $input->param('categorycode'); my $description = $input->param('description'); @@ -78,6 +67,7 @@ elsif ( $op eq 'add_validate' ) { my $exclude_from_local_holds_priority = $input->param('exclude_from_local_holds_priority'); my $min_password_length = $input->param('min_password_length'); my $require_strong_password = $input->param('require_strong_password'); + my $article_request_fee = $input->param('article_request_fee'); my @branches = grep { $_ ne q{} } $input->multi_param('branches'); $reset_password = undef if $reset_password eq -1; @@ -87,88 +77,95 @@ elsif ( $op eq 'add_validate' ) { my $is_a_modif = $input->param("is_a_modif"); - if ($enrolmentperioddate) { - $enrolmentperioddate = output_pref( - { - dt => dt_from_string($enrolmentperioddate), - dateformat => 'iso', - dateonly => 1, - } - ); - } + if ($article_request_fee < 0) { + push @messages, {type => 'error', code => 'article_request_negative_fee' }; + $op = 'add_form'; + } else { + if ($enrolmentperioddate) { + $enrolmentperioddate = output_pref( + { + dt => dt_from_string($enrolmentperioddate), + dateformat => 'iso', + dateonly => 1, + } + ); + } - if ($is_a_modif) { - my $category = Koha::Patron::Categories->find( $categorycode ); - $category->categorycode($categorycode); - $category->description($description); - $category->enrolmentperiod($enrolmentperiod); - $category->enrolmentperioddate($enrolmentperioddate); - $category->upperagelimit($upperagelimit); - $category->dateofbirthrequired($dateofbirthrequired); - $category->enrolmentfee($enrolmentfee); - $category->reservefee($reservefee); - $category->hidelostitems($hidelostitems); - $category->overduenoticerequired($overduenoticerequired); - $category->category_type($category_type); - $category->BlockExpiredPatronOpacActions($BlockExpiredPatronOpacActions); - $category->checkprevcheckout($checkPrevCheckout); - $category->default_privacy($default_privacy); - $category->reset_password($reset_password); - $category->change_password($change_password); - $category->exclude_from_local_holds_priority($exclude_from_local_holds_priority); - $category->min_password_length($min_password_length); - $category->require_strong_password($require_strong_password); - eval { - $category->store; - $category->replace_library_limits( \@branches ); - }; - if ( $@ ) { - push @messages, {type => 'error', code => 'error_on_update' }; - } else { - push @messages, { type => 'message', code => 'success_on_update' }; + if ($is_a_modif) { + my $category = Koha::Patron::Categories->find( $categorycode ); + $category->categorycode($categorycode); + $category->description($description); + $category->enrolmentperiod($enrolmentperiod); + $category->enrolmentperioddate($enrolmentperioddate); + $category->upperagelimit($upperagelimit); + $category->dateofbirthrequired($dateofbirthrequired); + $category->enrolmentfee($enrolmentfee); + $category->reservefee($reservefee); + $category->hidelostitems($hidelostitems); + $category->overduenoticerequired($overduenoticerequired); + $category->category_type($category_type); + $category->BlockExpiredPatronOpacActions($BlockExpiredPatronOpacActions); + $category->checkprevcheckout($checkPrevCheckout); + $category->default_privacy($default_privacy); + $category->reset_password($reset_password); + $category->change_password($change_password); + $category->exclude_from_local_holds_priority($exclude_from_local_holds_priority); + $category->min_password_length($min_password_length); + $category->require_strong_password($require_strong_password); + $category->article_request_fee($article_request_fee); + eval { + $category->store; + $category->replace_library_limits( \@branches ); + }; + if ( $@ ) { + push @messages, {type => 'error', code => 'error_on_update' }; + } else { + push @messages, { type => 'message', code => 'success_on_update' }; + } } - } - else { - my $category = Koha::Patron::Category->new({ - categorycode => $categorycode, - description => $description, - enrolmentperiod => $enrolmentperiod, - enrolmentperioddate => $enrolmentperioddate, - upperagelimit => $upperagelimit, - dateofbirthrequired => $dateofbirthrequired, - enrolmentfee => $enrolmentfee, - reservefee => $reservefee, - hidelostitems => $hidelostitems, - overduenoticerequired => $overduenoticerequired, - category_type => $category_type, - BlockExpiredPatronOpacActions => $BlockExpiredPatronOpacActions, - checkprevcheckout => $checkPrevCheckout, - default_privacy => $default_privacy, - reset_password => $reset_password, - change_password => $change_password, - exclude_from_local_holds_priority => $exclude_from_local_holds_priority, - min_password_length => $min_password_length, - require_strong_password => $require_strong_password, - }); - eval { - $category->store; - $category->replace_library_limits( \@branches ); - }; - - if ( $@ ) { - push @messages, { type => 'error', code => 'error_on_insert' }; - } else { - push @messages, { type => 'message', code => 'success_on_insert' }; + else { + my $category = Koha::Patron::Category->new({ + categorycode => $categorycode, + description => $description, + enrolmentperiod => $enrolmentperiod, + enrolmentperioddate => $enrolmentperioddate, + upperagelimit => $upperagelimit, + dateofbirthrequired => $dateofbirthrequired, + enrolmentfee => $enrolmentfee, + reservefee => $reservefee, + hidelostitems => $hidelostitems, + overduenoticerequired => $overduenoticerequired, + category_type => $category_type, + BlockExpiredPatronOpacActions => $BlockExpiredPatronOpacActions, + checkprevcheckout => $checkPrevCheckout, + default_privacy => $default_privacy, + reset_password => $reset_password, + change_password => $change_password, + exclude_from_local_holds_priority => $exclude_from_local_holds_priority, + min_password_length => $min_password_length, + require_strong_password => $require_strong_password, + article_request_fee => $article_request_fee, + }); + eval { + $category->store; + $category->replace_library_limits( \@branches ); + }; + + if ( $@ ) { + push @messages, { type => 'error', code => 'error_on_insert' }; + } else { + push @messages, { type => 'message', code => 'success_on_insert' }; + } } - } - if ( C4::Context->preference('EnhancedMessagingPreferences') ) { - C4::Form::MessagingPreferences::handle_form_action( $input, - { categorycode => scalar $input->param('categorycode') }, $template ); - } + if ( C4::Context->preference('EnhancedMessagingPreferences') ) { + C4::Form::MessagingPreferences::handle_form_action( $input, + { categorycode => scalar $input->param('categorycode') }, $template ); + } - $searchfield = q||; - $op = 'list'; + $searchfield = q||; + $op = 'list'; + } } elsif ( $op eq 'delete_confirm' ) { @@ -199,6 +196,18 @@ elsif ( $op eq 'delete_confirmed' ) { $op = 'list'; } +if ( $op eq 'add_form' ) { + + $template->param( + category => scalar Koha::Patron::Categories->find($categorycode), + ); + + if ( C4::Context->preference('EnhancedMessagingPreferences') ) { + C4::Form::MessagingPreferences::set_form_values( + { categorycode => $categorycode }, $template ); + } +} + if ( $op eq 'list' ) { my $categories = Koha::Patron::Categories->search( { diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt index 1e3f8dfe6c..6be219fdb4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt @@ -108,6 +108,8 @@ Patron category deleted successfully. [% CASE 'already_exists' %] This patron category already exists. + [% CASE 'article_request_negative_fee' %] + Article request fee cannot be negative. [% CASE %] [% m.code | html %] [% END %] @@ -202,6 +204,12 @@ + [% IF Koha.Preference('ArticleRequests') %] +
  • + + +
  • + [% END %]
  • diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-request-article.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-request-article.tt index ca8e3feb75..4dfcf7137b 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-request-article.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-request-article.tt @@ -2,6 +2,7 @@ [% USE Branches %] [% USE ItemTypes %] [% USE KohaNews %] +[% USE Price %] [% USE raw %] [% INCLUDE 'doc-head-open.inc' %] @@ -49,6 +50,12 @@ [% IF article_request_type == 'item_only' %] [% SET mandatory_fields = Koha.Preference('ArticleRequestsMandatoryFieldsItemOnly') %] [% END %] + [% IF patron.category.article_request_fee > 0 %] +
    + You will be charged with [% patron.category.article_request_fee | $Price %] for every request +
    + [% END %] +
    Place article request -- 2.25.1