View | Details | Raw Unified | Return to bug 10612
Collapse All | Expand All

(-)a/C4/Members.pm (-11 / +20 lines)
Lines 40-45 use Koha::Patron::Debarments qw(IsDebarred); Link Here
40
use Text::Unaccent qw( unac_string );
40
use Text::Unaccent qw( unac_string );
41
use Koha::AuthUtils qw(hash_password);
41
use Koha::AuthUtils qw(hash_password);
42
use Koha::Database;
42
use Koha::Database;
43
use Koha::List::Patron;
43
44
44
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
45
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
45
46
Lines 1851-1856 sub GetHideLostItemsPreference { Link Here
1851
      not_borrowered_since => $not_borrowered_since,
1852
      not_borrowered_since => $not_borrowered_since,
1852
      expired_before       => $expired_before,
1853
      expired_before       => $expired_before,
1853
      category_code        => $category_code,
1854
      category_code        => $category_code,
1855
      patron_list_id       => $patron_list_id,
1854
      branchcode           => $branchcode
1856
      branchcode           => $branchcode
1855
  );
1857
  );
1856
1858
Lines 1859-1876 sub GetHideLostItemsPreference { Link Here
1859
=cut
1861
=cut
1860
1862
1861
sub GetBorrowersToExpunge {
1863
sub GetBorrowersToExpunge {
1862
    my $params = shift;
1863
1864
1864
    my $filterdate     = $params->{'not_borrowered_since'};
1865
    my $params = shift;
1865
    my $filterexpiry   = $params->{'expired_before'};
1866
    my $filterdate       = $params->{'not_borrowered_since'};
1866
    my $filtercategory = $params->{'category_code'};
1867
    my $filterexpiry     = $params->{'expired_before'};
1867
    my $filterbranch   = $params->{'branchcode'} ||
1868
    my $filtercategory   = $params->{'category_code'};
1869
    my $filterbranch     = $params->{'branchcode'} ||
1868
                        ((C4::Context->preference('IndependentBranches')
1870
                        ((C4::Context->preference('IndependentBranches')
1869
                             && C4::Context->userenv 
1871
                             && C4::Context->userenv 
1870
                             && !C4::Context->IsSuperLibrarian()
1872
                             && !C4::Context->IsSuperLibrarian()
1871
                             && C4::Context->userenv->{branch})
1873
                             && C4::Context->userenv->{branch})
1872
                         ? C4::Context->userenv->{branch}
1874
                         ? C4::Context->userenv->{branch}
1873
                         : "");  
1875
                         : "");  
1876
    my $filterpatronlist = $params->{'patron_list_id'};
1874
1877
1875
    my $dbh   = C4::Context->dbh;
1878
    my $dbh   = C4::Context->dbh;
1876
    my $query = q|
1879
    my $query = q|
Lines 1886-1896 sub GetBorrowersToExpunge { Link Here
1886
                AND guarantorid <> 0
1889
                AND guarantorid <> 0
1887
        ) as tmp ON borrowers.borrowernumber=tmp.guarantorid
1890
        ) as tmp ON borrowers.borrowernumber=tmp.guarantorid
1888
        LEFT JOIN old_issues USING (borrowernumber)
1891
        LEFT JOIN old_issues USING (borrowernumber)
1889
        LEFT JOIN issues USING (borrowernumber) 
1892
        LEFT JOIN issues USING (borrowernumber)|;
1890
        WHERE  category_type <> 'S'
1893
    if ( $filterpatronlist  ){
1894
        $query .= q| LEFT JOIN patron_list_patrons USING (borrowernumber)|;
1895
    }
1896
    $query .= q| WHERE  category_type <> 'S'
1891
        AND tmp.guarantorid IS NULL
1897
        AND tmp.guarantorid IS NULL
1892
   |;
1898
   |;
1893
1894
    my @query_params;
1899
    my @query_params;
1895
    if ( $filterbranch && $filterbranch ne "" ) {
1900
    if ( $filterbranch && $filterbranch ne "" ) {
1896
        $query.= " AND borrowers.branchcode = ? ";
1901
        $query.= " AND borrowers.branchcode = ? ";
Lines 1904-1923 sub GetBorrowersToExpunge { Link Here
1904
        $query .= " AND categorycode = ? ";
1909
        $query .= " AND categorycode = ? ";
1905
        push( @query_params, $filtercategory );
1910
        push( @query_params, $filtercategory );
1906
    }
1911
    }
1912
    if ( $filterpatronlist ){
1913
        $query.=" AND patron_list_id = ? ";
1914
        push( @query_params, $filterpatronlist );
1915
    }
1907
    $query.=" GROUP BY borrowers.borrowernumber HAVING currentissue IS NULL ";
1916
    $query.=" GROUP BY borrowers.borrowernumber HAVING currentissue IS NULL ";
1908
    if ( $filterdate ) {
1917
    if ( $filterdate ) {
1909
        $query.=" AND ( latestissue < ? OR latestissue IS NULL ) ";
1918
        $query.=" AND ( latestissue < ? OR latestissue IS NULL ) ";
1910
        push @query_params,$filterdate;
1919
        push @query_params,$filterdate;
1911
    }
1920
    }
1912
    warn $query if $debug;
1921
    warn $query;# if $debug;
1913
1922
1914
    my $sth = $dbh->prepare($query);
1923
    my $sth = $dbh->prepare($query);
1915
    if (scalar(@query_params)>0){  
1924
    if (scalar(@query_params)>0){  
1916
        $sth->execute(@query_params);
1925
        $sth->execute(@query_params);
1917
    } 
1926
    }
1918
    else {
1927
    else {
1919
        $sth->execute;
1928
        $sth->execute;
1920
    }      
1929
    }
1921
    
1930
    
1922
    my @results;
1931
    my @results;
1923
    while ( my $data = $sth->fetchrow_hashref ) {
1932
    while ( my $data = $sth->fetchrow_hashref ) {
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/patron_lists/lists.tt (+20 lines)
Lines 49-54 Link Here
49
                    <th>Name</th>
49
                    <th>Name</th>
50
                    <th>Patrons in list</th>
50
                    <th>Patrons in list</th>
51
                    <th>&nbsp;</th>
51
                    <th>&nbsp;</th>
52
                    [% IF CAN_user_tools_edit_patrons %]
53
                        <th>&nbsp;</th>
54
                    [% END %]
55
                    [% IF CAN_user_tools_delete_anonymize_patrons %]
56
                        <th>&nbsp;</th>
57
                    [% END %]
52
                </tr>
58
                </tr>
53
            </thead>
59
            </thead>
54
60
Lines 70-75 Link Here
70
                                </ul>
76
                                </ul>
71
                            </div>
77
                            </div>
72
                        </td>
78
                        </td>
79
                        [% IF CAN_user_tools_edit_patrons %]
80
                            <td>
81
                                <a class="btn btn-mini" href="/cgi-bin/koha/tools/modborrowers.pl?patron_list_id=[% l.patron_list_id %]&op=show">
82
                                    <i class="fa fa-edit"></i> Edit patrons</i>
83
                                </a>
84
                            </td>
85
                        [% END %]
86
                        [% IF CAN_user_tools_delete_anonymize_patrons %]
87
                            <td>
88
                                <a class="btn btn-mini" href="/cgi-bin/koha/tools/cleanborrowers.pl?step=2&patron_list_id=[% l.patron_list_id %]&checkbox=borrower">
89
                                    <i class="fa fa-trash"></i> Delete patrons</i>
90
                                </a>
91
                            </td>
92
                        [% END %]
73
                    </tr>
93
                    </tr>
74
                [% END %]
94
                [% END %]
75
            </tbody>
95
            </tbody>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/cleanborrowers.tt (-8 / +21 lines)
Lines 12-18 Link Here
12
         */
12
         */
13
          function checkForm(form) {
13
          function checkForm(form) {
14
              if((form.checkbox[0].checked)){
14
              if((form.checkbox[0].checked)){
15
                  if ( (!form.date1.value) && (!form.borrower_dateexpiry.value) && (!form.borrower_categorycode.value) ){
15
                  if ( (!form.date1.value) && (!form.borrower_dateexpiry.value) && (!form.borrower_categorycode.value) && (!form.patron_list_id.value)){
16
                    alert(_("Please enter at least one criterion for deletion!"));
16
                    alert(_("Please enter at least one criterion for deletion!"));
17
                    return false;
17
                    return false;
18
                  }
18
                  }
Lines 88-95 Link Here
88
                        [% END %]
88
                        [% END %]
89
                    </select>
89
                    </select>
90
                </li>
90
                </li>
91
                [% IF patron_lists %]
92
                <li>
93
                    <label for="patron_list_id">who are in patron list: </label>
94
                    <select id="patron_list_id" name="patron_list_id">
95
                        <option value=""></option>
96
                        [% FOREACH pl IN patron_lists %]
97
                            <option value="[% pl.patron_list_id %]">[% pl.name %]</option>
98
                        [% END %]
99
                    </select>
100
                </li>
101
                [% END %]
91
            </ul>
102
            </ul>
92
        </fieldset>
103
        </fieldset>
104
93
        <fieldset>
105
        <fieldset>
94
        <legend>Anonymize checkout history</legend>
106
        <legend>Anonymize checkout history</legend>
95
        [% UNLESS Koha.Preference('AnonymousPatron') %]
107
        [% UNLESS Koha.Preference('AnonymousPatron') %]
Lines 121-132 Link Here
121
    <fieldset>
133
    <fieldset>
122
        <legend>Warnings</legend>
134
        <legend>Warnings</legend>
123
        <ul>
135
        <ul>
124
            <li>[% IF ( totalToDelete ) %][% totalToDelete %] [% ELSE %]0 [% END %] patrons will be deleted</li>
136
            <li>[% patrons_to_delete.size || 0 %] patrons will be deleted</li>
125
            <li>[% IF ( totalToAnonymize ) %][% totalToAnonymize %] [% ELSE %]0 [% END %] checkout history will be anonymized</li>
137
            <li>[% patrons_to_anonymize.size || 0 %] patron's checkout histories will be anonymized</li>
126
        </ul>
138
        </ul>
127
139
128
        <br />
140
        <br />
129
            [% IF ( totalToDelete ) %]
141
            [% IF patrons_to_delete.size %]
130
                <fieldset><legend>What do you want to do for deleted patrons?</legend>
142
                <fieldset><legend>What do you want to do for deleted patrons?</legend>
131
                <input id="delete" type="radio" name="radio" value="delete" />
143
                <input id="delete" type="radio" name="radio" value="delete" />
132
                <label for="delete">Permanently delete these patrons</label>
144
                <label for="delete">Permanently delete these patrons</label>
Lines 136-147 Link Here
136
148
137
                <br /><input id="testrun" type="radio" name="radio" value="testrun" checked="checked" />
149
                <br /><input id="testrun" type="radio" name="radio" value="testrun" checked="checked" />
138
                <label for="testrun">Do not remove any patrons (test run)</label>
150
                <label for="testrun">Do not remove any patrons (test run)</label>
139
                <input type="hidden" name="do_delete" value="[% totalToDelete %]" /></fieldset>
151
                <input type="hidden" name="do_delete" value="[% patrons_to_delete.size %]" /></fieldset>
140
152
141
            [% END %]
153
            [% END %]
142
            [% IF ( totalToAnonymize ) %]
154
            [% IF patrons_to_anonymize.size %]
143
                Checkout history for [% totalToAnonymize %] patrons will be anonymized
155
                Checkout history for [% patrons_to_anonymize.size %] patrons will be anonymized
144
                <input type="hidden" name="do_anonym" value="[% totalToAnonymize %]" />
156
                <input type="hidden" name="do_anonym" value="[% patrons_to_anonymize.size %]" />
145
            [% END %]
157
            [% END %]
146
158
147
            <input type="hidden" name="step" value="3" />
159
            <input type="hidden" name="step" value="3" />
Lines 149-154 Link Here
149
            <input type="hidden" name="last_issue_date" value="[% last_issue_date | $KohaDates %]" />
161
            <input type="hidden" name="last_issue_date" value="[% last_issue_date | $KohaDates %]" />
150
            <input type="hidden" name="borrower_dateexpiry" value="[% borrower_dateexpiry | $KohaDates %]" />
162
            <input type="hidden" name="borrower_dateexpiry" value="[% borrower_dateexpiry | $KohaDates %]" />
151
            <input type="hidden" name="borrower_categorycode" value="[% borrower_categorycode %]" />
163
            <input type="hidden" name="borrower_categorycode" value="[% borrower_categorycode %]" />
164
            <input type="hidden" name="patron_list_id" value="[% patron_list_id %]" />
152
    </fieldset>
165
    </fieldset>
153
    <fieldset class="action"><input type="submit" value="Finish" /> <a class="cancel" href="/cgi-bin/koha/tools/cleanborrowers.pl">Cancel</a></fieldset>
166
    <fieldset class="action"><input type="submit" value="Finish" /> <a class="cancel" href="/cgi-bin/koha/tools/cleanborrowers.pl">Cancel</a></fieldset>
154
        </form>
167
        </form>
(-)a/tools/cleanborrowers.pl (-27 / +43 lines)
Lines 40-46 use C4::Output; Link Here
40
use C4::Members;        # GetBorrowersWhoHavexxxBorrowed.
40
use C4::Members;        # GetBorrowersWhoHavexxxBorrowed.
41
use C4::Circulation;    # AnonymiseIssueHistory.
41
use C4::Circulation;    # AnonymiseIssueHistory.
42
use Koha::DateUtils qw( dt_from_string output_pref );
42
use Koha::DateUtils qw( dt_from_string output_pref );
43
use Koha::Database;
43
use Date::Calc qw/Today Add_Delta_YM/;
44
use Date::Calc qw/Today Add_Delta_YM/;
45
use Koha::List::Patron;
44
46
45
my $cgi = new CGI;
47
my $cgi = new CGI;
46
48
Lines 63-68 my $borrower_dateexpiry = Link Here
63
  $params->{borrower_dateexpiry}
65
  $params->{borrower_dateexpiry}
64
  ? dt_from_string $params->{borrower_dateexpiry}
66
  ? dt_from_string $params->{borrower_dateexpiry}
65
  : undef;
67
  : undef;
68
my $patron_list_id = $params->{patron_list_id};
66
69
67
my $borrower_categorycode = $params->{'borrower_categorycode'} || q{};
70
my $borrower_categorycode = $params->{'borrower_categorycode'} || q{};
68
71
Lines 80-107 if ( $step == 2 ) { Link Here
80
83
81
    my %checkboxes = map { $_ => 1 } split /\0/, $params->{'checkbox'};
84
    my %checkboxes = map { $_ => 1 } split /\0/, $params->{'checkbox'};
82
85
83
    my $totalDel;
86
    my $patrons_to_delete;
84
    my $membersToDelete;
85
    if ( $checkboxes{borrower} ) {
87
    if ( $checkboxes{borrower} ) {
86
        $membersToDelete = GetBorrowersToExpunge(
88
        $patrons_to_delete = GetBorrowersToExpunge(
87
            _get_selection_params($not_borrowered_since, $borrower_dateexpiry, $borrower_categorycode)
89
             _get_selection_params(
90
                  $not_borrowered_since,
91
                  $borrower_dateexpiry,
92
                  $borrower_categorycode,
93
                  $patron_list_id,
94
             )
88
        );
95
        );
89
        _skip_borrowers_with_nonzero_balance( $membersToDelete );
90
        $totalDel = scalar @$membersToDelete;
91
92
    }
96
    }
93
    my $totalAno;
97
    _skip_borrowers_with_nonzero_balance($patrons_to_delete);
94
    my $membersToAnonymize;
98
99
    my $members_to_anonymize;
95
    if ( $checkboxes{issue} ) {
100
    if ( $checkboxes{issue} ) {
96
        $membersToAnonymize = GetBorrowersWithIssuesHistoryOlderThan($last_issue_date);
101
        $members_to_anonymize = GetBorrowersWithIssuesHistoryOlderThan($last_issue_date);
97
        $totalAno           = scalar @$membersToAnonymize;
98
    }
102
    }
99
103
100
    $template->param(
104
    $template->param(
101
        totalToDelete           => $totalDel,
105
        patrons_to_delete    => $patrons_to_delete,
102
        totalToAnonymize        => $totalAno,
106
        patrons_to_anonymize => $members_to_anonymize,
103
        memberstodelete_list    => $membersToDelete,
107
        patron_list_id          => $patron_list_id,
104
        memberstoanonymize_list => $membersToAnonymize,
105
    );
108
    );
106
}
109
}
107
110
Lines 113-130 elsif ( $step == 3 ) { Link Here
113
116
114
    # delete members
117
    # delete members
115
    if ($do_delete) {
118
    if ($do_delete) {
116
        my $membersToDelete = GetBorrowersToExpunge(
119
        my $patrons_to_delete = GetBorrowersToExpunge(
117
            _get_selection_params($not_borrowered_since, $borrower_dateexpiry, $borrower_categorycode)
120
                _get_selection_params(
118
        );
121
                    $not_borrowered_since, $borrower_dateexpiry,
119
        _skip_borrowers_with_nonzero_balance( $membersToDelete );
122
                    $borrower_categorycode, $patron_list_id
120
        $totalDel = scalar(@$membersToDelete);
123
                )
124
            );
125
        _skip_borrowers_with_nonzero_balance($patrons_to_delete);
126
127
        $totalDel = scalar(@$patrons_to_delete);
121
        $radio    = $params->{'radio'};
128
        $radio    = $params->{'radio'};
122
        for ( my $i = 0 ; $i < $totalDel ; $i++ ) {
129
        for ( my $i = 0 ; $i < $totalDel ; $i++ ) {
123
            $radio eq 'testrun' && last;
130
            $radio eq 'testrun' && last;
124
            my $borrowernumber = $membersToDelete->[$i]->{'borrowernumber'};
131
            my $borrowernumber = $patrons_to_delete->[$i]->{'borrowernumber'}
125
            $radio eq 'trash' && MoveMemberToDeleted( $borrowernumber );
132
              || $patrons_to_delete->[$i]->get_column('borrowernumber');
126
            C4::Members::HandleDelBorrower( $borrowernumber );
133
            $radio eq 'trash' && MoveMemberToDeleted($borrowernumber);
127
            DelMember( $borrowernumber );
134
            C4::Members::HandleDelBorrower($borrowernumber);
135
            DelMember($borrowernumber);
128
        }
136
        }
129
        $template->param(
137
        $template->param(
130
            do_delete => '1',
138
            do_delete => '1',
Lines 145-150 elsif ( $step == 3 ) { Link Here
145
        trash => ( $radio eq "trash" ) ? (1) : (0),
153
        trash => ( $radio eq "trash" ) ? (1) : (0),
146
        testrun => ( $radio eq "testrun" ) ? 1: 0,
154
        testrun => ( $radio eq "testrun" ) ? 1: 0,
147
    );
155
    );
156
} else { # $step == 1
157
    my @all_lists = GetPatronLists();
158
    my @non_empty_lists;
159
    foreach my $list (@all_lists){
160
    my @patrons = $list->patron_list_patrons();
161
        if( scalar @patrons ) { push(@non_empty_lists,$list) }
162
    }
163
    $template->param( patron_lists => [ @non_empty_lists ] );
148
}
164
}
149
165
150
$template->param(
166
$template->param(
Lines 163-175 sub _skip_borrowers_with_nonzero_balance { Link Here
163
    my $borrowers = shift;
179
    my $borrowers = shift;
164
    my $balance;
180
    my $balance;
165
    @$borrowers = map {
181
    @$borrowers = map {
166
        (undef, undef, $balance) = GetMemberIssuesAndFines( $_->{borrowernumber} );
182
        (undef, undef, $balance) = GetMemberIssuesAndFines( $_->{borrowernumber} || $_->get_column('borrowernumber') );
167
        ($balance != 0) ? (): ($_);
183
        ($balance != 0) ? (): ($_);
168
    } @$borrowers;
184
    } @$borrowers;
169
}
185
}
170
186
171
sub _get_selection_params {
187
sub _get_selection_params {
172
    my ($not_borrowered_since, $borrower_dateexpiry, $borrower_categorycode) = @_;
188
    my ($not_borrowered_since, $borrower_dateexpiry, $borrower_categorycode, $patron_list_id) = @_;
173
189
174
    my $params = {};
190
    my $params = {};
175
    $params->{not_borrowered_since} = output_pref({
191
    $params->{not_borrowered_since} = output_pref({
Lines 183-188 sub _get_selection_params { Link Here
183
        dateonly   => 1
199
        dateonly   => 1
184
    }) if $borrower_dateexpiry;
200
    }) if $borrower_dateexpiry;
185
    $params->{category_code} = $borrower_categorycode if $borrower_categorycode;
201
    $params->{category_code} = $borrower_categorycode if $borrower_categorycode;
202
    $params->{patron_list_id} = $patron_list_id if $patron_list_id;
186
203
187
    return $params;
204
    return $params;
188
};
205
};
189
- 

Return to bug 10612