Bug 15607: batch patron mod - do not update dates if not given
[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 borrowered since a given date. see C<datefilter2>.
29
30 =back
31
32 =cut
33
34 use strict;
35
36 #use warnings; FIXME - Bug 2505
37 use CGI qw ( -utf8 );
38 use C4::Auth;
39 use C4::Output;
40 use C4::Members;        # GetBorrowersWhoHavexxxBorrowed.
41 use C4::Circulation;    # AnonymiseIssueHistory.
42 use Koha::DateUtils qw( dt_from_string output_pref );
43 use Date::Calc qw/Today Add_Delta_YM/;
44
45 my $cgi = new CGI;
46
47 # Fetch the paramater list as a hash in scalar context:
48 #  * returns paramater list as tied hash ref
49 #  * we can edit the values by changing the key
50 #  * multivalued CGI paramaters are returned as a packaged string separated by "\0" (null)
51 my $params = $cgi->Vars;
52
53 my $step = $params->{step} || 1;
54 my $not_borrowered_since =    # the date which filter on issue history.
55   $params->{not_borrowered_since}
56   ? dt_from_string $params->{not_borrowered_since}
57   : undef;
58 my $last_issue_date =         # the date which filter on borrowers last issue.
59   $params->{last_issue_date}
60   ? dt_from_string $params->{last_issue_date}
61   : undef;
62 my $borrower_dateexpiry =
63   $params->{borrower_dateexpiry}
64   ? dt_from_string $params->{borrower_dateexpiry}
65   : undef;
66
67 my $borrower_categorycode = $params->{'borrower_categorycode'} || q{};
68
69 # getting the template
70 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
71     {   template_name   => "tools/cleanborrowers.tt",
72         query           => $cgi,
73         type            => "intranet",
74         authnotrequired => 0,
75         flagsrequired   => { tools => 'delete_anonymize_patrons', catalogue => 1 },
76     }
77 );
78
79 if ( $step == 2 ) {
80
81     my %checkboxes = map { $_ => 1 } split /\0/, $params->{'checkbox'};
82
83     my $totalDel;
84     my $membersToDelete;
85     if ( $checkboxes{borrower} ) {
86         $membersToDelete = GetBorrowersToExpunge(
87             _get_selection_params($not_borrowered_since, $borrower_dateexpiry, $borrower_categorycode)
88         );
89         _skip_borrowers_with_nonzero_balance( $membersToDelete );
90         $totalDel = scalar @$membersToDelete;
91
92     }
93     my $totalAno;
94     my $membersToAnonymize;
95     if ( $checkboxes{issue} ) {
96         $membersToAnonymize = GetBorrowersWithIssuesHistoryOlderThan($last_issue_date);
97         $totalAno           = scalar @$membersToAnonymize;
98     }
99
100     $template->param(
101         totalToDelete           => $totalDel,
102         totalToAnonymize        => $totalAno,
103         memberstodelete_list    => $membersToDelete,
104         memberstoanonymize_list => $membersToAnonymize,
105     );
106 }
107
108 elsif ( $step == 3 ) {
109     my $do_delete = $params->{'do_delete'};
110     my $do_anonym = $params->{'do_anonym'};
111
112     my ( $totalDel, $totalAno, $radio ) = ( 0, 0, 0 );
113
114     # delete members
115     if ($do_delete) {
116         my $membersToDelete = GetBorrowersToExpunge(
117             _get_selection_params($not_borrowered_since, $borrower_dateexpiry, $borrower_categorycode)
118         );
119         _skip_borrowers_with_nonzero_balance( $membersToDelete );
120         $totalDel = scalar(@$membersToDelete);
121         $radio    = $params->{'radio'};
122         for ( my $i = 0 ; $i < $totalDel ; $i++ ) {
123             $radio eq 'testrun' && last;
124             my $borrowernumber = $membersToDelete->[$i]->{'borrowernumber'};
125             $radio eq 'trash' && MoveMemberToDeleted( $borrowernumber );
126             C4::Members::HandleDelBorrower( $borrowernumber );
127             DelMember( $borrowernumber );
128         }
129         $template->param(
130             do_delete => '1',
131             TotalDel  => $totalDel
132         );
133     }
134
135     # Anonymising all members
136     if ($do_anonym) {
137         #FIXME: anonymisation errors are not handled
138         ($totalAno,my $anonymisation_error) = AnonymiseIssueHistory($last_issue_date);
139         $template->param(
140             do_anonym   => '1',
141         );
142     }
143
144     $template->param(
145         trash => ( $radio eq "trash" ) ? (1) : (0),
146         testrun => ( $radio eq "testrun" ) ? 1: 0,
147     );
148 }
149
150 $template->param(
151     step                   => $step,
152     not_borrowered_since   => $not_borrowered_since,
153     borrower_dateexpiry    => $borrower_dateexpiry,
154     last_issue_date        => $last_issue_date,
155     borrower_categorycodes => GetBorrowercategoryList(),
156     borrower_categorycode  => $borrower_categorycode,
157 );
158
159 #writing the template
160 output_html_with_http_headers $cgi, $cookie, $template->output;
161
162 sub _skip_borrowers_with_nonzero_balance {
163     my $borrowers = shift;
164     my $balance;
165     @$borrowers = map {
166         (undef, undef, $balance) = GetMemberIssuesAndFines( $_->{borrowernumber} );
167         ($balance != 0) ? (): ($_);
168     } @$borrowers;
169 }
170
171 sub _get_selection_params {
172     my ($not_borrowered_since, $borrower_dateexpiry, $borrower_categorycode) = @_;
173
174     my $params = {};
175     $params->{not_borrowered_since} = output_pref({
176         dt         => $not_borrowered_since,
177         dateformat => 'iso',
178         dateonly   => 1
179     }) if $not_borrowered_since;
180     $params->{expired_before} = output_pref({
181         dt         => $borrower_dateexpiry,
182         dateformat => 'iso',
183         dateonly   => 1
184     }) if $borrower_dateexpiry;
185     $params->{category_code} = $borrower_categorycode if $borrower_categorycode;
186
187     return $params;
188 };