1 package Koha::Patron::Debarments;
3 # This file is part of Koha.
5 # Copyright 2013 ByWater Solutions
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
23 use C4::Log qw( logaction );
26 use Koha::Patron::Restriction::Types;
27 use Koha::Patron::Restrictions;
29 our ( @ISA, @EXPORT_OK );
45 =head1 Koha::Patron::Debarments
47 Koha::Patron::Debarments - Module for managing patron debarments
53 my $success = AddDebarment({
54 borrowernumber => $borrowernumber,
55 expiration => $expiration,
56 type => $type, ## enum('FINES','OVERDUES','MANUAL')
60 Creates a new debarment.
62 Required keys: borrowernumber, type
69 my $borrowernumber = $params->{'borrowernumber'};
70 my $expiration = $params->{'expiration'} || undef;
71 my $type = $params->{'type'} || 'MANUAL';
72 my $comment = $params->{'comment'} || undef;
74 return unless ( $borrowernumber && $type );
77 $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
79 my $restriction = Koha::Patron::Restriction->new(
81 borrowernumber => $borrowernumber,
82 expiration => $expiration,
85 manager_id => $manager_id,
89 UpdateBorrowerDebarmentFlags($borrowernumber);
91 logaction( "MEMBERS", "CREATE_RESTRICTION", $borrowernumber, $restriction )
92 if C4::Context->preference("BorrowersLog");
94 return $restriction ? 1 : 0;
99 my $success = DelDebarment( $borrower_debarment_id );
106 my ($borrower_debarment_id) = @_;
108 my $restriction = Koha::Patron::Restrictions->find($borrower_debarment_id);
110 return unless $restriction;
112 Koha::Database->new->schema->txn_do(
114 my $borrowernumber = $restriction->borrowernumber;
115 logaction( "MEMBERS", "DELETE_RESTRICTION", $borrowernumber, $restriction )
116 if C4::Context->preference("BorrowersLog");
118 $restriction->delete;
119 UpdateBorrowerDebarmentFlags($borrowernumber);
128 my $success = ModDebarment({
129 borrower_debarment_id => $borrower_debarment_id,
130 expiration => $expiration,
131 type => $type, ## enum('FINES','OVERDUES','MANUAL','DISCHARGE')
135 Updates an existing debarment.
137 Required keys: borrower_debarment_id
144 my $borrower_debarment_id = $params->{'borrower_debarment_id'};
146 return unless ($borrower_debarment_id);
148 delete( $params->{'borrower_debarment_id'} );
150 delete( $params->{'created'} );
151 delete( $params->{'updated'} );
153 $params->{'manager_id'} = C4::Context->userenv->{'number'} if C4::Context->userenv;
155 my @keys = keys %$params;
156 my @values = values %$params;
158 my $sql = join( ',', map { "$_ = ?" } @keys );
160 $sql = "UPDATE borrower_debarments SET $sql, updated = NOW() WHERE borrower_debarment_id = ?";
162 my $r = C4::Context->dbh->do( $sql, {}, ( @values, $borrower_debarment_id ) );
164 my $borrowernumber = _GetBorrowernumberByDebarmentId($borrower_debarment_id);
165 UpdateBorrowerDebarmentFlags($borrowernumber);
168 "MEMBERS", "MODIFY_RESTRICTION", $borrowernumber,
169 Koha::Patron::Restrictions->find($borrower_debarment_id)
170 ) if C4::Context->preference("BorrowersLog");
175 =head2 AddUniqueDebarment
177 my $success = AddUniqueDebarment({
178 borrowernumber => $borrowernumber,
180 expiration => $expiration,
184 Creates a new debarment of the type defined by the key type.
185 If a unique debarment already exists of the given type, it is updated instead.
186 The current unique debarment types are OVERDUES, and SUSPENSION
188 Required keys: borrowernumber, type
192 sub AddUniqueDebarment {
195 my $borrowernumber = $params->{'borrowernumber'};
196 my $type = $params->{'type'};
198 return unless ( $borrowernumber && $type );
200 my $patron = Koha::Patrons->find($borrowernumber);
201 return unless $patron;
204 $patron->restrictions->search( { type => $type }, { rows => 1 } )->single;
209 # 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
210 $params->{'expiration'} = $debarment->expiration
211 if ( $debarment->expiration
212 && $debarment->expiration gt $params->{'expiration'} );
214 $params->{'borrower_debarment_id'} =
215 $debarment->borrower_debarment_id;
216 $r = ModDebarment($params);
219 $r = AddDebarment($params);
222 UpdateBorrowerDebarmentFlags($borrowernumber);
227 =head2 DelUniqueDebarment
229 my $success = _DelUniqueDebarment({
230 borrowernumber => $borrowernumber,
234 Deletes a unique debarment of the type defined by the key type.
235 The current unique debarment types are OVERDUES, and SUSPENSION
237 Required keys: borrowernumber, type
241 sub DelUniqueDebarment {
244 my $borrowernumber = $params->{'borrowernumber'};
245 my $type = $params->{'type'};
247 return unless ( $borrowernumber && $type );
249 my $patron = Koha::Patrons->find($borrowernumber);
250 return unless $patron;
253 $patron->restrictions->search( { type => $type }, { rows => 1 } )->single;
255 return unless ( $debarment );
257 return DelDebarment( $debarment->borrower_debarment_id );
260 =head2 UpdateBorrowerDebarmentFlags
262 my $success = UpdateBorrowerDebarmentFlags( $borrowernumber );
264 So as not to create additional latency, the fields borrowers.debarred
265 and borrowers.debarredcomment remain in the borrowers table. Whenever
266 the a borrowers debarrments are modified, this subroutine is run to
267 decide if the borrower is currently debarred and update the 'quick flags'
268 in the borrowers table accordingly.
272 sub UpdateBorrowerDebarmentFlags {
273 my ($borrowernumber) = @_;
275 return unless ($borrowernumber);
277 my $dbh = C4::Context->dbh;
280 SELECT COUNT(*), COUNT(*) - COUNT(expiration), MAX(expiration), GROUP_CONCAT(comment SEPARATOR '\n') FROM borrower_debarments
281 WHERE ( expiration > CURRENT_DATE() OR expiration IS NULL ) AND borrowernumber = ?
283 my $sth = $dbh->prepare($sql);
284 $sth->execute($borrowernumber);
285 my ( $count, $indefinite_expiration, $expiration, $comment ) = $sth->fetchrow_array();
288 $expiration = "9999-12-31" if ($indefinite_expiration);
294 return $dbh->do( "UPDATE borrowers SET debarred = ?, debarredcomment = ? WHERE borrowernumber = ?", {}, ( $expiration, $comment, $borrowernumber ) );
297 =head2 del_restrictions_after_payment
299 my $success = del_restrictions_after_payment({
300 borrowernumber => $borrowernumber,
303 Deletes any restrictions from patron by following the rules
304 defined in "Patron restrictions".
308 sub del_restrictions_after_payment {
311 my $borrowernumber = $params->{'borrowernumber'};
312 return unless ($borrowernumber);
314 my $patron = Koha::Patrons->find($borrowernumber);
315 return unless ($patron);
317 my $restrictions = $patron->restrictions;
318 return unless ( $restrictions->count );
320 my $lines = Koha::Account::Lines->search( { borrowernumber => $borrowernumber } );
321 my $total_due = $lines->total_outstanding;
323 while ( my $restriction = $restrictions->next ) {
324 if ( $restriction->type->lift_after_payment
325 && $total_due <= $restriction->type->fee_limit )
327 DelDebarment( $restriction->borrower_debarment_id );
332 =head2 _GetBorrowernumberByDebarmentId
334 my $borrowernumber = _GetBorrowernumberByDebarmentId( $borrower_debarment_id );
338 sub _GetBorrowernumberByDebarmentId {
339 my ($borrower_debarment_id) = @_;
341 return unless ($borrower_debarment_id);
343 my $sql = "SELECT borrowernumber FROM borrower_debarments WHERE borrower_debarment_id = ?";
344 my $sth = C4::Context->dbh->prepare($sql);
345 $sth->execute($borrower_debarment_id);
346 my ($borrowernumber) = $sth->fetchrow_array();
348 return $borrowernumber;
355 Kyle M Hall <kyle@bywatersoltuions.com>