From 50e5af43d90db89c9a353f45133a9fbb0dd33112 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 | 196 +++++++++++++------- 2 files changed, 176 insertions(+), 77 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 af5040d..3e73112 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 %] + @@ -237,7 +260,7 @@ [% FOREACH borrower IN borrowers %] [% IF ( op == 'show' ) %] - + [% END %] @@ -335,9 +358,17 @@ [% END %] + +
    +
  1. + + +
  2. +
+
- + Cancel
diff --git a/tools/modborrowers.pl b/tools/modborrowers.pl index 5bd2103..bc3f4bf 100755 --- a/tools/modborrowers.pl +++ b/tools/modborrowers.pl @@ -227,6 +227,8 @@ 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; @@ -239,86 +241,152 @@ if ( $op eq 'do' ) { my @attributes = $input->param('patron_attributes'); my @attr_values = $input->param('patron_attributes_value'); - 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; - } + if ( $input->param("delete") ) { + my @deleted_borrowers; + + 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 %]