From 0dd6bd9acf1218b42ad296868ed32ff173fc75e5 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Thu, 18 Jul 2013 10:00:41 -0400 Subject: [PATCH] Bug 10612 - Add ability to delete patrons with batch patron modification tool The batch patron deletion/anonymization does not allow for batch deletion of arbitrary lists of patrons. The batch patron modification tool allows for modification of arbitrary lists of patrons, but not deletion. If would be highly beneficial to add patron deletion to the batch patron modification tool. Test Plan: 1) Apply all dependencies for this patch 2) Apply this patch 3) Create a list of patrons with the new Patron Lists feature a) Include at least one patron owing fines b) Include at least one patron with items currently checked out c) Include at least one patron not falling into a) or b) 4) Browse to the batch patron modifications tool 5) Select your list from the pulldown, and submit 6) Check the "Delete patrons" checkbox, the click the submit button 7) You should a list of errors for the patrons with fines or issues and a table of patrons that were deleted successfully. 8) Click the link for a deleted patron, you should get a "patron not found" message. Signed-off-by: Nora Blake --- .../prog/en/modules/tools/modborrowers.tt | 57 +++++-- tools/modborrowers.pl | 205 +++++++++++++------- 2 files changed, 175 insertions(+), 87 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/modborrowers.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/modborrowers.tt index b4b899c..db388fd 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/modborrowers.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/modborrowers.tt @@ -107,6 +107,9 @@ $("#"+nodeid).val(""); } + function TogglePatronDelete() { + $("#modifications-form").find(":input").not(".prevent-disable").not(":hidden").attr("disabled", $("#delete-checkbox").is(":checked") ); + } //]]> @@ -191,22 +194,38 @@ [% IF ( op == 'show_results' ) %] [% IF ( errors ) %]
-

Errors occured:

-
    - [% FOREACH error IN errors %] - [% IF ( error.error == 'can_not_update' ) %] -
  • Can not update patron with borrowernumber [% error.borrowernumber %]
  • - [% ELSE %] -
  • [% error.error %]
  • - [% END %] - [% END %] -
+

Errors occured:

+
[% END %] [% END %] [% IF ( op == 'show' ) %] -
+ [% IF ( borrowers ) %] @@ -215,6 +234,10 @@ [% IF borrowers %]
+ [% IF action == 'delete_patrons' %] +

Patrons deleted

+ [% END %] + @@ -238,7 +261,7 @@ [% FOREACH borrower IN borrowers %] [% IF ( op == 'show' ) %] - + [% END %] @@ -341,9 +364,17 @@ [% END %] + +
    +
  1. + + +
  2. +
+
- + Cancel
diff --git a/tools/modborrowers.pl b/tools/modborrowers.pl index 7009014..8717d8e 100755 --- a/tools/modborrowers.pl +++ b/tools/modborrowers.pl @@ -239,98 +239,155 @@ if ( $op eq 'show' ) { # Process modifications if ( $op eq 'do' ) { + my @borrowernumbers = $input->param('borrowernumber'); + my @errors; - my @disabled = $input->param('disable_input'); - my $infos; - for my $field ( qw/surname firstname branchcode categorycode sort1 sort2 dateenrolled dateexpiry debarred debarredcomment borrowernotes/ ) { - my $value = $input->param($field); - $infos->{$field} = $value if $value; - $infos->{$field} = "" if grep { /^$field$/ } @disabled; - } - - my @attributes = $input->param('patron_attributes'); - my @attr_values = $input->param('patron_attributes_value'); + if ( $input->param("delete") ) { + my @deleted_borrowers; - my @errors; - my @borrowernumbers = $input->param('borrowernumber'); - # For each borrower selected - for my $borrowernumber ( @borrowernumbers ) { - # If at least one field are filled, we want to modify the borrower - if ( defined $infos ) { - $infos->{borrowernumber} = $borrowernumber; - my $success = ModMember(%$infos); - push @errors, { error => "can_not_update", borrowernumber => $infos->{borrowernumber} } if not $success; - } + for my $borrowernumber (@borrowernumbers) { + my $borrower = GetMember( borrowernumber => $borrowernumber ); + my ( $overdue_count, $issue_count, $total_fines ) = + GetMemberIssuesAndFines($borrowernumber); - # - my $borrower_categorycode = GetBorrowerCategorycode $borrowernumber; - my $i=0; - for ( @attributes ) { - my $attribute; - $attribute->{code} = $_; - $attribute->{attribute} = $attr_values[$i]; - my $attr_type = C4::Members::AttributeTypes->fetch( $_ ); - # If this borrower is not in the category of this attribute, we don't want to modify this attribute - ++$i and next if $attr_type->{category_code} and $attr_type->{category_code} ne $borrower_categorycode; - my $valuename = "attr" . $i . "_value"; - if ( grep { /^$valuename$/ } @disabled ) { - # The attribute is disabled, we remove it for this borrower ! - eval { - C4::Members::Attributes::DeleteBorrowerAttribute( $borrowernumber, $attribute ); - }; - push @errors, { error => $@ } if $@; - } else { - # Attribute's value is empty, we don't want to modify it - ++$i and next if not $attribute->{attribute}; - - eval { - C4::Members::Attributes::UpdateBorrowerAttribute( $borrowernumber, $attribute ); - }; - push @errors, { error => $@ } if $@; + if ($issue_count) { + push( @errors, + { error => "current_issues", borrower => $borrower } ); + } + elsif ($total_fines) { + push( @errors, + { error => "fees_owed", borrower => $borrower } ); + } + else { + MoveMemberToDeleted($borrowernumber); + DelMember($borrowernumber); + push( @deleted_borrowers, $borrower ); } - $i++; } + + $template->param( + borrowers => \@deleted_borrowers, + action => 'delete_patrons', + ); } - $op = "show_results"; # We have process modifications, the user want to view its + else { + my @disabled = $input->param('disable_input'); + my $infos; - # Construct the results list - my @borrowers; - my $max_nb_attr = 0; - for my $borrowernumber ( @borrowernumbers ) { - my $borrower = GetBorrowerInfos( borrowernumber => $borrowernumber ); - if ( $borrower ) { - $max_nb_attr = scalar( @{ $borrower->{patron_attributes} } ) - if scalar( @{ $borrower->{patron_attributes} } ) > $max_nb_attr; - push @borrowers, $borrower; + for my $field ( + qw/surname firstname branchcode categorycode sort1 sort2 dateenrolled dateexpiry debarred debarredcomment borrowernotes/ + ) + { + my $value = $input->param($field); + $infos->{$field} = $value if $value; + $infos->{$field} = "" if grep { /^$field$/ } @disabled; } - } - my @patron_attributes_option; - for my $borrower ( @borrowers ) { - push @patron_attributes_option, { value => "$_->{code}", lib => $_->{code} } for @{ $borrower->{patron_attributes} }; - my $length = scalar( @{ $borrower->{patron_attributes} } ); - push @{ $borrower->{patron_attributes} }, {} for ( $length .. $max_nb_attr - 1); - } - my @attributes_header = (); - for ( 1 .. scalar( $max_nb_attr ) ) { - push @attributes_header, { attribute => "Attributes $_" }; - } + my @attributes = $input->param('patron_attributes'); + my @attr_values = $input->param('patron_attributes_value'); + + # For each borrower selected + for my $borrowernumber (@borrowernumbers) { + + # If at least one field are filled, we want to modify the borrower + if ( defined $infos ) { + $infos->{borrowernumber} = $borrowernumber; + my $success = ModMember(%$infos); + push @errors, + { + error => "can_not_update", + borrowernumber => $infos->{borrowernumber} + } + if not $success; + } - $template->param( borrowers => \@borrowers ); - $template->param( attributes_header => \@attributes_header ); + my $borrower_categorycode = GetBorrowerCategorycode $borrowernumber; + my $i = 0; + for (@attributes) { + my $attribute; + $attribute->{code} = $_; + $attribute->{attribute} = $attr_values[$i]; + my $attr_type = C4::Members::AttributeTypes->fetch($_); + + # If this borrower is not in the category of this attribute, we don't want to modify this attribute + ++$i and next + if $attr_type->{category_code} + and $attr_type->{category_code} ne $borrower_categorycode; + + my $valuename = "attr" . $i . "_value"; + if ( grep { /^$valuename$/ } @disabled ) { + + # The attribute is disabled, we remove it for this borrower ! + eval { + C4::Members::Attributes::DeleteBorrowerAttribute( + $borrowernumber, $attribute ); + }; + push @errors, { error => $@ } if $@; + } + else { + + # Attribute's value is empty, we don't want to modify it + ++$i and next if not $attribute->{attribute}; + + eval { + C4::Members::Attributes::UpdateBorrowerAttribute( + $borrowernumber, $attribute ); + }; + push @errors, { error => $@ } if $@; + } + $i++; + } + + # Construct the results list + my @borrowers; + my $max_nb_attr = 0; + for my $borrowernumber (@borrowernumbers) { + my $borrower = + GetBorrowerInfos( borrowernumber => $borrowernumber ); + if ($borrower) { + $max_nb_attr = scalar( @{ $borrower->{patron_attributes} } ) + if scalar( @{ $borrower->{patron_attributes} } ) > + $max_nb_attr; + push @borrowers, $borrower; + } + } + my @patron_attributes_option; + for my $borrower (@borrowers) { + push @patron_attributes_option, + { value => "$_->{code}", lib => $_->{code} } + for @{ $borrower->{patron_attributes} }; + + my $length = scalar( @{ $borrower->{patron_attributes} } ); + + push @{ $borrower->{patron_attributes} }, {} + for ( $length .. $max_nb_attr - 1 ); + } + + my @attributes_header = (); + for ( 1 .. scalar($max_nb_attr) ) { + push @attributes_header, { attribute => "Attributes $_" }; + } + + $template->param( + borrowers => \@borrowers, + attributes_header => \@attributes_header + ); + } + + } - $template->param( borrowers => \@borrowers ); $template->param( errors => \@errors ); + + $op = "show_results"; + } else { $template->param( patron_lists => [ GetPatronLists() ] ); } -$template->param( - op => $op, -); +$template->param( op => $op ); + output_html_with_http_headers $input, $cookie, $template->output; -exit; sub GetBorrowerInfos { my ( %info ) = @_; -- 1.7.2.5
[% borrower.cardnumber %] [% borrower.surname %]