Bug 17588: Koha::Patrons - Move GetMemberIssuesAndFines
[koha.git] / tools / cleanborrowers.pl
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17 #
18 #   Written by Antoine Farnault antoine@koha-fr.org on Nov. 2006.
19
20 =head1 cleanborrowers.pl
21
22 This script allows to do 2 things.
23
24 =over 2
25
26 =item * Anonymise the borrowers' issues if issue is older than a given date. see C<datefilter1>.
27
28 =item * Delete the borrowers who has not borrowed since a given date. see C<datefilter2>.
29
30 =back
31
32 =cut
33
34 use Modern::Perl;
35
36 use CGI qw ( -utf8 );
37 use C4::Auth;
38 use C4::Output;
39 use C4::Members;
40 use C4::Circulation;    # AnonymiseIssueHistory.
41 use Koha::DateUtils qw( dt_from_string output_pref );
42 use Koha::Patron::Categories;
43 use Koha::Patrons;
44 use Date::Calc qw/Today Add_Delta_YM/;
45 use Koha::List::Patron;
46
47 my $cgi = new CGI;
48
49 # Fetch the paramater list as a hash in scalar context:
50 #  * returns paramater list as tied hash ref
51 #  * we can edit the values by changing the key
52 #  * multivalued CGI paramaters are returned as a packaged string separated by "\0" (null)
53 my $params = $cgi->Vars;
54
55 my $step = $params->{step} || 1;
56 my $not_borrowed_since =    # the date which filter on issue history.
57   $params->{not_borrowed_since}
58   ? dt_from_string $params->{not_borrowed_since}
59   : undef;
60 my $last_issue_date =         # the date which filter on borrowers last issue.
61   $params->{last_issue_date}
62   ? dt_from_string $params->{last_issue_date}
63   : undef;
64 my $borrower_dateexpiry =
65   $params->{borrower_dateexpiry}
66   ? dt_from_string $params->{borrower_dateexpiry}
67   : undef;
68 my $borrower_lastseen =
69   $params->{borrower_lastseen}
70   ? dt_from_string $params->{borrower_lastseen}
71   : undef;
72 my $patron_list_id = $params->{patron_list_id};
73
74 my $borrower_categorycode = $params->{'borrower_categorycode'} || q{};
75
76 # getting the template
77 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
78     {   template_name   => "tools/cleanborrowers.tt",
79         query           => $cgi,
80         type            => "intranet",
81         authnotrequired => 0,
82         flagsrequired   => { tools => 'delete_anonymize_patrons', catalogue => 1 },
83     }
84 );
85
86 my $branch = $params->{ branch } || '*';
87 $template->param( current_branch => $branch );
88 $template->param( OnlyMine => C4::Context->only_my_library );
89
90 if ( $step == 2 ) {
91
92     my %checkboxes = map { $_ => 1 } split /\0/, $params->{'checkbox'};
93
94     my $patrons_to_delete;
95     if ( $checkboxes{borrower} ) {
96         $patrons_to_delete = GetBorrowersToExpunge(
97              _get_selection_params(
98                   $not_borrowed_since,
99                   $borrower_dateexpiry,
100                   $borrower_lastseen,
101                   $borrower_categorycode,
102                   $patron_list_id,
103                   $branch
104              )
105         );
106     }
107     _skip_borrowers_with_nonzero_balance($patrons_to_delete);
108
109     my $members_to_anonymize;
110     if ( $checkboxes{issue} ) {
111         if ( $branch eq '*' ) {
112             $members_to_anonymize = GetBorrowersWithIssuesHistoryOlderThan($last_issue_date);
113         } else {
114             $members_to_anonymize = GetBorrowersWithIssuesHistoryOlderThan($last_issue_date, $branch);
115         }
116     }
117
118     $template->param(
119         patrons_to_delete    => $patrons_to_delete,
120         patrons_to_anonymize => $members_to_anonymize,
121         patron_list_id       => $patron_list_id
122     );
123 }
124
125 elsif ( $step == 3 ) {
126     my $do_delete = $params->{'do_delete'};
127     my $do_anonym = $params->{'do_anonym'};
128
129     my ( $totalDel, $totalAno, $radio ) = ( 0, 0, 0 );
130
131     # delete members
132     if ($do_delete) {
133         my $patrons_to_delete = GetBorrowersToExpunge(
134                 _get_selection_params(
135                     $not_borrowed_since,
136                     $borrower_dateexpiry,
137                     $borrower_lastseen,
138                     $borrower_categorycode,
139                     $patron_list_id,
140                     $branch
141                 )
142             );
143         _skip_borrowers_with_nonzero_balance($patrons_to_delete);
144
145         $totalDel = scalar(@$patrons_to_delete);
146         $radio    = $params->{'radio'};
147         for ( my $i = 0 ; $i < $totalDel ; $i++ ) {
148             $radio eq 'testrun' && last;
149             my $borrowernumber = $patrons_to_delete->[$i]->{'borrowernumber'};
150             my $patron = Koha::Patrons->find($borrowernumber);
151             $radio eq 'trash' && $patron->move_to_deleted;
152             $patron->delete;
153         }
154         $template->param(
155             do_delete => '1',
156             TotalDel  => $totalDel
157         );
158     }
159
160     # Anonymising all members
161     if ($do_anonym) {
162         #FIXME: anonymisation errors are not handled
163         ($totalAno,my $anonymisation_error) = AnonymiseIssueHistory($last_issue_date);
164         $template->param(
165             do_anonym   => '1',
166         );
167     }
168
169     $template->param(
170         trash => ( $radio eq "trash" ) ? (1) : (0),
171         testrun => ( $radio eq "testrun" ) ? 1: 0,
172     );
173 } else { # $step == 1
174     my @all_lists = GetPatronLists();
175     my @non_empty_lists;
176     foreach my $list (@all_lists){
177     my @patrons = $list->patron_list_patrons();
178         if( scalar @patrons ) { push(@non_empty_lists,$list) }
179     }
180     $template->param( patron_lists => [ @non_empty_lists ] );
181 }
182
183 my $patron_categories = Koha::Patron::Categories->search_limited({}, {order_by => ['description']});
184
185 $template->param(
186     step                   => $step,
187     not_borrowed_since   => $not_borrowed_since,
188     borrower_dateexpiry    => $borrower_dateexpiry,
189     borrower_lastseen      => $borrower_lastseen,
190     last_issue_date        => $last_issue_date,
191     borrower_categorycodes => $patron_categories,
192     borrower_categorycode  => $borrower_categorycode,
193 );
194
195 #writing the template
196 output_html_with_http_headers $cgi, $cookie, $template->output;
197
198 sub _skip_borrowers_with_nonzero_balance {
199     my $borrowers = shift;
200     my $balance;
201     @$borrowers = map {
202         my $patron = Koha::Patrons->find( $_->{borrowernumber} );
203         my $balance = $patron->get_account_lines->get_balance;
204         (defined $balance && $balance != 0) ? (): ($_);
205     } @$borrowers;
206 }
207
208 sub _get_selection_params {
209     my ($not_borrowed_since, $borrower_dateexpiry, $borrower_lastseen,
210         $borrower_categorycode, $patron_list_id, $branch) = @_;
211
212     my $params = {};
213     $params->{not_borrowed_since} = output_pref({
214         dt         => $not_borrowed_since,
215         dateformat => 'iso',
216         dateonly   => 1
217     }) if $not_borrowed_since;
218     $params->{expired_before} = output_pref({
219         dt         => $borrower_dateexpiry,
220         dateformat => 'iso',
221         dateonly   => 1
222     }) if $borrower_dateexpiry;
223     $params->{last_seen} = output_pref({
224         dt         => $borrower_lastseen,
225         dateformat => 'iso',
226         dateonly   => 1
227     }) if $borrower_lastseen;
228     $params->{category_code} = $borrower_categorycode if $borrower_categorycode;
229     $params->{patron_list_id} = $patron_list_id if $patron_list_id;
230
231     if ( defined $branch and $branch ne '*' ) {
232         $params->{ branchcode } = $branch;
233     }
234
235     return $params;
236 };