Lines 18-25
package C4::Circulation;
Link Here
|
18 |
# with Koha; if not, write to the Free Software Foundation, Inc., |
18 |
# with Koha; if not, write to the Free Software Foundation, Inc., |
19 |
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 |
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
20 |
|
20 |
|
21 |
|
|
|
22 |
use strict; |
21 |
use strict; |
|
|
22 |
|
23 |
#use warnings; FIXME - Bug 2505 |
23 |
#use warnings; FIXME - Bug 2505 |
24 |
use DateTime; |
24 |
use DateTime; |
25 |
use C4::Context; |
25 |
use C4::Context; |
Lines 34-45
use C4::Accounts;
Link Here
|
34 |
use C4::ItemCirculationAlertPreference; |
34 |
use C4::ItemCirculationAlertPreference; |
35 |
use C4::Message; |
35 |
use C4::Message; |
36 |
use C4::Debug; |
36 |
use C4::Debug; |
37 |
use C4::Branch; # GetBranches |
37 |
use C4::Branch; # GetBranches |
38 |
use C4::Log; # logaction |
38 |
use C4::Log; # logaction |
39 |
use C4::Koha qw( |
39 |
use C4::Koha qw( |
40 |
GetAuthorisedValueByCode |
40 |
GetAuthorisedValueByCode |
41 |
GetAuthValCode |
41 |
GetAuthValCode |
42 |
GetKohaAuthorisedValueLib |
42 |
GetKohaAuthorisedValueLib |
43 |
); |
43 |
); |
44 |
use C4::Overdues qw(CalcFine UpdateFine); |
44 |
use C4::Overdues qw(CalcFine UpdateFine); |
45 |
use Algorithm::CheckDigits; |
45 |
use Algorithm::CheckDigits; |
Lines 62-115
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
Link Here
|
62 |
|
62 |
|
63 |
BEGIN { |
63 |
BEGIN { |
64 |
require Exporter; |
64 |
require Exporter; |
65 |
$VERSION = 3.07.00.049; # for version checking |
65 |
$VERSION = 3.07.00.049; # for version checking |
66 |
@ISA = qw(Exporter); |
66 |
@ISA = qw(Exporter); |
67 |
|
67 |
|
68 |
# FIXME subs that should probably be elsewhere |
68 |
# FIXME subs that should probably be elsewhere |
69 |
push @EXPORT, qw( |
69 |
push @EXPORT, qw( |
70 |
&barcodedecode |
70 |
&barcodedecode |
71 |
&LostItem |
71 |
&LostItem |
72 |
&ReturnLostItem |
72 |
&ReturnLostItem |
73 |
); |
73 |
); |
74 |
|
74 |
|
75 |
# subs to deal with issuing a book |
75 |
# subs to deal with issuing a book |
76 |
push @EXPORT, qw( |
76 |
push @EXPORT, qw( |
77 |
&CanBookBeIssued |
77 |
&CanBookBeIssued |
78 |
&CanBookBeRenewed |
78 |
&CanBookBeRenewed |
79 |
&AddIssue |
79 |
&AddIssue |
80 |
&AddRenewal |
80 |
&AddRenewal |
81 |
&GetRenewCount |
81 |
&GetRenewCount |
82 |
&GetItemIssue |
82 |
&GetItemIssue |
83 |
&GetItemIssues |
83 |
&GetItemIssues |
84 |
&GetIssuingCharges |
84 |
&GetIssuingCharges |
85 |
&GetIssuingRule |
85 |
&GetIssuingRule |
86 |
&GetBranchBorrowerCircRule |
86 |
&GetBranchBorrowerCircRule |
87 |
&GetBranchItemRule |
87 |
&GetBranchItemRule |
88 |
&GetBiblioIssues |
88 |
&GetBiblioIssues |
89 |
&GetOpenIssue |
89 |
&GetOpenIssue |
90 |
&AnonymiseIssueHistory |
90 |
&AnonymiseIssueHistory |
91 |
&CheckIfIssuedToPatron |
91 |
&CheckIfIssuedToPatron |
92 |
&IsItemIssued |
92 |
&IsItemIssued |
93 |
); |
93 |
); |
94 |
|
94 |
|
95 |
# subs to deal with returns |
95 |
# subs to deal with returns |
96 |
push @EXPORT, qw( |
96 |
push @EXPORT, qw( |
97 |
&AddReturn |
97 |
&AddReturn |
98 |
&MarkIssueReturned |
98 |
&MarkIssueReturned |
99 |
); |
99 |
); |
100 |
|
100 |
|
101 |
# subs to deal with transfers |
101 |
# subs to deal with transfers |
102 |
push @EXPORT, qw( |
102 |
push @EXPORT, qw( |
103 |
&transferbook |
103 |
&transferbook |
104 |
&GetTransfers |
104 |
&GetTransfers |
105 |
&GetTransfersFromTo |
105 |
&GetTransfersFromTo |
106 |
&updateWrongTransfer |
106 |
&updateWrongTransfer |
107 |
&DeleteTransfer |
107 |
&DeleteTransfer |
108 |
&CanItemBeTransferred |
108 |
&CanItemBeTransferred |
109 |
&IsBranchTransferAllowed |
109 |
&IsBranchTransferAllowed |
110 |
&CreateBranchTransferLimit |
110 |
&CreateBranchTransferLimit |
111 |
&DeleteBranchTransferLimits |
111 |
&DeleteBranchTransferLimits |
112 |
&TransferSlip |
112 |
&TransferSlip |
113 |
); |
113 |
); |
114 |
|
114 |
|
115 |
# subs to deal with offline circulation |
115 |
# subs to deal with offline circulation |
Lines 159-198
System Pref options.
Link Here
|
159 |
# FIXME -- these plugins should be moved out of Circulation.pm |
159 |
# FIXME -- these plugins should be moved out of Circulation.pm |
160 |
# |
160 |
# |
161 |
sub barcodedecode { |
161 |
sub barcodedecode { |
162 |
my ($barcode, $filter) = @_; |
162 |
my ( $barcode, $filter ) = @_; |
163 |
my $branch = C4::Branch::mybranch(); |
163 |
my $branch = C4::Branch::mybranch(); |
164 |
$filter = C4::Context->preference('itemBarcodeInputFilter') unless $filter; |
164 |
$filter = C4::Context->preference('itemBarcodeInputFilter') unless $filter; |
165 |
$filter or return $barcode; # ensure filter is defined, else return untouched barcode |
165 |
$filter |
166 |
if ($filter eq 'whitespace') { |
166 |
or |
|
|
167 |
return $barcode; # ensure filter is defined, else return untouched barcode |
168 |
if ( $filter eq 'whitespace' ) { |
167 |
$barcode =~ s/\s//g; |
169 |
$barcode =~ s/\s//g; |
168 |
} elsif ($filter eq 'cuecat') { |
170 |
} |
|
|
171 |
elsif ( $filter eq 'cuecat' ) { |
169 |
chomp($barcode); |
172 |
chomp($barcode); |
170 |
my @fields = split( /\./, $barcode ); |
173 |
my @fields = split( /\./, $barcode ); |
171 |
my @results = map( decode($_), @fields[ 1 .. $#fields ] ); |
174 |
my @results = map( decode($_), @fields[ 1 .. $#fields ] ); |
172 |
($#results == 2) and return $results[2]; |
175 |
( $#results == 2 ) and return $results[2]; |
173 |
} elsif ($filter eq 'T-prefix') { |
176 |
} |
174 |
if ($barcode =~ /^[Tt](\d)/) { |
177 |
elsif ( $filter eq 'T-prefix' ) { |
175 |
(defined($1) and $1 eq '0') and return $barcode; |
178 |
if ( $barcode =~ /^[Tt](\d)/ ) { |
176 |
$barcode = substr($barcode, 2) + 0; # FIXME: probably should be substr($barcode, 1) |
179 |
( defined($1) and $1 eq '0' ) and return $barcode; |
177 |
} |
180 |
$barcode = substr( $barcode, 2 ) + |
178 |
return sprintf("T%07d", $barcode); |
181 |
0; # FIXME: probably should be substr($barcode, 1) |
179 |
# FIXME: $barcode could be "T1", causing warning: substr outside of string |
182 |
} |
180 |
# Why drop the nonzero digit after the T? |
183 |
return sprintf( "T%07d", $barcode ); |
181 |
# Why pass non-digits (or empty string) to "T%07d"? |
184 |
|
182 |
} elsif ($filter eq 'libsuite8') { |
185 |
# FIXME: $barcode could be "T1", causing warning: substr outside of string |
183 |
unless($barcode =~ m/^($branch)-/i){ #if barcode starts with branch code its in Koha style. Skip it. |
186 |
# Why drop the nonzero digit after the T? |
184 |
if($barcode =~ m/^(\d)/i){ #Some barcodes even start with 0's & numbers and are assumed to have b as the item type in the libsuite8 software |
187 |
# Why pass non-digits (or empty string) to "T%07d"? |
185 |
$barcode =~ s/^[0]*(\d+)$/$branch-b-$1/i; |
188 |
} |
186 |
}else{ |
189 |
elsif ( $filter eq 'libsuite8' ) { |
|
|
190 |
unless ( $barcode =~ m/^($branch)-/i ) |
191 |
{ #if barcode starts with branch code its in Koha style. Skip it. |
192 |
if ( $barcode =~ m/^(\d)/i ) |
193 |
{ #Some barcodes even start with 0's & numbers and are assumed to have b as the item type in the libsuite8 software |
194 |
$barcode =~ s/^[0]*(\d+)$/$branch-b-$1/i; |
195 |
} |
196 |
else { |
187 |
$barcode =~ s/^(\D+)[0]*(\d+)$/$branch-$1-$2/i; |
197 |
$barcode =~ s/^(\D+)[0]*(\d+)$/$branch-$1-$2/i; |
188 |
} |
198 |
} |
189 |
} |
199 |
} |
190 |
} elsif ($filter eq 'EAN13') { |
200 |
} |
|
|
201 |
elsif ( $filter eq 'EAN13' ) { |
191 |
my $ean = CheckDigits('ean'); |
202 |
my $ean = CheckDigits('ean'); |
192 |
if ( $ean->is_valid($barcode) ) { |
203 |
if ( $ean->is_valid($barcode) ) { |
193 |
#$barcode = sprintf('%013d',$barcode); # this doesn't work on 32-bit systems |
204 |
|
|
|
205 |
#$barcode = sprintf('%013d',$barcode); # this doesn't work on 32-bit systems |
194 |
$barcode = '0' x ( 13 - length($barcode) ) . $barcode; |
206 |
$barcode = '0' x ( 13 - length($barcode) ) . $barcode; |
195 |
} else { |
207 |
} |
|
|
208 |
else { |
196 |
warn "# [$barcode] not valid EAN-13/UPC-A\n"; |
209 |
warn "# [$barcode] not valid EAN-13/UPC-A\n"; |
197 |
} |
210 |
} |
198 |
} |
211 |
} |
Lines 219-224
sub decode {
Link Here
|
219 |
my $l = ( $#s + 1 ) % 4; |
232 |
my $l = ( $#s + 1 ) % 4; |
220 |
if ($l) { |
233 |
if ($l) { |
221 |
if ( $l == 1 ) { |
234 |
if ( $l == 1 ) { |
|
|
235 |
|
222 |
# warn "Error: Cuecat decode parsing failed!"; |
236 |
# warn "Error: Cuecat decode parsing failed!"; |
223 |
return; |
237 |
return; |
224 |
} |
238 |
} |
Lines 230-237
sub decode {
Link Here
|
230 |
my $n = ( ( $s[0] << 6 | $s[1] ) << 6 | $s[2] ) << 6 | $s[3]; |
244 |
my $n = ( ( $s[0] << 6 | $s[1] ) << 6 | $s[2] ) << 6 | $s[3]; |
231 |
$r .= |
245 |
$r .= |
232 |
chr( ( $n >> 16 ) ^ 67 ) |
246 |
chr( ( $n >> 16 ) ^ 67 ) |
233 |
.chr( ( $n >> 8 & 255 ) ^ 67 ) |
247 |
. chr( ( $n >> 8 & 255 ) ^ 67 ) |
234 |
.chr( ( $n & 255 ) ^ 67 ); |
248 |
. chr( ( $n & 255 ) ^ 67 ); |
235 |
@s = @s[ 4 .. $#s ]; |
249 |
@s = @s[ 4 .. $#s ]; |
236 |
} |
250 |
} |
237 |
$r = substr( $r, 0, length($r) - $l ); |
251 |
$r = substr( $r, 0, length($r) - $l ); |
Lines 299-310
The item was eligible to be transferred. Barring problems communicating with the
Link Here
|
299 |
sub transferbook { |
313 |
sub transferbook { |
300 |
my ( $tbr, $barcode, $ignoreRs ) = @_; |
314 |
my ( $tbr, $barcode, $ignoreRs ) = @_; |
301 |
my $messages; |
315 |
my $messages; |
302 |
my $dotransfer = 1; |
316 |
my $dotransfer = 1; |
303 |
my $branches = GetBranches(); |
317 |
my $branches = GetBranches(); |
304 |
my $item = GetItem(undef,$barcode,undef); |
318 |
my $item = GetItem( undef, $barcode, undef ); |
305 |
my $itemnumber = $item->{itemnumber}; |
319 |
my $itemnumber = $item->{itemnumber}; |
306 |
my $issue = GetItemIssue($itemnumber); |
320 |
my $issue = GetItemIssue($itemnumber); |
307 |
my $biblio = GetBiblioFromItemNumber($itemnumber); |
321 |
my $biblio = GetBiblioFromItemNumber($itemnumber); |
308 |
|
322 |
|
309 |
# bad barcode.. |
323 |
# bad barcode.. |
310 |
if ( not $itemnumber ) { |
324 |
if ( not $itemnumber ) { |
Lines 318-325
sub transferbook {
Link Here
|
318 |
|
332 |
|
319 |
# if using Branch Transfer Limits |
333 |
# if using Branch Transfer Limits |
320 |
my $errMsg; |
334 |
my $errMsg; |
321 |
($dotransfer, $errMsg) = CanItemBeTransferred( $tbr, $fbr, $item, $biblio ); |
335 |
( $dotransfer, $errMsg ) = |
322 |
if ( ! $dotransfer ) { |
336 |
CanItemBeTransferred( $tbr, $fbr, $item, $biblio ); |
|
|
337 |
if ( !$dotransfer ) { |
323 |
$messages->{'NotAllowed'} = $errMsg; |
338 |
$messages->{'NotAllowed'} = $errMsg; |
324 |
} |
339 |
} |
325 |
|
340 |
|
Lines 336-350
sub transferbook {
Link Here
|
336 |
} |
351 |
} |
337 |
|
352 |
|
338 |
# check if it is still issued to someone, return it... |
353 |
# check if it is still issued to someone, return it... |
339 |
if ($issue->{borrowernumber}) { |
354 |
if ( $issue->{borrowernumber} ) { |
340 |
AddReturn( $barcode, $fbr ); |
355 |
AddReturn( $barcode, $fbr ); |
341 |
$messages->{'WasReturned'} = $issue->{borrowernumber}; |
356 |
$messages->{'WasReturned'} = $issue->{borrowernumber}; |
342 |
} |
357 |
} |
343 |
|
358 |
|
344 |
# find reserves..... |
359 |
# find reserves..... |
345 |
# That'll save a database query. |
360 |
# That'll save a database query. |
346 |
my ( $resfound, $resrec, undef ) = |
361 |
my ( $resfound, $resrec, undef ) = CheckReserves($itemnumber); |
347 |
CheckReserves( $itemnumber ); |
|
|
348 |
if ( $resfound and not $ignoreRs ) { |
362 |
if ( $resfound and not $ignoreRs ) { |
349 |
$resrec->{'ResFound'} = $resfound; |
363 |
$resrec->{'ResFound'} = $resfound; |
350 |
|
364 |
|
Lines 360-408
sub transferbook {
Link Here
|
360 |
$messages->{'WasTransfered'} = 1; |
374 |
$messages->{'WasTransfered'} = 1; |
361 |
|
375 |
|
362 |
} |
376 |
} |
363 |
ModDateLastSeen( $itemnumber ); |
377 |
ModDateLastSeen($itemnumber); |
364 |
return ( $dotransfer, $messages, $biblio ); |
378 |
return ( $dotransfer, $messages, $biblio ); |
365 |
} |
379 |
} |
366 |
|
380 |
|
367 |
|
|
|
368 |
sub TooMany { |
381 |
sub TooMany { |
369 |
my $borrower = shift; |
382 |
my $borrower = shift; |
370 |
my $biblionumber = shift; |
383 |
my $biblionumber = shift; |
371 |
my $item = shift; |
384 |
my $item = shift; |
372 |
my $cat_borrower = $borrower->{'categorycode'}; |
385 |
my $cat_borrower = $borrower->{'categorycode'}; |
373 |
my $dbh = C4::Context->dbh; |
386 |
my $dbh = C4::Context->dbh; |
374 |
my $branch; |
387 |
my $branch; |
|
|
388 |
|
375 |
# Get which branchcode we need |
389 |
# Get which branchcode we need |
376 |
$branch = _GetCircControlBranch($item,$borrower); |
390 |
$branch = _GetCircControlBranch( $item, $borrower ); |
377 |
my $type = (C4::Context->preference('item-level_itypes')) |
391 |
my $type = ( C4::Context->preference('item-level_itypes') ) |
378 |
? $item->{'itype'} # item-level |
392 |
? $item->{'itype'} # item-level |
379 |
: $item->{'itemtype'}; # biblio-level |
393 |
: $item->{'itemtype'}; # biblio-level |
380 |
|
394 |
|
381 |
# given branch, patron category, and item type, determine |
395 |
# given branch, patron category, and item type, determine |
382 |
# applicable issuing rule |
396 |
# applicable issuing rule |
383 |
my $issuing_rule = GetIssuingRule($cat_borrower, $type, $branch); |
397 |
my $issuing_rule = GetIssuingRule( $cat_borrower, $type, $branch ); |
384 |
|
398 |
|
385 |
# if a rule is found and has a loan limit set, count |
399 |
# if a rule is found and has a loan limit set, count |
386 |
# how many loans the patron already has that meet that |
400 |
# how many loans the patron already has that meet that |
387 |
# rule |
401 |
# rule |
388 |
if (defined($issuing_rule) and defined($issuing_rule->{'maxissueqty'})) { |
402 |
if ( defined($issuing_rule) and defined( $issuing_rule->{'maxissueqty'} ) ) |
|
|
403 |
{ |
389 |
my @bind_params; |
404 |
my @bind_params; |
390 |
my $count_query = "SELECT COUNT(*) FROM issues |
405 |
my $count_query = "SELECT COUNT(*) FROM issues |
391 |
JOIN items USING (itemnumber) "; |
406 |
JOIN items USING (itemnumber) "; |
392 |
|
407 |
|
393 |
my $rule_itemtype = $issuing_rule->{itemtype}; |
408 |
my $rule_itemtype = $issuing_rule->{itemtype}; |
394 |
if ($rule_itemtype eq "*") { |
409 |
if ( $rule_itemtype eq "*" ) { |
|
|
410 |
|
395 |
# matching rule has the default item type, so count only |
411 |
# matching rule has the default item type, so count only |
396 |
# those existing loans that don't fall under a more |
412 |
# those existing loans that don't fall under a more |
397 |
# specific rule |
413 |
# specific rule |
398 |
if (C4::Context->preference('item-level_itypes')) { |
414 |
if ( C4::Context->preference('item-level_itypes') ) { |
399 |
$count_query .= " WHERE items.itype NOT IN ( |
415 |
$count_query .= " WHERE items.itype NOT IN ( |
400 |
SELECT itemtype FROM issuingrules |
416 |
SELECT itemtype FROM issuingrules |
401 |
WHERE branchcode = ? |
417 |
WHERE branchcode = ? |
402 |
AND (categorycode = ? OR categorycode = ?) |
418 |
AND (categorycode = ? OR categorycode = ?) |
403 |
AND itemtype <> '*' |
419 |
AND itemtype <> '*' |
404 |
) "; |
420 |
) "; |
405 |
} else { |
421 |
} |
|
|
422 |
else { |
406 |
$count_query .= " JOIN biblioitems USING (biblionumber) |
423 |
$count_query .= " JOIN biblioitems USING (biblionumber) |
407 |
WHERE biblioitems.itemtype NOT IN ( |
424 |
WHERE biblioitems.itemtype NOT IN ( |
408 |
SELECT itemtype FROM issuingrules |
425 |
SELECT itemtype FROM issuingrules |
Lines 414-425
sub TooMany {
Link Here
|
414 |
push @bind_params, $issuing_rule->{branchcode}; |
431 |
push @bind_params, $issuing_rule->{branchcode}; |
415 |
push @bind_params, $issuing_rule->{categorycode}; |
432 |
push @bind_params, $issuing_rule->{categorycode}; |
416 |
push @bind_params, $cat_borrower; |
433 |
push @bind_params, $cat_borrower; |
417 |
} else { |
434 |
} |
|
|
435 |
else { |
418 |
# rule has specific item type, so count loans of that |
436 |
# rule has specific item type, so count loans of that |
419 |
# specific item type |
437 |
# specific item type |
420 |
if (C4::Context->preference('item-level_itypes')) { |
438 |
if ( C4::Context->preference('item-level_itypes') ) { |
421 |
$count_query .= " WHERE items.itype = ? "; |
439 |
$count_query .= " WHERE items.itype = ? "; |
422 |
} else { |
440 |
} |
|
|
441 |
else { |
423 |
$count_query .= " JOIN biblioitems USING (biblionumber) |
442 |
$count_query .= " JOIN biblioitems USING (biblionumber) |
424 |
WHERE biblioitems.itemtype= ? "; |
443 |
WHERE biblioitems.itemtype= ? "; |
425 |
} |
444 |
} |
Lines 429-441
sub TooMany {
Link Here
|
429 |
$count_query .= " AND borrowernumber = ? "; |
448 |
$count_query .= " AND borrowernumber = ? "; |
430 |
push @bind_params, $borrower->{'borrowernumber'}; |
449 |
push @bind_params, $borrower->{'borrowernumber'}; |
431 |
my $rule_branch = $issuing_rule->{branchcode}; |
450 |
my $rule_branch = $issuing_rule->{branchcode}; |
432 |
if ($rule_branch ne "*") { |
451 |
if ( $rule_branch ne "*" ) { |
433 |
if (C4::Context->preference('CircControl') eq 'PickupLibrary') { |
452 |
if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) { |
434 |
$count_query .= " AND issues.branchcode = ? "; |
453 |
$count_query .= " AND issues.branchcode = ? "; |
435 |
push @bind_params, $branch; |
454 |
push @bind_params, $branch; |
436 |
} elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') { |
455 |
} |
|
|
456 |
elsif ( C4::Context->preference('CircControl') eq 'PatronLibrary' ) |
457 |
{ |
437 |
; # if branch is the patron's home branch, then count all loans by patron |
458 |
; # if branch is the patron's home branch, then count all loans by patron |
438 |
} else { |
459 |
} |
|
|
460 |
else { |
439 |
$count_query .= " AND items.homebranch = ? "; |
461 |
$count_query .= " AND items.homebranch = ? "; |
440 |
push @bind_params, $branch; |
462 |
push @bind_params, $branch; |
441 |
} |
463 |
} |
Lines 446-471
sub TooMany {
Link Here
|
446 |
my ($current_loan_count) = $count_sth->fetchrow_array; |
468 |
my ($current_loan_count) = $count_sth->fetchrow_array; |
447 |
|
469 |
|
448 |
my $max_loans_allowed = $issuing_rule->{'maxissueqty'}; |
470 |
my $max_loans_allowed = $issuing_rule->{'maxissueqty'}; |
449 |
if ($current_loan_count >= $max_loans_allowed) { |
471 |
if ( $current_loan_count >= $max_loans_allowed ) { |
450 |
return ($current_loan_count, $max_loans_allowed); |
472 |
return ( $current_loan_count, $max_loans_allowed ); |
451 |
} |
473 |
} |
452 |
} |
474 |
} |
453 |
|
475 |
|
454 |
# Now count total loans against the limit for the branch |
476 |
# Now count total loans against the limit for the branch |
455 |
my $branch_borrower_circ_rule = GetBranchBorrowerCircRule($branch, $cat_borrower); |
477 |
my $branch_borrower_circ_rule = |
456 |
if (defined($branch_borrower_circ_rule->{maxissueqty})) { |
478 |
GetBranchBorrowerCircRule( $branch, $cat_borrower ); |
457 |
my @bind_params = (); |
479 |
if ( defined( $branch_borrower_circ_rule->{maxissueqty} ) ) { |
|
|
480 |
my @bind_params = (); |
458 |
my $branch_count_query = "SELECT COUNT(*) FROM issues |
481 |
my $branch_count_query = "SELECT COUNT(*) FROM issues |
459 |
JOIN items USING (itemnumber) |
482 |
JOIN items USING (itemnumber) |
460 |
WHERE borrowernumber = ? "; |
483 |
WHERE borrowernumber = ? "; |
461 |
push @bind_params, $borrower->{borrowernumber}; |
484 |
push @bind_params, $borrower->{borrowernumber}; |
462 |
|
485 |
|
463 |
if (C4::Context->preference('CircControl') eq 'PickupLibrary') { |
486 |
if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) { |
464 |
$branch_count_query .= " AND issues.branchcode = ? "; |
487 |
$branch_count_query .= " AND issues.branchcode = ? "; |
465 |
push @bind_params, $branch; |
488 |
push @bind_params, $branch; |
466 |
} elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') { |
489 |
} |
|
|
490 |
elsif ( C4::Context->preference('CircControl') eq 'PatronLibrary' ) { |
467 |
; # if branch is the patron's home branch, then count all loans by patron |
491 |
; # if branch is the patron's home branch, then count all loans by patron |
468 |
} else { |
492 |
} |
|
|
493 |
else { |
469 |
$branch_count_query .= " AND items.homebranch = ? "; |
494 |
$branch_count_query .= " AND items.homebranch = ? "; |
470 |
push @bind_params, $branch; |
495 |
push @bind_params, $branch; |
471 |
} |
496 |
} |
Lines 474-481
sub TooMany {
Link Here
|
474 |
my ($current_loan_count) = $branch_count_sth->fetchrow_array; |
499 |
my ($current_loan_count) = $branch_count_sth->fetchrow_array; |
475 |
|
500 |
|
476 |
my $max_loans_allowed = $branch_borrower_circ_rule->{maxissueqty}; |
501 |
my $max_loans_allowed = $branch_borrower_circ_rule->{maxissueqty}; |
477 |
if ($current_loan_count >= $max_loans_allowed) { |
502 |
if ( $current_loan_count >= $max_loans_allowed ) { |
478 |
return ($current_loan_count, $max_loans_allowed); |
503 |
return ( $current_loan_count, $max_loans_allowed ); |
479 |
} |
504 |
} |
480 |
} |
505 |
} |
481 |
|
506 |
|
Lines 562-571
sub itemissues {
Link Here
|
562 |
$data->{'borrower'} = $data2->{'borrowernumber'}; |
587 |
$data->{'borrower'} = $data2->{'borrowernumber'}; |
563 |
} |
588 |
} |
564 |
else { |
589 |
else { |
565 |
$data->{'date_due'} = ($data->{'withdrawn'} eq '1') ? 'Cancelled' : 'Available'; |
590 |
$data->{'date_due'} = |
|
|
591 |
( $data->{'withdrawn'} eq '1' ) ? 'Cancelled' : 'Available'; |
566 |
} |
592 |
} |
567 |
|
593 |
|
568 |
|
|
|
569 |
# Find the last 3 people who borrowed this item. |
594 |
# Find the last 3 people who borrowed this item. |
570 |
$sth2 = $dbh->prepare( |
595 |
$sth2 = $dbh->prepare( |
571 |
"SELECT * FROM old_issues |
596 |
"SELECT * FROM old_issues |
Lines 688-701
if the borrower borrows to much things
Link Here
|
688 |
sub CanBookBeIssued { |
713 |
sub CanBookBeIssued { |
689 |
my ( $borrower, $barcode, $duedate, $inprocess, $ignore_reserves ) = @_; |
714 |
my ( $borrower, $barcode, $duedate, $inprocess, $ignore_reserves ) = @_; |
690 |
my %needsconfirmation; # filled with problems that needs confirmations |
715 |
my %needsconfirmation; # filled with problems that needs confirmations |
691 |
my %issuingimpossible; # filled with problems that causes the issue to be IMPOSSIBLE |
716 |
my %issuingimpossible |
692 |
my %alerts; # filled with messages that shouldn't stop issuing, but the librarian should be aware of. |
717 |
; # filled with problems that causes the issue to be IMPOSSIBLE |
693 |
|
718 |
my %alerts |
694 |
my $item = GetItem(GetItemnumberFromBarcode( $barcode )); |
719 |
; # filled with messages that shouldn't stop issuing, but the librarian should be aware of. |
695 |
my $issue = GetItemIssue($item->{itemnumber}); |
720 |
|
696 |
my $biblioitem = GetBiblioItemData($item->{biblioitemnumber}); |
721 |
my $item = GetItem( GetItemnumberFromBarcode($barcode) ); |
697 |
$item->{'itemtype'}=$item->{'itype'}; |
722 |
my $issue = GetItemIssue( $item->{itemnumber} ); |
698 |
my $dbh = C4::Context->dbh; |
723 |
my $biblioitem = GetBiblioItemData( $item->{biblioitemnumber} ); |
|
|
724 |
$item->{'itemtype'} = $item->{'itype'}; |
725 |
my $dbh = C4::Context->dbh; |
699 |
|
726 |
|
700 |
# MANDATORY CHECKS - unless item exists, nothing else matters |
727 |
# MANDATORY CHECKS - unless item exists, nothing else matters |
701 |
unless ( $item->{barcode} ) { |
728 |
unless ( $item->{barcode} ) { |
Lines 706-720
sub CanBookBeIssued {
Link Here
|
706 |
# |
733 |
# |
707 |
# DUE DATE is OK ? -- should already have checked. |
734 |
# DUE DATE is OK ? -- should already have checked. |
708 |
# |
735 |
# |
709 |
if ($duedate && ref $duedate ne 'DateTime') { |
736 |
if ( $duedate && ref $duedate ne 'DateTime' ) { |
710 |
$duedate = dt_from_string($duedate); |
737 |
$duedate = dt_from_string($duedate); |
711 |
} |
738 |
} |
712 |
my $now = DateTime->now( time_zone => C4::Context->tz() ); |
739 |
my $now = DateTime->now( time_zone => C4::Context->tz() ); |
713 |
unless ( $duedate ) { |
740 |
unless ($duedate) { |
714 |
my $issuedate = $now->clone(); |
741 |
my $issuedate = $now->clone(); |
715 |
|
742 |
|
716 |
my $branch = _GetCircControlBranch($item,$borrower); |
743 |
my $branch = _GetCircControlBranch( $item, $borrower ); |
717 |
my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'}; |
744 |
my $itype = |
|
|
745 |
( C4::Context->preference('item-level_itypes') ) |
746 |
? $item->{'itype'} |
747 |
: $biblioitem->{'itemtype'}; |
718 |
$duedate = CalcDateDue( $issuedate, $itype, $branch, $borrower ); |
748 |
$duedate = CalcDateDue( $issuedate, $itype, $branch, $borrower ); |
719 |
|
749 |
|
720 |
# Offline circ calls AddIssue directly, doesn't run through here |
750 |
# Offline circ calls AddIssue directly, doesn't run through here |
Lines 722-743
sub CanBookBeIssued {
Link Here
|
722 |
} |
752 |
} |
723 |
if ($duedate) { |
753 |
if ($duedate) { |
724 |
my $today = $now->clone(); |
754 |
my $today = $now->clone(); |
725 |
$today->truncate( to => 'minute'); |
755 |
$today->truncate( to => 'minute' ); |
726 |
if (DateTime->compare($duedate,$today) == -1 ) { # duedate cannot be before now |
756 |
if ( DateTime->compare( $duedate, $today ) == -1 ) |
|
|
757 |
{ # duedate cannot be before now |
727 |
$needsconfirmation{INVALID_DATE} = output_pref($duedate); |
758 |
$needsconfirmation{INVALID_DATE} = output_pref($duedate); |
728 |
} |
759 |
} |
729 |
} else { |
760 |
} |
730 |
$issuingimpossible{INVALID_DATE} = output_pref($duedate); |
761 |
else { |
|
|
762 |
$issuingimpossible{INVALID_DATE} = output_pref($duedate); |
731 |
} |
763 |
} |
732 |
|
764 |
|
733 |
# |
765 |
# |
734 |
# BORROWER STATUS |
766 |
# BORROWER STATUS |
735 |
# |
767 |
# |
736 |
if ( $borrower->{'category_type'} eq 'X' && ( $item->{barcode} )) { |
768 |
if ( $borrower->{'category_type'} eq 'X' && ( $item->{barcode} ) ) { |
737 |
# stats only borrower -- add entry to statistics table, and return issuingimpossible{STATS} = 1 . |
769 |
|
738 |
&UpdateStats(C4::Context->userenv->{'branch'},'localuse','','',$item->{'itemnumber'},$item->{'itemtype'},$borrower->{'borrowernumber'}, undef, $item->{'ccode'}); |
770 |
# stats only borrower -- add entry to statistics table, and return issuingimpossible{STATS} = 1 . |
|
|
771 |
&UpdateStats( |
772 |
C4::Context->userenv->{'branch'}, 'localuse', |
773 |
'', '', |
774 |
$item->{'itemnumber'}, $item->{'itemtype'}, |
775 |
$borrower->{'borrowernumber'}, undef, |
776 |
$item->{'ccode'} |
777 |
); |
739 |
ModDateLastSeen( $item->{'itemnumber'} ); |
778 |
ModDateLastSeen( $item->{'itemnumber'} ); |
740 |
return( { STATS => 1 }, {}); |
779 |
return ( { STATS => 1 }, {} ); |
741 |
} |
780 |
} |
742 |
if ( $borrower->{flags}->{GNA} ) { |
781 |
if ( $borrower->{flags}->{GNA} ) { |
743 |
$issuingimpossible{GNA} = 1; |
782 |
$issuingimpossible{GNA} = 1; |
Lines 748-770
sub CanBookBeIssued {
Link Here
|
748 |
if ( $borrower->{flags}->{'DBARRED'} ) { |
787 |
if ( $borrower->{flags}->{'DBARRED'} ) { |
749 |
$issuingimpossible{DEBARRED} = 1; |
788 |
$issuingimpossible{DEBARRED} = 1; |
750 |
} |
789 |
} |
751 |
if ( !defined $borrower->{dateexpiry} || $borrower->{'dateexpiry'} eq '0000-00-00') { |
790 |
if ( !defined $borrower->{dateexpiry} |
|
|
791 |
|| $borrower->{'dateexpiry'} eq '0000-00-00' ) |
792 |
{ |
752 |
$issuingimpossible{EXPIRED} = 1; |
793 |
$issuingimpossible{EXPIRED} = 1; |
753 |
} else { |
794 |
} |
754 |
my ($y, $m, $d) = split /-/,$borrower->{'dateexpiry'}; |
795 |
else { |
755 |
if ($y && $m && $d) { # are we really writing oinvalid dates to borrs |
796 |
my ( $y, $m, $d ) = split /-/, $borrower->{'dateexpiry'}; |
|
|
797 |
if ( $y && $m && $d ) { # are we really writing oinvalid dates to borrs |
756 |
my $expiry_dt = DateTime->new( |
798 |
my $expiry_dt = DateTime->new( |
757 |
year => $y, |
799 |
year => $y, |
758 |
month => $m, |
800 |
month => $m, |
759 |
day => $d, |
801 |
day => $d, |
760 |
time_zone => C4::Context->tz, |
802 |
time_zone => C4::Context->tz, |
761 |
); |
803 |
); |
762 |
$expiry_dt->truncate( to => 'day'); |
804 |
$expiry_dt->truncate( to => 'day' ); |
763 |
my $today = $now->clone()->truncate(to => 'day'); |
805 |
my $today = $now->clone()->truncate( to => 'day' ); |
764 |
if (DateTime->compare($today, $expiry_dt) == 1) { |
806 |
if ( DateTime->compare( $today, $expiry_dt ) == 1 ) { |
765 |
$issuingimpossible{EXPIRED} = 1; |
807 |
$issuingimpossible{EXPIRED} = 1; |
766 |
} |
808 |
} |
767 |
} else { |
809 |
} |
|
|
810 |
else { |
768 |
carp("Invalid expity date in borr"); |
811 |
carp("Invalid expity date in borr"); |
769 |
$issuingimpossible{EXPIRED} = 1; |
812 |
$issuingimpossible{EXPIRED} = 1; |
770 |
} |
813 |
} |
Lines 774-837
sub CanBookBeIssued {
Link Here
|
774 |
# |
817 |
# |
775 |
|
818 |
|
776 |
# DEBTS |
819 |
# DEBTS |
777 |
my ($balance, $non_issue_charges, $other_charges) = |
820 |
my ( $balance, $non_issue_charges, $other_charges ) = |
778 |
C4::Members::GetMemberAccountBalance( $borrower->{'borrowernumber'} ); |
821 |
C4::Members::GetMemberAccountBalance( $borrower->{'borrowernumber'} ); |
779 |
my $amountlimit = C4::Context->preference("noissuescharge"); |
822 |
my $amountlimit = C4::Context->preference("noissuescharge"); |
780 |
my $allowfineoverride = C4::Context->preference("AllowFineOverride"); |
823 |
my $allowfineoverride = C4::Context->preference("AllowFineOverride"); |
781 |
my $allfinesneedoverride = C4::Context->preference("AllFinesNeedOverride"); |
824 |
my $allfinesneedoverride = C4::Context->preference("AllFinesNeedOverride"); |
782 |
if ( C4::Context->preference("IssuingInProcess") ) { |
825 |
if ( C4::Context->preference("IssuingInProcess") ) { |
783 |
if ( $non_issue_charges > $amountlimit && !$inprocess && !$allowfineoverride) { |
826 |
if ( $non_issue_charges > $amountlimit |
|
|
827 |
&& !$inprocess |
828 |
&& !$allowfineoverride ) |
829 |
{ |
784 |
$issuingimpossible{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
830 |
$issuingimpossible{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
785 |
} elsif ( $non_issue_charges > $amountlimit && !$inprocess && $allowfineoverride) { |
831 |
} |
|
|
832 |
elsif ($non_issue_charges > $amountlimit |
833 |
&& !$inprocess |
834 |
&& $allowfineoverride ) |
835 |
{ |
786 |
$needsconfirmation{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
836 |
$needsconfirmation{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
787 |
} elsif ( $allfinesneedoverride && $non_issue_charges > 0 && $non_issue_charges <= $amountlimit && !$inprocess ) { |
837 |
} |
|
|
838 |
elsif ($allfinesneedoverride |
839 |
&& $non_issue_charges > 0 |
840 |
&& $non_issue_charges <= $amountlimit |
841 |
&& !$inprocess ) |
842 |
{ |
788 |
$needsconfirmation{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
843 |
$needsconfirmation{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
789 |
} |
844 |
} |
790 |
} |
845 |
} |
791 |
else { |
846 |
else { |
792 |
if ( $non_issue_charges > $amountlimit && $allowfineoverride ) { |
847 |
if ( $non_issue_charges > $amountlimit && $allowfineoverride ) { |
793 |
$needsconfirmation{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
848 |
$needsconfirmation{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
794 |
} elsif ( $non_issue_charges > $amountlimit && !$allowfineoverride) { |
849 |
} |
|
|
850 |
elsif ( $non_issue_charges > $amountlimit && !$allowfineoverride ) { |
795 |
$issuingimpossible{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
851 |
$issuingimpossible{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
796 |
} elsif ( $non_issue_charges > 0 && $allfinesneedoverride ) { |
852 |
} |
|
|
853 |
elsif ( $non_issue_charges > 0 && $allfinesneedoverride ) { |
797 |
$needsconfirmation{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
854 |
$needsconfirmation{DEBT} = sprintf( "%.2f", $non_issue_charges ); |
798 |
} |
855 |
} |
799 |
} |
856 |
} |
800 |
if ($balance > 0 && $other_charges > 0) { |
857 |
if ( $balance > 0 && $other_charges > 0 ) { |
801 |
$alerts{OTHER_CHARGES} = sprintf( "%.2f", $other_charges ); |
858 |
$alerts{OTHER_CHARGES} = sprintf( "%.2f", $other_charges ); |
802 |
} |
859 |
} |
803 |
|
860 |
|
804 |
my ($blocktype, $count) = C4::Members::IsMemberBlocked($borrower->{'borrowernumber'}); |
861 |
my ( $blocktype, $count ) = |
805 |
if ($blocktype == -1) { |
862 |
C4::Members::IsMemberBlocked( $borrower->{'borrowernumber'} ); |
|
|
863 |
if ( $blocktype == -1 ) { |
806 |
## patron has outstanding overdue loans |
864 |
## patron has outstanding overdue loans |
807 |
if ( C4::Context->preference("OverduesBlockCirc") eq 'block'){ |
865 |
if ( C4::Context->preference("OverduesBlockCirc") eq 'block' ) { |
808 |
$issuingimpossible{USERBLOCKEDOVERDUE} = $count; |
866 |
$issuingimpossible{USERBLOCKEDOVERDUE} = $count; |
809 |
} |
867 |
} |
810 |
elsif ( C4::Context->preference("OverduesBlockCirc") eq 'confirmation'){ |
868 |
elsif ( C4::Context->preference("OverduesBlockCirc") eq 'confirmation' ) |
|
|
869 |
{ |
811 |
$needsconfirmation{USERBLOCKEDOVERDUE} = $count; |
870 |
$needsconfirmation{USERBLOCKEDOVERDUE} = $count; |
812 |
} |
871 |
} |
813 |
} elsif($blocktype == 1) { |
872 |
} |
|
|
873 |
elsif ( $blocktype == 1 ) { |
874 |
|
814 |
# patron has accrued fine days |
875 |
# patron has accrued fine days |
815 |
$issuingimpossible{USERBLOCKEDREMAINING} = $count; |
876 |
$issuingimpossible{USERBLOCKEDREMAINING} = $count; |
816 |
} |
877 |
} |
817 |
|
878 |
|
818 |
# |
879 |
# |
819 |
# JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS |
880 |
# JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS |
820 |
# |
881 |
# |
821 |
my ($current_loan_count, $max_loans_allowed) = TooMany( $borrower, $item->{biblionumber}, $item ); |
882 |
my ( $current_loan_count, $max_loans_allowed ) = |
822 |
# if TooMany max_loans_allowed returns 0 the user doesn't have permission to check out this book |
883 |
TooMany( $borrower, $item->{biblionumber}, $item ); |
823 |
if (defined $max_loans_allowed && $max_loans_allowed == 0) { |
884 |
|
|
|
885 |
# if TooMany max_loans_allowed returns 0 the user doesn't have permission to check out this book |
886 |
if ( defined $max_loans_allowed && $max_loans_allowed == 0 ) { |
824 |
$needsconfirmation{PATRON_CANT} = 1; |
887 |
$needsconfirmation{PATRON_CANT} = 1; |
825 |
} else { |
888 |
} |
826 |
if($max_loans_allowed){ |
889 |
else { |
|
|
890 |
if ($max_loans_allowed) { |
827 |
if ( C4::Context->preference("AllowTooManyOverride") ) { |
891 |
if ( C4::Context->preference("AllowTooManyOverride") ) { |
828 |
$needsconfirmation{TOO_MANY} = 1; |
892 |
$needsconfirmation{TOO_MANY} = 1; |
829 |
$needsconfirmation{current_loan_count} = $current_loan_count; |
893 |
$needsconfirmation{current_loan_count} = $current_loan_count; |
830 |
$needsconfirmation{max_loans_allowed} = $max_loans_allowed; |
894 |
$needsconfirmation{max_loans_allowed} = $max_loans_allowed; |
831 |
} else { |
895 |
} |
832 |
$issuingimpossible{TOO_MANY} = 1; |
896 |
else { |
|
|
897 |
$issuingimpossible{TOO_MANY} = 1; |
833 |
$issuingimpossible{current_loan_count} = $current_loan_count; |
898 |
$issuingimpossible{current_loan_count} = $current_loan_count; |
834 |
$issuingimpossible{max_loans_allowed} = $max_loans_allowed; |
899 |
$issuingimpossible{max_loans_allowed} = $max_loans_allowed; |
835 |
} |
900 |
} |
836 |
} |
901 |
} |
837 |
} |
902 |
} |
Lines 839-883
sub CanBookBeIssued {
Link Here
|
839 |
# |
904 |
# |
840 |
# ITEM CHECKING |
905 |
# ITEM CHECKING |
841 |
# |
906 |
# |
842 |
if ( $item->{'notforloan'} ) |
907 |
if ( $item->{'notforloan'} ) { |
843 |
{ |
908 |
if ( !C4::Context->preference("AllowNotForLoanOverride") ) { |
844 |
if(!C4::Context->preference("AllowNotForLoanOverride")){ |
909 |
$issuingimpossible{NOT_FOR_LOAN} = 1; |
845 |
$issuingimpossible{NOT_FOR_LOAN} = 1; |
|
|
846 |
$issuingimpossible{item_notforloan} = $item->{'notforloan'}; |
910 |
$issuingimpossible{item_notforloan} = $item->{'notforloan'}; |
847 |
}else{ |
911 |
} |
|
|
912 |
else { |
848 |
$needsconfirmation{NOT_FOR_LOAN_FORCING} = 1; |
913 |
$needsconfirmation{NOT_FOR_LOAN_FORCING} = 1; |
849 |
$needsconfirmation{item_notforloan} = $item->{'notforloan'}; |
914 |
$needsconfirmation{item_notforloan} = $item->{'notforloan'}; |
850 |
} |
915 |
} |
851 |
} |
916 |
} |
852 |
else { |
917 |
else { |
853 |
# we have to check itemtypes.notforloan also |
918 |
# we have to check itemtypes.notforloan also |
854 |
if (C4::Context->preference('item-level_itypes')){ |
919 |
if ( C4::Context->preference('item-level_itypes') ) { |
|
|
920 |
|
855 |
# this should probably be a subroutine |
921 |
# this should probably be a subroutine |
856 |
my $sth = $dbh->prepare("SELECT notforloan FROM itemtypes WHERE itemtype = ?"); |
922 |
my $sth = $dbh->prepare( |
857 |
$sth->execute($item->{'itemtype'}); |
923 |
"SELECT notforloan FROM itemtypes WHERE itemtype = ?"); |
858 |
my $notforloan=$sth->fetchrow_hashref(); |
924 |
$sth->execute( $item->{'itemtype'} ); |
859 |
if ($notforloan->{'notforloan'}) { |
925 |
my $notforloan = $sth->fetchrow_hashref(); |
860 |
if (!C4::Context->preference("AllowNotForLoanOverride")) { |
926 |
if ( $notforloan->{'notforloan'} ) { |
861 |
$issuingimpossible{NOT_FOR_LOAN} = 1; |
927 |
if ( !C4::Context->preference("AllowNotForLoanOverride") ) { |
|
|
928 |
$issuingimpossible{NOT_FOR_LOAN} = 1; |
862 |
$issuingimpossible{itemtype_notforloan} = $item->{'itype'}; |
929 |
$issuingimpossible{itemtype_notforloan} = $item->{'itype'}; |
863 |
} else { |
930 |
} |
|
|
931 |
else { |
864 |
$needsconfirmation{NOT_FOR_LOAN_FORCING} = 1; |
932 |
$needsconfirmation{NOT_FOR_LOAN_FORCING} = 1; |
865 |
$needsconfirmation{itemtype_notforloan} = $item->{'itype'}; |
933 |
$needsconfirmation{itemtype_notforloan} = $item->{'itype'}; |
866 |
} |
934 |
} |
867 |
} |
935 |
} |
868 |
} |
936 |
} |
869 |
elsif ($biblioitem->{'notforloan'} == 1){ |
937 |
elsif ( $biblioitem->{'notforloan'} == 1 ) { |
870 |
if (!C4::Context->preference("AllowNotForLoanOverride")) { |
938 |
if ( !C4::Context->preference("AllowNotForLoanOverride") ) { |
871 |
$issuingimpossible{NOT_FOR_LOAN} = 1; |
939 |
$issuingimpossible{NOT_FOR_LOAN} = 1; |
872 |
$issuingimpossible{itemtype_notforloan} = $biblioitem->{'itemtype'}; |
940 |
$issuingimpossible{itemtype_notforloan} = |
873 |
} else { |
941 |
$biblioitem->{'itemtype'}; |
|
|
942 |
} |
943 |
else { |
874 |
$needsconfirmation{NOT_FOR_LOAN_FORCING} = 1; |
944 |
$needsconfirmation{NOT_FOR_LOAN_FORCING} = 1; |
875 |
$needsconfirmation{itemtype_notforloan} = $biblioitem->{'itemtype'}; |
945 |
$needsconfirmation{itemtype_notforloan} = |
|
|
946 |
$biblioitem->{'itemtype'}; |
876 |
} |
947 |
} |
877 |
} |
948 |
} |
878 |
} |
949 |
} |
879 |
if ( $item->{'withdrawn'} && $item->{'withdrawn'} > 0 ) |
950 |
if ( $item->{'withdrawn'} && $item->{'withdrawn'} > 0 ) { |
880 |
{ |
|
|
881 |
$issuingimpossible{WTHDRAWN} = 1; |
951 |
$issuingimpossible{WTHDRAWN} = 1; |
882 |
} |
952 |
} |
883 |
if ( $item->{'restricted'} |
953 |
if ( $item->{'restricted'} |
Lines 885-903
sub CanBookBeIssued {
Link Here
|
885 |
{ |
955 |
{ |
886 |
$issuingimpossible{RESTRICTED} = 1; |
956 |
$issuingimpossible{RESTRICTED} = 1; |
887 |
} |
957 |
} |
888 |
if ( $item->{'itemlost'} && C4::Context->preference("IssueLostItem") ne 'nothing' ) { |
958 |
if ( $item->{'itemlost'} |
|
|
959 |
&& C4::Context->preference("IssueLostItem") ne 'nothing' ) |
960 |
{ |
889 |
my $code = GetAuthorisedValueByCode( 'LOST', $item->{'itemlost'} ); |
961 |
my $code = GetAuthorisedValueByCode( 'LOST', $item->{'itemlost'} ); |
890 |
$needsconfirmation{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'confirm' ); |
962 |
$needsconfirmation{ITEM_LOST} = $code |
891 |
$alerts{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'alert' ); |
963 |
if ( C4::Context->preference("IssueLostItem") eq 'confirm' ); |
|
|
964 |
$alerts{ITEM_LOST} = $code |
965 |
if ( C4::Context->preference("IssueLostItem") eq 'alert' ); |
892 |
} |
966 |
} |
893 |
if ( C4::Context->preference("IndependentBranches") ) { |
967 |
if ( C4::Context->preference("IndependentBranches") ) { |
894 |
my $userenv = C4::Context->userenv; |
968 |
my $userenv = C4::Context->userenv; |
895 |
if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) { |
969 |
if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) { |
896 |
if ( $item->{C4::Context->preference("HomeOrHoldingBranch")} ne $userenv->{branch} ){ |
970 |
if ( $item->{ C4::Context->preference("HomeOrHoldingBranch") } ne |
|
|
971 |
$userenv->{branch} ) |
972 |
{ |
897 |
$issuingimpossible{ITEMNOTSAMEBRANCH} = 1; |
973 |
$issuingimpossible{ITEMNOTSAMEBRANCH} = 1; |
898 |
$issuingimpossible{'itemhomebranch'} = $item->{C4::Context->preference("HomeOrHoldingBranch")}; |
974 |
$issuingimpossible{'itemhomebranch'} = |
|
|
975 |
$item->{ C4::Context->preference("HomeOrHoldingBranch") }; |
899 |
} |
976 |
} |
900 |
$needsconfirmation{BORRNOTSAMEBRANCH} = GetBranchName( $borrower->{'branchcode'} ) |
977 |
$needsconfirmation{BORRNOTSAMEBRANCH} = |
|
|
978 |
GetBranchName( $borrower->{'branchcode'} ) |
901 |
if ( $borrower->{'branchcode'} ne $userenv->{branch} ); |
979 |
if ( $borrower->{'branchcode'} ne $userenv->{branch} ); |
902 |
} |
980 |
} |
903 |
} |
981 |
} |
Lines 905-919
sub CanBookBeIssued {
Link Here
|
905 |
# |
983 |
# |
906 |
# CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER |
984 |
# CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER |
907 |
# |
985 |
# |
908 |
if ( $issue->{borrowernumber} && $issue->{borrowernumber} eq $borrower->{'borrowernumber'} ) |
986 |
if ( $issue->{borrowernumber} |
|
|
987 |
&& $issue->{borrowernumber} eq $borrower->{'borrowernumber'} ) |
909 |
{ |
988 |
{ |
910 |
|
989 |
|
911 |
# Already issued to current borrower. Ask whether the loan should |
990 |
# Already issued to current borrower. Ask whether the loan should |
912 |
# be renewed. |
991 |
# be renewed. |
913 |
my ($CanBookBeRenewed,$renewerror) = CanBookBeRenewed( |
992 |
my ( $CanBookBeRenewed, $renewerror ) = |
914 |
$borrower->{'borrowernumber'}, |
993 |
CanBookBeRenewed( $borrower->{'borrowernumber'}, |
915 |
$item->{'itemnumber'} |
994 |
$item->{'itemnumber'} ); |
916 |
); |
|
|
917 |
if ( $CanBookBeRenewed == 0 ) { # no more renewals allowed |
995 |
if ( $CanBookBeRenewed == 0 ) { # no more renewals allowed |
918 |
$issuingimpossible{NO_MORE_RENEWALS} = 1; |
996 |
$issuingimpossible{NO_MORE_RENEWALS} = 1; |
919 |
} |
997 |
} |
Lines 921-968
sub CanBookBeIssued {
Link Here
|
921 |
$needsconfirmation{RENEW_ISSUE} = 1; |
999 |
$needsconfirmation{RENEW_ISSUE} = 1; |
922 |
} |
1000 |
} |
923 |
} |
1001 |
} |
924 |
elsif ($issue->{borrowernumber}) { |
1002 |
elsif ( $issue->{borrowernumber} ) { |
925 |
|
1003 |
|
926 |
# issued to someone else |
1004 |
# issued to someone else |
927 |
my $currborinfo = C4::Members::GetMember( borrowernumber => $issue->{borrowernumber} ); |
1005 |
my $currborinfo = |
|
|
1006 |
C4::Members::GetMember( borrowernumber => $issue->{borrowernumber} ); |
928 |
|
1007 |
|
929 |
# warn "=>.$currborinfo->{'firstname'} $currborinfo->{'surname'} ($currborinfo->{'cardnumber'})"; |
1008 |
# warn "=>.$currborinfo->{'firstname'} $currborinfo->{'surname'} ($currborinfo->{'cardnumber'})"; |
930 |
$needsconfirmation{ISSUED_TO_ANOTHER} = 1; |
1009 |
$needsconfirmation{ISSUED_TO_ANOTHER} = 1; |
931 |
$needsconfirmation{issued_firstname} = $currborinfo->{'firstname'}; |
1010 |
$needsconfirmation{issued_firstname} = $currborinfo->{'firstname'}; |
932 |
$needsconfirmation{issued_surname} = $currborinfo->{'surname'}; |
1011 |
$needsconfirmation{issued_surname} = $currborinfo->{'surname'}; |
933 |
$needsconfirmation{issued_cardnumber} = $currborinfo->{'cardnumber'}; |
1012 |
$needsconfirmation{issued_cardnumber} = $currborinfo->{'cardnumber'}; |
934 |
$needsconfirmation{issued_borrowernumber} = $currborinfo->{'borrowernumber'}; |
1013 |
$needsconfirmation{issued_borrowernumber} = |
|
|
1014 |
$currborinfo->{'borrowernumber'}; |
935 |
} |
1015 |
} |
936 |
|
1016 |
|
937 |
unless ( $ignore_reserves ) { |
1017 |
unless ($ignore_reserves) { |
|
|
1018 |
|
938 |
# See if the item is on reserve. |
1019 |
# See if the item is on reserve. |
939 |
my ( $restype, $res ) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); |
1020 |
my ( $restype, $res ) = |
|
|
1021 |
C4::Reserves::CheckReserves( $item->{'itemnumber'} ); |
940 |
if ($restype) { |
1022 |
if ($restype) { |
941 |
my $resbor = $res->{'borrowernumber'}; |
1023 |
my $resbor = $res->{'borrowernumber'}; |
942 |
if ( $resbor ne $borrower->{'borrowernumber'} ) { |
1024 |
if ( $resbor ne $borrower->{'borrowernumber'} ) { |
943 |
my ( $resborrower ) = C4::Members::GetMember( borrowernumber => $resbor ); |
1025 |
my ($resborrower) = |
|
|
1026 |
C4::Members::GetMember( borrowernumber => $resbor ); |
944 |
my $branchname = GetBranchName( $res->{'branchcode'} ); |
1027 |
my $branchname = GetBranchName( $res->{'branchcode'} ); |
945 |
if ( $restype eq "Waiting" ) |
1028 |
if ( $restype eq "Waiting" ) { |
946 |
{ |
1029 |
|
947 |
# The item is on reserve and waiting, but has been |
1030 |
# The item is on reserve and waiting, but has been |
948 |
# reserved by some other patron. |
1031 |
# reserved by some other patron. |
949 |
$needsconfirmation{RESERVE_WAITING} = 1; |
1032 |
$needsconfirmation{RESERVE_WAITING} = 1; |
950 |
$needsconfirmation{'resfirstname'} = $resborrower->{'firstname'}; |
1033 |
$needsconfirmation{'resfirstname'} = |
951 |
$needsconfirmation{'ressurname'} = $resborrower->{'surname'}; |
1034 |
$resborrower->{'firstname'}; |
952 |
$needsconfirmation{'rescardnumber'} = $resborrower->{'cardnumber'}; |
1035 |
$needsconfirmation{'ressurname'} = |
953 |
$needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'}; |
1036 |
$resborrower->{'surname'}; |
|
|
1037 |
$needsconfirmation{'rescardnumber'} = |
1038 |
$resborrower->{'cardnumber'}; |
1039 |
$needsconfirmation{'resborrowernumber'} = |
1040 |
$resborrower->{'borrowernumber'}; |
954 |
$needsconfirmation{'resbranchname'} = $branchname; |
1041 |
$needsconfirmation{'resbranchname'} = $branchname; |
955 |
$needsconfirmation{'reswaitingdate'} = format_date($res->{'waitingdate'}); |
1042 |
$needsconfirmation{'reswaitingdate'} = |
|
|
1043 |
format_date( $res->{'waitingdate'} ); |
956 |
} |
1044 |
} |
957 |
elsif ( $restype eq "Reserved" ) { |
1045 |
elsif ( $restype eq "Reserved" ) { |
|
|
1046 |
|
958 |
# The item is on reserve for someone else. |
1047 |
# The item is on reserve for someone else. |
959 |
$needsconfirmation{RESERVED} = 1; |
1048 |
$needsconfirmation{RESERVED} = 1; |
960 |
$needsconfirmation{'resfirstname'} = $resborrower->{'firstname'}; |
1049 |
$needsconfirmation{'resfirstname'} = |
961 |
$needsconfirmation{'ressurname'} = $resborrower->{'surname'}; |
1050 |
$resborrower->{'firstname'}; |
962 |
$needsconfirmation{'rescardnumber'} = $resborrower->{'cardnumber'}; |
1051 |
$needsconfirmation{'ressurname'} = |
963 |
$needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'}; |
1052 |
$resborrower->{'surname'}; |
|
|
1053 |
$needsconfirmation{'rescardnumber'} = |
1054 |
$resborrower->{'cardnumber'}; |
1055 |
$needsconfirmation{'resborrowernumber'} = |
1056 |
$resborrower->{'borrowernumber'}; |
964 |
$needsconfirmation{'resbranchname'} = $branchname; |
1057 |
$needsconfirmation{'resbranchname'} = $branchname; |
965 |
$needsconfirmation{'resreservedate'} = format_date($res->{'reservedate'}); |
1058 |
$needsconfirmation{'resreservedate'} = |
|
|
1059 |
format_date( $res->{'reservedate'} ); |
966 |
} |
1060 |
} |
967 |
} |
1061 |
} |
968 |
} |
1062 |
} |
Lines 971-1019
sub CanBookBeIssued {
Link Here
|
971 |
# CHECK AGE RESTRICTION |
1065 |
# CHECK AGE RESTRICTION |
972 |
# |
1066 |
# |
973 |
|
1067 |
|
974 |
# get $marker from preferences. Could be something like "FSK|PEGI|Alter|Age:" |
1068 |
# get $marker from preferences. Could be something like "FSK|PEGI|Alter|Age:" |
975 |
my $markers = C4::Context->preference('AgeRestrictionMarker' ); |
1069 |
my $markers = C4::Context->preference('AgeRestrictionMarker'); |
976 |
my $bibvalues = $biblioitem->{'agerestriction'}; |
1070 |
my $bibvalues = $biblioitem->{'agerestriction'}; |
977 |
if (($markers)&&($bibvalues)) |
1071 |
if ( ($markers) && ($bibvalues) ) { |
978 |
{ |
1072 |
|
979 |
# Split $bibvalues to something like FSK 16 or PEGI 6 |
1073 |
# Split $bibvalues to something like FSK 16 or PEGI 6 |
980 |
my @values = split ' ', $bibvalues; |
1074 |
my @values = split ' ', $bibvalues; |
981 |
|
1075 |
|
982 |
# Search first occurence of one of the markers |
1076 |
# Search first occurence of one of the markers |
983 |
my @markers = split /\|/, $markers; |
1077 |
my @markers = split /\|/, $markers; |
984 |
my $index = 0; |
1078 |
my $index = 0; |
985 |
my $take = -1; |
1079 |
my $take = -1; |
986 |
for my $value (@values) { |
1080 |
for my $value (@values) { |
987 |
$index ++; |
1081 |
$index++; |
988 |
for my $marker (@markers) { |
1082 |
for my $marker (@markers) { |
989 |
$marker =~ s/^\s+//; #remove leading spaces |
1083 |
$marker =~ s/^\s+//; #remove leading spaces |
990 |
$marker =~ s/\s+$//; #remove trailing spaces |
1084 |
$marker =~ s/\s+$//; #remove trailing spaces |
991 |
if (uc($marker) eq uc($value)) { |
1085 |
if ( uc($marker) eq uc($value) ) { |
992 |
$take = $index; |
1086 |
$take = $index; |
993 |
last; |
1087 |
last; |
994 |
} |
1088 |
} |
995 |
} |
1089 |
} |
996 |
if ($take > -1) { |
1090 |
if ( $take > -1 ) { |
997 |
last; |
1091 |
last; |
998 |
} |
1092 |
} |
999 |
} |
1093 |
} |
|
|
1094 |
|
1000 |
# Index points to the next value |
1095 |
# Index points to the next value |
1001 |
my $restrictionyear = 0; |
1096 |
my $restrictionyear = 0; |
1002 |
if (($take <= $#values) && ($take >= 0)){ |
1097 |
if ( ( $take <= $#values ) && ( $take >= 0 ) ) { |
1003 |
$restrictionyear += $values[$take]; |
1098 |
$restrictionyear += $values[$take]; |
1004 |
} |
1099 |
} |
1005 |
|
1100 |
|
1006 |
if ($restrictionyear > 0) { |
1101 |
if ( $restrictionyear > 0 ) { |
1007 |
if ( $borrower->{'dateofbirth'} ) { |
1102 |
if ( $borrower->{'dateofbirth'} ) { |
1008 |
my @alloweddate = split /-/,$borrower->{'dateofbirth'} ; |
1103 |
my @alloweddate = split /-/, $borrower->{'dateofbirth'}; |
1009 |
$alloweddate[0] += $restrictionyear; |
1104 |
$alloweddate[0] += $restrictionyear; |
|
|
1105 |
|
1010 |
#Prevent runime eror on leap year (invalid date) |
1106 |
#Prevent runime eror on leap year (invalid date) |
1011 |
if (($alloweddate[1] == 2) && ($alloweddate[2] == 29)) { |
1107 |
if ( ( $alloweddate[1] == 2 ) && ( $alloweddate[2] == 29 ) ) { |
1012 |
$alloweddate[2] = 28; |
1108 |
$alloweddate[2] = 28; |
1013 |
} |
1109 |
} |
1014 |
|
1110 |
|
1015 |
if ( Date_to_Days(Today) < Date_to_Days(@alloweddate) -1 ) { |
1111 |
if ( Date_to_Days(Today) < Date_to_Days(@alloweddate) - 1 ) { |
1016 |
if (C4::Context->preference('AgeRestrictionOverride' )) { |
1112 |
if ( C4::Context->preference('AgeRestrictionOverride') ) { |
1017 |
$needsconfirmation{AGE_RESTRICTION} = "$bibvalues"; |
1113 |
$needsconfirmation{AGE_RESTRICTION} = "$bibvalues"; |
1018 |
} |
1114 |
} |
1019 |
else { |
1115 |
else { |
Lines 1069-1094
Returns:
Link Here
|
1069 |
=cut |
1165 |
=cut |
1070 |
|
1166 |
|
1071 |
sub CanBookBeReturned { |
1167 |
sub CanBookBeReturned { |
1072 |
my ($item, $branch) = @_; |
1168 |
my ( $item, $branch ) = @_; |
1073 |
my $allowreturntobranch = C4::Context->preference("AllowReturnToBranch") || 'anywhere'; |
1169 |
my $allowreturntobranch = |
1074 |
|
1170 |
C4::Context->preference("AllowReturnToBranch") || 'anywhere'; |
1075 |
# assume return is allowed to start |
1171 |
|
1076 |
my $allowed = 1; |
1172 |
# assume return is allowed to start |
1077 |
my $message; |
1173 |
my $allowed = 1; |
1078 |
|
1174 |
my $message; |
1079 |
# identify all cases where return is forbidden |
1175 |
|
1080 |
if ($allowreturntobranch eq 'homebranch' && $branch ne $item->{'homebranch'}) { |
1176 |
# identify all cases where return is forbidden |
1081 |
$allowed = 0; |
1177 |
if ( $allowreturntobranch eq 'homebranch' |
1082 |
$message = $item->{'homebranch'}; |
1178 |
&& $branch ne $item->{'homebranch'} ) |
1083 |
} elsif ($allowreturntobranch eq 'holdingbranch' && $branch ne $item->{'holdingbranch'}) { |
1179 |
{ |
1084 |
$allowed = 0; |
1180 |
$allowed = 0; |
1085 |
$message = $item->{'holdingbranch'}; |
1181 |
$message = $item->{'homebranch'}; |
1086 |
} elsif ($allowreturntobranch eq 'homeorholdingbranch' && $branch ne $item->{'homebranch'} && $branch ne $item->{'holdingbranch'}) { |
1182 |
} |
1087 |
$allowed = 0; |
1183 |
elsif ($allowreturntobranch eq 'holdingbranch' |
1088 |
$message = $item->{'homebranch'}; # FIXME: choice of homebranch is arbitrary |
1184 |
&& $branch ne $item->{'holdingbranch'} ) |
1089 |
} |
1185 |
{ |
1090 |
|
1186 |
$allowed = 0; |
1091 |
return ($allowed, $message); |
1187 |
$message = $item->{'holdingbranch'}; |
|
|
1188 |
} |
1189 |
elsif ($allowreturntobranch eq 'homeorholdingbranch' |
1190 |
&& $branch ne $item->{'homebranch'} |
1191 |
&& $branch ne $item->{'holdingbranch'} ) |
1192 |
{ |
1193 |
$allowed = 0; |
1194 |
$message = |
1195 |
$item->{'homebranch'}; # FIXME: choice of homebranch is arbitrary |
1196 |
} |
1197 |
|
1198 |
return ( $allowed, $message ); |
1092 |
} |
1199 |
} |
1093 |
|
1200 |
|
1094 |
=head2 CheckHighHolds |
1201 |
=head2 CheckHighHolds |
Lines 1174-1331
AddIssue does the following things :
Link Here
|
1174 |
=cut |
1281 |
=cut |
1175 |
|
1282 |
|
1176 |
sub AddIssue { |
1283 |
sub AddIssue { |
1177 |
my ( $borrower, $barcode, $datedue, $cancelreserve, $issuedate, $sipmode) = @_; |
1284 |
my ( $borrower, $barcode, $datedue, $cancelreserve, $issuedate, $sipmode ) |
1178 |
my $dbh = C4::Context->dbh; |
1285 |
= @_; |
1179 |
my $barcodecheck=CheckValidBarcode($barcode); |
1286 |
my $dbh = C4::Context->dbh; |
1180 |
if ($datedue && ref $datedue ne 'DateTime') { |
1287 |
my $barcodecheck = CheckValidBarcode($barcode); |
|
|
1288 |
if ( $datedue && ref $datedue ne 'DateTime' ) { |
1181 |
$datedue = dt_from_string($datedue); |
1289 |
$datedue = dt_from_string($datedue); |
1182 |
} |
1290 |
} |
|
|
1291 |
|
1183 |
# $issuedate defaults to today. |
1292 |
# $issuedate defaults to today. |
1184 |
if ( ! defined $issuedate ) { |
1293 |
if ( !defined $issuedate ) { |
1185 |
$issuedate = DateTime->now(time_zone => C4::Context->tz()); |
1294 |
$issuedate = DateTime->now( time_zone => C4::Context->tz() ); |
1186 |
} |
1295 |
} |
1187 |
else { |
1296 |
else { |
1188 |
if ( ref $issuedate ne 'DateTime') { |
1297 |
if ( ref $issuedate ne 'DateTime' ) { |
1189 |
$issuedate = dt_from_string($issuedate); |
1298 |
$issuedate = dt_from_string($issuedate); |
1190 |
|
1299 |
|
1191 |
} |
1300 |
} |
1192 |
} |
1301 |
} |
1193 |
if ($borrower and $barcode and $barcodecheck ne '0'){#??? wtf |
1302 |
if ( $borrower and $barcode and $barcodecheck ne '0' ) { #??? wtf |
1194 |
# find which item we issue |
1303 |
# find which item we issue |
1195 |
my $item = GetItem('', $barcode) or return; # if we don't get an Item, abort. |
1304 |
my $item = GetItem( '', $barcode ) |
1196 |
my $branch = _GetCircControlBranch($item,$borrower); |
1305 |
or return; # if we don't get an Item, abort. |
|
|
1306 |
my $branch = _GetCircControlBranch( $item, $borrower ); |
1197 |
|
1307 |
|
1198 |
# get actual issuing if there is one |
1308 |
# get actual issuing if there is one |
1199 |
my $actualissue = GetItemIssue( $item->{itemnumber}); |
1309 |
my $actualissue = GetItemIssue( $item->{itemnumber} ); |
1200 |
|
1310 |
|
1201 |
# get biblioinformation for this item |
1311 |
# get biblioinformation for this item |
1202 |
my $biblio = GetBiblioFromItemNumber($item->{itemnumber}); |
1312 |
my $biblio = GetBiblioFromItemNumber( $item->{itemnumber} ); |
1203 |
|
1313 |
|
1204 |
# |
1314 |
# |
1205 |
# check if we just renew the issue. |
1315 |
# check if we just renew the issue. |
1206 |
# |
1316 |
# |
1207 |
if ($actualissue->{borrowernumber} eq $borrower->{'borrowernumber'}) { |
1317 |
if ( $actualissue->{borrowernumber} eq $borrower->{'borrowernumber'} ) { |
1208 |
$datedue = AddRenewal( |
1318 |
$datedue = AddRenewal( |
1209 |
$borrower->{'borrowernumber'}, |
1319 |
$borrower->{'borrowernumber'}, |
1210 |
$item->{'itemnumber'}, |
1320 |
$item->{'itemnumber'}, |
1211 |
$branch, |
1321 |
$branch, |
1212 |
$datedue, |
1322 |
$datedue, |
1213 |
$issuedate, # here interpreted as the renewal date |
1323 |
$issuedate, # here interpreted as the renewal date |
1214 |
); |
1324 |
); |
1215 |
} |
1325 |
} |
1216 |
else { |
1326 |
else { |
1217 |
# it's NOT a renewal |
1327 |
# it's NOT a renewal |
1218 |
if ( $actualissue->{borrowernumber}) { |
1328 |
if ( $actualissue->{borrowernumber} ) { |
1219 |
# This book is currently on loan, but not to the person |
1329 |
|
1220 |
# who wants to borrow it now. mark it returned before issuing to the new borrower |
1330 |
# This book is currently on loan, but not to the person |
1221 |
AddReturn( |
1331 |
# who wants to borrow it now. mark it returned before issuing to the new borrower |
1222 |
$item->{'barcode'}, |
1332 |
AddReturn( $item->{'barcode'}, |
1223 |
C4::Context->userenv->{'branch'} |
1333 |
C4::Context->userenv->{'branch'} ); |
1224 |
); |
|
|
1225 |
} |
1334 |
} |
1226 |
|
1335 |
|
1227 |
MoveReserve( $item->{'itemnumber'}, $borrower->{'borrowernumber'}, $cancelreserve ); |
1336 |
MoveReserve( $item->{'itemnumber'}, $borrower->{'borrowernumber'}, |
1228 |
# Starting process for transfer job (checking transfert and validate it if we have one) |
1337 |
$cancelreserve ); |
1229 |
my ($datesent) = GetTransfers($item->{'itemnumber'}); |
1338 |
|
|
|
1339 |
# Starting process for transfer job (checking transfert and validate it if we have one) |
1340 |
my ($datesent) = GetTransfers( $item->{'itemnumber'} ); |
1230 |
if ($datesent) { |
1341 |
if ($datesent) { |
1231 |
# updating line of branchtranfert to finish it, and changing the to branch value, implement a comment for visibility of this case (maybe for stats ....) |
1342 |
|
1232 |
my $sth = |
1343 |
# updating line of branchtranfert to finish it, and changing the to branch value, implement a comment for visibility of this case (maybe for stats ....) |
1233 |
$dbh->prepare( |
1344 |
my $sth = $dbh->prepare( |
1234 |
"UPDATE branchtransfers |
1345 |
"UPDATE branchtransfers |
1235 |
SET datearrived = now(), |
1346 |
SET datearrived = now(), |
1236 |
tobranch = ?, |
1347 |
tobranch = ?, |
1237 |
comments = 'Forced branchtransfer' |
1348 |
comments = 'Forced branchtransfer' |
1238 |
WHERE itemnumber= ? AND datearrived IS NULL" |
1349 |
WHERE itemnumber= ? AND datearrived IS NULL" |
1239 |
); |
1350 |
); |
1240 |
$sth->execute(C4::Context->userenv->{'branch'},$item->{'itemnumber'}); |
1351 |
$sth->execute( C4::Context->userenv->{'branch'}, |
|
|
1352 |
$item->{'itemnumber'} ); |
1241 |
} |
1353 |
} |
1242 |
|
1354 |
|
1243 |
# Record in the database the fact that the book was issued. |
1355 |
# Record in the database the fact that the book was issued. |
1244 |
my $sth = |
1356 |
my $sth = $dbh->prepare( |
1245 |
$dbh->prepare( |
|
|
1246 |
"INSERT INTO issues |
1357 |
"INSERT INTO issues |
1247 |
(borrowernumber, itemnumber,issuedate, date_due, branchcode) |
1358 |
(borrowernumber, itemnumber,issuedate, date_due, branchcode) |
1248 |
VALUES (?,?,?,?,?)" |
1359 |
VALUES (?,?,?,?,?)" |
1249 |
); |
1360 |
); |
1250 |
unless ($datedue) { |
1361 |
unless ($datedue) { |
1251 |
my $itype = ( C4::Context->preference('item-level_itypes') ) ? $biblio->{'itype'} : $biblio->{'itemtype'}; |
1362 |
my $itype = |
1252 |
$datedue = CalcDateDue( $issuedate, $itype, $branch, $borrower ); |
1363 |
( C4::Context->preference('item-level_itypes') ) |
1253 |
|
1364 |
? $biblio->{'itype'} |
1254 |
} |
1365 |
: $biblio->{'itemtype'}; |
1255 |
$datedue->truncate( to => 'minute'); |
1366 |
$datedue = |
1256 |
$sth->execute( |
1367 |
CalcDateDue( $issuedate, $itype, $branch, $borrower ); |
1257 |
$borrower->{'borrowernumber'}, # borrowernumber |
|
|
1258 |
$item->{'itemnumber'}, # itemnumber |
1259 |
$issuedate->strftime('%Y-%m-%d %H:%M:00'), # issuedate |
1260 |
$datedue->strftime('%Y-%m-%d %H:%M:00'), # date_due |
1261 |
C4::Context->userenv->{'branch'} # branchcode |
1262 |
); |
1263 |
if ( C4::Context->preference('ReturnToShelvingCart') ) { ## ReturnToShelvingCart is on, anything issued should be taken off the cart. |
1264 |
CartToShelf( $item->{'itemnumber'} ); |
1265 |
} |
1266 |
$item->{'issues'}++; |
1267 |
if ( C4::Context->preference('UpdateTotalIssuesOnCirc') ) { |
1268 |
UpdateTotalIssues($item->{'biblionumber'}, 1); |
1269 |
} |
1270 |
|
1368 |
|
1271 |
## If item was lost, it has now been found, reverse any list item charges if neccessary. |
|
|
1272 |
if ( $item->{'itemlost'} ) { |
1273 |
if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) { |
1274 |
_FixAccountForLostAndReturned( $item->{'itemnumber'}, undef, $item->{'barcode'} ); |
1275 |
} |
1369 |
} |
1276 |
} |
1370 |
$datedue->truncate( to => 'minute' ); |
|
|
1371 |
$sth->execute( |
1372 |
$borrower->{'borrowernumber'}, # borrowernumber |
1373 |
$item->{'itemnumber'}, # itemnumber |
1374 |
$issuedate->strftime('%Y-%m-%d %H:%M:00'), # issuedate |
1375 |
$datedue->strftime('%Y-%m-%d %H:%M:00'), # date_due |
1376 |
C4::Context->userenv->{'branch'} # branchcode |
1377 |
); |
1378 |
if ( C4::Context->preference('ReturnToShelvingCart') ) |
1379 |
{ ## ReturnToShelvingCart is on, anything issued should be taken off the cart. |
1380 |
CartToShelf( $item->{'itemnumber'} ); |
1381 |
} |
1382 |
$item->{'issues'}++; |
1383 |
if ( C4::Context->preference('UpdateTotalIssuesOnCirc') ) { |
1384 |
UpdateTotalIssues( $item->{'biblionumber'}, 1 ); |
1385 |
} |
1277 |
|
1386 |
|
1278 |
ModItem({ issues => $item->{'issues'}, |
1387 |
## If item was lost, it has now been found, reverse any list item charges if neccessary. |
1279 |
holdingbranch => C4::Context->userenv->{'branch'}, |
1388 |
if ( $item->{'itemlost'} ) { |
1280 |
itemlost => 0, |
1389 |
if ( C4::Context->preference('RefundLostItemFeeOnReturn') ) { |
1281 |
datelastborrowed => DateTime->now(time_zone => C4::Context->tz())->ymd(), |
1390 |
_FixAccountForLostAndReturned( $item->{'itemnumber'}, |
1282 |
onloan => $datedue->ymd(), |
1391 |
undef, $item->{'barcode'} ); |
1283 |
}, $item->{'biblionumber'}, $item->{'itemnumber'}); |
1392 |
} |
1284 |
ModDateLastSeen( $item->{'itemnumber'} ); |
1393 |
} |
1285 |
|
1394 |
|
1286 |
# If it costs to borrow this book, charge it to the patron's account. |
1395 |
ModItem( |
1287 |
my ( $charge, $itemtype ) = GetIssuingCharges( |
1396 |
{ |
1288 |
$item->{'itemnumber'}, |
1397 |
issues => $item->{'issues'}, |
1289 |
$borrower->{'borrowernumber'} |
1398 |
holdingbranch => C4::Context->userenv->{'branch'}, |
1290 |
); |
1399 |
itemlost => 0, |
1291 |
if ( $charge > 0 ) { |
1400 |
datelastborrowed => |
1292 |
AddIssuingCharge( |
1401 |
DateTime->now( time_zone => C4::Context->tz() )->ymd(), |
1293 |
$item->{'itemnumber'}, |
1402 |
onloan => $datedue->ymd(), |
1294 |
$borrower->{'borrowernumber'}, $charge |
1403 |
}, |
|
|
1404 |
$item->{'biblionumber'}, |
1405 |
$item->{'itemnumber'} |
1295 |
); |
1406 |
); |
1296 |
$item->{'charge'} = $charge; |
1407 |
ModDateLastSeen( $item->{'itemnumber'} ); |
1297 |
} |
1408 |
|
|
|
1409 |
# If it costs to borrow this book, charge it to the patron's account. |
1410 |
my ( $charge, $itemtype ) = |
1411 |
GetIssuingCharges( $item->{'itemnumber'}, |
1412 |
$borrower->{'borrowernumber'} ); |
1413 |
if ( $charge > 0 ) { |
1414 |
AddIssuingCharge( $item->{'itemnumber'}, |
1415 |
$borrower->{'borrowernumber'}, $charge ); |
1416 |
$item->{'charge'} = $charge; |
1417 |
} |
1298 |
|
1418 |
|
1299 |
# Record the fact that this book was issued. |
1419 |
# Record the fact that this book was issued. |
1300 |
&UpdateStats( |
1420 |
&UpdateStats( |
1301 |
C4::Context->userenv->{'branch'}, |
1421 |
C4::Context->userenv->{'branch'}, |
1302 |
'issue', $charge, |
1422 |
'issue', |
1303 |
($sipmode ? "SIP-$sipmode" : ''), $item->{'itemnumber'}, |
1423 |
$charge, |
1304 |
$item->{'itype'}, $borrower->{'borrowernumber'}, undef, $item->{'ccode'} |
1424 |
( $sipmode ? "SIP-$sipmode" : '' ), |
1305 |
); |
1425 |
$item->{'itemnumber'}, |
|
|
1426 |
$item->{'itype'}, |
1427 |
$borrower->{'borrowernumber'}, |
1428 |
undef, |
1429 |
$item->{'ccode'} |
1430 |
); |
1306 |
|
1431 |
|
1307 |
# Send a checkout slip. |
1432 |
# Send a checkout slip. |
1308 |
my $circulation_alert = 'C4::ItemCirculationAlertPreference'; |
1433 |
my $circulation_alert = 'C4::ItemCirculationAlertPreference'; |
1309 |
my %conditions = ( |
1434 |
my %conditions = ( |
1310 |
branchcode => $branch, |
1435 |
branchcode => $branch, |
1311 |
categorycode => $borrower->{categorycode}, |
1436 |
categorycode => $borrower->{categorycode}, |
1312 |
item_type => $item->{itype}, |
1437 |
item_type => $item->{itype}, |
1313 |
notification => 'CHECKOUT', |
1438 |
notification => 'CHECKOUT', |
1314 |
); |
1439 |
); |
1315 |
if ($circulation_alert->is_enabled_for(\%conditions)) { |
1440 |
if ( $circulation_alert->is_enabled_for( \%conditions ) ) { |
1316 |
SendCirculationAlert({ |
1441 |
SendCirculationAlert( |
1317 |
type => 'CHECKOUT', |
1442 |
{ |
1318 |
item => $item, |
1443 |
type => 'CHECKOUT', |
1319 |
borrower => $borrower, |
1444 |
item => $item, |
1320 |
branch => $branch, |
1445 |
borrower => $borrower, |
1321 |
}); |
1446 |
branch => $branch, |
|
|
1447 |
} |
1448 |
); |
1449 |
} |
1322 |
} |
1450 |
} |
1323 |
} |
|
|
1324 |
|
1451 |
|
1325 |
logaction("CIRCULATION", "ISSUE", $borrower->{'borrowernumber'}, $biblio->{'itemnumber'}) |
1452 |
logaction( |
1326 |
if C4::Context->preference("IssueLog"); |
1453 |
"CIRCULATION", "ISSUE", |
1327 |
} |
1454 |
$borrower->{'borrowernumber'}, |
1328 |
return ($datedue); # not necessarily the same as when it came in! |
1455 |
$biblio->{'itemnumber'} |
|
|
1456 |
) if C4::Context->preference("IssueLog"); |
1457 |
} |
1458 |
return ($datedue); # not necessarily the same as when it came in! |
1329 |
} |
1459 |
} |
1330 |
|
1460 |
|
1331 |
=head2 GetLoanLength |
1461 |
=head2 GetLoanLength |
Lines 1339-1355
Get loan length for an itemtype, a borrower type and a branch
Link Here
|
1339 |
sub GetLoanLength { |
1469 |
sub GetLoanLength { |
1340 |
my ( $borrowertype, $itemtype, $branchcode ) = @_; |
1470 |
my ( $borrowertype, $itemtype, $branchcode ) = @_; |
1341 |
my $dbh = C4::Context->dbh; |
1471 |
my $dbh = C4::Context->dbh; |
1342 |
my $sth = $dbh->prepare(qq{ |
1472 |
my $sth = $dbh->prepare( |
|
|
1473 |
qq{ |
1343 |
SELECT issuelength, lengthunit, renewalperiod |
1474 |
SELECT issuelength, lengthunit, renewalperiod |
1344 |
FROM issuingrules |
1475 |
FROM issuingrules |
1345 |
WHERE categorycode=? |
1476 |
WHERE categorycode=? |
1346 |
AND itemtype=? |
1477 |
AND itemtype=? |
1347 |
AND branchcode=? |
1478 |
AND branchcode=? |
1348 |
AND issuelength IS NOT NULL |
1479 |
AND issuelength IS NOT NULL |
1349 |
}); |
1480 |
} |
|
|
1481 |
); |
1350 |
|
1482 |
|
1351 |
# try to find issuelength & return the 1st available. |
1483 |
# try to find issuelength & return the 1st available. |
1352 |
# check with borrowertype, itemtype and branchcode, then without one of those parameters |
1484 |
# check with borrowertype, itemtype and branchcode, then without one of those parameters |
1353 |
$sth->execute( $borrowertype, $itemtype, $branchcode ); |
1485 |
$sth->execute( $borrowertype, $itemtype, $branchcode ); |
1354 |
my $loanlength = $sth->fetchrow_hashref; |
1486 |
my $loanlength = $sth->fetchrow_hashref; |
1355 |
|
1487 |
|
Lines 1393-1406
sub GetLoanLength {
Link Here
|
1393 |
|
1525 |
|
1394 |
# if no rule is set => 21 days (hardcoded) |
1526 |
# if no rule is set => 21 days (hardcoded) |
1395 |
return { |
1527 |
return { |
1396 |
issuelength => 21, |
1528 |
issuelength => 21, |
1397 |
renewalperiod => 21, |
1529 |
renewalperiod => 21, |
1398 |
lengthunit => 'days', |
1530 |
lengthunit => 'days', |
1399 |
}; |
1531 |
}; |
1400 |
|
1532 |
|
1401 |
} |
1533 |
} |
1402 |
|
1534 |
|
1403 |
|
|
|
1404 |
=head2 GetHardDueDate |
1535 |
=head2 GetHardDueDate |
1405 |
|
1536 |
|
1406 |
my ($hardduedate,$hardduedatecompare) = &GetHardDueDate($borrowertype,$itemtype,branchcode) |
1537 |
my ($hardduedate,$hardduedatecompare) = &GetHardDueDate($borrowertype,$itemtype,branchcode) |
Lines 1414-1424
sub GetHardDueDate {
Link Here
|
1414 |
|
1545 |
|
1415 |
my $rule = GetIssuingRule( $borrowertype, $itemtype, $branchcode ); |
1546 |
my $rule = GetIssuingRule( $borrowertype, $itemtype, $branchcode ); |
1416 |
|
1547 |
|
1417 |
if ( defined( $rule ) ) { |
1548 |
if ( defined($rule) ) { |
1418 |
if ( $rule->{hardduedate} ) { |
1549 |
if ( $rule->{hardduedate} ) { |
1419 |
return (dt_from_string($rule->{hardduedate}, 'iso'),$rule->{hardduedatecompare}); |
1550 |
return ( dt_from_string( $rule->{hardduedate}, 'iso' ), |
1420 |
} else { |
1551 |
$rule->{hardduedatecompare} ); |
1421 |
return (undef, undef); |
1552 |
} |
|
|
1553 |
else { |
1554 |
return ( undef, undef ); |
1422 |
} |
1555 |
} |
1423 |
} |
1556 |
} |
1424 |
} |
1557 |
} |
Lines 1439-1478
Returns a hashref from the issuingrules table.
Link Here
|
1439 |
sub GetIssuingRule { |
1572 |
sub GetIssuingRule { |
1440 |
my ( $borrowertype, $itemtype, $branchcode ) = @_; |
1573 |
my ( $borrowertype, $itemtype, $branchcode ) = @_; |
1441 |
my $dbh = C4::Context->dbh; |
1574 |
my $dbh = C4::Context->dbh; |
1442 |
my $sth = $dbh->prepare( "select * from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null" ); |
1575 |
my $sth = $dbh->prepare( |
|
|
1576 |
"select * from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null" |
1577 |
); |
1443 |
my $irule; |
1578 |
my $irule; |
1444 |
|
1579 |
|
1445 |
$sth->execute( $borrowertype, $itemtype, $branchcode ); |
1580 |
$sth->execute( $borrowertype, $itemtype, $branchcode ); |
1446 |
$irule = $sth->fetchrow_hashref; |
1581 |
$irule = $sth->fetchrow_hashref; |
1447 |
return $irule if defined($irule) ; |
1582 |
return $irule if defined($irule); |
1448 |
|
1583 |
|
1449 |
$sth->execute( $borrowertype, "*", $branchcode ); |
1584 |
$sth->execute( $borrowertype, "*", $branchcode ); |
1450 |
$irule = $sth->fetchrow_hashref; |
1585 |
$irule = $sth->fetchrow_hashref; |
1451 |
return $irule if defined($irule) ; |
1586 |
return $irule if defined($irule); |
1452 |
|
1587 |
|
1453 |
$sth->execute( "*", $itemtype, $branchcode ); |
1588 |
$sth->execute( "*", $itemtype, $branchcode ); |
1454 |
$irule = $sth->fetchrow_hashref; |
1589 |
$irule = $sth->fetchrow_hashref; |
1455 |
return $irule if defined($irule) ; |
1590 |
return $irule if defined($irule); |
1456 |
|
1591 |
|
1457 |
$sth->execute( "*", "*", $branchcode ); |
1592 |
$sth->execute( "*", "*", $branchcode ); |
1458 |
$irule = $sth->fetchrow_hashref; |
1593 |
$irule = $sth->fetchrow_hashref; |
1459 |
return $irule if defined($irule) ; |
1594 |
return $irule if defined($irule); |
1460 |
|
1595 |
|
1461 |
$sth->execute( $borrowertype, $itemtype, "*" ); |
1596 |
$sth->execute( $borrowertype, $itemtype, "*" ); |
1462 |
$irule = $sth->fetchrow_hashref; |
1597 |
$irule = $sth->fetchrow_hashref; |
1463 |
return $irule if defined($irule) ; |
1598 |
return $irule if defined($irule); |
1464 |
|
1599 |
|
1465 |
$sth->execute( $borrowertype, "*", "*" ); |
1600 |
$sth->execute( $borrowertype, "*", "*" ); |
1466 |
$irule = $sth->fetchrow_hashref; |
1601 |
$irule = $sth->fetchrow_hashref; |
1467 |
return $irule if defined($irule) ; |
1602 |
return $irule if defined($irule); |
1468 |
|
1603 |
|
1469 |
$sth->execute( "*", $itemtype, "*" ); |
1604 |
$sth->execute( "*", $itemtype, "*" ); |
1470 |
$irule = $sth->fetchrow_hashref; |
1605 |
$irule = $sth->fetchrow_hashref; |
1471 |
return $irule if defined($irule) ; |
1606 |
return $irule if defined($irule); |
1472 |
|
1607 |
|
1473 |
$sth->execute( "*", "*", "*" ); |
1608 |
$sth->execute( "*", "*", "*" ); |
1474 |
$irule = $sth->fetchrow_hashref; |
1609 |
$irule = $sth->fetchrow_hashref; |
1475 |
return $irule if defined($irule) ; |
1610 |
return $irule if defined($irule); |
1476 |
|
1611 |
|
1477 |
# if no rule matches, |
1612 |
# if no rule matches, |
1478 |
return; |
1613 |
return; |
Lines 1511-1517
wildcards.
Link Here
|
1511 |
=cut |
1646 |
=cut |
1512 |
|
1647 |
|
1513 |
sub GetBranchBorrowerCircRule { |
1648 |
sub GetBranchBorrowerCircRule { |
1514 |
my $branchcode = shift; |
1649 |
my $branchcode = shift; |
1515 |
my $categorycode = shift; |
1650 |
my $categorycode = shift; |
1516 |
|
1651 |
|
1517 |
my $branch_cat_query = "SELECT maxissueqty |
1652 |
my $branch_cat_query = "SELECT maxissueqty |
Lines 1520-1528
sub GetBranchBorrowerCircRule {
Link Here
|
1520 |
AND categorycode = ?"; |
1655 |
AND categorycode = ?"; |
1521 |
my $dbh = C4::Context->dbh(); |
1656 |
my $dbh = C4::Context->dbh(); |
1522 |
my $sth = $dbh->prepare($branch_cat_query); |
1657 |
my $sth = $dbh->prepare($branch_cat_query); |
1523 |
$sth->execute($branchcode, $categorycode); |
1658 |
$sth->execute( $branchcode, $categorycode ); |
1524 |
my $result; |
1659 |
my $result; |
1525 |
if ($result = $sth->fetchrow_hashref()) { |
1660 |
if ( $result = $sth->fetchrow_hashref() ) { |
1526 |
return $result; |
1661 |
return $result; |
1527 |
} |
1662 |
} |
1528 |
|
1663 |
|
Lines 1532-1538
sub GetBranchBorrowerCircRule {
Link Here
|
1532 |
WHERE branchcode = ?"; |
1667 |
WHERE branchcode = ?"; |
1533 |
$sth = $dbh->prepare($branch_query); |
1668 |
$sth = $dbh->prepare($branch_query); |
1534 |
$sth->execute($branchcode); |
1669 |
$sth->execute($branchcode); |
1535 |
if ($result = $sth->fetchrow_hashref()) { |
1670 |
if ( $result = $sth->fetchrow_hashref() ) { |
1536 |
return $result; |
1671 |
return $result; |
1537 |
} |
1672 |
} |
1538 |
|
1673 |
|
Lines 1542-1564
sub GetBranchBorrowerCircRule {
Link Here
|
1542 |
WHERE categorycode = ?"; |
1677 |
WHERE categorycode = ?"; |
1543 |
$sth = $dbh->prepare($category_query); |
1678 |
$sth = $dbh->prepare($category_query); |
1544 |
$sth->execute($categorycode); |
1679 |
$sth->execute($categorycode); |
1545 |
if ($result = $sth->fetchrow_hashref()) { |
1680 |
if ( $result = $sth->fetchrow_hashref() ) { |
1546 |
return $result; |
1681 |
return $result; |
1547 |
} |
1682 |
} |
1548 |
|
1683 |
|
1549 |
# try default branch, default borrower category |
1684 |
# try default branch, default borrower category |
1550 |
my $default_query = "SELECT maxissueqty |
1685 |
my $default_query = "SELECT maxissueqty |
1551 |
FROM default_circ_rules"; |
1686 |
FROM default_circ_rules"; |
1552 |
$sth = $dbh->prepare($default_query); |
1687 |
$sth = $dbh->prepare($default_query); |
1553 |
$sth->execute(); |
1688 |
$sth->execute(); |
1554 |
if ($result = $sth->fetchrow_hashref()) { |
1689 |
if ( $result = $sth->fetchrow_hashref() ) { |
1555 |
return $result; |
1690 |
return $result; |
1556 |
} |
1691 |
} |
1557 |
|
1692 |
|
1558 |
# built-in default circulation rule |
1693 |
# built-in default circulation rule |
1559 |
return { |
1694 |
return { maxissueqty => undef, }; |
1560 |
maxissueqty => undef, |
|
|
1561 |
}; |
1562 |
} |
1695 |
} |
1563 |
|
1696 |
|
1564 |
=head2 GetBranchItemRule |
1697 |
=head2 GetBranchItemRule |
Lines 1592-1630
Neither C<$branchcode> nor C<$itemtype> should be '*'.
Link Here
|
1592 |
|
1725 |
|
1593 |
sub GetBranchItemRule { |
1726 |
sub GetBranchItemRule { |
1594 |
my ( $branchcode, $itemtype ) = @_; |
1727 |
my ( $branchcode, $itemtype ) = @_; |
1595 |
my $dbh = C4::Context->dbh(); |
1728 |
my $dbh = C4::Context->dbh(); |
1596 |
my $result = {}; |
1729 |
my $result = {}; |
1597 |
|
1730 |
|
1598 |
my @attempts = ( |
1731 |
my @attempts = ( |
1599 |
['SELECT holdallowed, returnbranch |
1732 |
[ |
|
|
1733 |
'SELECT holdallowed, returnbranch |
1600 |
FROM branch_item_rules |
1734 |
FROM branch_item_rules |
1601 |
WHERE branchcode = ? |
1735 |
WHERE branchcode = ? |
1602 |
AND itemtype = ?', $branchcode, $itemtype], |
1736 |
AND itemtype = ?', $branchcode, $itemtype |
1603 |
['SELECT holdallowed, returnbranch |
1737 |
], |
|
|
1738 |
[ |
1739 |
'SELECT holdallowed, returnbranch |
1604 |
FROM default_branch_circ_rules |
1740 |
FROM default_branch_circ_rules |
1605 |
WHERE branchcode = ?', $branchcode], |
1741 |
WHERE branchcode = ?', $branchcode |
1606 |
['SELECT holdallowed, returnbranch |
1742 |
], |
|
|
1743 |
[ |
1744 |
'SELECT holdallowed, returnbranch |
1607 |
FROM default_branch_item_rules |
1745 |
FROM default_branch_item_rules |
1608 |
WHERE itemtype = ?', $itemtype], |
1746 |
WHERE itemtype = ?', $itemtype |
1609 |
['SELECT holdallowed, returnbranch |
1747 |
], |
1610 |
FROM default_circ_rules'], |
1748 |
[ |
|
|
1749 |
'SELECT holdallowed, returnbranch |
1750 |
FROM default_circ_rules' |
1751 |
], |
1611 |
); |
1752 |
); |
1612 |
|
1753 |
|
1613 |
foreach my $attempt (@attempts) { |
1754 |
foreach my $attempt (@attempts) { |
1614 |
my ($query, @bind_params) = @{$attempt}; |
1755 |
my ( $query, @bind_params ) = @{$attempt}; |
1615 |
my $search_result = $dbh->selectrow_hashref ( $query , {}, @bind_params ) |
1756 |
my $search_result = $dbh->selectrow_hashref( $query, {}, @bind_params ) |
1616 |
or next; |
1757 |
or next; |
1617 |
|
1758 |
|
1618 |
# Since branch/category and branch/itemtype use the same per-branch |
1759 |
# Since branch/category and branch/itemtype use the same per-branch |
1619 |
# defaults tables, we have to check that the key we want is set, not |
1760 |
# defaults tables, we have to check that the key we want is set, not |
1620 |
# just that a row was returned |
1761 |
# just that a row was returned |
1621 |
$result->{'holdallowed'} = $search_result->{'holdallowed'} unless ( defined $result->{'holdallowed'} ); |
1762 |
$result->{'holdallowed'} = $search_result->{'holdallowed'} |
1622 |
$result->{'returnbranch'} = $search_result->{'returnbranch'} unless ( defined $result->{'returnbranch'} ); |
1763 |
unless ( defined $result->{'holdallowed'} ); |
|
|
1764 |
$result->{'returnbranch'} = $search_result->{'returnbranch'} |
1765 |
unless ( defined $result->{'returnbranch'} ); |
1623 |
} |
1766 |
} |
1624 |
|
1767 |
|
1625 |
# built-in default circulation rule |
1768 |
# built-in default circulation rule |
1626 |
$result->{'holdallowed'} = 2 unless ( defined $result->{'holdallowed'} ); |
1769 |
$result->{'holdallowed'} = 2 unless ( defined $result->{'holdallowed'} ); |
1627 |
$result->{'returnbranch'} = 'homebranch' unless ( defined $result->{'returnbranch'} ); |
1770 |
$result->{'returnbranch'} = 'homebranch' |
|
|
1771 |
unless ( defined $result->{'returnbranch'} ); |
1628 |
|
1772 |
|
1629 |
return $result; |
1773 |
return $result; |
1630 |
} |
1774 |
} |
Lines 1706-1766
patron who last borrowed the book.
Link Here
|
1706 |
sub AddReturn { |
1850 |
sub AddReturn { |
1707 |
my ( $barcode, $branch, $exemptfine, $dropbox ) = @_; |
1851 |
my ( $barcode, $branch, $exemptfine, $dropbox ) = @_; |
1708 |
|
1852 |
|
1709 |
if ($branch and not GetBranchDetail($branch)) { |
1853 |
if ( $branch and not GetBranchDetail($branch) ) { |
1710 |
warn "AddReturn error: branch '$branch' not found. Reverting to " . C4::Context->userenv->{'branch'}; |
1854 |
warn "AddReturn error: branch '$branch' not found. Reverting to " |
|
|
1855 |
. C4::Context->userenv->{'branch'}; |
1711 |
undef $branch; |
1856 |
undef $branch; |
1712 |
} |
1857 |
} |
1713 |
$branch = C4::Context->userenv->{'branch'} unless $branch; # we trust userenv to be a safe fallback/default |
1858 |
$branch = C4::Context->userenv->{'branch'} |
|
|
1859 |
unless $branch; # we trust userenv to be a safe fallback/default |
1714 |
my $messages; |
1860 |
my $messages; |
1715 |
my $borrower; |
1861 |
my $borrower; |
1716 |
my $biblio; |
1862 |
my $biblio; |
1717 |
my $doreturn = 1; |
1863 |
my $doreturn = 1; |
1718 |
my $validTransfert = 0; |
1864 |
my $validTransfert = 0; |
1719 |
my $stat_type = 'return'; |
1865 |
my $stat_type = 'return'; |
1720 |
|
1866 |
|
1721 |
# get information on item |
1867 |
# get information on item |
1722 |
my $itemnumber = GetItemnumberFromBarcode( $barcode ); |
1868 |
my $itemnumber = GetItemnumberFromBarcode($barcode); |
1723 |
unless ($itemnumber) { |
1869 |
unless ($itemnumber) { |
1724 |
return (0, { BadBarcode => $barcode }); # no barcode means no item or borrower. bail out. |
1870 |
return ( 0, { BadBarcode => $barcode } ) |
1725 |
} |
1871 |
; # no barcode means no item or borrower. bail out. |
1726 |
my $issue = GetItemIssue($itemnumber); |
1872 |
} |
1727 |
# warn Dumper($iteminformation); |
1873 |
my $issue = GetItemIssue($itemnumber); |
1728 |
if ($issue and $issue->{borrowernumber}) { |
1874 |
|
1729 |
$borrower = C4::Members::GetMemberDetails($issue->{borrowernumber}) |
1875 |
# warn Dumper($iteminformation); |
1730 |
or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existant borrowernumber '$issue->{borrowernumber}'\n" |
1876 |
if ( $issue and $issue->{borrowernumber} ) { |
1731 |
. Dumper($issue) . "\n"; |
1877 |
$borrower = C4::Members::GetMemberDetails( $issue->{borrowernumber} ) |
1732 |
} else { |
1878 |
or die |
|
|
1879 |
"Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existant borrowernumber '$issue->{borrowernumber}'\n" |
1880 |
. Dumper($issue) . "\n"; |
1881 |
} |
1882 |
else { |
1733 |
$messages->{'NotIssued'} = $barcode; |
1883 |
$messages->{'NotIssued'} = $barcode; |
1734 |
# even though item is not on loan, it may still be transferred; therefore, get current branch info |
1884 |
|
|
|
1885 |
# even though item is not on loan, it may still be transferred; therefore, get current branch info |
1735 |
$doreturn = 0; |
1886 |
$doreturn = 0; |
1736 |
# No issue, no borrowernumber. ONLY if $doreturn, *might* you have a $borrower later. |
1887 |
|
1737 |
# Record this as a local use, instead of a return, if the RecordLocalUseOnReturn is on |
1888 |
# No issue, no borrowernumber. ONLY if $doreturn, *might* you have a $borrower later. |
1738 |
if (C4::Context->preference("RecordLocalUseOnReturn")) { |
1889 |
# Record this as a local use, instead of a return, if the RecordLocalUseOnReturn is on |
1739 |
$messages->{'LocalUse'} = 1; |
1890 |
if ( C4::Context->preference("RecordLocalUseOnReturn") ) { |
1740 |
$stat_type = 'localuse'; |
1891 |
$messages->{'LocalUse'} = 1; |
|
|
1892 |
$stat_type = 'localuse'; |
1741 |
} |
1893 |
} |
1742 |
} |
1894 |
} |
1743 |
|
1895 |
|
1744 |
my $item = GetItem($itemnumber) or die "GetItem($itemnumber) failed"; |
1896 |
my $item = GetItem($itemnumber) or die "GetItem($itemnumber) failed"; |
1745 |
# full item data, but no borrowernumber or checkout info (no issue) |
1897 |
|
1746 |
# we know GetItem should work because GetItemnumberFromBarcode worked |
1898 |
# full item data, but no borrowernumber or checkout info (no issue) |
1747 |
my $hbr = GetBranchItemRule($item->{'homebranch'}, $item->{'itype'})->{'returnbranch'} || "homebranch"; |
1899 |
# we know GetItem should work because GetItemnumberFromBarcode worked |
1748 |
# get the proper branch to which to return the item |
1900 |
my $hbr = GetBranchItemRule( $item->{'homebranch'}, $item->{'itype'} ) |
1749 |
$hbr = $item->{$hbr} || $branch ; |
1901 |
->{'returnbranch'} || "homebranch"; |
1750 |
# if $hbr was "noreturn" or any other non-item table value, then it should 'float' (i.e. stay at this branch) |
1902 |
|
1751 |
|
1903 |
# get the proper branch to which to return the item |
1752 |
my $borrowernumber = $borrower->{'borrowernumber'} || undef; # we don't know if we had a borrower or not |
1904 |
$hbr = $item->{$hbr} || $branch; |
1753 |
|
1905 |
|
1754 |
# check if the book is in a permanent collection.... |
1906 |
# if $hbr was "noreturn" or any other non-item table value, then it should 'float' (i.e. stay at this branch) |
1755 |
# FIXME -- This 'PE' attribute is largely undocumented. afaict, there's no user interface that reflects this functionality. |
1907 |
|
1756 |
if ( $hbr ) { |
1908 |
my $borrowernumber = $borrower->{'borrowernumber'} |
1757 |
my $branches = GetBranches(); # a potentially expensive call for a non-feature. |
1909 |
|| undef; # we don't know if we had a borrower or not |
|
|
1910 |
|
1911 |
# check if the book is in a permanent collection.... |
1912 |
# FIXME -- This 'PE' attribute is largely undocumented. afaict, there's no user interface that reflects this functionality. |
1913 |
if ($hbr) { |
1914 |
my $branches = |
1915 |
GetBranches(); # a potentially expensive call for a non-feature. |
1758 |
$branches->{$hbr}->{PE} and $messages->{'IsPermanent'} = $hbr; |
1916 |
$branches->{$hbr}->{PE} and $messages->{'IsPermanent'} = $hbr; |
1759 |
} |
1917 |
} |
1760 |
|
1918 |
|
1761 |
# check if the return is allowed at this branch |
1919 |
# check if the return is allowed at this branch |
1762 |
my ($returnallowed, $message) = CanBookBeReturned($item, $branch); |
1920 |
my ( $returnallowed, $message ) = CanBookBeReturned( $item, $branch ); |
1763 |
unless ($returnallowed){ |
1921 |
unless ($returnallowed) { |
1764 |
$messages->{'Wrongbranch'} = { |
1922 |
$messages->{'Wrongbranch'} = { |
1765 |
Wrongbranch => $branch, |
1923 |
Wrongbranch => $branch, |
1766 |
Rightbranch => $message |
1924 |
Rightbranch => $message |
Lines 1769-1775
sub AddReturn {
Link Here
|
1769 |
return ( $doreturn, $messages, $issue, $borrower ); |
1927 |
return ( $doreturn, $messages, $issue, $borrower ); |
1770 |
} |
1928 |
} |
1771 |
|
1929 |
|
1772 |
if ( $item->{'withdrawn'} ) { # book has been cancelled |
1930 |
if ( $item->{'withdrawn'} ) { # book has been cancelled |
1773 |
$messages->{'withdrawn'} = 1; |
1931 |
$messages->{'withdrawn'} = 1; |
1774 |
$doreturn = 0 if C4::Context->preference("BlockReturnOfWithdrawnItems"); |
1932 |
$doreturn = 0 if C4::Context->preference("BlockReturnOfWithdrawnItems"); |
1775 |
} |
1933 |
} |
Lines 1777-1798
sub AddReturn {
Link Here
|
1777 |
# case of a return of document (deal with issues and holdingbranch) |
1935 |
# case of a return of document (deal with issues and holdingbranch) |
1778 |
my $today = DateTime->now( time_zone => C4::Context->tz() ); |
1936 |
my $today = DateTime->now( time_zone => C4::Context->tz() ); |
1779 |
if ($doreturn) { |
1937 |
if ($doreturn) { |
1780 |
my $datedue = $issue->{date_due}; |
1938 |
my $datedue = $issue->{date_due}; |
1781 |
$borrower or warn "AddReturn without current borrower"; |
1939 |
$borrower or warn "AddReturn without current borrower"; |
1782 |
my $circControlBranch; |
1940 |
my $circControlBranch; |
1783 |
if ($dropbox) { |
1941 |
if ($dropbox) { |
1784 |
# define circControlBranch only if dropbox mode is set |
1942 |
|
1785 |
# don't allow dropbox mode to create an invalid entry in issues (issuedate > today) |
1943 |
# define circControlBranch only if dropbox mode is set |
1786 |
# FIXME: check issuedate > returndate, factoring in holidays |
1944 |
# don't allow dropbox mode to create an invalid entry in issues (issuedate > today) |
1787 |
#$circControlBranch = _GetCircControlBranch($item,$borrower) unless ( $item->{'issuedate'} eq C4::Dates->today('iso') );; |
1945 |
# FIXME: check issuedate > returndate, factoring in holidays |
1788 |
$circControlBranch = _GetCircControlBranch($item,$borrower); |
1946 |
#$circControlBranch = _GetCircControlBranch($item,$borrower) unless ( $item->{'issuedate'} eq C4::Dates->today('iso') );; |
1789 |
$issue->{'overdue'} = DateTime->compare($issue->{'date_due'}, $today ) == -1 ? 1 : 0; |
1947 |
$circControlBranch = _GetCircControlBranch( $item, $borrower ); |
|
|
1948 |
$issue->{'overdue'} = |
1949 |
DateTime->compare( $issue->{'date_due'}, $today ) == -1 ? 1 : 0; |
1790 |
} |
1950 |
} |
1791 |
|
1951 |
|
1792 |
if ($borrowernumber) { |
1952 |
if ($borrowernumber) { |
1793 |
if( C4::Context->preference('CalculateFinesOnReturn') && $issue->{'overdue'}){ |
1953 |
if ( C4::Context->preference('CalculateFinesOnReturn') |
1794 |
# we only need to calculate and change the fines if we want to do that on return |
1954 |
&& $issue->{'overdue'} ) |
1795 |
# Should be on for hourly loans |
1955 |
{ |
|
|
1956 |
# we only need to calculate and change the fines if we want to do that on return |
1957 |
# Should be on for hourly loans |
1796 |
my $control = C4::Context->preference('CircControl'); |
1958 |
my $control = C4::Context->preference('CircControl'); |
1797 |
my $control_branchcode = |
1959 |
my $control_branchcode = |
1798 |
( $control eq 'ItemHomeLibrary' ) ? $item->{homebranch} |
1960 |
( $control eq 'ItemHomeLibrary' ) ? $item->{homebranch} |
Lines 1822-1947
sub AddReturn {
Link Here
|
1822 |
|
1984 |
|
1823 |
} |
1985 |
} |
1824 |
|
1986 |
|
1825 |
ModItem({ onloan => undef }, $issue->{'biblionumber'}, $item->{'itemnumber'}); |
1987 |
ModItem( |
|
|
1988 |
{ onloan => undef }, |
1989 |
$issue->{'biblionumber'}, |
1990 |
$item->{'itemnumber'} |
1991 |
); |
1826 |
} |
1992 |
} |
1827 |
|
1993 |
|
1828 |
# the holdingbranch is updated if the document is returned to another location. |
1994 |
# the holdingbranch is updated if the document is returned to another location. |
1829 |
# this is always done regardless of whether the item was on loan or not |
1995 |
# this is always done regardless of whether the item was on loan or not |
1830 |
if ($item->{'holdingbranch'} ne $branch) { |
1996 |
if ( $item->{'holdingbranch'} ne $branch ) { |
1831 |
UpdateHoldingbranch($branch, $item->{'itemnumber'}); |
1997 |
UpdateHoldingbranch( $branch, $item->{'itemnumber'} ); |
1832 |
$item->{'holdingbranch'} = $branch; # update item data holdingbranch too |
1998 |
$item->{'holdingbranch'} = $branch; # update item data holdingbranch too |
1833 |
} |
1999 |
} |
1834 |
ModDateLastSeen( $item->{'itemnumber'} ); |
2000 |
ModDateLastSeen( $item->{'itemnumber'} ); |
1835 |
|
2001 |
|
1836 |
# check if we have a transfer for this document |
2002 |
# check if we have a transfer for this document |
1837 |
my ($datesent,$frombranch,$tobranch) = GetTransfers( $item->{'itemnumber'} ); |
2003 |
my ( $datesent, $frombranch, $tobranch ) = |
|
|
2004 |
GetTransfers( $item->{'itemnumber'} ); |
1838 |
|
2005 |
|
1839 |
# if we have a transfer to do, we update the line of transfers with the datearrived |
2006 |
# if we have a transfer to do, we update the line of transfers with the datearrived |
1840 |
if ($datesent) { |
2007 |
if ($datesent) { |
1841 |
if ( $tobranch eq $branch ) { |
2008 |
if ( $tobranch eq $branch ) { |
1842 |
my $sth = C4::Context->dbh->prepare( |
2009 |
my $sth = C4::Context->dbh->prepare( |
1843 |
"UPDATE branchtransfers SET datearrived = now() WHERE itemnumber= ? AND datearrived IS NULL" |
2010 |
"UPDATE branchtransfers SET datearrived = now() WHERE itemnumber= ? AND datearrived IS NULL" |
1844 |
); |
2011 |
); |
1845 |
$sth->execute( $item->{'itemnumber'} ); |
2012 |
$sth->execute( $item->{'itemnumber'} ); |
1846 |
# if we have a reservation with valid transfer, we can set it's status to 'W' |
2013 |
|
1847 |
ShelfToCart( $item->{'itemnumber'} ) if ( C4::Context->preference("ReturnToShelvingCart") ); |
2014 |
# if we have a reservation with valid transfer, we can set it's status to 'W' |
1848 |
C4::Reserves::ModReserveStatus($item->{'itemnumber'}, 'W'); |
2015 |
ShelfToCart( $item->{'itemnumber'} ) |
1849 |
} else { |
2016 |
if ( C4::Context->preference("ReturnToShelvingCart") ); |
|
|
2017 |
C4::Reserves::ModReserveStatus( $item->{'itemnumber'}, 'W' ); |
2018 |
} |
2019 |
else { |
1850 |
$messages->{'WrongTransfer'} = $tobranch; |
2020 |
$messages->{'WrongTransfer'} = $tobranch; |
1851 |
$messages->{'WrongTransferItem'} = $item->{'itemnumber'}; |
2021 |
$messages->{'WrongTransferItem'} = $item->{'itemnumber'}; |
1852 |
} |
2022 |
} |
1853 |
$validTransfert = 1; |
2023 |
$validTransfert = 1; |
1854 |
} else { |
2024 |
} |
1855 |
ShelfToCart( $item->{'itemnumber'} ) if ( C4::Context->preference("ReturnToShelvingCart") ); |
2025 |
else { |
|
|
2026 |
ShelfToCart( $item->{'itemnumber'} ) |
2027 |
if ( C4::Context->preference("ReturnToShelvingCart") ); |
1856 |
} |
2028 |
} |
1857 |
|
2029 |
|
1858 |
# fix up the accounts..... |
2030 |
# fix up the accounts..... |
1859 |
if ( $item->{'itemlost'} ) { |
2031 |
if ( $item->{'itemlost'} ) { |
1860 |
$messages->{'WasLost'} = 1; |
2032 |
$messages->{'WasLost'} = 1; |
1861 |
|
2033 |
|
1862 |
if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) { |
2034 |
if ( C4::Context->preference('RefundLostItemFeeOnReturn') ) { |
1863 |
_FixAccountForLostAndReturned($item->{'itemnumber'}, $borrowernumber, $barcode); # can tolerate undef $borrowernumber |
2035 |
_FixAccountForLostAndReturned( $item->{'itemnumber'}, |
|
|
2036 |
$borrowernumber, $barcode ) |
2037 |
; # can tolerate undef $borrowernumber |
1864 |
$messages->{'LostItemFeeRefunded'} = 1; |
2038 |
$messages->{'LostItemFeeRefunded'} = 1; |
1865 |
} |
2039 |
} |
1866 |
} |
2040 |
} |
1867 |
|
2041 |
|
1868 |
# fix up the overdues in accounts... |
2042 |
# fix up the overdues in accounts... |
1869 |
if ($borrowernumber) { |
2043 |
if ($borrowernumber) { |
1870 |
my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox); |
2044 |
my $fix = _FixOverduesOnReturn( $borrowernumber, $item->{itemnumber}, |
1871 |
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!"; # zero is OK, check defined |
2045 |
$exemptfine, $dropbox ); |
1872 |
|
2046 |
defined($fix) |
|
|
2047 |
or warn |
2048 |
"_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!" |
2049 |
; # zero is OK, check defined |
2050 |
|
1873 |
if ( $issue->{overdue} && $issue->{date_due} ) { |
2051 |
if ( $issue->{overdue} && $issue->{date_due} ) { |
1874 |
# fix fine days |
2052 |
|
|
|
2053 |
# fix fine days |
1875 |
my $debardate = |
2054 |
my $debardate = |
1876 |
_debar_user_on_return( $borrower, $item, $issue->{date_due}, $today ); |
2055 |
_debar_user_on_return( $borrower, $item, $issue->{date_due}, |
|
|
2056 |
$today ); |
1877 |
$messages->{Debarred} = $debardate if ($debardate); |
2057 |
$messages->{Debarred} = $debardate if ($debardate); |
1878 |
} |
2058 |
} |
1879 |
} |
2059 |
} |
1880 |
|
2060 |
|
1881 |
# find reserves..... |
2061 |
# find reserves..... |
1882 |
# if we don't have a reserve with the status W, we launch the Checkreserves routine |
2062 |
# if we don't have a reserve with the status W, we launch the Checkreserves routine |
1883 |
my ($resfound, $resrec); |
2063 |
my ( $resfound, $resrec ); |
1884 |
my $lookahead= C4::Context->preference('ConfirmFutureHolds'); #number of days to look for future holds |
2064 |
my $lookahead = C4::Context->preference('ConfirmFutureHolds') |
1885 |
($resfound, $resrec, undef) = C4::Reserves::CheckReserves( $item->{'itemnumber'}, undef, $lookahead ) unless ( $item->{'withdrawn'} ); |
2065 |
; #number of days to look for future holds |
|
|
2066 |
( $resfound, $resrec, undef ) = |
2067 |
C4::Reserves::CheckReserves( $item->{'itemnumber'}, undef, $lookahead ) |
2068 |
unless ( $item->{'withdrawn'} ); |
1886 |
if ($resfound) { |
2069 |
if ($resfound) { |
1887 |
$resrec->{'ResFound'} = $resfound; |
2070 |
$resrec->{'ResFound'} = $resfound; |
1888 |
$messages->{'ResFound'} = $resrec; |
2071 |
$messages->{'ResFound'} = $resrec; |
1889 |
} |
2072 |
} |
1890 |
|
2073 |
|
1891 |
# update stats? |
2074 |
# update stats? |
1892 |
# Record the fact that this book was returned. |
2075 |
# Record the fact that this book was returned. |
1893 |
UpdateStats( |
2076 |
UpdateStats( $branch, $stat_type, '0', '', $item->{'itemnumber'}, |
1894 |
$branch, $stat_type, '0', '', |
2077 |
$biblio->{'itemtype'}, $borrowernumber, undef, $item->{'ccode'} ); |
1895 |
$item->{'itemnumber'}, |
|
|
1896 |
$biblio->{'itemtype'}, |
1897 |
$borrowernumber, undef, $item->{'ccode'} |
1898 |
); |
1899 |
|
2078 |
|
1900 |
# Send a check-in slip. # NOTE: borrower may be undef. probably shouldn't try to send messages then. |
2079 |
# Send a check-in slip. # NOTE: borrower may be undef. probably shouldn't try to send messages then. |
1901 |
my $circulation_alert = 'C4::ItemCirculationAlertPreference'; |
2080 |
my $circulation_alert = 'C4::ItemCirculationAlertPreference'; |
1902 |
my %conditions = ( |
2081 |
my %conditions = ( |
1903 |
branchcode => $branch, |
2082 |
branchcode => $branch, |
1904 |
categorycode => $borrower->{categorycode}, |
2083 |
categorycode => $borrower->{categorycode}, |
1905 |
item_type => $item->{itype}, |
2084 |
item_type => $item->{itype}, |
1906 |
notification => 'CHECKIN', |
2085 |
notification => 'CHECKIN', |
1907 |
); |
2086 |
); |
1908 |
if ($doreturn && $circulation_alert->is_enabled_for(\%conditions)) { |
2087 |
if ( $doreturn && $circulation_alert->is_enabled_for( \%conditions ) ) { |
1909 |
SendCirculationAlert({ |
2088 |
SendCirculationAlert( |
1910 |
type => 'CHECKIN', |
2089 |
{ |
1911 |
item => $item, |
2090 |
type => 'CHECKIN', |
1912 |
borrower => $borrower, |
2091 |
item => $item, |
1913 |
branch => $branch, |
2092 |
borrower => $borrower, |
1914 |
}); |
2093 |
branch => $branch, |
1915 |
} |
2094 |
} |
1916 |
|
2095 |
); |
1917 |
logaction("CIRCULATION", "RETURN", $borrowernumber, $item->{'itemnumber'}) |
2096 |
} |
1918 |
if C4::Context->preference("ReturnLog"); |
2097 |
|
1919 |
|
2098 |
logaction( "CIRCULATION", "RETURN", $borrowernumber, $item->{'itemnumber'} ) |
|
|
2099 |
if C4::Context->preference("ReturnLog"); |
2100 |
|
1920 |
# Remove any OVERDUES related debarment if the borrower has no overdues |
2101 |
# Remove any OVERDUES related debarment if the borrower has no overdues |
1921 |
if ( $borrowernumber |
2102 |
if ( |
1922 |
&& $borrower->{'debarred'} |
2103 |
$borrowernumber |
1923 |
&& C4::Context->preference('AutoRemoveOverduesRestrictions') |
2104 |
&& $borrower->{'debarred'} |
1924 |
&& !HasOverdues( $borrowernumber ) |
2105 |
&& C4::Context->preference('AutoRemoveOverduesRestrictions') |
1925 |
&& @{ GetDebarments({ borrowernumber => $borrowernumber, type => 'OVERDUES' }) } |
2106 |
&& !HasOverdues($borrowernumber) |
1926 |
) { |
2107 |
&& @{ |
1927 |
DelUniqueDebarment({ borrowernumber => $borrowernumber, type => 'OVERDUES' }); |
2108 |
GetDebarments( |
1928 |
} |
2109 |
{ borrowernumber => $borrowernumber, type => 'OVERDUES' } |
1929 |
|
2110 |
) |
1930 |
# FIXME: make this comment intelligible. |
2111 |
} |
1931 |
#adding message if holdingbranch is non equal a userenv branch to return the document to homebranch |
2112 |
) |
1932 |
#we check, if we don't have reserv or transfert for this document, if not, return it to homebranch . |
2113 |
{ |
1933 |
|
2114 |
DelUniqueDebarment( |
1934 |
if (($doreturn or $messages->{'NotIssued'}) and !$resfound and ($branch ne $hbr) and not $messages->{'WrongTransfer'}){ |
2115 |
{ borrowernumber => $borrowernumber, type => 'OVERDUES' } ); |
1935 |
if ( C4::Context->preference("AutomaticItemReturn" ) or |
2116 |
} |
1936 |
(C4::Context->preference("UseBranchTransferLimits") and |
2117 |
|
1937 |
! IsBranchTransferAllowed($branch, $hbr, $item->{C4::Context->preference("BranchTransferLimitsType")} ) |
2118 |
# FIXME: make this comment intelligible. |
1938 |
)) { |
2119 |
#adding message if holdingbranch is non equal a userenv branch to return the document to homebranch |
1939 |
$debug and warn sprintf "about to call ModItemTransfer(%s, %s, %s)", $item->{'itemnumber'},$branch, $hbr; |
2120 |
#we check, if we don't have reserv or transfert for this document, if not, return it to homebranch . |
|
|
2121 |
|
2122 |
if ( ( $doreturn or $messages->{'NotIssued'} ) |
2123 |
and !$resfound |
2124 |
and ( $branch ne $hbr ) |
2125 |
and not $messages->{'WrongTransfer'} ) |
2126 |
{ |
2127 |
if ( |
2128 |
C4::Context->preference("AutomaticItemReturn") |
2129 |
or ( |
2130 |
C4::Context->preference("UseBranchTransferLimits") |
2131 |
and !IsBranchTransferAllowed( |
2132 |
$branch, |
2133 |
$hbr, |
2134 |
$item->{ C4::Context->preference("BranchTransferLimitsType") |
2135 |
} |
2136 |
) |
2137 |
) |
2138 |
) |
2139 |
{ |
2140 |
$debug |
2141 |
and warn sprintf "about to call ModItemTransfer(%s, %s, %s)", |
2142 |
$item->{'itemnumber'}, $branch, $hbr; |
1940 |
$debug and warn "item: " . Dumper($item); |
2143 |
$debug and warn "item: " . Dumper($item); |
1941 |
ModItemTransfer($item->{'itemnumber'}, $branch, $hbr); |
2144 |
ModItemTransfer( $item->{'itemnumber'}, $branch, $hbr ); |
1942 |
$messages->{'WasTransfered'} = 1; |
2145 |
$messages->{'WasTransfered'} = 1; |
1943 |
} else { |
2146 |
} |
1944 |
$messages->{'NeedsTransfer'} = 1; # TODO: instead of 1, specify branchcode that the transfer SHOULD go to, $item->{homebranch} |
2147 |
else { |
|
|
2148 |
$messages->{'NeedsTransfer'} = 1 |
2149 |
; # TODO: instead of 1, specify branchcode that the transfer SHOULD go to, $item->{homebranch} |
1945 |
} |
2150 |
} |
1946 |
} |
2151 |
} |
1947 |
return ( $doreturn, $messages, $issue, $borrower ); |
2152 |
return ( $doreturn, $messages, $issue, $borrower ); |
Lines 1971-2016
routine in C<C4::Accounts>.
Link Here
|
1971 |
=cut |
2176 |
=cut |
1972 |
|
2177 |
|
1973 |
sub MarkIssueReturned { |
2178 |
sub MarkIssueReturned { |
1974 |
my ( $borrowernumber, $itemnumber, $dropbox_branch, $returndate, $privacy ) = @_; |
2179 |
my ( $borrowernumber, $itemnumber, $dropbox_branch, $returndate, $privacy ) |
|
|
2180 |
= @_; |
1975 |
|
2181 |
|
1976 |
my $dbh = C4::Context->dbh; |
2182 |
my $dbh = C4::Context->dbh; |
1977 |
my $query = 'UPDATE issues SET returndate='; |
2183 |
my $query = 'UPDATE issues SET returndate='; |
1978 |
my @bind; |
2184 |
my @bind; |
1979 |
if ($dropbox_branch) { |
2185 |
if ($dropbox_branch) { |
1980 |
my $calendar = Koha::Calendar->new( branchcode => $dropbox_branch ); |
2186 |
my $calendar = Koha::Calendar->new( branchcode => $dropbox_branch ); |
1981 |
my $dropboxdate = $calendar->addDate( DateTime->now( time_zone => C4::Context->tz), -1 ); |
2187 |
my $dropboxdate = |
|
|
2188 |
$calendar->addDate( DateTime->now( time_zone => C4::Context->tz ), |
2189 |
-1 ); |
1982 |
$query .= ' ? '; |
2190 |
$query .= ' ? '; |
1983 |
push @bind, $dropboxdate->strftime('%Y-%m-%d %H:%M'); |
2191 |
push @bind, $dropboxdate->strftime('%Y-%m-%d %H:%M'); |
1984 |
} elsif ($returndate) { |
2192 |
} |
|
|
2193 |
elsif ($returndate) { |
1985 |
$query .= ' ? '; |
2194 |
$query .= ' ? '; |
1986 |
push @bind, $returndate; |
2195 |
push @bind, $returndate; |
1987 |
} else { |
2196 |
} |
|
|
2197 |
else { |
1988 |
$query .= ' now() '; |
2198 |
$query .= ' now() '; |
1989 |
} |
2199 |
} |
1990 |
$query .= ' WHERE borrowernumber = ? AND itemnumber = ?'; |
2200 |
$query .= ' WHERE borrowernumber = ? AND itemnumber = ?'; |
1991 |
push @bind, $borrowernumber, $itemnumber; |
2201 |
push @bind, $borrowernumber, $itemnumber; |
|
|
2202 |
|
1992 |
# FIXME transaction |
2203 |
# FIXME transaction |
1993 |
my $sth_upd = $dbh->prepare($query); |
2204 |
my $sth_upd = $dbh->prepare($query); |
1994 |
$sth_upd->execute(@bind); |
2205 |
$sth_upd->execute(@bind); |
1995 |
my $sth_copy = $dbh->prepare('INSERT INTO old_issues SELECT * FROM issues |
2206 |
my $sth_copy = $dbh->prepare( |
|
|
2207 |
'INSERT INTO old_issues SELECT * FROM issues |
1996 |
WHERE borrowernumber = ? |
2208 |
WHERE borrowernumber = ? |
1997 |
AND itemnumber = ?'); |
2209 |
AND itemnumber = ?' |
1998 |
$sth_copy->execute($borrowernumber, $itemnumber); |
2210 |
); |
1999 |
# anonymise patron checkout immediately if $privacy set to 2 and AnonymousPatron is set to a valid borrowernumber |
2211 |
$sth_copy->execute( $borrowernumber, $itemnumber ); |
2000 |
if ( $privacy == 2) { |
2212 |
|
2001 |
# The default of 0 does not work due to foreign key constraints |
2213 |
# anonymise patron checkout immediately if $privacy set to 2 and AnonymousPatron is set to a valid borrowernumber |
2002 |
# The anonymisation will fail quietly if AnonymousPatron is not a valid entry |
2214 |
if ( $privacy == 2 ) { |
2003 |
# FIXME the above is unacceptable - bug 9942 relates |
2215 |
|
2004 |
my $anonymouspatron = (C4::Context->preference('AnonymousPatron')) ? C4::Context->preference('AnonymousPatron') : 0; |
2216 |
# The default of 0 does not work due to foreign key constraints |
2005 |
my $sth_ano = $dbh->prepare("UPDATE old_issues SET borrowernumber=? |
2217 |
# The anonymisation will fail quietly if AnonymousPatron is not a valid entry |
|
|
2218 |
# FIXME the above is unacceptable - bug 9942 relates |
2219 |
my $anonymouspatron = |
2220 |
( C4::Context->preference('AnonymousPatron') ) |
2221 |
? C4::Context->preference('AnonymousPatron') |
2222 |
: 0; |
2223 |
my $sth_ano = $dbh->prepare( |
2224 |
"UPDATE old_issues SET borrowernumber=? |
2006 |
WHERE borrowernumber = ? |
2225 |
WHERE borrowernumber = ? |
2007 |
AND itemnumber = ?"); |
2226 |
AND itemnumber = ?" |
2008 |
$sth_ano->execute($anonymouspatron, $borrowernumber, $itemnumber); |
2227 |
); |
|
|
2228 |
$sth_ano->execute( $anonymouspatron, $borrowernumber, $itemnumber ); |
2009 |
} |
2229 |
} |
2010 |
my $sth_del = $dbh->prepare("DELETE FROM issues |
2230 |
my $sth_del = $dbh->prepare( |
|
|
2231 |
"DELETE FROM issues |
2011 |
WHERE borrowernumber = ? |
2232 |
WHERE borrowernumber = ? |
2012 |
AND itemnumber = ?"); |
2233 |
AND itemnumber = ?" |
2013 |
$sth_del->execute($borrowernumber, $itemnumber); |
2234 |
); |
|
|
2235 |
$sth_del->execute( $borrowernumber, $itemnumber ); |
2014 |
} |
2236 |
} |
2015 |
|
2237 |
|
2016 |
=head2 _debar_user_on_return |
2238 |
=head2 _debar_user_on_return |
Lines 2061-2071
sub _debar_user_on_return {
Link Here
|
2061 |
my $new_debar_dt = |
2283 |
my $new_debar_dt = |
2062 |
$dt_today->clone()->add_duration( $deltadays * $finedays ); |
2284 |
$dt_today->clone()->add_duration( $deltadays * $finedays ); |
2063 |
|
2285 |
|
2064 |
Koha::Borrower::Debarments::AddUniqueDebarment({ |
2286 |
Koha::Borrower::Debarments::AddUniqueDebarment( |
2065 |
borrowernumber => $borrower->{borrowernumber}, |
2287 |
{ |
2066 |
expiration => $new_debar_dt->ymd(), |
2288 |
borrowernumber => $borrower->{borrowernumber}, |
2067 |
type => 'SUSPENSION', |
2289 |
expiration => $new_debar_dt->ymd(), |
2068 |
}); |
2290 |
type => 'SUSPENSION', |
|
|
2291 |
} |
2292 |
); |
2069 |
|
2293 |
|
2070 |
return $new_debar_dt->ymd(); |
2294 |
return $new_debar_dt->ymd(); |
2071 |
} |
2295 |
} |
Lines 2089-2104
Internal function, called only by AddReturn
Link Here
|
2089 |
=cut |
2313 |
=cut |
2090 |
|
2314 |
|
2091 |
sub _FixOverduesOnReturn { |
2315 |
sub _FixOverduesOnReturn { |
2092 |
my ($borrowernumber, $item); |
2316 |
my ( $borrowernumber, $item ); |
2093 |
unless ($borrowernumber = shift) { |
2317 |
unless ( $borrowernumber = shift ) { |
2094 |
warn "_FixOverduesOnReturn() not supplied valid borrowernumber"; |
2318 |
warn "_FixOverduesOnReturn() not supplied valid borrowernumber"; |
2095 |
return; |
2319 |
return; |
2096 |
} |
2320 |
} |
2097 |
unless ($item = shift) { |
2321 |
unless ( $item = shift ) { |
2098 |
warn "_FixOverduesOnReturn() not supplied valid itemnumber"; |
2322 |
warn "_FixOverduesOnReturn() not supplied valid itemnumber"; |
2099 |
return; |
2323 |
return; |
2100 |
} |
2324 |
} |
2101 |
my ($exemptfine, $dropbox) = @_; |
2325 |
my ( $exemptfine, $dropbox ) = @_; |
2102 |
my $dbh = C4::Context->dbh; |
2326 |
my $dbh = C4::Context->dbh; |
2103 |
|
2327 |
|
2104 |
# check for overdue fine |
2328 |
# check for overdue fine |
Lines 2112-2135
sub _FixOverduesOnReturn {
Link Here
|
2112 |
return 0 unless $data; # no warning, there's just nothing to fix |
2336 |
return 0 unless $data; # no warning, there's just nothing to fix |
2113 |
|
2337 |
|
2114 |
my $uquery; |
2338 |
my $uquery; |
2115 |
my @bind = ($data->{'accountlines_id'}); |
2339 |
my @bind = ( $data->{'accountlines_id'} ); |
2116 |
if ($exemptfine) { |
2340 |
if ($exemptfine) { |
2117 |
$uquery = "update accountlines set accounttype='FFOR', amountoutstanding=0"; |
2341 |
$uquery = |
2118 |
if (C4::Context->preference("FinesLog")) { |
2342 |
"update accountlines set accounttype='FFOR', amountoutstanding=0"; |
2119 |
&logaction("FINES", 'MODIFY',$borrowernumber,"Overdue forgiven: item $item"); |
2343 |
if ( C4::Context->preference("FinesLog") ) { |
2120 |
} |
2344 |
&logaction( "FINES", 'MODIFY', $borrowernumber, |
2121 |
} elsif ($dropbox && $data->{lastincrement}) { |
2345 |
"Overdue forgiven: item $item" ); |
2122 |
my $outstanding = $data->{amountoutstanding} - $data->{lastincrement} ; |
2346 |
} |
2123 |
my $amt = $data->{amount} - $data->{lastincrement} ; |
2347 |
} |
2124 |
if (C4::Context->preference("FinesLog")) { |
2348 |
elsif ( $dropbox && $data->{lastincrement} ) { |
2125 |
&logaction("FINES", 'MODIFY',$borrowernumber,"Dropbox adjustment $amt, item $item"); |
2349 |
my $outstanding = $data->{amountoutstanding} - $data->{lastincrement}; |
2126 |
} |
2350 |
my $amt = $data->{amount} - $data->{lastincrement}; |
2127 |
$uquery = "update accountlines set accounttype='F' "; |
2351 |
if ( C4::Context->preference("FinesLog") ) { |
2128 |
if($outstanding >= 0 && $amt >=0) { |
2352 |
&logaction( "FINES", 'MODIFY', $borrowernumber, |
|
|
2353 |
"Dropbox adjustment $amt, item $item" ); |
2354 |
} |
2355 |
$uquery = "update accountlines set accounttype='F' "; |
2356 |
if ( $outstanding >= 0 && $amt >= 0 ) { |
2129 |
$uquery .= ", amount = ? , amountoutstanding=? "; |
2357 |
$uquery .= ", amount = ? , amountoutstanding=? "; |
2130 |
unshift @bind, ($amt, $outstanding) ; |
2358 |
unshift @bind, ( $amt, $outstanding ); |
2131 |
} |
2359 |
} |
2132 |
} else { |
2360 |
} |
|
|
2361 |
else { |
2133 |
$uquery = "update accountlines set accounttype='F' "; |
2362 |
$uquery = "update accountlines set accounttype='F' "; |
2134 |
} |
2363 |
} |
2135 |
$uquery .= " where (accountlines_id = ?)"; |
2364 |
$uquery .= " where (accountlines_id = ?)"; |
Lines 2151-2162
FIXME: Give a positive return value on success. It might be the $borrowernumber
Link Here
|
2151 |
=cut |
2380 |
=cut |
2152 |
|
2381 |
|
2153 |
sub _FixAccountForLostAndReturned { |
2382 |
sub _FixAccountForLostAndReturned { |
2154 |
my $itemnumber = shift or return; |
2383 |
my $itemnumber = shift or return; |
2155 |
my $borrowernumber = @_ ? shift : undef; |
2384 |
my $borrowernumber = @_ ? shift : undef; |
2156 |
my $item_id = @_ ? shift : $itemnumber; # Send the barcode if you want that logged in the description |
2385 |
my $item_id = |
|
|
2386 |
@_ |
2387 |
? shift |
2388 |
: $itemnumber |
2389 |
; # Send the barcode if you want that logged in the description |
2157 |
my $dbh = C4::Context->dbh; |
2390 |
my $dbh = C4::Context->dbh; |
|
|
2391 |
|
2158 |
# check for charge made for lost book |
2392 |
# check for charge made for lost book |
2159 |
my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE itemnumber = ? AND accounttype IN ('L', 'Rep', 'W') ORDER BY date DESC, accountno DESC"); |
2393 |
my $sth = $dbh->prepare( |
|
|
2394 |
"SELECT * FROM accountlines WHERE itemnumber = ? AND accounttype IN ('L', 'Rep', 'W') ORDER BY date DESC, accountno DESC" |
2395 |
); |
2160 |
$sth->execute($itemnumber); |
2396 |
$sth->execute($itemnumber); |
2161 |
my $data = $sth->fetchrow_hashref; |
2397 |
my $data = $sth->fetchrow_hashref; |
2162 |
$data or return; # bail if there is nothing to do |
2398 |
$data or return; # bail if there is nothing to do |
Lines 2166-2226
sub _FixAccountForLostAndReturned {
Link Here
|
2166 |
my $offset; |
2402 |
my $offset; |
2167 |
my $amount = $data->{'amount'}; |
2403 |
my $amount = $data->{'amount'}; |
2168 |
my $acctno = $data->{'accountno'}; |
2404 |
my $acctno = $data->{'accountno'}; |
2169 |
my $amountleft; # Starts off undef/zero. |
2405 |
my $amountleft; # Starts off undef/zero. |
2170 |
if ($data->{'amountoutstanding'} == $amount) { |
2406 |
if ( $data->{'amountoutstanding'} == $amount ) { |
2171 |
$offset = $data->{'amount'}; |
2407 |
$offset = $data->{'amount'}; |
2172 |
$amountleft = 0; # Hey, it's zero here, too. |
2408 |
$amountleft = 0; # Hey, it's zero here, too. |
2173 |
} else { |
2409 |
} |
2174 |
$offset = $amount - $data->{'amountoutstanding'}; # Um, isn't this the same as ZERO? We just tested those two things are == |
2410 |
else { |
2175 |
$amountleft = $data->{'amountoutstanding'} - $amount; # Um, isn't this the same as ZERO? We just tested those two things are == |
2411 |
$offset = $amount - $data->{'amountoutstanding'} |
2176 |
} |
2412 |
; # Um, isn't this the same as ZERO? We just tested those two things are == |
2177 |
my $usth = $dbh->prepare("UPDATE accountlines SET accounttype = 'LR',amountoutstanding='0' |
2413 |
$amountleft = |
2178 |
WHERE (accountlines_id = ?)"); |
2414 |
$data->{'amountoutstanding'} - |
2179 |
$usth->execute($data->{'accountlines_id'}); # We might be adjusting an account for some OTHER borrowernumber now. Not the one we passed in. |
2415 |
$amount |
2180 |
#check if any credit is left if so writeoff other accounts |
2416 |
; # Um, isn't this the same as ZERO? We just tested those two things are == |
2181 |
my $nextaccntno = getnextacctno($data->{'borrowernumber'}); |
2417 |
} |
2182 |
$amountleft *= -1 if ($amountleft < 0); |
2418 |
my $usth = $dbh->prepare( |
2183 |
if ($amountleft > 0) { |
2419 |
"UPDATE accountlines SET accounttype = 'LR',amountoutstanding='0' |
2184 |
my $msth = $dbh->prepare("SELECT * FROM accountlines WHERE (borrowernumber = ?) |
2420 |
WHERE (accountlines_id = ?)" |
2185 |
AND (amountoutstanding >0) ORDER BY date"); # might want to order by amountoustanding ASC (pay smallest first) |
2421 |
); |
2186 |
$msth->execute($data->{'borrowernumber'}); |
2422 |
$usth->execute( $data->{'accountlines_id'} ) |
|
|
2423 |
; # We might be adjusting an account for some OTHER borrowernumber now. Not the one we passed in. |
2424 |
#check if any credit is left if so writeoff other accounts |
2425 |
my $nextaccntno = getnextacctno( $data->{'borrowernumber'} ); |
2426 |
$amountleft *= -1 if ( $amountleft < 0 ); |
2427 |
if ( $amountleft > 0 ) { |
2428 |
my $msth = $dbh->prepare( |
2429 |
"SELECT * FROM accountlines WHERE (borrowernumber = ?) |
2430 |
AND (amountoutstanding >0) ORDER BY date" |
2431 |
); # might want to order by amountoustanding ASC (pay smallest first) |
2432 |
$msth->execute( $data->{'borrowernumber'} ); |
2433 |
|
2187 |
# offset transactions |
2434 |
# offset transactions |
2188 |
my $newamtos; |
2435 |
my $newamtos; |
2189 |
my $accdata; |
2436 |
my $accdata; |
2190 |
while (($accdata=$msth->fetchrow_hashref) and ($amountleft>0)){ |
2437 |
while ( ( $accdata = $msth->fetchrow_hashref ) and ( $amountleft > 0 ) ) |
2191 |
if ($accdata->{'amountoutstanding'} < $amountleft) { |
2438 |
{ |
|
|
2439 |
if ( $accdata->{'amountoutstanding'} < $amountleft ) { |
2192 |
$newamtos = 0; |
2440 |
$newamtos = 0; |
2193 |
$amountleft -= $accdata->{'amountoutstanding'}; |
2441 |
$amountleft -= $accdata->{'amountoutstanding'}; |
2194 |
} else { |
2442 |
} |
2195 |
$newamtos = $accdata->{'amountoutstanding'} - $amountleft; |
2443 |
else { |
|
|
2444 |
$newamtos = $accdata->{'amountoutstanding'} - $amountleft; |
2196 |
$amountleft = 0; |
2445 |
$amountleft = 0; |
2197 |
} |
2446 |
} |
2198 |
my $thisacct = $accdata->{'accountlines_id'}; |
2447 |
my $thisacct = $accdata->{'accountlines_id'}; |
|
|
2448 |
|
2199 |
# FIXME: move prepares outside while loop! |
2449 |
# FIXME: move prepares outside while loop! |
2200 |
my $usth = $dbh->prepare("UPDATE accountlines SET amountoutstanding= ? |
2450 |
my $usth = $dbh->prepare( |
2201 |
WHERE (accountlines_id = ?)"); |
2451 |
"UPDATE accountlines SET amountoutstanding= ? |
2202 |
$usth->execute($newamtos,$thisacct); |
2452 |
WHERE (accountlines_id = ?)" |
2203 |
$usth = $dbh->prepare("INSERT INTO accountoffsets |
2453 |
); |
|
|
2454 |
$usth->execute( $newamtos, $thisacct ); |
2455 |
$usth = $dbh->prepare( |
2456 |
"INSERT INTO accountoffsets |
2204 |
(borrowernumber, accountno, offsetaccount, offsetamount) |
2457 |
(borrowernumber, accountno, offsetaccount, offsetamount) |
2205 |
VALUES |
2458 |
VALUES |
2206 |
(?,?,?,?)"); |
2459 |
(?,?,?,?)" |
2207 |
$usth->execute($data->{'borrowernumber'},$accdata->{'accountno'},$nextaccntno,$newamtos); |
2460 |
); |
|
|
2461 |
$usth->execute( |
2462 |
$data->{'borrowernumber'}, |
2463 |
$accdata->{'accountno'}, |
2464 |
$nextaccntno, $newamtos |
2465 |
); |
2208 |
} |
2466 |
} |
2209 |
} |
2467 |
} |
2210 |
$amountleft *= -1 if ($amountleft > 0); |
2468 |
$amountleft *= -1 if ( $amountleft > 0 ); |
2211 |
my $desc = "Item Returned " . $item_id; |
2469 |
my $desc = "Item Returned " . $item_id; |
2212 |
$usth = $dbh->prepare("INSERT INTO accountlines |
2470 |
$usth = $dbh->prepare( |
|
|
2471 |
"INSERT INTO accountlines |
2213 |
(borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding) |
2472 |
(borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding) |
2214 |
VALUES (?,?,now(),?,?,'CR',?)"); |
2473 |
VALUES (?,?,now(),?,?,'CR',?)" |
2215 |
$usth->execute($data->{'borrowernumber'},$nextaccntno,0-$amount,$desc,$amountleft); |
2474 |
); |
|
|
2475 |
$usth->execute( |
2476 |
$data->{'borrowernumber'}, |
2477 |
$nextaccntno, 0 - $amount, |
2478 |
$desc, $amountleft |
2479 |
); |
2216 |
if ($borrowernumber) { |
2480 |
if ($borrowernumber) { |
|
|
2481 |
|
2217 |
# FIXME: same as query above. use 1 sth for both |
2482 |
# FIXME: same as query above. use 1 sth for both |
2218 |
$usth = $dbh->prepare("INSERT INTO accountoffsets |
2483 |
$usth = $dbh->prepare( |
|
|
2484 |
"INSERT INTO accountoffsets |
2219 |
(borrowernumber, accountno, offsetaccount, offsetamount) |
2485 |
(borrowernumber, accountno, offsetaccount, offsetamount) |
2220 |
VALUES (?,?,?,?)"); |
2486 |
VALUES (?,?,?,?)" |
2221 |
$usth->execute($borrowernumber, $data->{'accountno'}, $nextaccntno, $offset); |
2487 |
); |
|
|
2488 |
$usth->execute( $borrowernumber, $data->{'accountno'}, $nextaccntno, |
2489 |
$offset ); |
2222 |
} |
2490 |
} |
2223 |
ModItem({ paidfor => '' }, undef, $itemnumber); |
2491 |
ModItem( { paidfor => '' }, undef, $itemnumber ); |
2224 |
return; |
2492 |
return; |
2225 |
} |
2493 |
} |
2226 |
|
2494 |
|
Lines 2241-2271
C<$borrower> is a hashref to borrower. Only {branchcode} is used.
Link Here
|
2241 |
=cut |
2509 |
=cut |
2242 |
|
2510 |
|
2243 |
sub _GetCircControlBranch { |
2511 |
sub _GetCircControlBranch { |
2244 |
my ($item, $borrower) = @_; |
2512 |
my ( $item, $borrower ) = @_; |
2245 |
my $circcontrol = C4::Context->preference('CircControl'); |
2513 |
my $circcontrol = C4::Context->preference('CircControl'); |
2246 |
my $branch; |
2514 |
my $branch; |
2247 |
|
2515 |
|
2248 |
if ($circcontrol eq 'PickupLibrary' and (C4::Context->userenv and C4::Context->userenv->{'branch'}) ) { |
2516 |
if ( $circcontrol eq 'PickupLibrary' |
2249 |
$branch= C4::Context->userenv->{'branch'}; |
2517 |
and ( C4::Context->userenv and C4::Context->userenv->{'branch'} ) ) |
2250 |
} elsif ($circcontrol eq 'PatronLibrary') { |
2518 |
{ |
2251 |
$branch=$borrower->{branchcode}; |
2519 |
$branch = C4::Context->userenv->{'branch'}; |
2252 |
} else { |
2520 |
} |
2253 |
my $branchfield = C4::Context->preference('HomeOrHoldingBranch') || 'homebranch'; |
2521 |
elsif ( $circcontrol eq 'PatronLibrary' ) { |
|
|
2522 |
$branch = $borrower->{branchcode}; |
2523 |
} |
2524 |
else { |
2525 |
my $branchfield = |
2526 |
C4::Context->preference('HomeOrHoldingBranch') || 'homebranch'; |
2254 |
$branch = $item->{$branchfield}; |
2527 |
$branch = $item->{$branchfield}; |
|
|
2528 |
|
2255 |
# default to item home branch if holdingbranch is used |
2529 |
# default to item home branch if holdingbranch is used |
2256 |
# and is not defined |
2530 |
# and is not defined |
2257 |
if (!defined($branch) && $branchfield eq 'holdingbranch') { |
2531 |
if ( !defined($branch) && $branchfield eq 'holdingbranch' ) { |
2258 |
$branch = $item->{homebranch}; |
2532 |
$branch = $item->{homebranch}; |
2259 |
} |
2533 |
} |
2260 |
} |
2534 |
} |
2261 |
return $branch; |
2535 |
return $branch; |
2262 |
} |
2536 |
} |
2263 |
|
2537 |
|
2264 |
|
|
|
2265 |
|
2266 |
|
2267 |
|
2268 |
|
2269 |
=head2 GetItemIssue |
2538 |
=head2 GetItemIssue |
2270 |
|
2539 |
|
2271 |
$issue = &GetItemIssue($itemnumber); |
2540 |
$issue = &GetItemIssue($itemnumber); |
Lines 2285-2300
sub GetItemIssue {
Link Here
|
2285 |
"SELECT items.*, issues.* |
2554 |
"SELECT items.*, issues.* |
2286 |
FROM issues |
2555 |
FROM issues |
2287 |
LEFT JOIN items ON issues.itemnumber=items.itemnumber |
2556 |
LEFT JOIN items ON issues.itemnumber=items.itemnumber |
2288 |
WHERE issues.itemnumber=?"); |
2557 |
WHERE issues.itemnumber=?" |
|
|
2558 |
); |
2289 |
$sth->execute($itemnumber); |
2559 |
$sth->execute($itemnumber); |
2290 |
my $data = $sth->fetchrow_hashref; |
2560 |
my $data = $sth->fetchrow_hashref; |
2291 |
return unless $data; |
2561 |
return unless $data; |
2292 |
$data->{issuedate} = dt_from_string($data->{issuedate}, 'sql'); |
2562 |
$data->{issuedate} = dt_from_string( $data->{issuedate}, 'sql' ); |
2293 |
$data->{issuedate}->truncate(to => 'minute'); |
2563 |
$data->{issuedate}->truncate( to => 'minute' ); |
2294 |
$data->{date_due} = dt_from_string($data->{date_due}, 'sql'); |
2564 |
$data->{date_due} = dt_from_string( $data->{date_due}, 'sql' ); |
2295 |
$data->{date_due}->truncate(to => 'minute'); |
2565 |
$data->{date_due}->truncate( to => 'minute' ); |
2296 |
my $dt = DateTime->now( time_zone => C4::Context->tz)->truncate( to => 'minute'); |
2566 |
my $dt = |
2297 |
$data->{'overdue'} = DateTime->compare($data->{'date_due'}, $dt ) == -1 ? 1 : 0; |
2567 |
DateTime->now( time_zone => C4::Context->tz )->truncate( to => 'minute' ); |
|
|
2568 |
$data->{'overdue'} = |
2569 |
DateTime->compare( $data->{'date_due'}, $dt ) == -1 ? 1 : 0; |
2298 |
return $data; |
2570 |
return $data; |
2299 |
} |
2571 |
} |
2300 |
|
2572 |
|
Lines 2311-2322
Returns a hashref
Link Here
|
2311 |
=cut |
2583 |
=cut |
2312 |
|
2584 |
|
2313 |
sub GetOpenIssue { |
2585 |
sub GetOpenIssue { |
2314 |
my ( $itemnumber ) = @_; |
2586 |
my ($itemnumber) = @_; |
2315 |
return unless $itemnumber; |
2587 |
return unless $itemnumber; |
2316 |
my $dbh = C4::Context->dbh; |
2588 |
my $dbh = C4::Context->dbh; |
2317 |
my $sth = $dbh->prepare( "SELECT * FROM issues WHERE itemnumber = ? AND returndate IS NULL" ); |
2589 |
my $sth = $dbh->prepare( |
2318 |
$sth->execute( $itemnumber ); |
2590 |
"SELECT * FROM issues WHERE itemnumber = ? AND returndate IS NULL"); |
2319 |
return $sth->fetchrow_hashref(); |
2591 |
$sth->execute($itemnumber); |
|
|
2592 |
return $sth->fetchrow_hashref(); |
2320 |
|
2593 |
|
2321 |
} |
2594 |
} |
2322 |
|
2595 |
|
Lines 2336-2343
Returns reference to an array of hashes
Link Here
|
2336 |
|
2609 |
|
2337 |
sub GetItemIssues { |
2610 |
sub GetItemIssues { |
2338 |
my ( $itemnumber, $history ) = @_; |
2611 |
my ( $itemnumber, $history ) = @_; |
2339 |
|
2612 |
|
2340 |
my $today = DateTime->now( time_zome => C4::Context->tz); # get today date |
2613 |
my $today = DateTime->now( time_zome => C4::Context->tz ); # get today date |
2341 |
$today->truncate( to => 'minute' ); |
2614 |
$today->truncate( to => 'minute' ); |
2342 |
my $sql = "SELECT * FROM issues |
2615 |
my $sql = "SELECT * FROM issues |
2343 |
JOIN borrowers USING (borrowernumber) |
2616 |
JOIN borrowers USING (borrowernumber) |
Lines 2353-2368
sub GetItemIssues {
Link Here
|
2353 |
$sql .= "ORDER BY date_due DESC"; |
2626 |
$sql .= "ORDER BY date_due DESC"; |
2354 |
my $sth = C4::Context->dbh->prepare($sql); |
2627 |
my $sth = C4::Context->dbh->prepare($sql); |
2355 |
if ($history) { |
2628 |
if ($history) { |
2356 |
$sth->execute($itemnumber, $itemnumber); |
2629 |
$sth->execute( $itemnumber, $itemnumber ); |
2357 |
} else { |
2630 |
} |
|
|
2631 |
else { |
2358 |
$sth->execute($itemnumber); |
2632 |
$sth->execute($itemnumber); |
2359 |
} |
2633 |
} |
2360 |
my $results = $sth->fetchall_arrayref({}); |
2634 |
my $results = $sth->fetchall_arrayref( {} ); |
2361 |
foreach (@$results) { |
2635 |
foreach (@$results) { |
2362 |
my $date_due = dt_from_string($_->{date_due},'sql'); |
2636 |
my $date_due = dt_from_string( $_->{date_due}, 'sql' ); |
2363 |
$date_due->truncate( to => 'minute' ); |
2637 |
$date_due->truncate( to => 'minute' ); |
2364 |
|
2638 |
|
2365 |
$_->{overdue} = (DateTime->compare($date_due, $today) == -1) ? 1 : 0; |
2639 |
$_->{overdue} = |
|
|
2640 |
( DateTime->compare( $date_due, $today ) == -1 ) ? 1 : 0; |
2366 |
} |
2641 |
} |
2367 |
return $results; |
2642 |
return $results; |
2368 |
} |
2643 |
} |
Lines 2402-2408
sub GetBiblioIssues {
Link Here
|
2402 |
ORDER BY timestamp |
2677 |
ORDER BY timestamp |
2403 |
"; |
2678 |
"; |
2404 |
my $sth = $dbh->prepare($query); |
2679 |
my $sth = $dbh->prepare($query); |
2405 |
$sth->execute($biblionumber, $biblionumber); |
2680 |
$sth->execute( $biblionumber, $biblionumber ); |
2406 |
|
2681 |
|
2407 |
my @issues; |
2682 |
my @issues; |
2408 |
while ( my $data = $sth->fetchrow_hashref ) { |
2683 |
while ( my $data = $sth->fetchrow_hashref ) { |
Lines 2433-2442
HAVING days_until_due >= 0 AND days_until_due <= ?
Link Here
|
2433 |
END_SQL |
2708 |
END_SQL |
2434 |
|
2709 |
|
2435 |
my @bind_parameters = ( $params->{'days_in_advance'} ); |
2710 |
my @bind_parameters = ( $params->{'days_in_advance'} ); |
2436 |
|
2711 |
|
2437 |
my $sth = $dbh->prepare( $statement ); |
2712 |
my $sth = $dbh->prepare($statement); |
2438 |
$sth->execute( @bind_parameters ); |
2713 |
$sth->execute(@bind_parameters); |
2439 |
my $upcoming_dues = $sth->fetchall_arrayref({}); |
2714 |
my $upcoming_dues = $sth->fetchall_arrayref( {} ); |
2440 |
|
2715 |
|
2441 |
return $upcoming_dues; |
2716 |
return $upcoming_dues; |
2442 |
} |
2717 |
} |
Lines 2478-2498
sub CanBookBeRenewed {
Link Here
|
2478 |
my $borrower = C4::Members::GetMemberDetails($borrowernumber) |
2753 |
my $borrower = C4::Members::GetMemberDetails($borrowernumber) |
2479 |
or return; |
2754 |
or return; |
2480 |
|
2755 |
|
2481 |
my $branchcode = _GetCircControlBranch($item, $borrower); |
2756 |
my $branchcode = _GetCircControlBranch( $item, $borrower ); |
2482 |
|
2757 |
|
2483 |
my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{itype}, $branchcode); |
2758 |
my $issuingrule = |
|
|
2759 |
GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode ); |
2484 |
|
2760 |
|
2485 |
if ( ( $issuingrule->{renewalsallowed} > $itemissue->{renewals} ) || $override_limit ) { |
2761 |
if ( ( $issuingrule->{renewalsallowed} > $itemissue->{renewals} ) |
|
|
2762 |
|| $override_limit ) |
2763 |
{ |
2486 |
$renewokay = 1; |
2764 |
$renewokay = 1; |
2487 |
} else { |
2765 |
} |
|
|
2766 |
else { |
2488 |
$error = "too_many"; |
2767 |
$error = "too_many"; |
2489 |
} |
2768 |
} |
2490 |
|
2769 |
|
2491 |
my ( $resfound, $resrec, undef ) = C4::Reserves::CheckReserves( $itemnumber ); |
2770 |
my ( $resfound, $resrec, undef ) = C4::Reserves::CheckReserves($itemnumber); |
2492 |
|
2771 |
|
2493 |
if ( $resfound ) { # '' when no hold was found |
2772 |
if ($resfound) { # '' when no hold was found |
2494 |
$renewokay = 0; |
2773 |
$renewokay = 0; |
2495 |
$error = "on_reserve"; |
2774 |
$error = "on_reserve"; |
2496 |
} |
2775 |
} |
2497 |
|
2776 |
|
2498 |
return ( $renewokay, $error ); |
2777 |
return ( $renewokay, $error ); |
Lines 2523-2546
from the book's item type.
Link Here
|
2523 |
=cut |
2802 |
=cut |
2524 |
|
2803 |
|
2525 |
sub AddRenewal { |
2804 |
sub AddRenewal { |
2526 |
my $borrowernumber = shift; |
2805 |
my $borrowernumber = shift; |
2527 |
my $itemnumber = shift or return; |
2806 |
my $itemnumber = shift or return; |
2528 |
my $branch = shift; |
2807 |
my $branch = shift; |
2529 |
my $datedue = shift; |
2808 |
my $datedue = shift; |
2530 |
my $lastreneweddate = shift || DateTime->now(time_zone => C4::Context->tz)->ymd(); |
2809 |
my $lastreneweddate = |
|
|
2810 |
shift || DateTime->now( time_zone => C4::Context->tz )->ymd(); |
2531 |
|
2811 |
|
2532 |
my $item = GetItem($itemnumber) or return; |
2812 |
my $item = GetItem($itemnumber) or return; |
2533 |
my $biblio = GetBiblioFromItemNumber($itemnumber) or return; |
2813 |
my $biblio = GetBiblioFromItemNumber($itemnumber) or return; |
2534 |
|
2814 |
|
2535 |
my $dbh = C4::Context->dbh; |
2815 |
my $dbh = C4::Context->dbh; |
2536 |
|
2816 |
|
2537 |
# Find the issues record for this book |
2817 |
# Find the issues record for this book |
2538 |
my $sth = |
2818 |
my $sth = $dbh->prepare("SELECT * FROM issues WHERE itemnumber = ?"); |
2539 |
$dbh->prepare("SELECT * FROM issues WHERE itemnumber = ?"); |
2819 |
$sth->execute($itemnumber); |
2540 |
$sth->execute( $itemnumber ); |
|
|
2541 |
my $issuedata = $sth->fetchrow_hashref; |
2820 |
my $issuedata = $sth->fetchrow_hashref; |
2542 |
|
2821 |
|
2543 |
return unless ( $issuedata ); |
2822 |
return unless ($issuedata); |
2544 |
|
2823 |
|
2545 |
$borrowernumber ||= $issuedata->{borrowernumber}; |
2824 |
$borrowernumber ||= $issuedata->{borrowernumber}; |
2546 |
|
2825 |
|
Lines 2554-2591
sub AddRenewal {
Link Here
|
2554 |
# based on the value of the RenewalPeriodBase syspref. |
2833 |
# based on the value of the RenewalPeriodBase syspref. |
2555 |
unless ($datedue) { |
2834 |
unless ($datedue) { |
2556 |
|
2835 |
|
2557 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) or return; |
2836 |
my $borrower = |
2558 |
my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'}; |
2837 |
C4::Members::GetMember( borrowernumber => $borrowernumber ) |
|
|
2838 |
or return; |
2839 |
my $itemtype = |
2840 |
( C4::Context->preference('item-level_itypes') ) |
2841 |
? $biblio->{'itype'} |
2842 |
: $biblio->{'itemtype'}; |
2559 |
|
2843 |
|
2560 |
$datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ? |
2844 |
$datedue = |
2561 |
dt_from_string( $issuedata->{date_due} ) : |
2845 |
( C4::Context->preference('RenewalPeriodBase') eq 'date_due' ) |
2562 |
DateTime->now( time_zone => C4::Context->tz()); |
2846 |
? dt_from_string( $issuedata->{date_due} ) |
2563 |
$datedue = CalcDateDue($datedue, $itemtype, $issuedata->{'branchcode'}, $borrower, 'is a renewal'); |
2847 |
: DateTime->now( time_zone => C4::Context->tz() ); |
|
|
2848 |
$datedue = CalcDateDue( $datedue, $itemtype, $issuedata->{'branchcode'}, |
2849 |
$borrower, 'is a renewal' ); |
2564 |
} |
2850 |
} |
2565 |
|
2851 |
|
2566 |
# Update the issues record to have the new due date, and a new count |
2852 |
# Update the issues record to have the new due date, and a new count |
2567 |
# of how many times it has been renewed. |
2853 |
# of how many times it has been renewed. |
2568 |
my $renews = $issuedata->{'renewals'} + 1; |
2854 |
my $renews = $issuedata->{'renewals'} + 1; |
2569 |
$sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ? |
2855 |
$sth = $dbh->prepare( |
|
|
2856 |
"UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ? |
2570 |
WHERE borrowernumber=? |
2857 |
WHERE borrowernumber=? |
2571 |
AND itemnumber=?" |
2858 |
AND itemnumber=?" |
2572 |
); |
2859 |
); |
2573 |
|
2860 |
|
2574 |
$sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), $renews, $lastreneweddate, $borrowernumber, $itemnumber ); |
2861 |
$sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), |
|
|
2862 |
$renews, $lastreneweddate, $borrowernumber, $itemnumber ); |
2575 |
|
2863 |
|
2576 |
# Update the renewal count on the item, and tell zebra to reindex |
2864 |
# Update the renewal count on the item, and tell zebra to reindex |
2577 |
$renews = $biblio->{'renewals'} + 1; |
2865 |
$renews = $biblio->{'renewals'} + 1; |
2578 |
ModItem({ renewals => $renews, onloan => $datedue->strftime('%Y-%m-%d %H:%M')}, $biblio->{'biblionumber'}, $itemnumber); |
2866 |
ModItem( |
|
|
2867 |
{ renewals => $renews, onloan => $datedue->strftime('%Y-%m-%d %H:%M') }, |
2868 |
$biblio->{'biblionumber'}, $itemnumber |
2869 |
); |
2579 |
|
2870 |
|
2580 |
# Charge a new rental fee, if applicable? |
2871 |
# Charge a new rental fee, if applicable? |
2581 |
my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber ); |
2872 |
my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber ); |
2582 |
if ( $charge > 0 ) { |
2873 |
if ( $charge > 0 ) { |
2583 |
my $accountno = getnextacctno( $borrowernumber ); |
2874 |
my $accountno = getnextacctno($borrowernumber); |
2584 |
my $item = GetBiblioFromItemNumber($itemnumber); |
2875 |
my $item = GetBiblioFromItemNumber($itemnumber); |
2585 |
my $manager_id = 0; |
2876 |
my $manager_id = 0; |
2586 |
$manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; |
2877 |
$manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; |
2587 |
$sth = $dbh->prepare( |
2878 |
$sth = $dbh->prepare( |
2588 |
"INSERT INTO accountlines |
2879 |
"INSERT INTO accountlines |
2589 |
(date, borrowernumber, accountno, amount, manager_id, |
2880 |
(date, borrowernumber, accountno, amount, manager_id, |
2590 |
description,accounttype, amountoutstanding, itemnumber) |
2881 |
description,accounttype, amountoutstanding, itemnumber) |
2591 |
VALUES (now(),?,?,?,?,?,?,?,?)" |
2882 |
VALUES (now(),?,?,?,?,?,?,?,?)" |
Lines 2596-2636
sub AddRenewal {
Link Here
|
2596 |
} |
2887 |
} |
2597 |
|
2888 |
|
2598 |
# Send a renewal slip according to checkout alert preferencei |
2889 |
# Send a renewal slip according to checkout alert preferencei |
2599 |
if ( C4::Context->preference('RenewalSendNotice') eq '1') { |
2890 |
if ( C4::Context->preference('RenewalSendNotice') eq '1' ) { |
2600 |
my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ); |
2891 |
my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ); |
2601 |
my $circulation_alert = 'C4::ItemCirculationAlertPreference'; |
2892 |
my $circulation_alert = 'C4::ItemCirculationAlertPreference'; |
2602 |
my %conditions = ( |
2893 |
my %conditions = ( |
2603 |
branchcode => $branch, |
2894 |
branchcode => $branch, |
2604 |
categorycode => $borrower->{categorycode}, |
2895 |
categorycode => $borrower->{categorycode}, |
2605 |
item_type => $item->{itype}, |
2896 |
item_type => $item->{itype}, |
2606 |
notification => 'CHECKOUT', |
2897 |
notification => 'CHECKOUT', |
2607 |
); |
2898 |
); |
2608 |
if ($circulation_alert->is_enabled_for(\%conditions)) { |
2899 |
if ( $circulation_alert->is_enabled_for( \%conditions ) ) { |
2609 |
SendCirculationAlert({ |
2900 |
SendCirculationAlert( |
2610 |
type => 'RENEWAL', |
2901 |
{ |
2611 |
item => $item, |
2902 |
type => 'RENEWAL', |
2612 |
borrower => $borrower, |
2903 |
item => $item, |
2613 |
branch => $branch, |
2904 |
borrower => $borrower, |
2614 |
}); |
2905 |
branch => $branch, |
2615 |
} |
2906 |
} |
|
|
2907 |
); |
2908 |
} |
2616 |
} |
2909 |
} |
2617 |
|
2910 |
|
2618 |
# Remove any OVERDUES related debarment if the borrower has no overdues |
2911 |
# Remove any OVERDUES related debarment if the borrower has no overdues |
2619 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ); |
2912 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ); |
2620 |
if ( $borrowernumber |
2913 |
if ( |
2621 |
&& $borrower->{'debarred'} |
2914 |
$borrowernumber |
2622 |
&& !HasOverdues( $borrowernumber ) |
2915 |
&& $borrower->{'debarred'} |
2623 |
&& @{ GetDebarments({ borrowernumber => $borrowernumber, type => 'OVERDUES' }) } |
2916 |
&& !HasOverdues($borrowernumber) |
2624 |
) { |
2917 |
&& @{ |
2625 |
DelUniqueDebarment({ borrowernumber => $borrowernumber, type => 'OVERDUES' }); |
2918 |
GetDebarments( |
|
|
2919 |
{ borrowernumber => $borrowernumber, type => 'OVERDUES' } |
2920 |
) |
2921 |
} |
2922 |
) |
2923 |
{ |
2924 |
DelUniqueDebarment( |
2925 |
{ borrowernumber => $borrowernumber, type => 'OVERDUES' } ); |
2626 |
} |
2926 |
} |
2627 |
|
2927 |
|
2628 |
# Log the renewal |
2928 |
# Log the renewal |
2629 |
UpdateStats( $branch, 'renew', $charge, '', $itemnumber, $item->{itype}, $borrowernumber, undef, $item->{'ccode'}); |
2929 |
UpdateStats( |
|
|
2930 |
$branch, 'renew', $charge, '', |
2931 |
$itemnumber, $item->{itype}, $borrowernumber, undef, |
2932 |
$item->{'ccode'} |
2933 |
); |
2630 |
return $datedue; |
2934 |
return $datedue; |
2631 |
} |
2935 |
} |
2632 |
|
2936 |
|
2633 |
sub GetRenewCount { |
2937 |
sub GetRenewCount { |
|
|
2938 |
|
2634 |
# check renewal status |
2939 |
# check renewal status |
2635 |
my ( $bornum, $itemno ) = @_; |
2940 |
my ( $bornum, $itemno ) = @_; |
2636 |
my $dbh = C4::Context->dbh; |
2941 |
my $dbh = C4::Context->dbh; |
Lines 2638-2645
sub GetRenewCount {
Link Here
|
2638 |
my $renewsallowed = 0; |
2943 |
my $renewsallowed = 0; |
2639 |
my $renewsleft = 0; |
2944 |
my $renewsleft = 0; |
2640 |
|
2945 |
|
2641 |
my $borrower = C4::Members::GetMember( borrowernumber => $bornum); |
2946 |
my $borrower = C4::Members::GetMember( borrowernumber => $bornum ); |
2642 |
my $item = GetItem($itemno); |
2947 |
my $item = GetItem($itemno); |
2643 |
|
2948 |
|
2644 |
# Look in the issues table for this item, lent to this borrower, |
2949 |
# Look in the issues table for this item, lent to this borrower, |
2645 |
# and not yet returned. |
2950 |
# and not yet returned. |
Lines 2653-2666
sub GetRenewCount {
Link Here
|
2653 |
$sth->execute( $bornum, $itemno ); |
2958 |
$sth->execute( $bornum, $itemno ); |
2654 |
my $data = $sth->fetchrow_hashref; |
2959 |
my $data = $sth->fetchrow_hashref; |
2655 |
$renewcount = $data->{'renewals'} if $data->{'renewals'}; |
2960 |
$renewcount = $data->{'renewals'} if $data->{'renewals'}; |
|
|
2961 |
|
2656 |
# $item and $borrower should be calculated |
2962 |
# $item and $borrower should be calculated |
2657 |
my $branchcode = _GetCircControlBranch($item, $borrower); |
2963 |
my $branchcode = _GetCircControlBranch( $item, $borrower ); |
2658 |
|
2964 |
|
2659 |
my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{itype}, $branchcode); |
2965 |
my $issuingrule = |
2660 |
|
2966 |
GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode ); |
|
|
2967 |
|
2661 |
$renewsallowed = $issuingrule->{'renewalsallowed'}; |
2968 |
$renewsallowed = $issuingrule->{'renewalsallowed'}; |
2662 |
$renewsleft = $renewsallowed - $renewcount; |
2969 |
$renewsleft = $renewsallowed - $renewcount; |
2663 |
if($renewsleft < 0){ $renewsleft = 0; } |
2970 |
if ( $renewsleft < 0 ) { $renewsleft = 0; } |
2664 |
return ( $renewcount, $renewsallowed, $renewsleft ); |
2971 |
return ( $renewcount, $renewsallowed, $renewsleft ); |
2665 |
} |
2972 |
} |
2666 |
|
2973 |
|
Lines 2692-2700
sub GetIssuingCharges {
Link Here
|
2692 |
# Get the book's item type and rental charge (via its biblioitem). |
2999 |
# Get the book's item type and rental charge (via its biblioitem). |
2693 |
my $charge_query = 'SELECT itemtypes.itemtype,rentalcharge FROM items |
3000 |
my $charge_query = 'SELECT itemtypes.itemtype,rentalcharge FROM items |
2694 |
LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber'; |
3001 |
LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber'; |
2695 |
$charge_query .= (C4::Context->preference('item-level_itypes')) |
3002 |
$charge_query .= |
2696 |
? ' LEFT JOIN itemtypes ON items.itype = itemtypes.itemtype' |
3003 |
( C4::Context->preference('item-level_itypes') ) |
2697 |
: ' LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype'; |
3004 |
? ' LEFT JOIN itemtypes ON items.itype = itemtypes.itemtype' |
|
|
3005 |
: ' LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype'; |
2698 |
|
3006 |
|
2699 |
$charge_query .= ' WHERE items.itemnumber =?'; |
3007 |
$charge_query .= ' WHERE items.itemnumber =?'; |
2700 |
|
3008 |
|
Lines 2703-2709
sub GetIssuingCharges {
Link Here
|
2703 |
if ( my $item_data = $sth->fetchrow_hashref ) { |
3011 |
if ( my $item_data = $sth->fetchrow_hashref ) { |
2704 |
$item_type = $item_data->{itemtype}; |
3012 |
$item_type = $item_data->{itemtype}; |
2705 |
$charge = $item_data->{rentalcharge}; |
3013 |
$charge = $item_data->{rentalcharge}; |
2706 |
my $branch = C4::Branch::mybranch(); |
3014 |
my $branch = C4::Branch::mybranch(); |
2707 |
my $discount_query = q|SELECT rentaldiscount, |
3015 |
my $discount_query = q|SELECT rentaldiscount, |
2708 |
issuingrules.itemtype, issuingrules.branchcode |
3016 |
issuingrules.itemtype, issuingrules.branchcode |
2709 |
FROM borrowers |
3017 |
FROM borrowers |
Lines 2713-2722
sub GetIssuingCharges {
Link Here
|
2713 |
AND (issuingrules.branchcode = ? OR issuingrules.branchcode = '*')|; |
3021 |
AND (issuingrules.branchcode = ? OR issuingrules.branchcode = '*')|; |
2714 |
my $discount_sth = $dbh->prepare($discount_query); |
3022 |
my $discount_sth = $dbh->prepare($discount_query); |
2715 |
$discount_sth->execute( $borrowernumber, $item_type, $branch ); |
3023 |
$discount_sth->execute( $borrowernumber, $item_type, $branch ); |
2716 |
my $discount_rules = $discount_sth->fetchall_arrayref({}); |
3024 |
my $discount_rules = $discount_sth->fetchall_arrayref( {} ); |
2717 |
if (@{$discount_rules}) { |
3025 |
|
|
|
3026 |
if ( @{$discount_rules} ) { |
3027 |
|
2718 |
# We may have multiple rules so get the most specific |
3028 |
# We may have multiple rules so get the most specific |
2719 |
my $discount = _get_discount_from_rule($discount_rules, $branch, $item_type); |
3029 |
my $discount = |
|
|
3030 |
_get_discount_from_rule( $discount_rules, $branch, $item_type ); |
2720 |
$charge = ( $charge * ( 100 - $discount ) ) / 100; |
3031 |
$charge = ( $charge * ( 100 - $discount ) ) / 100; |
2721 |
} |
3032 |
} |
2722 |
} |
3033 |
} |
Lines 2726-2762
sub GetIssuingCharges {
Link Here
|
2726 |
|
3037 |
|
2727 |
# Select most appropriate discount rule from those returned |
3038 |
# Select most appropriate discount rule from those returned |
2728 |
sub _get_discount_from_rule { |
3039 |
sub _get_discount_from_rule { |
2729 |
my ($rules_ref, $branch, $itemtype) = @_; |
3040 |
my ( $rules_ref, $branch, $itemtype ) = @_; |
2730 |
my $discount; |
3041 |
my $discount; |
2731 |
|
3042 |
|
2732 |
if (@{$rules_ref} == 1) { # only 1 applicable rule use it |
3043 |
if ( @{$rules_ref} == 1 ) { # only 1 applicable rule use it |
2733 |
$discount = $rules_ref->[0]->{rentaldiscount}; |
3044 |
$discount = $rules_ref->[0]->{rentaldiscount}; |
2734 |
return (defined $discount) ? $discount : 0; |
3045 |
return ( defined $discount ) ? $discount : 0; |
2735 |
} |
3046 |
} |
|
|
3047 |
|
2736 |
# could have up to 4 does one match $branch and $itemtype |
3048 |
# could have up to 4 does one match $branch and $itemtype |
2737 |
my @d = grep { $_->{branchcode} eq $branch && $_->{itemtype} eq $itemtype } @{$rules_ref}; |
3049 |
my @d = grep { $_->{branchcode} eq $branch && $_->{itemtype} eq $itemtype } |
|
|
3050 |
@{$rules_ref}; |
2738 |
if (@d) { |
3051 |
if (@d) { |
2739 |
$discount = $d[0]->{rentaldiscount}; |
3052 |
$discount = $d[0]->{rentaldiscount}; |
2740 |
return (defined $discount) ? $discount : 0; |
3053 |
return ( defined $discount ) ? $discount : 0; |
2741 |
} |
3054 |
} |
|
|
3055 |
|
2742 |
# do we have item type + all branches |
3056 |
# do we have item type + all branches |
2743 |
@d = grep { $_->{branchcode} eq q{*} && $_->{itemtype} eq $itemtype } @{$rules_ref}; |
3057 |
@d = grep { $_->{branchcode} eq q{*} && $_->{itemtype} eq $itemtype } |
|
|
3058 |
@{$rules_ref}; |
2744 |
if (@d) { |
3059 |
if (@d) { |
2745 |
$discount = $d[0]->{rentaldiscount}; |
3060 |
$discount = $d[0]->{rentaldiscount}; |
2746 |
return (defined $discount) ? $discount : 0; |
3061 |
return ( defined $discount ) ? $discount : 0; |
2747 |
} |
3062 |
} |
|
|
3063 |
|
2748 |
# do we all item types + this branch |
3064 |
# do we all item types + this branch |
2749 |
@d = grep { $_->{branchcode} eq $branch && $_->{itemtype} eq q{*} } @{$rules_ref}; |
3065 |
@d = grep { $_->{branchcode} eq $branch && $_->{itemtype} eq q{*} } |
|
|
3066 |
@{$rules_ref}; |
2750 |
if (@d) { |
3067 |
if (@d) { |
2751 |
$discount = $d[0]->{rentaldiscount}; |
3068 |
$discount = $d[0]->{rentaldiscount}; |
2752 |
return (defined $discount) ? $discount : 0; |
3069 |
return ( defined $discount ) ? $discount : 0; |
2753 |
} |
3070 |
} |
|
|
3071 |
|
2754 |
# so all and all (surely we wont get here) |
3072 |
# so all and all (surely we wont get here) |
2755 |
@d = grep { $_->{branchcode} eq q{*} && $_->{itemtype} eq q{*} } @{$rules_ref}; |
3073 |
@d = |
|
|
3074 |
grep { $_->{branchcode} eq q{*} && $_->{itemtype} eq q{*} } @{$rules_ref}; |
2756 |
if (@d) { |
3075 |
if (@d) { |
2757 |
$discount = $d[0]->{rentaldiscount}; |
3076 |
$discount = $d[0]->{rentaldiscount}; |
2758 |
return (defined $discount) ? $discount : 0; |
3077 |
return ( defined $discount ) ? $discount : 0; |
2759 |
} |
3078 |
} |
|
|
3079 |
|
2760 |
# none of the above |
3080 |
# none of the above |
2761 |
return 0; |
3081 |
return 0; |
2762 |
} |
3082 |
} |
Lines 2769-2779
sub _get_discount_from_rule {
Link Here
|
2769 |
|
3089 |
|
2770 |
sub AddIssuingCharge { |
3090 |
sub AddIssuingCharge { |
2771 |
my ( $itemnumber, $borrowernumber, $charge ) = @_; |
3091 |
my ( $itemnumber, $borrowernumber, $charge ) = @_; |
2772 |
my $dbh = C4::Context->dbh; |
3092 |
my $dbh = C4::Context->dbh; |
2773 |
my $nextaccntno = getnextacctno( $borrowernumber ); |
3093 |
my $nextaccntno = getnextacctno($borrowernumber); |
2774 |
my $manager_id = 0; |
3094 |
my $manager_id = 0; |
2775 |
$manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; |
3095 |
$manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; |
2776 |
my $query =" |
3096 |
my $query = " |
2777 |
INSERT INTO accountlines |
3097 |
INSERT INTO accountlines |
2778 |
(borrowernumber, itemnumber, accountno, |
3098 |
(borrowernumber, itemnumber, accountno, |
2779 |
date, amount, description, accounttype, |
3099 |
date, amount, description, accounttype, |
Lines 2781-2787
sub AddIssuingCharge {
Link Here
|
2781 |
VALUES (?, ?, ?,now(), ?, 'Rental', 'Rent',?,?) |
3101 |
VALUES (?, ?, ?,now(), ?, 'Rental', 'Rent',?,?) |
2782 |
"; |
3102 |
"; |
2783 |
my $sth = $dbh->prepare($query); |
3103 |
my $sth = $dbh->prepare($query); |
2784 |
$sth->execute( $borrowernumber, $itemnumber, $nextaccntno, $charge, $charge, $manager_id ); |
3104 |
$sth->execute( $borrowernumber, $itemnumber, $nextaccntno, $charge, |
|
|
3105 |
$charge, $manager_id ); |
2785 |
} |
3106 |
} |
2786 |
|
3107 |
|
2787 |
=head2 GetTransfers |
3108 |
=head2 GetTransfers |
Lines 2847-2854
sub GetTransfersFromTo {
Link Here
|
2847 |
sub DeleteTransfer { |
3168 |
sub DeleteTransfer { |
2848 |
my ($itemnumber) = @_; |
3169 |
my ($itemnumber) = @_; |
2849 |
return unless $itemnumber; |
3170 |
return unless $itemnumber; |
2850 |
my $dbh = C4::Context->dbh; |
3171 |
my $dbh = C4::Context->dbh; |
2851 |
my $sth = $dbh->prepare( |
3172 |
my $sth = $dbh->prepare( |
2852 |
"DELETE FROM branchtransfers |
3173 |
"DELETE FROM branchtransfers |
2853 |
WHERE itemnumber=? |
3174 |
WHERE itemnumber=? |
2854 |
AND datearrived IS NULL " |
3175 |
AND datearrived IS NULL " |
Lines 2881-2901
sub AnonymiseIssueHistory {
Link Here
|
2881 |
AND borrowernumber IS NOT NULL |
3202 |
AND borrowernumber IS NOT NULL |
2882 |
"; |
3203 |
"; |
2883 |
|
3204 |
|
2884 |
# The default of 0 does not work due to foreign key constraints |
3205 |
# The default of 0 does not work due to foreign key constraints |
2885 |
# The anonymisation will fail quietly if AnonymousPatron is not a valid entry |
3206 |
# The anonymisation will fail quietly if AnonymousPatron is not a valid entry |
2886 |
my $anonymouspatron = (C4::Context->preference('AnonymousPatron')) ? C4::Context->preference('AnonymousPatron') : 0; |
3207 |
my $anonymouspatron = |
2887 |
my @bind_params = ($anonymouspatron, $date); |
3208 |
( C4::Context->preference('AnonymousPatron') ) |
2888 |
if (defined $borrowernumber) { |
3209 |
? C4::Context->preference('AnonymousPatron') |
2889 |
$query .= " AND borrowernumber = ?"; |
3210 |
: 0; |
2890 |
push @bind_params, $borrowernumber; |
3211 |
my @bind_params = ( $anonymouspatron, $date ); |
2891 |
} else { |
3212 |
if ( defined $borrowernumber ) { |
2892 |
$query .= " AND (SELECT privacy FROM borrowers WHERE borrowers.borrowernumber=old_issues.borrowernumber) <> 0"; |
3213 |
$query .= " AND borrowernumber = ?"; |
|
|
3214 |
push @bind_params, $borrowernumber; |
3215 |
} |
3216 |
else { |
3217 |
$query .= |
3218 |
" AND (SELECT privacy FROM borrowers WHERE borrowers.borrowernumber=old_issues.borrowernumber) <> 0"; |
2893 |
} |
3219 |
} |
2894 |
my $sth = $dbh->prepare($query); |
3220 |
my $sth = $dbh->prepare($query); |
2895 |
$sth->execute(@bind_params); |
3221 |
$sth->execute(@bind_params); |
2896 |
my $anonymisation_err = $dbh->err; |
3222 |
my $anonymisation_err = $dbh->err; |
2897 |
my $rows_affected = $sth->rows; ### doublecheck row count return function |
3223 |
my $rows_affected = $sth->rows; ### doublecheck row count return function |
2898 |
return ($rows_affected, $anonymisation_err); |
3224 |
return ( $rows_affected, $anonymisation_err ); |
2899 |
} |
3225 |
} |
2900 |
|
3226 |
|
2901 |
=head2 SendCirculationAlert |
3227 |
=head2 SendCirculationAlert |
Lines 2937-2959
B<Example>:
Link Here
|
2937 |
|
3263 |
|
2938 |
sub SendCirculationAlert { |
3264 |
sub SendCirculationAlert { |
2939 |
my ($opts) = @_; |
3265 |
my ($opts) = @_; |
2940 |
my ($type, $item, $borrower, $branch) = |
3266 |
my ( $type, $item, $borrower, $branch ) = |
2941 |
($opts->{type}, $opts->{item}, $opts->{borrower}, $opts->{branch}); |
3267 |
( $opts->{type}, $opts->{item}, $opts->{borrower}, $opts->{branch} ); |
2942 |
my %message_name = ( |
3268 |
my %message_name = ( |
2943 |
CHECKIN => 'Item_Check_in', |
3269 |
CHECKIN => 'Item_Check_in', |
2944 |
CHECKOUT => 'Item_Checkout', |
3270 |
CHECKOUT => 'Item_Checkout', |
2945 |
RENEWAL => 'Item_Checkout', |
3271 |
RENEWAL => 'Item_Checkout', |
2946 |
); |
3272 |
); |
2947 |
my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences({ |
3273 |
my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( |
2948 |
borrowernumber => $borrower->{borrowernumber}, |
3274 |
{ |
2949 |
message_name => $message_name{$type}, |
3275 |
borrowernumber => $borrower->{borrowernumber}, |
2950 |
}); |
3276 |
message_name => $message_name{$type}, |
2951 |
my $issues_table = ( $type eq 'CHECKOUT' || $type eq 'RENEWAL' ) ? 'issues' : 'old_issues'; |
3277 |
} |
2952 |
my $letter = C4::Letters::GetPreparedLetter ( |
3278 |
); |
2953 |
module => 'circulation', |
3279 |
my $issues_table = |
|
|
3280 |
( $type eq 'CHECKOUT' || $type eq 'RENEWAL' ) ? 'issues' : 'old_issues'; |
3281 |
my $letter = C4::Letters::GetPreparedLetter( |
3282 |
module => 'circulation', |
2954 |
letter_code => $type, |
3283 |
letter_code => $type, |
2955 |
branchcode => $branch, |
3284 |
branchcode => $branch, |
2956 |
tables => { |
3285 |
tables => { |
2957 |
$issues_table => $item->{itemnumber}, |
3286 |
$issues_table => $item->{itemnumber}, |
2958 |
'items' => $item->{itemnumber}, |
3287 |
'items' => $item->{itemnumber}, |
2959 |
'biblio' => $item->{biblionumber}, |
3288 |
'biblio' => $item->{biblionumber}, |
Lines 2964-2977
sub SendCirculationAlert {
Link Here
|
2964 |
) or return; |
3293 |
) or return; |
2965 |
|
3294 |
|
2966 |
my @transports = keys %{ $borrower_preferences->{transports} }; |
3295 |
my @transports = keys %{ $borrower_preferences->{transports} }; |
|
|
3296 |
|
2967 |
# warn "no transports" unless @transports; |
3297 |
# warn "no transports" unless @transports; |
2968 |
for (@transports) { |
3298 |
for (@transports) { |
|
|
3299 |
|
2969 |
# warn "transport: $_"; |
3300 |
# warn "transport: $_"; |
2970 |
my $message = C4::Message->find_last_message($borrower, $type, $_); |
3301 |
my $message = C4::Message->find_last_message( $borrower, $type, $_ ); |
2971 |
if (!$message) { |
3302 |
if ( !$message ) { |
|
|
3303 |
|
2972 |
#warn "create new message"; |
3304 |
#warn "create new message"; |
2973 |
C4::Message->enqueue($letter, $borrower, $_); |
3305 |
C4::Message->enqueue( $letter, $borrower, $_ ); |
2974 |
} else { |
3306 |
} |
|
|
3307 |
else { |
2975 |
#warn "append to old message"; |
3308 |
#warn "append to old message"; |
2976 |
$message->append($letter); |
3309 |
$message->append($letter); |
2977 |
$message->update; |
3310 |
$message->update; |
Lines 2990-3009
This function validate the line of brachtransfer but with the wrong destination
Link Here
|
2990 |
=cut |
3323 |
=cut |
2991 |
|
3324 |
|
2992 |
sub updateWrongTransfer { |
3325 |
sub updateWrongTransfer { |
2993 |
my ( $itemNumber,$waitingAtLibrary,$FromLibrary ) = @_; |
3326 |
my ( $itemNumber, $waitingAtLibrary, $FromLibrary ) = @_; |
2994 |
my $dbh = C4::Context->dbh; |
3327 |
my $dbh = C4::Context->dbh; |
2995 |
# first step validate the actual line of transfert . |
3328 |
|
|
|
3329 |
# first step validate the actual line of transfert . |
2996 |
my $sth = |
3330 |
my $sth = |
2997 |
$dbh->prepare( |
3331 |
$dbh->prepare( |
2998 |
"update branchtransfers set datearrived = now(),tobranch=?,comments='wrongtransfer' where itemnumber= ? AND datearrived IS NULL" |
3332 |
"update branchtransfers set datearrived = now(),tobranch=?,comments='wrongtransfer' where itemnumber= ? AND datearrived IS NULL" |
2999 |
); |
3333 |
); |
3000 |
$sth->execute($FromLibrary,$itemNumber); |
3334 |
$sth->execute( $FromLibrary, $itemNumber ); |
3001 |
|
3335 |
|
3002 |
# second step create a new line of branchtransfer to the right location . |
3336 |
# second step create a new line of branchtransfer to the right location . |
3003 |
ModItemTransfer($itemNumber, $FromLibrary, $waitingAtLibrary); |
3337 |
ModItemTransfer( $itemNumber, $FromLibrary, $waitingAtLibrary ); |
3004 |
|
3338 |
|
3005 |
#third step changing holdingbranch of item |
3339 |
#third step changing holdingbranch of item |
3006 |
UpdateHoldingbranch($FromLibrary,$itemNumber); |
3340 |
UpdateHoldingbranch( $FromLibrary, $itemNumber ); |
3007 |
} |
3341 |
} |
3008 |
|
3342 |
|
3009 |
=head2 UpdateHoldingbranch |
3343 |
=head2 UpdateHoldingbranch |
Lines 3015-3022
Simple methode for updating hodlingbranch in items BDD line
Link Here
|
3015 |
=cut |
3349 |
=cut |
3016 |
|
3350 |
|
3017 |
sub UpdateHoldingbranch { |
3351 |
sub UpdateHoldingbranch { |
3018 |
my ( $branch,$itemnumber ) = @_; |
3352 |
my ( $branch, $itemnumber ) = @_; |
3019 |
ModItem({ holdingbranch => $branch }, undef, $itemnumber); |
3353 |
ModItem( { holdingbranch => $branch }, undef, $itemnumber ); |
3020 |
} |
3354 |
} |
3021 |
|
3355 |
|
3022 |
=head2 CalcDateDue |
3356 |
=head2 CalcDateDue |
Lines 3040-3086
sub CalcDateDue {
Link Here
|
3040 |
|
3374 |
|
3041 |
# loanlength now a href |
3375 |
# loanlength now a href |
3042 |
my $loanlength = |
3376 |
my $loanlength = |
3043 |
GetLoanLength( $borrower->{'categorycode'}, $itemtype, $branch ); |
3377 |
GetLoanLength( $borrower->{'categorycode'}, $itemtype, $branch ); |
3044 |
|
3378 |
|
3045 |
my $length_key = ( $isrenewal and defined $loanlength->{renewalperiod} ) |
3379 |
my $length_key = |
3046 |
? qq{renewalperiod} |
3380 |
( $isrenewal and defined $loanlength->{renewalperiod} ) |
3047 |
: qq{issuelength}; |
3381 |
? qq{renewalperiod} |
|
|
3382 |
: qq{issuelength}; |
3048 |
|
3383 |
|
3049 |
my $datedue; |
3384 |
my $datedue; |
3050 |
if ( $startdate ) { |
3385 |
if ($startdate) { |
3051 |
if (ref $startdate ne 'DateTime' ) { |
3386 |
if ( ref $startdate ne 'DateTime' ) { |
3052 |
$datedue = dt_from_string($datedue); |
3387 |
$datedue = dt_from_string($datedue); |
3053 |
} else { |
3388 |
} |
|
|
3389 |
else { |
3054 |
$datedue = $startdate->clone; |
3390 |
$datedue = $startdate->clone; |
3055 |
} |
3391 |
} |
3056 |
} else { |
3392 |
} |
|
|
3393 |
else { |
3057 |
$datedue = |
3394 |
$datedue = |
3058 |
DateTime->now( time_zone => C4::Context->tz() ) |
3395 |
DateTime->now( time_zone => C4::Context->tz() ) |
3059 |
->truncate( to => 'minute' ); |
3396 |
->truncate( to => 'minute' ); |
3060 |
} |
3397 |
} |
3061 |
|
3398 |
|
3062 |
|
|
|
3063 |
# calculate the datedue as normal |
3399 |
# calculate the datedue as normal |
3064 |
if ( C4::Context->preference('useDaysMode') eq 'Days' ) |
3400 |
if ( C4::Context->preference('useDaysMode') eq 'Days' ) |
3065 |
{ # ignoring calendar |
3401 |
{ # ignoring calendar |
3066 |
if ( $loanlength->{lengthunit} eq 'hours' ) { |
3402 |
if ( $loanlength->{lengthunit} eq 'hours' ) { |
3067 |
$datedue->add( hours => $loanlength->{$length_key} ); |
3403 |
$datedue->add( hours => $loanlength->{$length_key} ); |
3068 |
} else { # days |
3404 |
} |
|
|
3405 |
else { # days |
3069 |
$datedue->add( days => $loanlength->{$length_key} ); |
3406 |
$datedue->add( days => $loanlength->{$length_key} ); |
3070 |
$datedue->set_hour(23); |
3407 |
$datedue->set_hour(23); |
3071 |
$datedue->set_minute(59); |
3408 |
$datedue->set_minute(59); |
3072 |
} |
3409 |
} |
3073 |
} else { |
3410 |
} |
|
|
3411 |
else { |
3074 |
my $dur; |
3412 |
my $dur; |
3075 |
if ($loanlength->{lengthunit} eq 'hours') { |
3413 |
if ( $loanlength->{lengthunit} eq 'hours' ) { |
3076 |
$dur = DateTime::Duration->new( hours => $loanlength->{$length_key}); |
3414 |
$dur = |
|
|
3415 |
DateTime::Duration->new( hours => $loanlength->{$length_key} ); |
3077 |
} |
3416 |
} |
3078 |
else { # days |
3417 |
else { # days |
3079 |
$dur = DateTime::Duration->new( days => $loanlength->{$length_key}); |
3418 |
$dur = |
|
|
3419 |
DateTime::Duration->new( days => $loanlength->{$length_key} ); |
3080 |
} |
3420 |
} |
3081 |
my $calendar = Koha::Calendar->new( branchcode => $branch ); |
3421 |
my $calendar = Koha::Calendar->new( branchcode => $branch ); |
3082 |
$datedue = $calendar->addDate( $datedue, $dur, $loanlength->{lengthunit} ); |
3422 |
$datedue = |
3083 |
if ($loanlength->{lengthunit} eq 'days') { |
3423 |
$calendar->addDate( $datedue, $dur, $loanlength->{lengthunit} ); |
|
|
3424 |
if ( $loanlength->{lengthunit} eq 'days' ) { |
3084 |
$datedue->set_hour(23); |
3425 |
$datedue->set_hour(23); |
3085 |
$datedue->set_minute(59); |
3426 |
$datedue->set_minute(59); |
3086 |
} |
3427 |
} |
Lines 3109-3115
sub CalcDateDue {
Link Here
|
3109 |
# if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate |
3450 |
# if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate |
3110 |
if ( C4::Context->preference('ReturnBeforeExpiry') ) { |
3451 |
if ( C4::Context->preference('ReturnBeforeExpiry') ) { |
3111 |
my $expiry_dt = dt_from_string( $borrower->{dateexpiry}, 'iso' ); |
3452 |
my $expiry_dt = dt_from_string( $borrower->{dateexpiry}, 'iso' ); |
3112 |
$expiry_dt->set( hour => 23, minute => 59); |
3453 |
$expiry_dt->set( hour => 23, minute => 59 ); |
3113 |
if ( DateTime->compare( $datedue, $expiry_dt ) == 1 ) { |
3454 |
if ( DateTime->compare( $datedue, $expiry_dt ) == 1 ) { |
3114 |
$datedue = $expiry_dt->clone; |
3455 |
$datedue = $expiry_dt->clone; |
3115 |
} |
3456 |
} |
Lines 3118-3124
sub CalcDateDue {
Link Here
|
3118 |
return $datedue; |
3459 |
return $datedue; |
3119 |
} |
3460 |
} |
3120 |
|
3461 |
|
3121 |
|
|
|
3122 |
=head2 CheckRepeatableHolidays |
3462 |
=head2 CheckRepeatableHolidays |
3123 |
|
3463 |
|
3124 |
$countrepeatable = CheckRepeatableHoliday($itemnumber,$week_day,$branchcode); |
3464 |
$countrepeatable = CheckRepeatableHoliday($itemnumber,$week_day,$branchcode); |
Lines 3131-3150
C<$branchcode> = localisation of issue
Link Here
|
3131 |
|
3471 |
|
3132 |
=cut |
3472 |
=cut |
3133 |
|
3473 |
|
3134 |
sub CheckRepeatableHolidays{ |
3474 |
sub CheckRepeatableHolidays { |
3135 |
my($itemnumber,$week_day,$branchcode)=@_; |
3475 |
my ( $itemnumber, $week_day, $branchcode ) = @_; |
3136 |
my $dbh = C4::Context->dbh; |
3476 |
my $dbh = C4::Context->dbh; |
3137 |
my $query = qq|SELECT count(*) |
3477 |
my $query = qq|SELECT count(*) |
3138 |
FROM repeatable_holidays |
3478 |
FROM repeatable_holidays |
3139 |
WHERE branchcode=? |
3479 |
WHERE branchcode=? |
3140 |
AND weekday=?|; |
3480 |
AND weekday=?|; |
3141 |
my $sth = $dbh->prepare($query); |
3481 |
my $sth = $dbh->prepare($query); |
3142 |
$sth->execute($branchcode,$week_day); |
3482 |
$sth->execute( $branchcode, $week_day ); |
3143 |
my $result=$sth->fetchrow; |
3483 |
my $result = $sth->fetchrow; |
3144 |
return $result; |
3484 |
return $result; |
3145 |
} |
3485 |
} |
3146 |
|
3486 |
|
3147 |
|
|
|
3148 |
=head2 CheckSpecialHolidays |
3487 |
=head2 CheckSpecialHolidays |
3149 |
|
3488 |
|
3150 |
$countspecial = CheckSpecialHolidays($years,$month,$day,$itemnumber,$branchcode); |
3489 |
$countspecial = CheckSpecialHolidays($years,$month,$day,$itemnumber,$branchcode); |
Lines 3159-3178
C<$branchcode> = localisation of issue
Link Here
|
3159 |
|
3498 |
|
3160 |
=cut |
3499 |
=cut |
3161 |
|
3500 |
|
3162 |
sub CheckSpecialHolidays{ |
3501 |
sub CheckSpecialHolidays { |
3163 |
my ($years,$month,$day,$itemnumber,$branchcode) = @_; |
3502 |
my ( $years, $month, $day, $itemnumber, $branchcode ) = @_; |
3164 |
my $dbh = C4::Context->dbh; |
3503 |
my $dbh = C4::Context->dbh; |
3165 |
my $query=qq|SELECT count(*) |
3504 |
my $query = qq|SELECT count(*) |
3166 |
FROM `special_holidays` |
3505 |
FROM `special_holidays` |
3167 |
WHERE year=? |
3506 |
WHERE year=? |
3168 |
AND month=? |
3507 |
AND month=? |
3169 |
AND day=? |
3508 |
AND day=? |
3170 |
AND branchcode=? |
3509 |
AND branchcode=? |
3171 |
|; |
3510 |
|; |
3172 |
my $sth = $dbh->prepare($query); |
3511 |
my $sth = $dbh->prepare($query); |
3173 |
$sth->execute($years,$month,$day,$branchcode); |
3512 |
$sth->execute( $years, $month, $day, $branchcode ); |
3174 |
my $countspecial=$sth->fetchrow ; |
3513 |
my $countspecial = $sth->fetchrow; |
3175 |
return $countspecial; |
3514 |
return $countspecial; |
3176 |
} |
3515 |
} |
3177 |
|
3516 |
|
3178 |
=head2 CheckRepeatableSpecialHolidays |
3517 |
=head2 CheckRepeatableSpecialHolidays |
Lines 3188-3224
C<$branchcode> = localisation of issue
Link Here
|
3188 |
|
3527 |
|
3189 |
=cut |
3528 |
=cut |
3190 |
|
3529 |
|
3191 |
sub CheckRepeatableSpecialHolidays{ |
3530 |
sub CheckRepeatableSpecialHolidays { |
3192 |
my ($month,$day,$itemnumber,$branchcode) = @_; |
3531 |
my ( $month, $day, $itemnumber, $branchcode ) = @_; |
3193 |
my $dbh = C4::Context->dbh; |
3532 |
my $dbh = C4::Context->dbh; |
3194 |
my $query=qq|SELECT count(*) |
3533 |
my $query = qq|SELECT count(*) |
3195 |
FROM `repeatable_holidays` |
3534 |
FROM `repeatable_holidays` |
3196 |
WHERE month=? |
3535 |
WHERE month=? |
3197 |
AND day=? |
3536 |
AND day=? |
3198 |
AND branchcode=? |
3537 |
AND branchcode=? |
3199 |
|; |
3538 |
|; |
3200 |
my $sth = $dbh->prepare($query); |
3539 |
my $sth = $dbh->prepare($query); |
3201 |
$sth->execute($month,$day,$branchcode); |
3540 |
$sth->execute( $month, $day, $branchcode ); |
3202 |
my $countspecial=$sth->fetchrow ; |
3541 |
my $countspecial = $sth->fetchrow; |
3203 |
return $countspecial; |
3542 |
return $countspecial; |
3204 |
} |
3543 |
} |
3205 |
|
3544 |
|
3206 |
|
3545 |
sub CheckValidBarcode { |
3207 |
|
3546 |
my ($barcode) = @_; |
3208 |
sub CheckValidBarcode{ |
3547 |
my $dbh = C4::Context->dbh; |
3209 |
my ($barcode) = @_; |
3548 |
my $query = qq|SELECT count(*) |
3210 |
my $dbh = C4::Context->dbh; |
|
|
3211 |
my $query=qq|SELECT count(*) |
3212 |
FROM items |
3549 |
FROM items |
3213 |
WHERE barcode=? |
3550 |
WHERE barcode=? |
3214 |
|; |
3551 |
|; |
3215 |
my $sth = $dbh->prepare($query); |
3552 |
my $sth = $dbh->prepare($query); |
3216 |
$sth->execute($barcode); |
3553 |
$sth->execute($barcode); |
3217 |
my $exist=$sth->fetchrow ; |
3554 |
my $exist = $sth->fetchrow; |
3218 |
return $exist; |
3555 |
return $exist; |
3219 |
} |
3556 |
} |
3220 |
|
3557 |
|
3221 |
|
|
|
3222 |
=head2 CanItemBeTransferred |
3558 |
=head2 CanItemBeTransferred |
3223 |
|
3559 |
|
3224 |
A convenience function to easily check item transfer limits. |
3560 |
A convenience function to easily check item transfer limits. |
Lines 3248-3304
sub CanItemBeTransferred {
Link Here
|
3248 |
#When we check for BranchTransferLimit global settings centrally, it makes |
3584 |
#When we check for BranchTransferLimit global settings centrally, it makes |
3249 |
# using this functionality much easier. |
3585 |
# using this functionality much easier. |
3250 |
unless ( C4::Context->preference("UseBranchTransferLimits") == 1 ) { |
3586 |
unless ( C4::Context->preference("UseBranchTransferLimits") == 1 ) { |
3251 |
return 1; |
3587 |
return 1; |
3252 |
} |
3588 |
} |
3253 |
|
3589 |
|
3254 |
#Init parameter variables |
3590 |
#Init parameter variables |
3255 |
my ( $toBranch, $fromBranch, $item, $biblioitem ) = @_; |
3591 |
my ( $toBranch, $fromBranch, $item, $biblioitem ) = @_; |
3256 |
|
3592 |
|
3257 |
#Check the $fromBranch and set the DEFAULT value |
3593 |
#Check the $fromBranch and set the DEFAULT value |
3258 |
$fromBranch = $item->{holdingbranch} if ! defined $fromBranch; |
3594 |
$fromBranch = $item->{holdingbranch} if !defined $fromBranch; |
3259 |
|
3595 |
|
3260 |
if ( $toBranch eq $fromBranch ) { return 1; } ## Short circuit for speed. |
3596 |
if ( $toBranch eq $fromBranch ) { return 1; } ## Short circuit for speed. |
3261 |
|
3597 |
|
3262 |
#This is the CCode or itemtype value used to find the correct transfer rule for this item. |
3598 |
#This is the CCode or itemtype value used to find the correct transfer rule for this item. |
3263 |
my $code; |
3599 |
my $code; |
3264 |
|
3600 |
|
3265 |
## Figure out the $code! |
3601 |
## Figure out the $code! |
3266 |
## First we need to figure out are we using CCODE or itemtype, this limits do we need $biblioitem or not. |
3602 |
## First we need to figure out are we using CCODE or itemtype, this limits do we need $biblioitem or not. |
3267 |
## Since $biblioitem can be optional, we cannot count that it is defined. |
3603 |
## Since $biblioitem can be optional, we cannot count that it is defined. |
3268 |
if ( C4::Context->preference("BranchTransferLimitsType") eq 'itemtype' ) { |
3604 |
if ( C4::Context->preference("BranchTransferLimitsType") eq 'itemtype' ) { |
3269 |
if (C4::Context->preference("item-level_itypes") && defined $item->{'itype'}) { |
3605 |
if ( C4::Context->preference("item-level_itypes") |
3270 |
$code = $item->{'itype'}; #Easiest way to get the $code is from the item. |
3606 |
&& defined $item->{'itype'} ) |
3271 |
} |
3607 |
{ |
3272 |
elsif (defined $biblioitem->{itemtype}) { |
3608 |
$code = |
3273 |
$code = $biblioitem->{itemtype} |
3609 |
$item->{'itype'}; #Easiest way to get the $code is from the item. |
3274 |
} |
3610 |
} |
3275 |
#If code cannot be resolved from $item or $biblioitem, we need to escalate to the DB |
3611 |
elsif ( defined $biblioitem->{itemtype} ) { |
3276 |
else { |
3612 |
$code = $biblioitem->{itemtype}; |
3277 |
$biblioitem = C4::Biblio::GetBiblioFromItemNumber( $item->{itemnumber} ); |
3613 |
} |
3278 |
$code = $biblioitem->{itemtype} |
|
|
3279 |
} |
3280 |
|
3614 |
|
3281 |
} else { |
3615 |
#If code cannot be resolved from $item or $biblioitem, we need to escalate to the DB |
3282 |
my $limitType = C4::Context->preference("BranchTransferLimitsType"); |
3616 |
else { |
3283 |
if (defined $item->{ $limitType }) { |
3617 |
$biblioitem = |
3284 |
$code = $item->{ $limitType }; |
3618 |
C4::Biblio::GetBiblioFromItemNumber( $item->{itemnumber} ); |
3285 |
} |
3619 |
$code = $biblioitem->{itemtype}; |
3286 |
else { |
3620 |
} |
3287 |
#collection code (ccode) is not present in the Biblio, so no point looking there. |
3621 |
|
3288 |
# If the Item doesn't have a itemtype, then give up and let the transfer pass. |
3622 |
} |
3289 |
} |
3623 |
else { |
|
|
3624 |
my $limitType = C4::Context->preference("BranchTransferLimitsType"); |
3625 |
if ( defined $item->{$limitType} ) { |
3626 |
$code = $item->{$limitType}; |
3627 |
} |
3628 |
else { |
3629 |
#collection code (ccode) is not present in the Biblio, so no point looking there. |
3630 |
# If the Item doesn't have a itemtype, then give up and let the transfer pass. |
3631 |
} |
3290 |
} |
3632 |
} |
3291 |
## Phew we finally got the $code, now it's time to rumble! |
3633 |
## Phew we finally got the $code, now it's time to rumble! |
3292 |
|
3634 |
|
3293 |
if (! IsBranchTransferAllowed($toBranch, $fromBranch, $code)) { |
3635 |
if ( !IsBranchTransferAllowed( $toBranch, $fromBranch, $code ) ) { |
3294 |
return 0, "$fromBranch->$toBranch->$code"; |
3636 |
return 0, "$fromBranch->$toBranch->$code"; |
3295 |
} |
3637 |
} |
3296 |
else { |
3638 |
else { |
3297 |
return 1; |
3639 |
return 1; |
3298 |
} |
3640 |
} |
3299 |
} |
3641 |
} |
3300 |
|
3642 |
|
3301 |
|
|
|
3302 |
=head2 IsBranchTransferAllowed |
3643 |
=head2 IsBranchTransferAllowed |
3303 |
|
3644 |
|
3304 |
$allowed = IsBranchTransferAllowed( $toBranch, $fromBranch, $code ); |
3645 |
$allowed = IsBranchTransferAllowed( $toBranch, $fromBranch, $code ); |
Lines 3310-3331
Code is either an itemtype or collection doe depending on the pref BranchTransfe
Link Here
|
3310 |
sub IsBranchTransferAllowed { |
3651 |
sub IsBranchTransferAllowed { |
3311 |
my ( $toBranch, $fromBranch, $code ) = @_; |
3652 |
my ( $toBranch, $fromBranch, $code ) = @_; |
3312 |
|
3653 |
|
3313 |
if ( $toBranch eq $fromBranch ) { return 1; } ## Short circuit for speed. |
3654 |
if ( $toBranch eq $fromBranch ) { return 1; } ## Short circuit for speed. |
3314 |
|
3655 |
|
3315 |
my $limitType = C4::Context->preference("BranchTransferLimitsType"); |
3656 |
my $limitType = C4::Context->preference("BranchTransferLimitsType"); |
3316 |
my $dbh = C4::Context->dbh; |
3657 |
my $dbh = C4::Context->dbh; |
3317 |
|
3658 |
|
3318 |
my $sth = $dbh->prepare("SELECT * FROM branch_transfer_limits WHERE toBranch = ? AND fromBranch = ? AND $limitType = ?"); |
3659 |
my $sth = $dbh->prepare( |
|
|
3660 |
"SELECT * FROM branch_transfer_limits WHERE toBranch = ? AND fromBranch = ? AND $limitType = ?" |
3661 |
); |
3319 |
$sth->execute( $toBranch, $fromBranch, $code ); |
3662 |
$sth->execute( $toBranch, $fromBranch, $code ); |
3320 |
my $limit = $sth->fetchrow_hashref(); |
3663 |
my $limit = $sth->fetchrow_hashref(); |
3321 |
|
3664 |
|
3322 |
## If a row is found, then that combination is not allowed, if no matching row is found, then the combination *is allowed* |
3665 |
## If a row is found, then that combination is not allowed, if no matching row is found, then the combination *is allowed* |
3323 |
if ( $limit->{'limitId'} ) { |
3666 |
if ( $limit->{'limitId'} ) { |
3324 |
return 0; |
3667 |
return 0; |
3325 |
} else { |
3668 |
} |
|
|
3669 |
else { |
3326 |
return 1; |
3670 |
return 1; |
3327 |
} |
3671 |
} |
3328 |
} |
3672 |
} |
3329 |
|
3673 |
|
3330 |
=head2 CreateBranchTransferLimit |
3674 |
=head2 CreateBranchTransferLimit |
3331 |
|
3675 |
|
Lines 3336-3349
$code is either itemtype or collection code depending on what the pref BranchTra
Link Here
|
3336 |
=cut |
3680 |
=cut |
3337 |
|
3681 |
|
3338 |
sub CreateBranchTransferLimit { |
3682 |
sub CreateBranchTransferLimit { |
3339 |
my ( $toBranch, $fromBranch, $code ) = @_; |
3683 |
my ( $toBranch, $fromBranch, $code ) = @_; |
3340 |
return unless defined($toBranch) && defined($fromBranch); |
3684 |
return unless defined($toBranch) && defined($fromBranch); |
3341 |
my $limitType = C4::Context->preference("BranchTransferLimitsType"); |
3685 |
my $limitType = C4::Context->preference("BranchTransferLimitsType"); |
3342 |
|
3686 |
|
3343 |
my $dbh = C4::Context->dbh; |
3687 |
my $dbh = C4::Context->dbh; |
3344 |
|
3688 |
|
3345 |
my $sth = $dbh->prepare("INSERT INTO branch_transfer_limits ( $limitType, toBranch, fromBranch ) VALUES ( ?, ?, ? )"); |
3689 |
my $sth = $dbh->prepare( |
3346 |
return $sth->execute( $code, $toBranch, $fromBranch ); |
3690 |
"INSERT INTO branch_transfer_limits ( $limitType, toBranch, fromBranch ) VALUES ( ?, ?, ? )" |
|
|
3691 |
); |
3692 |
return $sth->execute( $code, $toBranch, $fromBranch ); |
3347 |
} |
3693 |
} |
3348 |
|
3694 |
|
3349 |
=head2 DeleteBranchTransferLimits |
3695 |
=head2 DeleteBranchTransferLimits |
Lines 3359-3418
no arguments are supplied.
Link Here
|
3359 |
sub DeleteBranchTransferLimits { |
3705 |
sub DeleteBranchTransferLimits { |
3360 |
my $branch = shift; |
3706 |
my $branch = shift; |
3361 |
return unless defined $branch; |
3707 |
return unless defined $branch; |
3362 |
my $dbh = C4::Context->dbh; |
3708 |
my $dbh = C4::Context->dbh; |
3363 |
my $sth = $dbh->prepare("DELETE FROM branch_transfer_limits WHERE fromBranch = ?"); |
3709 |
my $sth = |
|
|
3710 |
$dbh->prepare("DELETE FROM branch_transfer_limits WHERE fromBranch = ?"); |
3364 |
return $sth->execute($branch); |
3711 |
return $sth->execute($branch); |
3365 |
} |
3712 |
} |
3366 |
|
3713 |
|
3367 |
sub ReturnLostItem{ |
3714 |
sub ReturnLostItem { |
3368 |
my ( $borrowernumber, $itemnum ) = @_; |
3715 |
my ( $borrowernumber, $itemnum ) = @_; |
3369 |
|
3716 |
|
3370 |
MarkIssueReturned( $borrowernumber, $itemnum ); |
3717 |
MarkIssueReturned( $borrowernumber, $itemnum ); |
3371 |
my $borrower = C4::Members::GetMember( 'borrowernumber'=>$borrowernumber ); |
3718 |
my $borrower = |
3372 |
my $item = C4::Items::GetItem( $itemnum ); |
3719 |
C4::Members::GetMember( 'borrowernumber' => $borrowernumber ); |
3373 |
my $old_note = ($item->{'paidfor'} && ($item->{'paidfor'} ne q{})) ? $item->{'paidfor'}.' / ' : q{}; |
3720 |
my $item = C4::Items::GetItem($itemnum); |
|
|
3721 |
my $old_note = |
3722 |
( $item->{'paidfor'} && ( $item->{'paidfor'} ne q{} ) ) |
3723 |
? $item->{'paidfor'} . ' / ' |
3724 |
: q{}; |
3374 |
my @datearr = localtime(time); |
3725 |
my @datearr = localtime(time); |
3375 |
my $date = ( 1900 + $datearr[5] ) . "-" . ( $datearr[4] + 1 ) . "-" . $datearr[3]; |
3726 |
my $date = |
3376 |
my $bor = "$borrower->{'firstname'} $borrower->{'surname'} $borrower->{'cardnumber'}"; |
3727 |
( 1900 + $datearr[5] ) . "-" . ( $datearr[4] + 1 ) . "-" . $datearr[3]; |
3377 |
ModItem({ paidfor => $old_note."Paid for by $bor $date" }, undef, $itemnum); |
3728 |
my $bor = |
|
|
3729 |
"$borrower->{'firstname'} $borrower->{'surname'} $borrower->{'cardnumber'}"; |
3730 |
ModItem( { paidfor => $old_note . "Paid for by $bor $date" }, |
3731 |
undef, $itemnum ); |
3378 |
} |
3732 |
} |
3379 |
|
3733 |
|
3380 |
|
3734 |
sub LostItem { |
3381 |
sub LostItem{ |
3735 |
my ( $itemnumber, $mark_returned ) = @_; |
3382 |
my ($itemnumber, $mark_returned) = @_; |
|
|
3383 |
|
3736 |
|
3384 |
my $dbh = C4::Context->dbh(); |
3737 |
my $dbh = C4::Context->dbh(); |
3385 |
my $sth=$dbh->prepare("SELECT issues.*,items.*,biblio.title |
3738 |
my $sth = $dbh->prepare( |
|
|
3739 |
"SELECT issues.*,items.*,biblio.title |
3386 |
FROM issues |
3740 |
FROM issues |
3387 |
JOIN items USING (itemnumber) |
3741 |
JOIN items USING (itemnumber) |
3388 |
JOIN biblio USING (biblionumber) |
3742 |
JOIN biblio USING (biblionumber) |
3389 |
WHERE issues.itemnumber=?"); |
3743 |
WHERE issues.itemnumber=?" |
|
|
3744 |
); |
3390 |
$sth->execute($itemnumber); |
3745 |
$sth->execute($itemnumber); |
3391 |
my $issues=$sth->fetchrow_hashref(); |
3746 |
my $issues = $sth->fetchrow_hashref(); |
3392 |
|
3747 |
|
3393 |
# If a borrower lost the item, add a replacement cost to the their record |
3748 |
# If a borrower lost the item, add a replacement cost to the their record |
3394 |
if ( my $borrowernumber = $issues->{borrowernumber} ){ |
3749 |
if ( my $borrowernumber = $issues->{borrowernumber} ) { |
3395 |
my $borrower = C4::Members::GetMemberDetails( $borrowernumber ); |
3750 |
my $borrower = C4::Members::GetMemberDetails($borrowernumber); |
|
|
3751 |
|
3752 |
if ( C4::Context->preference('WhenLostForgiveFine') ) { |
3753 |
my $fix = _FixOverduesOnReturn( $borrowernumber, $itemnumber, 1, 0 ) |
3754 |
; # 1, 0 = exemptfine, no-dropbox |
3755 |
defined($fix) |
3756 |
or warn |
3757 |
"_FixOverduesOnReturn($borrowernumber, $itemnumber...) failed!" |
3758 |
; # zero is OK, check defined |
3759 |
} |
3760 |
if ( C4::Context->preference('WhenLostChargeReplacementFee') ) { |
3761 |
C4::Accounts::chargelostitem( |
3762 |
$borrowernumber, $itemnumber, |
3763 |
$issues->{'replacementprice'}, |
3764 |
"Lost Item $issues->{'title'} $issues->{'barcode'}" |
3765 |
); |
3396 |
|
3766 |
|
3397 |
if (C4::Context->preference('WhenLostForgiveFine')){ |
3767 |
#FIXME : Should probably have a way to distinguish this from an item that really was returned. |
3398 |
my $fix = _FixOverduesOnReturn($borrowernumber, $itemnumber, 1, 0); # 1, 0 = exemptfine, no-dropbox |
3768 |
#warn " $issues->{'borrowernumber'} / $itemnumber "; |
3399 |
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $itemnumber...) failed!"; # zero is OK, check defined |
|
|
3400 |
} |
3401 |
if (C4::Context->preference('WhenLostChargeReplacementFee')){ |
3402 |
C4::Accounts::chargelostitem($borrowernumber, $itemnumber, $issues->{'replacementprice'}, "Lost Item $issues->{'title'} $issues->{'barcode'}"); |
3403 |
#FIXME : Should probably have a way to distinguish this from an item that really was returned. |
3404 |
#warn " $issues->{'borrowernumber'} / $itemnumber "; |
3405 |
} |
3769 |
} |
3406 |
|
3770 |
|
3407 |
MarkIssueReturned($borrowernumber,$itemnumber,undef,undef,$borrower->{'privacy'}) if $mark_returned; |
3771 |
MarkIssueReturned( $borrowernumber, $itemnumber, undef, undef, |
|
|
3772 |
$borrower->{'privacy'} ) |
3773 |
if $mark_returned; |
3408 |
} |
3774 |
} |
3409 |
} |
3775 |
} |
3410 |
|
3776 |
|
3411 |
sub GetOfflineOperations { |
3777 |
sub GetOfflineOperations { |
3412 |
my $dbh = C4::Context->dbh; |
3778 |
my $dbh = C4::Context->dbh; |
3413 |
my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE branchcode=? ORDER BY timestamp"); |
3779 |
my $sth = $dbh->prepare( |
3414 |
$sth->execute(C4::Context->userenv->{'branch'}); |
3780 |
"SELECT * FROM pending_offline_operations WHERE branchcode=? ORDER BY timestamp" |
3415 |
my $results = $sth->fetchall_arrayref({}); |
3781 |
); |
|
|
3782 |
$sth->execute( C4::Context->userenv->{'branch'} ); |
3783 |
my $results = $sth->fetchall_arrayref( {} ); |
3416 |
return $results; |
3784 |
return $results; |
3417 |
} |
3785 |
} |
3418 |
|
3786 |
|
Lines 3420-3442
sub GetOfflineOperation {
Link Here
|
3420 |
my $operationid = shift; |
3788 |
my $operationid = shift; |
3421 |
return unless $operationid; |
3789 |
return unless $operationid; |
3422 |
my $dbh = C4::Context->dbh; |
3790 |
my $dbh = C4::Context->dbh; |
3423 |
my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE operationid=?"); |
3791 |
my $sth = $dbh->prepare( |
3424 |
$sth->execute( $operationid ); |
3792 |
"SELECT * FROM pending_offline_operations WHERE operationid=?"); |
|
|
3793 |
$sth->execute($operationid); |
3425 |
return $sth->fetchrow_hashref; |
3794 |
return $sth->fetchrow_hashref; |
3426 |
} |
3795 |
} |
3427 |
|
3796 |
|
3428 |
sub AddOfflineOperation { |
3797 |
sub AddOfflineOperation { |
3429 |
my ( $userid, $branchcode, $timestamp, $action, $barcode, $cardnumber, $amount ) = @_; |
3798 |
my ( |
|
|
3799 |
$userid, $branchcode, $timestamp, $action, |
3800 |
$barcode, $cardnumber, $amount |
3801 |
) = @_; |
3430 |
my $dbh = C4::Context->dbh; |
3802 |
my $dbh = C4::Context->dbh; |
3431 |
my $sth = $dbh->prepare("INSERT INTO pending_offline_operations (userid, branchcode, timestamp, action, barcode, cardnumber, amount) VALUES(?,?,?,?,?,?,?)"); |
3803 |
my $sth = $dbh->prepare( |
3432 |
$sth->execute( $userid, $branchcode, $timestamp, $action, $barcode, $cardnumber, $amount ); |
3804 |
"INSERT INTO pending_offline_operations (userid, branchcode, timestamp, action, barcode, cardnumber, amount) VALUES(?,?,?,?,?,?,?)" |
|
|
3805 |
); |
3806 |
$sth->execute( |
3807 |
$userid, $branchcode, $timestamp, $action, |
3808 |
$barcode, $cardnumber, $amount |
3809 |
); |
3433 |
return "Added."; |
3810 |
return "Added."; |
3434 |
} |
3811 |
} |
3435 |
|
3812 |
|
3436 |
sub DeleteOfflineOperation { |
3813 |
sub DeleteOfflineOperation { |
3437 |
my $dbh = C4::Context->dbh; |
3814 |
my $dbh = C4::Context->dbh; |
3438 |
my $sth = $dbh->prepare("DELETE FROM pending_offline_operations WHERE operationid=?"); |
3815 |
my $sth = $dbh->prepare( |
3439 |
$sth->execute( shift ); |
3816 |
"DELETE FROM pending_offline_operations WHERE operationid=?"); |
|
|
3817 |
$sth->execute(shift); |
3440 |
return "Deleted."; |
3818 |
return "Deleted."; |
3441 |
} |
3819 |
} |
3442 |
|
3820 |
|
Lines 3445-3458
sub ProcessOfflineOperation {
Link Here
|
3445 |
|
3823 |
|
3446 |
my $report; |
3824 |
my $report; |
3447 |
if ( $operation->{action} eq 'return' ) { |
3825 |
if ( $operation->{action} eq 'return' ) { |
3448 |
$report = ProcessOfflineReturn( $operation ); |
3826 |
$report = ProcessOfflineReturn($operation); |
3449 |
} elsif ( $operation->{action} eq 'issue' ) { |
3827 |
} |
3450 |
$report = ProcessOfflineIssue( $operation ); |
3828 |
elsif ( $operation->{action} eq 'issue' ) { |
3451 |
} elsif ( $operation->{action} eq 'payment' ) { |
3829 |
$report = ProcessOfflineIssue($operation); |
3452 |
$report = ProcessOfflinePayment( $operation ); |
3830 |
} |
|
|
3831 |
elsif ( $operation->{action} eq 'payment' ) { |
3832 |
$report = ProcessOfflinePayment($operation); |
3453 |
} |
3833 |
} |
3454 |
|
3834 |
|
3455 |
DeleteOfflineOperation( $operation->{operationid} ) if $operation->{operationid}; |
3835 |
DeleteOfflineOperation( $operation->{operationid} ) |
|
|
3836 |
if $operation->{operationid}; |
3456 |
|
3837 |
|
3457 |
return $report; |
3838 |
return $report; |
3458 |
} |
3839 |
} |
Lines 3460-3486
sub ProcessOfflineOperation {
Link Here
|
3460 |
sub ProcessOfflineReturn { |
3841 |
sub ProcessOfflineReturn { |
3461 |
my $operation = shift; |
3842 |
my $operation = shift; |
3462 |
|
3843 |
|
3463 |
my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} ); |
3844 |
my $itemnumber = |
|
|
3845 |
C4::Items::GetItemnumberFromBarcode( $operation->{barcode} ); |
3464 |
|
3846 |
|
3465 |
if ( $itemnumber ) { |
3847 |
if ($itemnumber) { |
3466 |
my $issue = GetOpenIssue( $itemnumber ); |
3848 |
my $issue = GetOpenIssue($itemnumber); |
3467 |
if ( $issue ) { |
3849 |
if ($issue) { |
3468 |
MarkIssueReturned( |
3850 |
MarkIssueReturned( |
3469 |
$issue->{borrowernumber}, |
3851 |
$issue->{borrowernumber}, |
3470 |
$itemnumber, |
3852 |
$itemnumber, undef, $operation->{timestamp}, |
3471 |
undef, |
|
|
3472 |
$operation->{timestamp}, |
3473 |
); |
3474 |
ModItem( |
3475 |
{ renewals => 0, onloan => undef }, |
3476 |
$issue->{'biblionumber'}, |
3477 |
$itemnumber |
3478 |
); |
3853 |
); |
|
|
3854 |
ModItem( { renewals => 0, onloan => undef }, |
3855 |
$issue->{'biblionumber'}, $itemnumber ); |
3479 |
return "Success."; |
3856 |
return "Success."; |
3480 |
} else { |
3857 |
} |
|
|
3858 |
else { |
3481 |
return "Item not issued."; |
3859 |
return "Item not issued."; |
3482 |
} |
3860 |
} |
3483 |
} else { |
3861 |
} |
|
|
3862 |
else { |
3484 |
return "Item not found."; |
3863 |
return "Item not found."; |
3485 |
} |
3864 |
} |
3486 |
} |
3865 |
} |
Lines 3488-3520
sub ProcessOfflineReturn {
Link Here
|
3488 |
sub ProcessOfflineIssue { |
3867 |
sub ProcessOfflineIssue { |
3489 |
my $operation = shift; |
3868 |
my $operation = shift; |
3490 |
|
3869 |
|
3491 |
my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber |
3870 |
my $borrower = |
|
|
3871 |
C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ) |
3872 |
; # Get borrower from operation cardnumber |
3492 |
|
3873 |
|
3493 |
if ( $borrower->{borrowernumber} ) { |
3874 |
if ( $borrower->{borrowernumber} ) { |
3494 |
my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} ); |
3875 |
my $itemnumber = |
|
|
3876 |
C4::Items::GetItemnumberFromBarcode( $operation->{barcode} ); |
3495 |
unless ($itemnumber) { |
3877 |
unless ($itemnumber) { |
3496 |
return "Barcode not found."; |
3878 |
return "Barcode not found."; |
3497 |
} |
3879 |
} |
3498 |
my $issue = GetOpenIssue( $itemnumber ); |
3880 |
my $issue = GetOpenIssue($itemnumber); |
3499 |
|
3881 |
|
3500 |
if ( $issue and ( $issue->{borrowernumber} ne $borrower->{borrowernumber} ) ) { # Item already issued to another borrower, mark it returned |
3882 |
if ( $issue |
|
|
3883 |
and ( $issue->{borrowernumber} ne $borrower->{borrowernumber} ) ) |
3884 |
{ # Item already issued to another borrower, mark it returned |
3501 |
MarkIssueReturned( |
3885 |
MarkIssueReturned( |
3502 |
$issue->{borrowernumber}, |
3886 |
$issue->{borrowernumber}, |
3503 |
$itemnumber, |
3887 |
$itemnumber, undef, $operation->{timestamp}, |
3504 |
undef, |
|
|
3505 |
$operation->{timestamp}, |
3506 |
); |
3888 |
); |
3507 |
} |
3889 |
} |
3508 |
AddIssue( |
3890 |
AddIssue( $borrower, $operation->{'barcode'}, |
3509 |
$borrower, |
3891 |
undef, 1, $operation->{timestamp}, undef, ); |
3510 |
$operation->{'barcode'}, |
|
|
3511 |
undef, |
3512 |
1, |
3513 |
$operation->{timestamp}, |
3514 |
undef, |
3515 |
); |
3516 |
return "Success."; |
3892 |
return "Success."; |
3517 |
} else { |
3893 |
} |
|
|
3894 |
else { |
3518 |
return "Borrower not found."; |
3895 |
return "Borrower not found."; |
3519 |
} |
3896 |
} |
3520 |
} |
3897 |
} |
Lines 3522-3536
sub ProcessOfflineIssue {
Link Here
|
3522 |
sub ProcessOfflinePayment { |
3899 |
sub ProcessOfflinePayment { |
3523 |
my $operation = shift; |
3900 |
my $operation = shift; |
3524 |
|
3901 |
|
3525 |
my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber |
3902 |
my $borrower = |
|
|
3903 |
C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ) |
3904 |
; # Get borrower from operation cardnumber |
3526 |
my $amount = $operation->{amount}; |
3905 |
my $amount = $operation->{amount}; |
3527 |
|
3906 |
|
3528 |
recordpayment( $borrower->{borrowernumber}, $amount ); |
3907 |
recordpayment( $borrower->{borrowernumber}, $amount ); |
3529 |
|
3908 |
|
3530 |
return "Success." |
3909 |
return "Success."; |
3531 |
} |
3910 |
} |
3532 |
|
3911 |
|
3533 |
|
|
|
3534 |
=head2 TransferSlip |
3912 |
=head2 TransferSlip |
3535 |
|
3913 |
|
3536 |
TransferSlip($user_branch, $itemnumber, $to_branch) |
3914 |
TransferSlip($user_branch, $itemnumber, $to_branch) |
Lines 3540-3560
sub ProcessOfflinePayment {
Link Here
|
3540 |
=cut |
3918 |
=cut |
3541 |
|
3919 |
|
3542 |
sub TransferSlip { |
3920 |
sub TransferSlip { |
3543 |
my ($branch, $itemnumber, $to_branch) = @_; |
3921 |
my ( $branch, $itemnumber, $to_branch ) = @_; |
3544 |
|
3922 |
|
3545 |
my $item = GetItem( $itemnumber ) |
3923 |
my $item = GetItem($itemnumber) |
3546 |
or return; |
3924 |
or return; |
3547 |
|
3925 |
|
3548 |
my $pulldate = C4::Dates->new(); |
3926 |
my $pulldate = C4::Dates->new(); |
3549 |
|
3927 |
|
3550 |
return C4::Letters::GetPreparedLetter ( |
3928 |
return C4::Letters::GetPreparedLetter( |
3551 |
module => 'circulation', |
3929 |
module => 'circulation', |
3552 |
letter_code => 'TRANSFERSLIP', |
3930 |
letter_code => 'TRANSFERSLIP', |
3553 |
branchcode => $branch, |
3931 |
branchcode => $branch, |
3554 |
tables => { |
3932 |
tables => { |
3555 |
'branches' => $to_branch, |
3933 |
'branches' => $to_branch, |
3556 |
'biblio' => $item->{biblionumber}, |
3934 |
'biblio' => $item->{biblionumber}, |
3557 |
'items' => $item, |
3935 |
'items' => $item, |
3558 |
}, |
3936 |
}, |
3559 |
); |
3937 |
); |
3560 |
} |
3938 |
} |
Lines 3568-3579
sub TransferSlip {
Link Here
|
3568 |
=cut |
3946 |
=cut |
3569 |
|
3947 |
|
3570 |
sub CheckIfIssuedToPatron { |
3948 |
sub CheckIfIssuedToPatron { |
3571 |
my ($borrowernumber, $biblionumber) = @_; |
3949 |
my ( $borrowernumber, $biblionumber ) = @_; |
3572 |
|
3950 |
|
3573 |
my $items = GetItemsByBiblioitemnumber($biblionumber); |
3951 |
my $items = GetItemsByBiblioitemnumber($biblionumber); |
3574 |
|
3952 |
|
3575 |
foreach my $item (@{$items}) { |
3953 |
foreach my $item ( @{$items} ) { |
3576 |
return 1 if ($item->{borrowernumber} && $item->{borrowernumber} eq $borrowernumber); |
3954 |
return 1 |
|
|
3955 |
if ( $item->{borrowernumber} |
3956 |
&& $item->{borrowernumber} eq $borrowernumber ); |
3577 |
} |
3957 |
} |
3578 |
|
3958 |
|
3579 |
return; |
3959 |
return; |
Lines 3589-3600
sub CheckIfIssuedToPatron {
Link Here
|
3589 |
|
3969 |
|
3590 |
sub IsItemIssued { |
3970 |
sub IsItemIssued { |
3591 |
my $itemnumber = shift; |
3971 |
my $itemnumber = shift; |
3592 |
my $dbh = C4::Context->dbh; |
3972 |
my $dbh = C4::Context->dbh; |
3593 |
my $sth = $dbh->prepare(q{ |
3973 |
my $sth = $dbh->prepare( |
|
|
3974 |
q{ |
3594 |
SELECT COUNT(*) |
3975 |
SELECT COUNT(*) |
3595 |
FROM issues |
3976 |
FROM issues |
3596 |
WHERE itemnumber = ? |
3977 |
WHERE itemnumber = ? |
3597 |
}); |
3978 |
} |
|
|
3979 |
); |
3598 |
$sth->execute($itemnumber); |
3980 |
$sth->execute($itemnumber); |
3599 |
return $sth->fetchrow; |
3981 |
return $sth->fetchrow; |
3600 |
} |
3982 |
} |