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

(-)a/C4/Circulation.pm (-11 / +26 lines)
Lines 47-52 use Algorithm::CheckDigits; Link Here
47
use Data::Dumper;
47
use Data::Dumper;
48
use Koha::DateUtils;
48
use Koha::DateUtils;
49
use Koha::Calendar;
49
use Koha::Calendar;
50
use Koha::Borrower::Debarments;
50
use Carp;
51
use Carp;
51
use Date::Calc qw(
52
use Date::Calc qw(
52
  Today
53
  Today
Lines 1911-1916 sub AddReturn { Link Here
1911
    logaction("CIRCULATION", "RETURN", $borrowernumber, $item->{'itemnumber'})
1912
    logaction("CIRCULATION", "RETURN", $borrowernumber, $item->{'itemnumber'})
1912
        if C4::Context->preference("ReturnLog");
1913
        if C4::Context->preference("ReturnLog");
1913
    
1914
    
1915
    # Remove any OVERDUES related debarment if the borrower has no overdues
1916
    if ( $borrowernumber
1917
      && $borrower->{'debarred'}
1918
      && C4::Context->preference('AutoRemoveOverduesRestrictions')
1919
      && !HasOverdues( $borrowernumber )
1920
      && @{ GetDebarments({ borrowernumber => $borrowernumber, type => 'OVERDUES' }) }
1921
    ) {
1922
        DelUniqueDebarment({ borrowernumber => $borrowernumber, type => 'OVERDUES' });
1923
    }
1924
1914
    # FIXME: make this comment intelligible.
1925
    # FIXME: make this comment intelligible.
1915
    #adding message if holdingbranch is non equal a userenv branch to return the document to homebranch
1926
    #adding message if holdingbranch is non equal a userenv branch to return the document to homebranch
1916
    #we check, if we don't have reserv or transfert for this document, if not, return it to homebranch .
1927
    #we check, if we don't have reserv or transfert for this document, if not, return it to homebranch .
Lines 2044-2062 sub _debar_user_on_return { Link Here
2044
2055
2045
            my $new_debar_dt =
2056
            my $new_debar_dt =
2046
              $dt_today->clone()->add_duration( $deltadays * $finedays );
2057
              $dt_today->clone()->add_duration( $deltadays * $finedays );
2047
            if ( $borrower->{debarred} ) {
2048
                my $borrower_debar_dt = dt_from_string( $borrower->{debarred} );
2049
2058
2050
                # Update patron only if new date > old
2059
            Koha::Borrower::Debarments::AddUniqueDebarment({
2051
                if ( DateTime->compare( $borrower_debar_dt, $new_debar_dt ) !=
2060
                borrowernumber => $borrower->{borrowernumber},
2052
                    -1 )
2061
                expiration     => $new_debar_dt->ymd(),
2053
                {
2062
                type           => 'SUSPENSION',
2054
                    return;
2063
            });
2055
                }
2056
2064
2057
            }
2058
            C4::Members::DebarMember( $borrower->{borrowernumber},
2059
                $new_debar_dt->ymd() );
2060
            return $new_debar_dt->ymd();
2065
            return $new_debar_dt->ymd();
2061
        }
2066
        }
2062
    }
2067
    }
Lines 2601-2606 sub AddRenewal { Link Here
2601
	}
2606
	}
2602
    }
2607
    }
2603
2608
2609
    # Remove any OVERDUES related debarment if the borrower has no overdues
2610
    my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber );
2611
    if ( $borrowernumber
2612
      && $borrower->{'debarred'}
2613
      && !HasOverdues( $borrowernumber )
2614
      && @{ GetDebarments({ borrowernumber => $borrowernumber, type => 'OVERDUES' }) }
2615
    ) {
2616
        DelUniqueDebarment({ borrowernumber => $borrowernumber, type => 'OVERDUES' });
2617
    }
2618
2604
    # Log the renewal
2619
    # Log the renewal
2605
    UpdateStats( $branch, 'renew', $charge, '', $itemnumber, $item->{itype}, $borrowernumber, undef, $item->{'ccode'});
2620
    UpdateStats( $branch, 'renew', $charge, '', $itemnumber, $item->{itype}, $borrowernumber, undef, $item->{'ccode'});
2606
	return $datedue;
2621
	return $datedue;
(-)a/C4/Members.pm (-27 / +15 lines)
Lines 39-44 use C4::NewsChannels; #get slip news Link Here
39
use DateTime;
39
use DateTime;
40
use DateTime::Format::DateParse;
40
use DateTime::Format::DateParse;
41
use Koha::DateUtils;
41
use Koha::DateUtils;
42
use Koha::Borrower::Debarments qw(IsDebarred);
42
use Text::Unaccent qw( unac_string );
43
use Text::Unaccent qw( unac_string );
43
44
44
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
45
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
Lines 103-108 BEGIN { Link Here
103
104
104
        &IssueSlip
105
        &IssueSlip
105
        GetBorrowersWithEmail
106
        GetBorrowersWithEmail
107
108
        HasOverdues
106
    );
109
    );
107
110
108
    #Modify data
111
    #Modify data
Lines 636-642 sub IsMemberBlocked { Link Here
636
    my $borrowernumber = shift;
639
    my $borrowernumber = shift;
637
    my $dbh            = C4::Context->dbh;
640
    my $dbh            = C4::Context->dbh;
638
641
639
    my $blockeddate = CheckBorrowerDebarred($borrowernumber);
642
    my $blockeddate = Koha::Borrower::Debarments::IsDebarred($borrowernumber);
640
643
641
    return ( 1, $blockeddate ) if $blockeddate;
644
    return ( 1, $blockeddate ) if $blockeddate;
642
645
Lines 2214-2245 sub GetBorrowersNamesAndLatestIssue { Link Here
2214
    return $results;
2217
    return $results;
2215
}
2218
}
2216
2219
2217
=head2 DebarMember
2218
2219
my $success = DebarMember( $borrowernumber, $todate );
2220
2221
marks a Member as debarred, and therefore unable to checkout any more
2222
items.
2223
2224
return :
2225
true on success, false on failure
2226
2227
=cut
2228
2229
sub DebarMember {
2230
    my $borrowernumber = shift;
2231
    my $todate         = shift;
2232
2233
    return unless defined $borrowernumber;
2234
    return unless $borrowernumber =~ /^\d+$/;
2235
2236
    return ModMember(
2237
        borrowernumber => $borrowernumber,
2238
        debarred       => $todate
2239
    );
2240
2241
}
2242
2243
=head2 ModPrivacy
2220
=head2 ModPrivacy
2244
2221
2245
=over 4
2222
=over 4
Lines 2509-2514 sub AddMember_Opac { Link Here
2509
    return ( $borrowernumber, $password );
2486
    return ( $borrowernumber, $password );
2510
}
2487
}
2511
2488
2489
sub HasOverdues {
2490
    my ( $borrowernumber ) = @_;
2491
2492
    my $sql = "SELECT COUNT(*) FROM issues WHERE date_due < NOW() AND borrowernumber = ?";
2493
    my $sth = C4::Context->dbh->prepare( $sql );
2494
    $sth->execute( $borrowernumber );
2495
    my ( $count ) = $sth->fetchrow_array();
2496
2497
    return $count;
2498
}
2499
2512
END { }    # module clean-up code here (global destructor)
2500
END { }    # module clean-up code here (global destructor)
2513
2501
2514
1;
2502
1;
(-)a/C4/Overdues.pm (-33 / +4 lines)
Lines 62-71 BEGIN { Link Here
62
	push @EXPORT, qw(
62
	push @EXPORT, qw(
63
        &GetIssuesIteminfo
63
        &GetIssuesIteminfo
64
	);
64
	);
65
	# subs to move to Members.pm
65
66
	push @EXPORT, qw(
66
     # &GetIssuingRules - delete.
67
        &CheckBorrowerDebarred
67
   # use C4::Circulation::GetIssuingRule instead.
68
	);
68
69
	# subs to move to Biblio.pm
69
	# subs to move to Biblio.pm
70
	push @EXPORT, qw(
70
	push @EXPORT, qw(
71
        &GetItems
71
        &GetItems
Lines 759-793 sub GetBranchcodesWithOverdueRules { Link Here
759
    return @branches;
759
    return @branches;
760
}
760
}
761
761
762
=head2 CheckBorrowerDebarred
763
764
    ($debarredstatus) = &CheckBorrowerDebarred($borrowernumber);
765
766
Check if the borrowers is already debarred
767
768
C<$debarredstatus> return 0 for not debarred and return 1 for debarred
769
770
C<$borrowernumber> contains the borrower number
771
772
=cut
773
774
# FIXME: Shouldn't this be in C4::Members?
775
sub CheckBorrowerDebarred {
776
    my ($borrowernumber) = @_;
777
    my $dbh   = C4::Context->dbh;
778
    my $query = qq|
779
        SELECT debarred
780
        FROM borrowers
781
        WHERE borrowernumber=?
782
        AND debarred > NOW()
783
    |;
784
    my $sth = $dbh->prepare($query);
785
    $sth->execute($borrowernumber);
786
    my $debarredstatus = $sth->fetchrow;
787
    return $debarredstatus;
788
}
789
790
791
=head2 CheckItemNotify
762
=head2 CheckItemNotify
792
763
793
Sql request to check if the document has alreday been notified
764
Sql request to check if the document has alreday been notified
(-)a/Koha/Borrower/Debarments.pm (+334 lines)
Line 0 Link Here
1
package Koha::Borrower::Debarments;
2
3
# Copyright 2013 ByWater Solutions
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along with
17
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18
# Suite 330, Boston, MA  02111-1307 USA
19
20
use Modern::Perl;
21
22
use C4::Context;
23
24
use parent qw( Exporter );
25
26
our @EXPORT = qw(
27
  GetDebarments
28
29
  AddDebarment
30
  DelDebarment
31
  ModDebarment
32
33
  AddUniqueDebarment
34
  DelUniqueDebarment
35
36
  IsDebarred
37
);
38
39
=head1 Koha::Borrower::Debarments
40
41
Koha::Borrower::Debarments - Module for managing borrower debarments
42
43
=cut
44
45
=head2 GetDebarments
46
47
my $arrayref = GetDebarments( $borrowernumber, { key => $value } );
48
49
=cut
50
51
sub GetDebarments {
52
    my ($params) = @_;
53
54
    return unless ( $params->{'borrowernumber'} );
55
56
    my @keys   = keys %$params;
57
    my @values = values %$params;
58
59
    my $where = join( ' AND ', map { "$_ = ?" } @keys );
60
    my $sql   = "SELECT * FROM borrower_debarments WHERE $where";
61
    my $sth   = C4::Context->dbh->prepare($sql);
62
    $sth->execute(@values);
63
64
    return $sth->fetchall_arrayref( {} );
65
}
66
67
=head2 AddDebarment
68
69
my $success = AddDebarment({
70
    borrowernumber => $borrowernumber,
71
    expiration     => $expiration,
72
    type           => $type, ## enum('FINES','OVERDUES','MANUAL')
73
    comment        => $comment,
74
});
75
76
Creates a new debarment.
77
78
Required keys: borrowernumber, type
79
80
=cut
81
82
sub AddDebarment {
83
    my ($params) = @_;
84
85
    my $borrowernumber = $params->{'borrowernumber'};
86
    my $expiration     = $params->{'expiration'} || undef;
87
    my $type           = $params->{'type'} || 'MANUAL';
88
    my $comment        = $params->{'comment'} || undef;
89
90
    return unless ( $borrowernumber && $type );
91
92
    my $manager_id;
93
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
94
95
    my $sql = "
96
        INSERT INTO borrower_debarments ( borrowernumber, expiration, type, comment, manager_id, created )
97
        VALUES ( ?, ?, ?, ?, ?, NOW() )
98
    ";
99
100
    my $r = C4::Context->dbh->do( $sql, {}, ( $borrowernumber, $expiration, $type, $comment, $manager_id ) );
101
102
    _UpdateBorrowerDebarmentFlags($borrowernumber);
103
104
    return $r;
105
}
106
107
=head2 DelDebarment
108
109
my $success = DelDebarment( $borrower_debarment_id );
110
111
Deletes a debarment.
112
113
=cut
114
115
sub DelDebarment {
116
    my ($id) = @_;
117
118
    my $borrowernumber = _GetBorrowernumberByDebarmentId($id);
119
120
    my $sql = "DELETE FROM borrower_debarments WHERE borrower_debarment_id = ?";
121
122
    my $r = C4::Context->dbh->do( $sql, {}, ($id) );
123
124
    _UpdateBorrowerDebarmentFlags($borrowernumber);
125
126
    return $r;
127
}
128
129
=head2 ModDebarment
130
131
my $success = ModDebarment({
132
    borrower_debarment_id => $borrower_debarment_id,
133
    expiration            => $expiration,
134
    type                  => $type, ## enum('FINES','OVERDUES','MANUAL')
135
    comment               => $comment,
136
});
137
138
Updates an existing debarment.
139
140
Required keys: borrower_debarment_id
141
142
=cut
143
144
sub ModDebarment {
145
    my ($params) = @_;
146
147
    my $borrower_debarment_id = $params->{'borrower_debarment_id'};
148
149
    return unless ($borrower_debarment_id);
150
151
    delete( $params->{'borrower_debarment_id'} );
152
153
    delete( $params->{'created'} );
154
    delete( $params->{'updated'} );
155
156
    $params->{'manager_id'} = C4::Context->userenv->{'number'} if C4::Context->userenv;
157
158
    my @keys   = keys %$params;
159
    my @values = values %$params;
160
161
    my $sql = join( ',', map { "$_ = ?" } @keys );
162
163
    $sql = "UPDATE borrower_debarments SET $sql, updated = NOW() WHERE borrower_debarment_id = ?";
164
165
    my $r = C4::Context->dbh->do( $sql, {}, ( @values, $borrower_debarment_id ) );
166
167
    _UpdateBorrowerDebarmentFlags( _GetBorrowernumberByDebarmentId($borrower_debarment_id) );
168
169
    return $r;
170
}
171
172
=head2 IsDebarred
173
174
my $debarment_expiration = IsDebarred( $borrowernumber );
175
176
Returns the date a borrowers debarment will expire, or
177
undef if the borrower is not debarred
178
179
=cut
180
181
sub IsDebarred {
182
    my ($borrowernumber) = @_;
183
184
    return unless ($borrowernumber);
185
186
    my $sql = "SELECT debarred FROM borrowers WHERE borrowernumber = ?";
187
    my $sth = C4::Context->dbh->prepare($sql);
188
    $sth->execute($borrowernumber);
189
    my ($debarred) = $sth->fetchrow_array();
190
191
    return $debarred;
192
}
193
194
=head2 AddUniqueDebarment
195
196
my $success = AddUniqueDebarment({
197
    borrowernumber => $borrowernumber,
198
    type           => $type,
199
    expiration     => $expiration,
200
    comment        => $comment,
201
});
202
203
Creates a new debarment of the type defined by the key type.
204
If a unique debarment already exists of the given type, it is updated instead.
205
The current unique debarment types are OVERDUES, and SUSPENSION
206
207
Required keys: borrowernumber, type
208
209
=cut
210
211
sub AddUniqueDebarment {
212
    my ($params) = @_;
213
214
    my $borrowernumber = $params->{'borrowernumber'};
215
    my $type           = $params->{'type'};
216
217
    return unless ( $borrowernumber && $type );
218
219
    my $debarment = @{ GetDebarments( { borrowernumber => $borrowernumber, type => $type } ) }[0];
220
    warn Data::Dumper::Dumper( $debarment );
221
222
    my $r;
223
    if ($debarment) {
224
225
        # We don't want to shorten a unique debarment's period, so if this 'update' would do so, just keep the current expiration date instead
226
        $params->{'expiration'} = $debarment->{'expiration'}
227
          if ( $debarment->{'expiration'}
228
            && $debarment->{'expiration'} gt $params->{'expiration'} );
229
230
        $params->{'borrower_debarment_id'} =
231
          $debarment->{'borrower_debarment_id'};
232
        $r = ModDebarment($params);
233
    } else {
234
235
        $r = AddDebarment($params);
236
    }
237
238
    _UpdateBorrowerDebarmentFlags($borrowernumber);
239
240
    return $r;
241
}
242
243
=head2 DelUniqueDebarment
244
245
my $success = _DelUniqueDebarment({
246
    borrowernumber => $borrowernumber,
247
    type           => $type,
248
});
249
250
Deletes a unique debarment of the type defined by the key type.
251
The current unique debarment types are OVERDUES, and SUSPENSION
252
253
Required keys: borrowernumber, type
254
255
=cut
256
257
sub DelUniqueDebarment {
258
    my ($params) = @_;
259
260
    my $borrowernumber = $params->{'borrowernumber'};
261
    my $type           = $params->{'type'};
262
263
    return unless ( $borrowernumber && $type );
264
265
    my $debarment = @{ GetDebarments( { borrowernumber => $borrowernumber, type => $type } ) }[0];
266
267
    return unless ( $debarment );
268
269
    return DelDebarment( $debarment->{'borrower_debarment_id'} );
270
}
271
272
=head2 _UpdateBorrowerDebarmentFlags
273
274
my $success = _UpdateBorrowerDebarmentFlags( $borrowernumber );
275
276
So as not to create additional latency, the fields borrowers.debarred
277
and borrowers.debarredcomment remain in the borrowers table. Whenever
278
the a borrowers debarrments are modified, this subroutine is run to
279
decide if the borrower is currently debarred and update the 'quick flags'
280
in the borrowers table accordingly.
281
282
=cut
283
284
sub _UpdateBorrowerDebarmentFlags {
285
    my ($borrowernumber) = @_;
286
287
    return unless ($borrowernumber);
288
289
    my $dbh = C4::Context->dbh;
290
291
    my $sql = q{
292
        SELECT COUNT(*), COUNT(*) - COUNT(expiration), MAX(expiration), GROUP_CONCAT(comment SEPARATOR '\n') FROM borrower_debarments
293
        WHERE ( expiration > CURRENT_DATE() OR expiration IS NULL ) AND borrowernumber = ?
294
    };
295
    my $sth = $dbh->prepare($sql);
296
    $sth->execute($borrowernumber);
297
    my ( $count, $indefinite_expiration, $expiration, $comment ) = $sth->fetchrow_array();
298
299
    if ($count) {
300
        $expiration = "9999-12-31" if ($indefinite_expiration);
301
    } else {
302
        $expiration = undef;
303
        $comment    = undef;
304
    }
305
306
    return $dbh->do( "UPDATE borrowers SET debarred = ?, debarredcomment = ? WHERE borrowernumber = ?", {}, ( $expiration, $comment, $borrowernumber ) );
307
}
308
309
=head2 _GetBorrowernumberByDebarmentId
310
311
my $borrowernumber = _GetBorrowernumberByDebarmentId( $borrower_debarment_id );
312
313
=cut
314
315
sub _GetBorrowernumberByDebarmentId {
316
    my ($borrower_debarment_id) = @_;
317
318
    return unless ($borrower_debarment_id);
319
320
    my $sql = "SELECT borrowernumber FROM borrower_debarments WHERE borrower_debarment_id = ?";
321
    my $sth = C4::Context->dbh->prepare($sql);
322
    $sth->execute($borrower_debarment_id);
323
    my ($borrowernumber) = $sth->fetchrow_array();
324
325
    return $borrowernumber;
326
}
327
328
1;
329
330
=head2 AUTHOR
331
332
Kyle M Hall <kyle@bywatersoltuions.com>
333
334
=cut
(-)a/circ/circulation.pl (-9 / +9 lines)
Lines 31-43 use C4::Dates qw/format_date/; Link Here
31
use C4::Branch; # GetBranches
31
use C4::Branch; # GetBranches
32
use C4::Koha;   # GetPrinter
32
use C4::Koha;   # GetPrinter
33
use C4::Circulation;
33
use C4::Circulation;
34
use C4::Overdues qw/CheckBorrowerDebarred/;
35
use C4::Members;
34
use C4::Members;
36
use C4::Biblio;
35
use C4::Biblio;
37
use C4::Reserves;
36
use C4::Reserves;
38
use C4::Context;
37
use C4::Context;
39
use CGI::Session;
38
use CGI::Session;
40
use C4::Members::Attributes qw(GetBorrowerAttributes);
39
use C4::Members::Attributes qw(GetBorrowerAttributes);
40
use Koha::Borrower::Debarments qw(GetDebarments);
41
use Koha::DateUtils;
41
use Koha::DateUtils;
42
42
43
use Date::Calc qw(
43
use Date::Calc qw(
Lines 263-275 if ($borrowernumber) { Link Here
263
        finetotal    => $fines
263
        finetotal    => $fines
264
    );
264
    );
265
265
266
    my $debar = CheckBorrowerDebarred($borrowernumber);
266
    $template->param(
267
    if ($debar) {
267
        'userdebarred'    => $borrower->{debarred},
268
        $template->param( 'userdebarred'    => 1 );
268
        'debarredcomment' => $borrower->{debarredcomment},
269
        $template->param( 'debarredcomment' => $borrower->{debarredcomment} );
269
    );
270
        if ( $debar ne "9999-12-31" ) {
270
    if ( $borrower->{debarred} ne "9999-12-31" ) {
271
            $template->param( 'userdebarreddate' => C4::Dates::format_date($debar) );
271
        $template->param( 'userdebarreddate' => C4::Dates::format_date( $borrower->{debarred} ) );
272
        }
273
    }
272
    }
274
273
275
}
274
}
Lines 743-752 $template->param( Link Here
743
    debt_confirmed            => $debt_confirmed,
742
    debt_confirmed            => $debt_confirmed,
744
    SpecifyDueDate            => $duedatespec_allow,
743
    SpecifyDueDate            => $duedatespec_allow,
745
    CircAutocompl             => C4::Context->preference("CircAutocompl"),
744
    CircAutocompl             => C4::Context->preference("CircAutocompl"),
746
	AllowRenewalLimitOverride => C4::Context->preference("AllowRenewalLimitOverride"),
745
    AllowRenewalLimitOverride => C4::Context->preference("AllowRenewalLimitOverride"),
747
    export_remove_fields      => C4::Context->preference("ExportRemoveFields"),
746
    export_remove_fields      => C4::Context->preference("ExportRemoveFields"),
748
    export_with_csv_profile   => C4::Context->preference("ExportWithCsvProfile"),
747
    export_with_csv_profile   => C4::Context->preference("ExportWithCsvProfile"),
749
    canned_bor_notes_loop     => $canned_notes,
748
    canned_bor_notes_loop     => $canned_notes,
749
    debarments                => GetDebarments({ borrowernumber => $borrowernumber }),
750
);
750
);
751
751
752
output_html_with_http_headers $query, $cookie, $template->output;
752
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 427-429 INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES(' Link Here
427
INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('UseCourseReserves', '0', 'Enable the course reserves feature.', NULL, 'YesNo');
427
INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('UseCourseReserves', '0', 'Enable the course reserves feature.', NULL, 'YesNo');
428
INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacHoldNotes',0,'Show hold notes on OPAC','','YesNo');
428
INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacHoldNotes',0,'Show hold notes on OPAC','','YesNo');
429
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('CalculateFinesOnReturn','1','Switch to control if overdue fines are calculated on return or not', '', 'YesNo');
429
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('CalculateFinesOnReturn','1','Switch to control if overdue fines are calculated on return or not', '', 'YesNo');
430
INSERT IGNORE INTO systempreferences (variable,value,explanation,type) VALUES ('AutoRemoveOverduesRestrictions','0','Defines whether an OVERDUES debarment should be lifted automatically if all overdue items are returned by the patron.','YesNo');
(-)a/installer/data/mysql/updatedatabase.pl (+30 lines)
Lines 7017-7022 if ( CheckVersion($DBversion) ) { Link Here
7017
    SetVersion($DBversion);
7017
    SetVersion($DBversion);
7018
}
7018
}
7019
7019
7020
$DBversion ="3.13.00.XXX";
7021
if ( CheckVersion($DBversion) ) {
7022
    $dbh->do(q{
7023
CREATE TABLE borrower_debarments (
7024
  borrower_debarment_id int(11) NOT NULL AUTO_INCREMENT,
7025
  borrowernumber int(11) NOT NULL,
7026
  expiration date DEFAULT NULL,
7027
  `type` enum('SUSPENSION','OVERDUES','MANUAL') NOT NULL DEFAULT 'MANUAL',
7028
  `comment` text,
7029
  manager_id int(11) DEFAULT NULL,
7030
  created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
7031
  updated timestamp NULL DEFAULT NULL,
7032
  PRIMARY KEY (borrower_debarment_id),
7033
  KEY borrowernumber (borrowernumber)
7034
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
7035
    });
7036
7037
    $dbh->do(q{
7038
INSERT INTO borrower_debarments ( borrowernumber, expiration, comment ) SELECT borrowernumber, debarred, debarredcomment FROM borrowers WHERE debarred IS NOT NULL
7039
    });
7040
7041
    $dbh->do(q{
7042
INSERT IGNORE INTO systempreferences (variable,value,explanation,type) VALUES
7043
('AutoRemoveOverduesRestrictions','0','Defines whether an OVERDUES debarment should be lifted automatically if all overdue items are returned by the patron.','YesNo')
7044
    });
7045
7046
    print "Upgrade to $DBversion done (Bug 2720 - Overdues which debar automatically should undebar automatically when returned)\n";
7047
    SetVersion($DBversion);
7048
}
7049
7020
=head1 FUNCTIONS
7050
=head1 FUNCTIONS
7021
7051
7022
=head2 TableExists($table)
7052
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/borrower_debarments.inc (+64 lines)
Line 0 Link Here
1
<script type="text/javascript">
2
   //<![CDATA[
3
4
        function confirm_remove_restriction() {
5
            return confirm(_("Remove restriction?"));
6
        }
7
8
    //]]>
9
</script>
10
11
<div id="reldebarments">
12
    [% UNLESS debarments %]<p>Patron is currently unrestricted.</p>[% END %]
13
14
    <table>
15
        <thead>
16
            <tr>
17
                 <th>Type</th>
18
                 <th>Comment</th>
19
                 <th>Expiration</th>
20
                 [% IF ( CAN_user_borrowers ) %]
21
                     <th>&nbsp;</th>
22
                 [% END %]
23
            </tr>
24
        </thead>
25
26
        <tbody>
27
            [% FOREACH d IN debarments %]
28
                <tr>
29
                    <td>[% d.type %]</td>
30
                    <td>[% d.comment %]</td>
31
                    <td>[% IF d.expiration %] [% d.expiration | $KohaDates %] [% ELSE %] <i>Indefinite</i> [% END %]</td>
32
                    [% IF ( CAN_user_borrowers )%]
33
                        <td>
34
                            <a href="/cgi-bin/koha/members/mod_debarment.pl?borrowernumber=[% borrowernumber %]&amp;borrower_debarment_id=[% d.borrower_debarment_id %]&amp;action=del" onclick="return confirm_remove_restriction()">
35
                                Remove
36
                            </a>
37
                        </td>
38
                    [% END %]
39
                </tr>
40
            [% END %]
41
        </tbody>
42
43
        [% IF ( CAN_user_borrowers )%]
44
            <form method="post" action="/cgi-bin/koha/members/mod_debarment.pl">
45
                <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
46
                <input type="hidden" name="action" value="add" />
47
48
                <tfoot>
49
                    <tr>
50
                        <td>MANUAL</td>
51
                        <td><input type="text" name="comment" /></td>
52
                        <td>
53
                            <input name="expiration" id="expiration" size="10" readonly="readonly" value="" class="datepicker" />
54
                            <a href='#' onclick="document.getElementById('expiration').value='';">Clear Date</a>
55
                        </td>
56
                        <td>
57
                            <input type="submit" value="Add restriction" />
58
                        </td>
59
                    </tr>
60
                </tfoot>
61
            </form>
62
        [% END %]
63
    </table>
64
</div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (+6 lines)
Lines 126-131 Circulation: Link Here
126
126
127
    Checkout Policy:
127
    Checkout Policy:
128
        -
128
        -
129
            - pref: AutoRemoveOverduesRestrictions
130
              choices:
131
                  yes: "Do"
132
                  no: "Do not"
133
            - allow OVERDUES restrictions triggered by sent notices to be cleared automatically when all overdue items are returned by a patron.
134
        -
129
            - pref: AllowNotForLoanOverride
135
            - pref: AllowNotForLoanOverride
130
              choices:
136
              choices:
131
                  yes: Allow
137
                  yes: Allow
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (-8 / +6 lines)
Lines 673-686 No patron matched <span class="ex">[% message %]</span> Link Here
673
673
674
            [% IF ( userdebarred ) %]
674
            [% IF ( userdebarred ) %]
675
               <li class="blocker">
675
               <li class="blocker">
676
               <span class="circ-hlt"> Restricted:</span> Patron's account is restricted [% IF (userdebarreddate ) %] until [% userdebarreddate %] [% END %] [% IF (debarredcomment ) %] with the comment "[% debarredcomment %]"[% END %]
676
                   <span class="circ-hlt"> Restricted:</span> Patron's account is restricted [% IF (userdebarreddate ) %] until [% userdebarreddate %] [% END %] [% IF (debarredcomment ) %] with the comment "[% debarredcomment %]"[% END %]
677
               <form class="inline compact" action="/cgi-bin/koha/members/setstatus.pl" method="post">
677
                   <a href="#reldebarments" onclick="$('#debarments-tab-link').click()">View restrictions</a>
678
	                <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
678
               </li>
679
	                <input type="hidden" name="destination" value="circ" />
679
            [% END %]
680
	                <input type="hidden" name="cardnumber" value="[% cardnumber %]" />
681
	                <input type="submit" value="Lift restriction" />
682
               </form>
683
			</li>[% END %]
684
680
685
        	[% IF ( odues ) %]<li>[% IF ( nonreturns ) %]<span class="circ-hlt">Overdues:</span> Patron has <span class="circ-hlt">ITEMS OVERDUE</span>. See highlighted items <a href="#checkouts">below</a>[% END %]</li>
681
        	[% IF ( odues ) %]<li>[% IF ( nonreturns ) %]<span class="circ-hlt">Overdues:</span> Patron has <span class="circ-hlt">ITEMS OVERDUE</span>. See highlighted items <a href="#checkouts">below</a>[% END %]</li>
686
            [% END %]
682
            [% END %]
Lines 780-785 No patron matched <span class="ex">[% message %]</span> Link Here
780
    [% ELSE %]
776
    [% ELSE %]
781
            <a href="#reserves">0 Holds</a>
777
            <a href="#reserves">0 Holds</a>
782
    [% END %]</li>
778
    [% END %]</li>
779
    <li><a id="debarments-tab-link" href="#reldebarments">[% debarments.size %] Restrictions</a></li>
783
780
784
</ul>
781
</ul>
785
782
Lines 1092-1097 No patron matched <span class="ex">[% message %]</span> Link Here
1092
</div>
1089
</div>
1093
[% END %]<!-- end displayrelissues -->
1090
[% END %]<!-- end displayrelissues -->
1094
1091
1092
[% INCLUDE borrower_debarments.inc %]
1095
1093
1096
<div id="reserves">
1094
<div id="reserves">
1097
[% IF ( reservloop ) %]
1095
[% IF ( reservloop ) %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt (-31 / +45 lines)
Lines 1-3 Link Here
1
[% USE KohaDates %]
1
[% INCLUDE 'doc-head-open.inc' %]
2
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Patrons &rsaquo; 
3
<title>Koha &rsaquo; Patrons &rsaquo; 
3
[% IF ( opadd ) %]Add[% ELSIF ( opduplicate ) %]Duplicate[% ELSE %] Modify[% END %] [% IF ( categoryname ) %] [% categoryname %] patron[% ELSE %][% IF ( I ) %] Organization patron[% END %][% IF ( A ) %] Adult patron[% END %][% IF ( C ) %] Child patron[% END %][% IF ( P ) %] Professional patron[% END %][% IF ( S ) %] Staff patron[% END %][% END %][% UNLESS ( opadd ) %] [% surname %], [% firstname %][% END %]</title>
4
[% IF ( opadd ) %]Add[% ELSIF ( opduplicate ) %]Duplicate[% ELSE %] Modify[% END %] [% IF ( categoryname ) %] [% categoryname %] patron[% ELSE %][% IF ( I ) %] Organization patron[% END %][% IF ( A ) %] Adult patron[% END %][% IF ( C ) %] Child patron[% END %][% IF ( P ) %] Professional patron[% END %][% IF ( S ) %] Staff patron[% END %][% END %][% UNLESS ( opadd ) %] [% surname %], [% firstname %][% END %]</title>
Lines 1275-1281 Link Here
1275
			[% FOREACH flagloo IN flagloop %]
1276
			[% FOREACH flagloo IN flagloop %]
1276
				<li><label class="radio" for="yes[% flagloo.name %]">
1277
				<li><label class="radio" for="yes[% flagloo.name %]">
1277
                [% IF ( flagloo.key == 'gonenoaddress' ) %]Gone no address:[% END %]
1278
                [% IF ( flagloo.key == 'gonenoaddress' ) %]Gone no address:[% END %]
1278
				[% IF ( flagloo.key == 'debarred' ) %]Restricted:[% END %]
1279
                [% IF ( flagloo.key == 'lost' ) %]Lost card:[% END %]
1279
                [% IF ( flagloo.key == 'lost' ) %]Lost card:[% END %]
1280
                </label>
1280
                </label>
1281
				<label for="yes[% flagloo.name %]">Yes </label>
1281
				<label for="yes[% flagloo.name %]">Yes </label>
Lines 1293-1332 Link Here
1293
1293
1294
            </li>
1294
            </li>
1295
			[% END %]
1295
			[% END %]
1296
			<li>
1297
				<label for="yesdebarred" class="radio">Restricted: </label>
1298
				[% IF ( debarred ) %]
1299
				<label for="yesdebarred">Yes </label>
1300
				<input type="radio" id="yesdebarred" name="debarred" value="1" checked="checked"/>
1301
                <label for="nodebarred">No </label>
1302
                <input type="radio" id="nodebarred" name="debarred" value="0"/>
1303
				[% ELSE %]
1304
				<label for="yesdebarred">Yes </label>
1305
				<input type="radio" id="yesdebarred" name="debarred" value="1" />
1306
                <label for="nodebarred">No </label>
1307
                <input type="radio" id="nodebarred" name="debarred" value="0" checked="checked"/>
1308
				[% END %]
1309
1310
                <span id="debarreduntil"><label for="datedebarred" class="inline">Until:</label>
1311
                                [% IF opduplicate %]
1312
                                    <input type="text" name="datedebarred" id="datedebarred" class="debarred datepicker" value="[% datedebarred %]" onclick="this.value=''" />
1313
                                [% ELSE %]
1314
                                    <input type="text" name="datedebarred" id="datedebarred" class="debarred datepicker" value="[% datedebarred %]" />
1315
                                [% END %]
1316
                <span class="hint">(optional)</span> </span>
1317
                </li>
1318
                <li>
1319
		        <label for="debarredcomment" class="radio">Comment:</label>
1320
			       [% IF ( opduplicate ) %] 
1321
			           <textarea id="debarredcomment" name="debarredcomment" cols="55" rows="3" onclick="this.value=''">[% debarredcomment %]</textarea>
1322
			       [% ELSE %]
1323
				   <textarea id="debarredcomment" name="debarredcomment" cols="55" rows="3">[% debarredcomment %]</textarea>
1324
			       [% END %]
1325
	        </li>
1326
1296
1327
			</ol>
1297
			</ol>
1328
			</fieldset>
1298
			</fieldset>
1329
    
1299
    
1300
              <fieldset class="rows">
1301
                <legend>Patron restrictions</legend>
1302
1303
                [% UNLESS debarments %]<p>Patron is currently unrestricted.</p>[% END %]
1304
1305
                <table>
1306
                    <thead>
1307
                        <tr>
1308
                             <th>Type</th>
1309
                             <th>Comment</th>
1310
                             <th>Expiration</th>
1311
                             <th>Remove?</th>
1312
                        </tr>
1313
                    </thead>
1314
1315
                    <tbody>
1316
                        [% FOREACH d IN debarments %]
1317
                            <tr>
1318
                                <td>[% d.type %]</td>
1319
                                <td>[% d.comment %]</td>
1320
                                <td>[% IF d.expiration %] [% d.expiration | $KohaDates %] [% ELSE %] <i>Indefinite</i> [% END %]</td>
1321
                                <td>
1322
                                    <input type="checkbox" id="debarment_[% d.borrower_debarment_id %]" name="remove_debarment" value="[% d.borrower_debarment_id %]" />
1323
                                </td>
1324
                            </tr>
1325
                        [% END %]
1326
                    </tbody>
1327
1328
                    <tfoot>
1329
                        <tr>
1330
                            <td>
1331
                                Add new
1332
                                <input type="checkbox" id="add_debarment" name="add_debarment" value="1" />
1333
                            </td>
1334
                            <td><input type="text" id="debarred_comment" name="debarred_comment" onchange="$('#add_debarment').prop('checked', true);" /></td>
1335
                            <td>
1336
                                <input name="debarred_expiration" id="debarred_expiration" size="10" readonly="readonly" value="" class="datepicker" onchange="$('#add_debarment').prop('checked', true);" />
1337
                                <a href='javascript:void(0)' onclick="$('#debarred_expiration').val('');">Clear date</a>
1338
                            </td>
1339
                            <td><a class="btn" href='javascript:void(0)' onclick="$('#debarred_expiration').val(''); $('#add_debarment').prop('checked', false); $('#debarred_comment').val('');">Clear new restriction</a></td>
1340
                        </tr>
1341
                    </tfoot>
1342
                </table>
1343
            </fieldset>
1330
		[% END %]
1344
		[% END %]
1331
1345
1332
[% END %]
1346
[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (-4 / +4 lines)
Lines 194-203 function validate1(date) { Link Here
194
        <ul>
194
        <ul>
195
        [% IF ( userdebarred ) %]
195
        [% IF ( userdebarred ) %]
196
            <li class="blocker">Patron is restricted[% IF ( userdebarreddate ) %] until [% userdebarreddate%] [% IF (debarredcomment ) %]([% debarredcomment %])[% END %][% END %]
196
            <li class="blocker">Patron is restricted[% IF ( userdebarreddate ) %] until [% userdebarreddate%] [% IF (debarredcomment ) %]([% debarredcomment %])[% END %][% END %]
197
            <form class="inline compact" action="/cgi-bin/koha/members/setdebar.pl" method="post">
197
            <a href="#reldebarments" onclick="$('#debarments-tab-link').click()">View restrictions</a>
198
                <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
199
                <input type="submit" value="Lift restriction" />
200
            </form>
201
            </li>
198
            </li>
202
        [% END %]
199
        [% END %]
203
        [% IF ( gonenoaddress ) %]<li class="blocker">Patron's address is in doubt.</li>[% END %]
200
        [% IF ( gonenoaddress ) %]<li class="blocker">Patron's address is in doubt.</li>[% END %]
Lines 439-444 function validate1(date) { Link Here
439
            <a href="#onhold">[% countreserv %] Hold(s)</a>    [% ELSE %]
436
            <a href="#onhold">[% countreserv %] Hold(s)</a>    [% ELSE %]
440
            <a href="#onhold">0 Holds</a>
437
            <a href="#onhold">0 Holds</a>
441
    [% END %]</li>
438
    [% END %]</li>
439
        <li><a id="debarments-tab-link" href="#reldebarments">[% debarments.size %] Restrictions</a></li>
442
    </ul>
440
    </ul>
443
441
444
    <form action="/cgi-bin/koha/reserve/renewscript.pl" method="post" class="checkboxed">
442
    <form action="/cgi-bin/koha/reserve/renewscript.pl" method="post" class="checkboxed">
Lines 614-619 function validate1(date) { Link Here
614
    [% END %]
612
    [% END %]
615
</div>
613
</div>
616
614
615
[% INCLUDE borrower_debarments.inc %]
616
617
<div id="onhold">
617
<div id="onhold">
618
[% IF ( reservloop ) %]
618
[% IF ( reservloop ) %]
619
<form action="/cgi-bin/koha/reserve/modrequest.pl" method="post">
619
<form action="/cgi-bin/koha/reserve/modrequest.pl" method="post">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/modborrowers.tt (-6 lines)
Lines 210-216 Link Here
210
                                                <th>Category</th>
210
                                                <th>Category</th>
211
                                                <th>Registration date</th>
211
                                                <th>Registration date</th>
212
                                                <th>Expiry date</th>
212
                                                <th>Expiry date</th>
213
                                                <th>Restricted</th>
214
                                                [% FOREACH attrh IN attributes_header %]
213
                                                [% FOREACH attrh IN attributes_header %]
215
                                                    <th>[% attrh.attribute %]</th>
214
                                                    <th>[% attrh.attribute %]</th>
216
                                                [% END %]
215
                                                [% END %]
Lines 229-235 Link Here
229
                                                    <td>[% borrower.categorycode %]</td>
228
                                                    <td>[% borrower.categorycode %]</td>
230
                                                    <td>[% borrower.dateenrolled | $KohaDates %]</td>
229
                                                    <td>[% borrower.dateenrolled | $KohaDates %]</td>
231
                                                    <td>[% borrower.dateexpiry | $KohaDates %]</td>
230
                                                    <td>[% borrower.dateexpiry | $KohaDates %]</td>
232
                                                    <td>[% borrower.debarred | $KohaDates %]</td>
233
                                                    [% FOREACH pa IN borrower.patron_attributes %]
231
                                                    [% FOREACH pa IN borrower.patron_attributes %]
234
                                                        [% IF ( pa.code ) %]
232
                                                        [% IF ( pa.code ) %]
235
                                                            <td>[% pa.code %]=[% pa.value %]</td>
233
                                                            <td>[% pa.code %]=[% pa.value %]</td>
Lines 274-283 Link Here
274
                                                Registration date:
272
                                                Registration date:
275
                                                [% CASE 'dateexpiry' %]
273
                                                [% CASE 'dateexpiry' %]
276
                                                Expiry date:
274
                                                Expiry date:
277
                                                [% CASE 'debarred' %]
278
                                                Restricted:
279
                                                [% CASE 'debarredcomment' %]
280
                                                Restriction comment:
281
                                                [% CASE 'borrowernotes' %]
275
                                                [% CASE 'borrowernotes' %]
282
                                                Circulation note:
276
                                                Circulation note:
283
                                            [% END %]
277
                                            [% END %]
(-)a/members/memberentry.pl (-13 / +27 lines)
Lines 41-46 use C4::Log; Link Here
41
use C4::Letters;
41
use C4::Letters;
42
use C4::Branch; # GetBranches
42
use C4::Branch; # GetBranches
43
use C4::Form::MessagingPreferences;
43
use C4::Form::MessagingPreferences;
44
use Koha::Borrower::Debarments;
45
use Koha::DateUtils;
44
46
45
use vars qw($debug);
47
use vars qw($debug);
46
48
Lines 62-67 my ($template, $loggedinuser, $cookie) Link Here
62
           flagsrequired => {borrowers => 1},
64
           flagsrequired => {borrowers => 1},
63
           debug => ($debug) ? 1 : 0,
65
           debug => ($debug) ? 1 : 0,
64
       });
66
       });
67
65
my $guarantorid    = $input->param('guarantorid');
68
my $guarantorid    = $input->param('guarantorid');
66
my $borrowernumber = $input->param('borrowernumber');
69
my $borrowernumber = $input->param('borrowernumber');
67
my $actionType     = $input->param('actionType') || '';
70
my $actionType     = $input->param('actionType') || '';
Lines 90-95 my $borrower_data; Link Here
90
my $NoUpdateLogin;
93
my $NoUpdateLogin;
91
my $userenv = C4::Context->userenv;
94
my $userenv = C4::Context->userenv;
92
95
96
97
## Deal with debarments
98
$template->param(
99
    debarments => GetDebarments( { borrowernumber => $borrowernumber } ) );
100
my @debarments_to_remove = $input->param('remove_debarment');
101
foreach my $d ( @debarments_to_remove ) {
102
    DelDebarment( $d );
103
}
104
if ( $input->param('add_debarment') ) {
105
106
    my $expiration = $input->param('debarred_expiration');
107
    $expiration = $expiration ? output_pref( dt_from_string($expiration), 'iso' ) : undef;
108
109
    AddUniqueDebarment(
110
        {
111
            borrowernumber => $borrowernumber,
112
            type           => 'MANUAL',
113
            comment        => $input->param('debarred_comment'),
114
            expiration     => $expiration,
115
        }
116
    );
117
}
118
93
$template->param("uppercasesurnames" => C4::Context->preference('uppercasesurnames'));
119
$template->param("uppercasesurnames" => C4::Context->preference('uppercasesurnames'));
94
120
95
my $minpw = C4::Context->preference('minPasswordLength');
121
my $minpw = C4::Context->preference('minPasswordLength');
Lines 142-157 if ( $op eq 'insert' || $op eq 'modify' || $op eq 'save' || $op eq 'duplicate' ) Link Here
142
        }
168
        }
143
    }
169
    }
144
170
145
    ## Manipulate debarred
146
    if ( $newdata{debarred} ) {
147
        $newdata{debarred} = $newdata{datedebarred} ? $newdata{datedebarred} : "9999-12-31";
148
    } elsif ( exists( $newdata{debarred} ) && !( $newdata{debarred} ) ) {
149
        undef( $newdata{debarred} );
150
        undef( $newdata{debarredcomment} );
151
    } elsif ( exists( $newdata{debarredcomment} ) && $newdata{debarredcomment} eq "" ) {
152
        undef( $newdata{debarredcomment} );
153
    }
154
    
155
    my $dateobject = C4::Dates->new();
171
    my $dateobject = C4::Dates->new();
156
    my $syspref = $dateobject->regexp();		# same syspref format for all 3 dates
172
    my $syspref = $dateobject->regexp();		# same syspref format for all 3 dates
157
    my $iso     = $dateobject->regexp('iso');	#
173
    my $iso     = $dateobject->regexp('iso');	#
Lines 661-669 if (C4::Context->preference('uppercasesurnames')) { Link Here
661
    $data{'contactname'} &&= uc( $data{'contactname'} );
677
    $data{'contactname'} &&= uc( $data{'contactname'} );
662
}
678
}
663
679
664
$data{debarred} = C4::Overdues::CheckBorrowerDebarred($borrowernumber);
680
foreach (qw(dateenrolled dateexpiry dateofbirth)) {
665
$data{datedebarred} = $data{debarred} if ( $data{debarred} && $data{debarred} ne "9999-12-31" );
666
foreach (qw(dateenrolled dateexpiry dateofbirth datedebarred)) {
667
	$data{$_} = format_date($data{$_});	# back to syspref for display
681
	$data{$_} = format_date($data{$_});	# back to syspref for display
668
	$template->param( $_ => $data{$_});
682
	$template->param( $_ => $data{$_});
669
}
683
}
(-)a/members/mod_debarment.pl (+63 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2013 ByWater Solutions
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use CGI;
23
24
use C4::Auth;
25
use Koha::DateUtils;
26
use Koha::Borrower::Debarments;
27
28
my $cgi = new CGI;
29
30
my ( $loggedinuser, $cookie, $sessionID ) = checkauth( $cgi, 0, { borrowers => 1 } );
31
32
my $borrowernumber = $cgi->param('borrowernumber');
33
my $action         = $cgi->param('action');
34
35
if ( $action eq 'del' ) {
36
    DelDebarment( $cgi->param('borrower_debarment_id') );
37
} elsif ( $action eq 'add' ) {
38
    my $expiration = $cgi->param('expiration');
39
    if ($expiration) {
40
        $expiration = dt_from_string($expiration);
41
        $expiration = $expiration->ymd();
42
    }
43
44
    AddDebarment(
45
        {   borrowernumber => $borrowernumber,
46
            type           => 'MANUAL',
47
            comment        => $cgi->param('comment'),
48
            expiration     => $expiration,
49
        }
50
    );
51
}
52
53
if ( $ENV{HTTP_REFERER} =~ /moremember/ ) {
54
    print $cgi->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$borrowernumber");
55
} else {
56
    print $cgi->redirect("/cgi-bin/koha/circ/circulation.pl?borrowernumber=$borrowernumber");
57
}
58
59
=head1 author
60
61
Kyle M Hall <kyle@bywatersolutions.com>
62
63
=cut
(-)a/members/moremember.pl (-3 / +3 lines)
Lines 48-58 use C4::Koha; Link Here
48
use C4::Letters;
48
use C4::Letters;
49
use C4::Biblio;
49
use C4::Biblio;
50
use C4::Branch; # GetBranchName
50
use C4::Branch; # GetBranchName
51
use C4::Overdues qw/CheckBorrowerDebarred/;
52
use C4::Form::MessagingPreferences;
51
use C4::Form::MessagingPreferences;
53
use List::MoreUtils qw/uniq/;
52
use List::MoreUtils qw/uniq/;
54
use C4::Members::Attributes qw(GetBorrowerAttributes);
53
use C4::Members::Attributes qw(GetBorrowerAttributes);
55
54
use Koha::Borrower::Debarments qw(GetDebarments);
56
#use Smart::Comments;
55
#use Smart::Comments;
57
#use Data::Dumper;
56
#use Data::Dumper;
58
use DateTime;
57
use DateTime;
Lines 147-153 for (qw(gonenoaddress lost borrowernotes)) { Link Here
147
	 $data->{$_} and $template->param(flagged => 1) and last;
146
	 $data->{$_} and $template->param(flagged => 1) and last;
148
}
147
}
149
148
150
my $debar = CheckBorrowerDebarred($borrowernumber);
149
my $debar = $data->{'debarred'};
151
if ($debar) {
150
if ($debar) {
152
    $template->param( 'userdebarred' => 1, 'flagged' => 1 );
151
    $template->param( 'userdebarred' => 1, 'flagged' => 1 );
153
    if ( $debar ne "9999-12-31" ) {
152
    if ( $debar ne "9999-12-31" ) {
Lines 426-431 $template->param( Link Here
426
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
425
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
427
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
426
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
428
    RoutingSerials => C4::Context->preference('RoutingSerials'),
427
    RoutingSerials => C4::Context->preference('RoutingSerials'),
428
    debarments => GetDebarments({ borrowernumber => $borrowernumber }),
429
);
429
);
430
$template->param( $error => 1 ) if $error;
430
$template->param( $error => 1 ) if $error;
431
431
(-)a/members/setdebar.pl (-50 lines)
Lines 1-50 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2000-2002 Katipo Communications
4
# Parts copyright 2011 BibLibre
5
#
6
# This file is part of Koha.
7
#
8
# Koha is free software; you can redistribute it and/or modify it under the
9
# terms of the GNU General Public License as published by the Free Software
10
# Foundation; either version 2 of the License, or (at your option) any later
11
# version.
12
#
13
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License along
18
# with Koha; if not, write to the Free Software Foundation, Inc.,
19
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21
22
=head1 setdebar.pl
23
24
script to set or lift debarred status
25
written 2/8/04
26
by oleonard@athenscounty.lib.oh.us
27
28
=cut
29
30
use strict;
31
use warnings;
32
33
use CGI;
34
use C4::Context;
35
use C4::Auth;
36
37
my $input = new CGI;
38
39
checkauth( $input, 0, { borrowers => 1 }, 'intranet' );
40
41
my $borrowernumber = $input->param('borrowernumber');
42
43
my $dbh = C4::Context->dbh;
44
my $sth =
45
  $dbh->prepare("Update borrowers set debarred = NULL where borrowernumber = ?");
46
$sth->execute( $borrowernumber );
47
$sth->finish;
48
49
print $input->redirect(
50
    "/cgi-bin/koha/members/moremember.pl?borrowernumber=$borrowernumber");
(-)a/misc/cronjobs/overdue_notices.pl (-1 / +11 lines)
Lines 42-47 use C4::Letters; Link Here
42
use C4::Overdues qw(GetFine);
42
use C4::Overdues qw(GetFine);
43
use C4::Budgets qw(GetCurrency);
43
use C4::Budgets qw(GetCurrency);
44
44
45
use Koha::Borrower::Debarments qw(AddUniqueDebarment);
46
use Koha::DateUtils;
47
45
=head1 NAME
48
=head1 NAME
46
49
47
overdue_notices.pl - prepare messages to be sent to patrons for overdue items
50
overdue_notices.pl - prepare messages to be sent to patrons for overdue items
Lines 515-521 END_SQL Link Here
515
                if ( $overdue_rules->{"debarred$i"} ) {
518
                if ( $overdue_rules->{"debarred$i"} ) {
516
    
519
    
517
                    #action taken is debarring
520
                    #action taken is debarring
518
                    C4::Members::DebarMember($borrowernumber, '9999-12-31');
521
                    AddUniqueDebarment(
522
                        {
523
                            borrowernumber => $borrowernumber,
524
                            type           => 'OVERDUES',
525
                            comment => "Restriction added by overdues process "
526
                              . output_pref( dt_from_string() ),
527
                        }
528
                    );
519
                    $verbose and warn "debarring $borr\n";
529
                    $verbose and warn "debarring $borr\n";
520
                }
530
                }
521
                my @params = ($listall ? ( $borrowernumber , 1 , $MAX ) : ( $borrowernumber, $mindays, $maxdays ));
531
                my @params = ($listall ? ( $borrowernumber , 1 , $MAX ) : ( $borrowernumber, $mindays, $maxdays ));
(-)a/opac/opac-reserve.pl (-1 / +1 lines)
Lines 307-313 if ( $borr->{lost} && ($borr->{lost} == 1) ) { Link Here
307
                     lost    => 1
307
                     lost    => 1
308
                    );
308
                    );
309
}
309
}
310
if ( CheckBorrowerDebarred($borrowernumber) ) {
310
if ( $borr->{'debarred'} ) {
311
    $noreserves = 1;
311
    $noreserves = 1;
312
    $template->param(
312
    $template->param(
313
                     message  => 1,
313
                     message  => 1,
(-)a/opac/opac-user.pl (-2 / +1 lines)
Lines 30-36 use C4::Members; Link Here
30
use C4::Members::AttributeTypes;
30
use C4::Members::AttributeTypes;
31
use C4::Members::Attributes qw/GetBorrowerAttributeValue/;
31
use C4::Members::Attributes qw/GetBorrowerAttributeValue/;
32
use C4::Output;
32
use C4::Output;
33
use C4::Overdues qw/CheckBorrowerDebarred/;
34
use C4::Biblio;
33
use C4::Biblio;
35
use C4::Items;
34
use C4::Items;
36
use C4::Letters;
35
use C4::Letters;
Lines 80-86 my ($warning_year, $warning_month, $warning_day) = split /-/, $borr->{'dateexpir Link Here
80
79
81
$borr->{'ethnicity'} = fixEthnicity( $borr->{'ethnicity'} );
80
$borr->{'ethnicity'} = fixEthnicity( $borr->{'ethnicity'} );
82
81
83
my $debar = CheckBorrowerDebarred($borrowernumber);
82
my $debar = $borr->{'debarred'};
84
my $userdebarred;
83
my $userdebarred;
85
84
86
if ($debar) {
85
if ($debar) {
(-)a/t/db_dependent/Borrower_Debarments.t (+102 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
use strict;
4
use warnings;
5
6
use C4::Context;
7
use C4::Members;
8
9
use Test::More tests => 18;
10
11
BEGIN {
12
    use FindBin;
13
    use lib $FindBin::Bin;
14
    use_ok('Koha::Borrower::Debarments');
15
}
16
17
# Get a borrower with no current debarments
18
my $dbh   = C4::Context->dbh;
19
my $query = "
20
    SELECT b.borrowernumber FROM borrowers b
21
    LEFT JOIN borrower_debarments bd ON ( b.borrowernumber = bd.borrowernumber )
22
    WHERE b.debarred IS NULL AND b.debarredcomment IS NULL AND bd.borrowernumber IS NULL
23
    LIMIT 1
24
";
25
my $sth = $dbh->prepare($query);
26
$sth->execute;
27
my ($borrowernumber) = $sth->fetchrow_array();
28
diag("Using borrowernumber: $borrowernumber");
29
30
31
my $success = AddDebarment({
32
    borrowernumber => $borrowernumber,
33
    expiration => '9999-06-10',
34
    type => 'MANUAL',
35
    comment => 'Test 1',
36
});
37
ok( $success, "AddDebarment returned true" );
38
39
40
my $debarments = GetDebarments({ borrowernumber => $borrowernumber });
41
ok( @$debarments == 1, "GetDebarments returns 1 debarment" );
42
ok( $debarments->[0]->{'type'} eq 'MANUAL', "Correctly stored 'type'" );
43
ok( $debarments->[0]->{'expiration'} eq '9999-06-10', "Correctly stored 'expiration'" );
44
ok( $debarments->[0]->{'comment'} eq 'Test 1', "Correctly stored 'comment'" );
45
46
47
$success = AddDebarment({
48
    borrowernumber => $borrowernumber,
49
    comment => 'Test 2',
50
});
51
52
$debarments = GetDebarments({ borrowernumber => $borrowernumber });
53
ok( @$debarments == 2, "GetDebarments returns 2 debarments" );
54
ok( $debarments->[1]->{'type'} eq 'MANUAL', "Correctly stored 'type'" );
55
ok( !$debarments->[1]->{'expiration'}, "Correctly stored debarrment with no expiration" );
56
ok( $debarments->[1]->{'comment'} eq 'Test 2', "Correctly stored 'comment'" );
57
58
59
ModDebarment({
60
    borrower_debarment_id => $debarments->[1]->{'borrower_debarment_id'},
61
    comment => 'Test 3',
62
    expiration => '9998-06-10',
63
});
64
$debarments = GetDebarments({ borrowernumber => $borrowernumber });
65
ok( $debarments->[1]->{'comment'} eq 'Test 3', "ModDebarment functions correctly" );
66
67
68
my $borrower = GetMember( borrowernumber => $borrowernumber );
69
ok( $borrower->{'debarred'} eq '9999-06-10', "Field borrowers.debarred set correctly" );
70
ok( $borrower->{'debarredcomment'} eq "Test 1\nTest 3", "Field borrowers.debarredcomment set correctly" );
71
72
73
AddUniqueDebarment({
74
    borrowernumber => $borrowernumber,
75
    type           => 'OVERDUES'
76
});
77
$debarments = GetDebarments({
78
    borrowernumber => $borrowernumber,
79
    type => 'OVERDUES',
80
});
81
ok( @$debarments == 1, "GetDebarments returns 1 OVERDUES debarment" );
82
ok( $debarments->[0]->{'type'} eq 'OVERDUES', "AddOverduesDebarment created new debarment correctly" );
83
84
AddUniqueDebarment({
85
    borrowernumber => $borrowernumber,
86
    expiration => '9999-11-09',
87
    type => 'OVERDUES'
88
});
89
$debarments = GetDebarments({
90
    borrowernumber => $borrowernumber,
91
    type => 'OVERDUES',
92
});
93
ok( @$debarments == 1, "GetDebarments returns 1 OVERDUES debarment after running AddOverduesDebarment twice" );
94
ok( $debarments->[0]->{'expiration'} eq '9999-11-09', "AddOverduesDebarment updated OVERDUES debarment correctly" );
95
96
97
$debarments = GetDebarments({ borrowernumber => $borrowernumber });
98
foreach my $d ( @$debarments ) {
99
    DelDebarment( $d->{'borrower_debarment_id'} );
100
}
101
$debarments = GetDebarments({ borrowernumber => $borrowernumber });
102
ok( @$debarments == 0, "DelDebarment functions correctly" )
(-)a/t/db_dependent/lib/KohaTest/Members/DebarMember.pm (-44 lines)
Lines 1-44 Link Here
1
package KohaTest::Members::DebarMember;
2
use base qw( KohaTest::Members );
3
4
use strict;
5
use warnings;
6
7
use Test::More;
8
9
use C4::Members;
10
sub testing_class { 'C4::Members' };
11
12
13
sub simple_usage : Test( 6 ) {
14
    my $self = shift;
15
16
    ok( $self->{'memberid'}, 'we have a valid memberid to test with' );
17
18
    my $details = C4::Members::GetMemberDetails( $self->{'memberid'} );
19
    ok(     exists $details->{'flags'},                  'member details has a "flags" attribute');
20
    isa_ok( $details->{'flags'},                 'HASH', 'the "flags" attribute is a hashref');
21
    ok(     ! $details->{'flags'}->{'DBARRED'},          'this member is NOT debarred' );
22
23
    # Now, let's debar this member and see what happens
24
    my $success = C4::Members::DebarMember( $self->{'memberid'}, '2099-12-31' );
25
26
    ok( $success, 'we were able to debar the member' );
27
    
28
    $details = C4::Members::GetMemberDetails( $self->{'memberid'} );
29
    ok( $details->{'flags'}->{'DBARRED'},         'this member is debarred now' )
30
      or diag( Data::Dumper->Dump( [ $details->{'flags'} ], [ 'flags' ] ) );
31
}
32
33
sub incorrect_usage : Test( 2 ) {
34
    my $self = shift;
35
36
    my $result = C4::Members::DebarMember();
37
    ok( ! defined $result, 'DebarMember returns undef when passed no parameters' );
38
39
    $result = C4::Members::DebarMember( 'this is not a borrowernumber' );
40
    ok( ! defined $result, 'DebarMember returns undef when not passed a numeric argument' );
41
42
}
43
44
1;
(-)a/t/db_dependent/lib/KohaTest/Overdues.pm (-1 lines)
Lines 25-31 sub methods : Test( 1 ) { Link Here
25
                       NumberNotifyId
25
                       NumberNotifyId
26
                       AmountNotify
26
                       AmountNotify
27
                       GetItems 
27
                       GetItems 
28
                       CheckBorrowerDebarred
29
                       CheckItemNotify 
28
                       CheckItemNotify 
30
                       GetOverduesForBranch 
29
                       GetOverduesForBranch 
31
                       AddNotifyLine 
30
                       AddNotifyLine 
(-)a/tools/modborrowers.pl (-16 / +3 lines)
Lines 21-27 Link Here
21
#
21
#
22
# Batch Edit Patrons
22
# Batch Edit Patrons
23
# Modification for patron's fields:
23
# Modification for patron's fields:
24
# surname firstname branchcode categorycode sort1 sort2 dateenrolled dateexpiry debarred debarredcomment borrowernotes
24
# surname firstname branchcode categorycode sort1 sort2 dateenrolled dateexpiry borrowernotes
25
# And for patron attributes.
25
# And for patron attributes.
26
26
27
use Modern::Perl;
27
use Modern::Perl;
Lines 206-223 if ( $op eq 'show' ) { Link Here
206
        }
206
        }
207
        ,
207
        ,
208
        {
208
        {
209
            name => "debarred",
210
            type => "date",
211
            mandatory => ( grep /debarred/, @mandatoryFields ) ? 1 : 0,
212
        }
213
        ,
214
        {
215
            name => "debarredcomment",
216
            type => "text",
217
            mandatory => ( grep /debarredcomment/, @mandatoryFields ) ? 1 : 0,
218
        }
219
        ,
220
        {
221
            name => "borrowernotes",
209
            name => "borrowernotes",
222
            type => "text",
210
            type => "text",
223
            mandatory => ( grep /borrowernotes/, @mandatoryFields ) ? 1 : 0,
211
            mandatory => ( grep /borrowernotes/, @mandatoryFields ) ? 1 : 0,
Lines 235-241 if ( $op eq 'do' ) { Link Here
235
223
236
    my @disabled = $input->param('disable_input');
224
    my @disabled = $input->param('disable_input');
237
    my $infos;
225
    my $infos;
238
    for my $field ( qw/surname firstname branchcode categorycode sort1 sort2 dateenrolled dateexpiry debarred debarredcomment borrowernotes/ ) {
226
    for my $field ( qw/surname firstname branchcode categorycode sort1 sort2 dateenrolled dateexpiry borrowernotes/ ) {
239
        my $value = $input->param($field);
227
        my $value = $input->param($field);
240
        $infos->{$field} = $value if $value;
228
        $infos->{$field} = $value if $value;
241
        $infos->{$field} = "" if grep { /^$field$/ } @disabled;
229
        $infos->{$field} = "" if grep { /^$field$/ } @disabled;
Lines 327-333 sub GetBorrowerInfos { Link Here
327
    my $borrower = GetMember( %info );
315
    my $borrower = GetMember( %info );
328
    if ( $borrower ) {
316
    if ( $borrower ) {
329
        $borrower->{branchname} = GetBranchName( $borrower->{branchcode} );
317
        $borrower->{branchname} = GetBranchName( $borrower->{branchcode} );
330
        for ( qw(dateenrolled dateexpiry debarred) ) {
318
        for ( qw(dateenrolled dateexpiry) ) {
331
            my $userdate = $borrower->{$_};
319
            my $userdate = $borrower->{$_};
332
            unless ($userdate && $userdate ne "0000-00-00" and $userdate ne "9999-12-31") {
320
            unless ($userdate && $userdate ne "0000-00-00" and $userdate ne "9999-12-31") {
333
                $borrower->{$_} = '';
321
                $borrower->{$_} = '';
334
- 

Return to bug 2720