From 1c923cf9874d77820b6a7182262d7bd10fbd1bfb Mon Sep 17 00:00:00 2001
From: Kyle M Hall <kyle@bywatersolutions.com>
Date: Wed, 11 Jun 2014 08:11:48 -0400
Subject: [PATCH] Bug 10612 - Add ability to delete patrons with batch patron
 deletion tool

This patch adds the ability to select a patron list for deletetion
when using the Batch patron deletion/anonymization tool. It also adds
buttons to the the patron lists table to access both the batch deletion
and batch modification directly from the lists view.

This is a squash of previous patches with a check added for issues
before deleting borrowers.

Test Plan:
1) Apply this patch
2) Create a list of patrons with the new Patron Lists feature
3) Try using the batch edit link form the lists table
4) Try using the batch delete link from the lists table

Signed-off-by: Jesse Weaver <jweaver@bywatersolutions.com>

ByWater internal signoff, still needs signoff from community.

Patch seems kosher, passes QA tools. Needs followup to fix one small
issue: squished patch undoes switch to FontAwesome icons in lists.tt.
---
 .../prog/en/modules/patron_lists/lists.tt          | 22 +++++-
 .../prog/en/modules/tools/cleanborrowers.tt        | 30 ++++++---
 tools/cleanborrowers.pl                            | 78 ++++++++++++++--------
 3 files changed, 95 insertions(+), 35 deletions(-)

diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/patron_lists/lists.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/patron_lists/lists.tt
index 50c7213..a56fc7c 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/patron_lists/lists.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/patron_lists/lists.tt
@@ -47,6 +47,12 @@
                     <th>&nbsp;</th>
                     <th>&nbsp;</th>
                     <th>&nbsp;</th>
+                    [% IF CAN_user_tools_edit_patrons %]
+                        <th>&nbsp;</th>
+                    [% END %]
+                    [% IF CAN_user_tools_delete_anonymize_patrons %]
+                        <th>&nbsp;</th>
+                    [% END %]
                 </tr>
             </thead>
 
@@ -57,7 +63,7 @@
                         <td>[% l.patron_list_patrons_rs.count || 0 %]</td>
                         <td>
                             <a class="btn btn-mini" href="list.pl?patron_list_id=[% l.patron_list_id %]">
-                                <i class="fa fa-plus-sign"></i> Add patrons <i class="fa fa-user"></i>
+                                <i class="icon-plus-sign"></i> Add patrons</i>
                             </a>
                         </td>
                         <td>
@@ -75,6 +81,20 @@
                                 <i class="icon-print"></i> Print patron cards
                             </a>
                         </td>
+                        [% IF CAN_user_tools_edit_patrons %]
+                            <td>
+                                <a class="btn btn-mini" href="/cgi-bin/koha/tools/modborrowers.pl?patron_list_id=[% l.patron_list_id %]&op=show">
+                                    <i class="icon-edit"></i> Edit patrons</i>
+                                </a>
+                            </td>
+                        [% END %]
+                        [% IF CAN_user_tools_delete_anonymize_patrons %]
+                            <td>
+                                <a class="btn btn-mini" href="/cgi-bin/koha/tools/cleanborrowers.pl?step=2&patron_list_id=[% l.patron_list_id %]">
+                                    <i class="icon-trash"></i> Delete patrons</i>
+                                </a>
+                            </td>
+                        [% END %]
                     </tr>
                 [% END %]
             </tbody>
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/cleanborrowers.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/cleanborrowers.tt
index 7de7652..f4781e7 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/cleanborrowers.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/cleanborrowers.tt
@@ -12,7 +12,7 @@
          */
           function checkForm(form) {
               if((form.checkbox[0].checked)){
-                  if ( (!form.date1.value) && (!form.borrower_dateexpiry.value) && (!form.borrower_categorycode.value) ){
+                  if ( (!form.date1.value) && (!form.borrower_dateexpiry.value) && (!form.borrower_categorycode.value) && (!form.patron_list_id.value)){
                     alert(_("Please enter at least one criterion for deletion!"));
                     return false;
                   }
@@ -88,8 +88,21 @@
                         [% END %]
                     </select>
                 </li>
+                [% IF patron_lists %]
+                <li>
+                    <label for="patron_list_id"><strong>Or</strong> use a patron list: </label>
+                    <select id="patron_list_id" name="patron_list_id">
+                        <option value=""></option>
+                        [% FOREACH pl IN patron_lists %]
+                            <option value="[% pl.patron_list_id %]">[% pl.name %]</option>
+                        [% END %]
+                    </select>
+                    <span class="hint">If using a patron list, no other criteria will be used.</span>
+                </li>
+                [% END %]
             </ul>
         </fieldset>
+
         <fieldset>
         <legend>Anonymize checkout history</legend>
         [% UNLESS Koha.Preference('AnonymousPatron') %]
@@ -121,12 +134,12 @@
     <fieldset>
         <legend>Warnings</legend>
         <ul>
-            <li>[% IF ( totalToDelete ) %][% totalToDelete %] [% ELSE %]0 [% END %] patrons will be deleted</li>
-            <li>[% IF ( totalToAnonymize ) %][% totalToAnonymize %] [% ELSE %]0 [% END %] checkout history will be anonymized</li>
+            <li>[% patrons_to_delete.size || 0 %] patrons will be deleted</li>
+            <li>[% patrons_to_anonymize.size || 0 %] patron's checkout histories will be anonymized</li>
         </ul>
 
         <br />
-            [% IF ( totalToDelete ) %]
+            [% IF patrons_to_delete.size %]
                 <fieldset><legend>What do you want to do for deleted patrons?</legend>
                 <input id="delete" type="radio" name="radio" value="delete" />
                 <label for="delete">Permanently delete these patrons</label>
@@ -136,12 +149,12 @@
 
                 <br /><input id="testrun" type="radio" name="radio" value="testrun" checked="checked" />
                 <label for="testrun">Do not remove any patrons (test run)</label>
-                <input type="hidden" name="do_delete" value="[% totalToDelete %]" /></fieldset>
+                <input type="hidden" name="do_delete" value="[% patrons_to_delete.size %]" /></fieldset>
 
             [% END %]
-            [% IF ( totalToAnonymize ) %]
-                Checkout history for [% totalToAnonymize %] patrons will be anonymized
-                <input type="hidden" name="do_anonym" value="[% totalToAnonymize %]" />
+            [% IF patrons_to_anonymize.size %]
+                Checkout history for [% patrons_to_anonymize.size %] patrons will be anonymized
+                <input type="hidden" name="do_anonym" value="[% patrons_to_anonymize.size %]" />
             [% END %]
 
             <input type="hidden" name="step" value="3" />
@@ -149,6 +162,7 @@
             <input type="hidden" name="last_issue_date" value="[% last_issue_date | $KohaDates %]" />
             <input type="hidden" name="borrower_dateexpiry" value="[% borrower_dateexpiry | $KohaDates %]" />
             <input type="hidden" name="borrower_categorycode" value="[% borrower_categorycode %]" />
+            <input type="hidden" name="patron_list_id" value="[% patron_list_id %] />
     </fieldset>
     <fieldset class="action"><input type="submit" value="Finish" /> <a class="cancel" href="/cgi-bin/koha/tools/cleanborrowers.pl">Cancel</a></fieldset>
         </form>
diff --git a/tools/cleanborrowers.pl b/tools/cleanborrowers.pl
index fdbf1b0..86b410f 100755
--- a/tools/cleanborrowers.pl
+++ b/tools/cleanborrowers.pl
@@ -40,7 +40,9 @@ use C4::Output;
 use C4::Members;        # GetBorrowersWhoHavexxxBorrowed.
 use C4::Circulation;    # AnonymiseIssueHistory.
 use Koha::DateUtils qw( dt_from_string output_pref );
+use Koha::Database;
 use Date::Calc qw/Today Add_Delta_YM/;
+use Koha::List::Patron;
 
 my $cgi = new CGI;
 
@@ -63,6 +65,7 @@ my $borrower_dateexpiry =
   $params->{borrower_dateexpiry}
   ? dt_from_string $params->{borrower_dateexpiry}
   : undef;
+my $patron_list_id = $params->{patron_list_id};
 
 my $borrower_categorycode = $params->{'borrower_categorycode'} || q{};
 
@@ -80,28 +83,35 @@ if ( $step == 2 ) {
 
     my %checkboxes = map { $_ => 1 } split /\0/, $params->{'checkbox'};
 
-    my $totalDel;
-    my $membersToDelete;
-    if ( $checkboxes{borrower} ) {
-        $membersToDelete = GetBorrowersToExpunge(
-            _get_selection_params($not_borrowered_since, $borrower_dateexpiry, $borrower_categorycode)
-        );
-        _skip_borrowers_with_nonzero_balance( $membersToDelete );
-        $totalDel = scalar @$membersToDelete;
-
+    my $patrons_to_delete;
+    if ($patron_list_id) {
+        my @patron_list_patrons =
+          Koha::Database->new()->schema()->resultset('PatronListPatron')
+          ->search( { patron_list_id => $patron_list_id } );
+        $patrons_to_delete = \@patron_list_patrons;
     }
-    my $totalAno;
-    my $membersToAnonymize;
+    else {
+        if ( $checkboxes{borrower} ) {
+            $patrons_to_delete = GetBorrowersToExpunge(
+                _get_selection_params(
+                    $not_borrowered_since,
+                    $borrower_dateexpiry,
+                    $borrower_categorycode,
+                )
+            );
+        }
+    }
+    _skip_borrowers_with_nonzero_balance_or_issues($patrons_to_delete);
+
+    my $members_to_anonymize;
     if ( $checkboxes{issue} ) {
-        $membersToAnonymize = GetBorrowersWithIssuesHistoryOlderThan($last_issue_date);
-        $totalAno           = scalar @$membersToAnonymize;
+        $members_to_anonymize = GetBorrowersWithIssuesHistoryOlderThan($last_issue_date);
     }
 
     $template->param(
-        totalToDelete           => $totalDel,
-        totalToAnonymize        => $totalAno,
-        memberstodelete_list    => $membersToDelete,
-        memberstoanonymize_list => $membersToAnonymize,
+        patrons_to_delete    => $patrons_to_delete,
+        patrons_to_anonymize => $members_to_anonymize,
+        patron_list_id          => $patron_list_id,
     );
 }
 
@@ -113,18 +123,32 @@ elsif ( $step == 3 ) {
 
     # delete members
     if ($do_delete) {
-        my $membersToDelete = GetBorrowersToExpunge(
-            _get_selection_params($not_borrowered_since, $borrower_dateexpiry, $borrower_categorycode)
-        );
-        _skip_borrowers_with_nonzero_balance( $membersToDelete );
-        $totalDel = scalar(@$membersToDelete);
+        my $patrons_to_delete;
+        if ($patron_list_id) {
+            my @patron_list_patrons =
+              Koha::Database->new()->schema()->resultset('PatronListPatron')
+              ->search( { patron_list_id => $patron_list_id } );
+            $patrons_to_delete = \@patron_list_patrons;
+        }
+        else {
+            $patrons_to_delete = GetBorrowersToExpunge(
+                _get_selection_params(
+                    $not_borrowered_since, $borrower_dateexpiry,
+                    $borrower_categorycode
+                )
+            );
+        }
+        _skip_borrowers_with_nonzero_balance_or_issues($patrons_to_delete);
+
+        $totalDel = scalar(@$patrons_to_delete);
         $radio    = $params->{'radio'};
         for ( my $i = 0 ; $i < $totalDel ; $i++ ) {
             $radio eq 'testrun' && last;
-            my $borrowernumber = $membersToDelete->[$i]->{'borrowernumber'};
-            $radio eq 'trash' && MoveMemberToDeleted( $borrowernumber );
-            C4::Members::HandleDelBorrower( $borrowernumber );
-            DelMember( $borrowernumber );
+            my $borrowernumber = $patrons_to_delete->[$i]->{'borrowernumber'}
+              || $patrons_to_delete->[$i]->get_column('borrowernumber');
+            $radio eq 'trash' && MoveMemberToDeleted($borrowernumber);
+            C4::Members::HandleDelBorrower($borrowernumber);
+            DelMember($borrowernumber);
         }
         $template->param(
             do_delete => '1',
@@ -145,6 +169,8 @@ elsif ( $step == 3 ) {
         trash => ( $radio eq "trash" ) ? (1) : (0),
         testrun => ( $radio eq "testrun" ) ? 1: 0,
     );
+} else { # $step == 1
+    $template->param( patron_lists => [ GetPatronLists() ] );
 }
 
 $template->param(
-- 
2.1.4