|
Lines 27-39
use C4::Koha;
Link Here
|
| 27 |
use C4::Biblio; |
27 |
use C4::Biblio; |
| 28 |
use C4::Items; |
28 |
use C4::Items; |
| 29 |
use C4::Members; |
29 |
use C4::Members; |
| 30 |
use C4::Dates; |
30 |
use C4::IssuingRules; |
|
|
31 |
use C4::Dates qw/format_date/; |
| 31 |
use C4::Calendar; |
32 |
use C4::Calendar; |
| 32 |
use C4::Accounts; |
33 |
use C4::Accounts; |
|
|
34 |
use C4::Overdues ; |
| 33 |
use C4::ItemCirculationAlertPreference; |
35 |
use C4::ItemCirculationAlertPreference; |
| 34 |
use C4::Dates qw(format_date); |
36 |
use C4::Dates qw(format_date); |
| 35 |
use C4::Message; |
37 |
use C4::Message; |
| 36 |
use C4::Debug; |
38 |
use C4::Debug; |
|
|
39 |
use YAML; |
| 37 |
use Date::Calc qw( |
40 |
use Date::Calc qw( |
| 38 |
Today |
41 |
Today |
| 39 |
Today_and_Now |
42 |
Today_and_Now |
|
Lines 42-47
use Date::Calc qw(
Link Here
|
| 42 |
Date_to_Days |
45 |
Date_to_Days |
| 43 |
Day_of_Week |
46 |
Day_of_Week |
| 44 |
Add_Delta_Days |
47 |
Add_Delta_Days |
|
|
48 |
Delta_Days |
| 49 |
check_date |
| 50 |
Add_Delta_Days |
| 45 |
); |
51 |
); |
| 46 |
use POSIX qw(strftime); |
52 |
use POSIX qw(strftime); |
| 47 |
use C4::Branch; # GetBranches |
53 |
use C4::Branch; # GetBranches |
|
Lines 73-81
BEGIN {
Link Here
|
| 73 |
&GetItemIssues |
79 |
&GetItemIssues |
| 74 |
&GetBorrowerIssues |
80 |
&GetBorrowerIssues |
| 75 |
&GetIssuingCharges |
81 |
&GetIssuingCharges |
| 76 |
&GetIssuingRule |
|
|
| 77 |
&GetBranchBorrowerCircRule |
| 78 |
&GetBranchItemRule |
| 79 |
&GetBiblioIssues |
82 |
&GetBiblioIssues |
| 80 |
&GetOpenIssue |
83 |
&GetOpenIssue |
| 81 |
&AnonymiseIssueHistory |
84 |
&AnonymiseIssueHistory |
|
Lines 98-103
BEGIN {
Link Here
|
| 98 |
&CreateBranchTransferLimit |
101 |
&CreateBranchTransferLimit |
| 99 |
&DeleteBranchTransferLimits |
102 |
&DeleteBranchTransferLimits |
| 100 |
); |
103 |
); |
|
|
104 |
|
| 105 |
# subs to deal with offline circulation |
| 106 |
push @EXPORT, qw( |
| 107 |
&GetOfflineOperations |
| 108 |
&GetOfflineOperation |
| 109 |
&AddOfflineOperation |
| 110 |
&DeleteOfflineOperation |
| 111 |
&ProcessOfflineOperation |
| 112 |
); |
| 101 |
} |
113 |
} |
| 102 |
|
114 |
|
| 103 |
=head1 NAME |
115 |
=head1 NAME |
|
Lines 346-461
sub TooMany {
Link Here
|
| 346 |
my $item = shift; |
358 |
my $item = shift; |
| 347 |
my $cat_borrower = $borrower->{'categorycode'}; |
359 |
my $cat_borrower = $borrower->{'categorycode'}; |
| 348 |
my $dbh = C4::Context->dbh; |
360 |
my $dbh = C4::Context->dbh; |
| 349 |
my $branch; |
361 |
my $exactbranch; |
| 350 |
# Get which branchcode we need |
362 |
# Get which branchcode we need |
| 351 |
$branch = _GetCircControlBranch($item,$borrower); |
363 |
$exactbranch = _GetCircControlBranch($item,$borrower); |
| 352 |
my $type = (C4::Context->preference('item-level_itypes')) |
364 |
my $itype = (C4::Context->preference('item-level_itypes')) |
| 353 |
? $item->{'itype'} # item-level |
365 |
? $item->{'itype'} # item-level |
| 354 |
: $item->{'itemtype'}; # biblio-level |
366 |
: $item->{'itemtype'}; # biblio-level |
| 355 |
|
367 |
|
| 356 |
# given branch, patron category, and item type, determine |
368 |
# given branch, patron category, and item type, determine |
| 357 |
# applicable issuing rule |
369 |
# applicable issuing rule |
| 358 |
my $issuing_rule = GetIssuingRule($cat_borrower, $type, $branch); |
370 |
my $branchfield = C4::Context->Preference('HomeOrHoldingBranch') || "homebranch"; |
| 359 |
|
371 |
#By default, Patron is supposed not to be able to borrow |
| 360 |
# if a rule is found and has a loan limit set, count |
372 |
my $toomany = 1; |
| 361 |
# how many loans the patron already has that meet that |
373 |
|
| 362 |
# rule |
374 |
foreach my $branch ( $exactbranch, '*' ) { |
| 363 |
if (defined($issuing_rule) and defined($issuing_rule->{'maxissueqty'})) { |
375 |
foreach my $type ( $itype, '*' ) { |
| 364 |
my @bind_params; |
376 |
my $issuing_rule = GetIssuingRule( $cat_borrower, $type, $branch ); |
| 365 |
my $count_query = "SELECT COUNT(*) FROM issues |
377 |
|
| 366 |
JOIN items USING (itemnumber) "; |
378 |
# if a rule is found and has a loan limit set, count |
| 367 |
|
379 |
# how many loans the patron already has that meet that |
| 368 |
my $rule_itemtype = $issuing_rule->{itemtype}; |
380 |
# rule |
| 369 |
if ($rule_itemtype eq "*") { |
381 |
if ( defined($issuing_rule) and defined( $issuing_rule->{'maxissueqty'} ) ) { |
| 370 |
# matching rule has the default item type, so count only |
382 |
my @bind_params; |
| 371 |
# those existing loans that don't fall under a more |
383 |
my $count_query = "SELECT COUNT(*) FROM issues |
| 372 |
# specific rule |
384 |
JOIN items USING (itemnumber) "; |
| 373 |
if (C4::Context->preference('item-level_itypes')) { |
385 |
|
| 374 |
$count_query .= " WHERE items.itype NOT IN ( |
386 |
my $rule_itemtype = $issuing_rule->{itemtype}; |
| 375 |
SELECT itemtype FROM issuingrules |
387 |
if ($rule_itemtype eq "*") { |
| 376 |
WHERE branchcode = ? |
388 |
# matching rule has the default item type, so count all the items issued for that branch no |
| 377 |
AND (categorycode = ? OR categorycode = ?) |
389 |
# those existing loans that don't fall under a more |
| 378 |
AND itemtype <> '*' |
390 |
# specific rule Not QUITE |
| 379 |
) "; |
391 |
if (C4::Context->preference('item-level_itypes')) { |
| 380 |
} else { |
392 |
$count_query .= " WHERE items.itype NOT IN ( |
| 381 |
$count_query .= " JOIN biblioitems USING (biblionumber) |
393 |
SELECT itemtype FROM issuingrules |
| 382 |
WHERE biblioitems.itemtype NOT IN ( |
394 |
WHERE branchcode = ? |
| 383 |
SELECT itemtype FROM issuingrules |
395 |
AND (categorycode = ? OR categorycode = ?) |
| 384 |
WHERE branchcode = ? |
396 |
AND itemtype <> '*' |
| 385 |
AND (categorycode = ? OR categorycode = ?) |
397 |
)"; |
| 386 |
AND itemtype <> '*' |
398 |
} else { |
| 387 |
) "; |
399 |
$count_query .= " JOIN biblioitems USING (biblionumber) |
| 388 |
} |
400 |
WHERE biblioitems.itemtype NOT IN ( |
| 389 |
push @bind_params, $issuing_rule->{branchcode}; |
401 |
SELECT itemtype FROM issuingrules |
| 390 |
push @bind_params, $issuing_rule->{categorycode}; |
402 |
WHERE branchcode = ? |
| 391 |
push @bind_params, $cat_borrower; |
403 |
AND (categorycode = ? OR categorycode = ?) |
| 392 |
} else { |
404 |
AND itemtype <> '*' |
| 393 |
# rule has specific item type, so count loans of that |
405 |
)"; |
| 394 |
# specific item type |
406 |
} |
| 395 |
if (C4::Context->preference('item-level_itypes')) { |
407 |
push @bind_params, $issuing_rule->{branchcode}; |
| 396 |
$count_query .= " WHERE items.itype = ? "; |
408 |
push @bind_params, $issuing_rule->{categorycode}; |
| 397 |
} else { |
409 |
push @bind_params, $cat_borrower; |
| 398 |
$count_query .= " JOIN biblioitems USING (biblionumber) |
410 |
} else { |
| 399 |
WHERE biblioitems.itemtype= ? "; |
411 |
# rule has specific item type, so count loans of that |
| 400 |
} |
412 |
# specific item type |
| 401 |
push @bind_params, $type; |
413 |
if (C4::Context->preference('item-level_itypes')) { |
| 402 |
} |
414 |
$count_query .= " WHERE items.itype = ? "; |
| 403 |
|
415 |
} else { |
| 404 |
$count_query .= " AND borrowernumber = ? "; |
416 |
$count_query .= " JOIN biblioitems USING (biblionumber) |
| 405 |
push @bind_params, $borrower->{'borrowernumber'}; |
417 |
WHERE biblioitems.itemtype= ? "; |
| 406 |
my $rule_branch = $issuing_rule->{branchcode}; |
418 |
} |
| 407 |
if ($rule_branch ne "*") { |
419 |
push @bind_params, $type; |
| 408 |
if (C4::Context->preference('CircControl') eq 'PickupLibrary') { |
420 |
} |
| 409 |
$count_query .= " AND issues.branchcode = ? "; |
|
|
| 410 |
push @bind_params, $branch; |
| 411 |
} elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') { |
| 412 |
; # if branch is the patron's home branch, then count all loans by patron |
| 413 |
} else { |
| 414 |
$count_query .= " AND items.homebranch = ? "; |
| 415 |
push @bind_params, $branch; |
| 416 |
} |
| 417 |
} |
| 418 |
|
| 419 |
my $count_sth = $dbh->prepare($count_query); |
| 420 |
$count_sth->execute(@bind_params); |
| 421 |
my ($current_loan_count) = $count_sth->fetchrow_array; |
| 422 |
|
421 |
|
| 423 |
my $max_loans_allowed = $issuing_rule->{'maxissueqty'}; |
422 |
$count_query .= " AND borrowernumber = ? "; |
| 424 |
if ($current_loan_count >= $max_loans_allowed) { |
423 |
push @bind_params, $borrower->{'borrowernumber'}; |
| 425 |
return ($current_loan_count, $max_loans_allowed); |
424 |
my $rule_branch = $issuing_rule->{branchcode}; |
| 426 |
} |
425 |
if ( $rule_branch ne "*" ) { |
| 427 |
} |
426 |
if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) { |
|
|
427 |
$count_query .= " AND issues.branchcode = ? "; |
| 428 |
push @bind_params, $branch; |
| 429 |
} elsif ( C4::Context->preference('CircControl') eq 'PatronLibrary' ) { |
| 430 |
; # if branch is the patron's home branch, then count all loans by patron |
| 431 |
} else { |
| 432 |
$count_query .= " AND items.$branchfield = ? "; |
| 433 |
push @bind_params, $branch; |
| 434 |
} |
| 435 |
} |
| 428 |
|
436 |
|
| 429 |
# Now count total loans against the limit for the branch |
437 |
my $count_sth = $dbh->prepare($count_query); |
| 430 |
my $branch_borrower_circ_rule = GetBranchBorrowerCircRule($branch, $cat_borrower); |
438 |
$count_sth->execute(@bind_params); |
| 431 |
if (defined($branch_borrower_circ_rule->{maxissueqty})) { |
439 |
my ($current_loan_count) = $count_sth->fetchrow_array; |
| 432 |
my @bind_params = (); |
|
|
| 433 |
my $branch_count_query = "SELECT COUNT(*) FROM issues |
| 434 |
JOIN items USING (itemnumber) |
| 435 |
WHERE borrowernumber = ? "; |
| 436 |
push @bind_params, $borrower->{borrowernumber}; |
| 437 |
|
| 438 |
if (C4::Context->preference('CircControl') eq 'PickupLibrary') { |
| 439 |
$branch_count_query .= " AND issues.branchcode = ? "; |
| 440 |
push @bind_params, $branch; |
| 441 |
} elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') { |
| 442 |
; # if branch is the patron's home branch, then count all loans by patron |
| 443 |
} else { |
| 444 |
$branch_count_query .= " AND items.homebranch = ? "; |
| 445 |
push @bind_params, $branch; |
| 446 |
} |
| 447 |
my $branch_count_sth = $dbh->prepare($branch_count_query); |
| 448 |
$branch_count_sth->execute(@bind_params); |
| 449 |
my ($current_loan_count) = $branch_count_sth->fetchrow_array; |
| 450 |
|
440 |
|
| 451 |
my $max_loans_allowed = $branch_borrower_circ_rule->{maxissueqty}; |
441 |
my $max_loans_allowed = $issuing_rule->{'maxissueqty'}; |
| 452 |
if ($current_loan_count >= $max_loans_allowed) { |
442 |
if ( $current_loan_count >= $max_loans_allowed ) { |
| 453 |
return ($current_loan_count, $max_loans_allowed); |
443 |
return 1,$current_loan_count,$max_loans_allowed; |
|
|
444 |
} |
| 445 |
else { |
| 446 |
$toomany=0; |
| 447 |
} |
| 448 |
} |
| 454 |
} |
449 |
} |
| 455 |
} |
450 |
} |
| 456 |
|
451 |
return $toomany; |
| 457 |
# OK, the patron can issue !!! |
|
|
| 458 |
return; |
| 459 |
} |
452 |
} |
| 460 |
|
453 |
|
| 461 |
=head2 itemissues |
454 |
=head2 itemissues |
|
Lines 684-690
sub CanBookBeIssued {
Link Here
|
| 684 |
my $branch = _GetCircControlBranch($item,$borrower); |
677 |
my $branch = _GetCircControlBranch($item,$borrower); |
| 685 |
my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'}; |
678 |
my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'}; |
| 686 |
my $loanlength = GetLoanLength( $borrower->{'categorycode'}, $itype, $branch ); |
679 |
my $loanlength = GetLoanLength( $borrower->{'categorycode'}, $itype, $branch ); |
| 687 |
$duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $loanlength, $branch, $borrower ); |
680 |
unless ($loanlength or C4::Context->preference("AllowNotForLoanOverride")) { |
|
|
681 |
$issuingimpossible{LOAN_LENGTH_UNDEFINED} = "$borrower->{'categorycode'}, $itype, $branch"; |
| 682 |
} |
| 683 |
$duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $loanlength, $branch, $borrower ) ; |
| 688 |
|
684 |
|
| 689 |
# Offline circ calls AddIssue directly, doesn't run through here |
685 |
# Offline circ calls AddIssue directly, doesn't run through here |
| 690 |
# So issuingimpossible should be ok. |
686 |
# So issuingimpossible should be ok. |
|
Lines 712-726
sub CanBookBeIssued {
Link Here
|
| 712 |
$issuingimpossible{CARD_LOST} = 1; |
708 |
$issuingimpossible{CARD_LOST} = 1; |
| 713 |
} |
709 |
} |
| 714 |
if ( $borrower->{flags}->{'DBARRED'} ) { |
710 |
if ( $borrower->{flags}->{'DBARRED'} ) { |
| 715 |
$issuingimpossible{DEBARRED} = 1; |
711 |
if (my $dateenddebarred=$borrower->{flags}->{'DBARRED'}->{'dateend'}){ |
|
|
712 |
$issuingimpossible{DEBARRED} = format_date($dateenddebarred); |
| 713 |
} |
| 714 |
else { |
| 715 |
$issuingimpossible{DEBARRED} = 1; |
| 716 |
} |
| 716 |
} |
717 |
} |
| 717 |
if ( $borrower->{'dateexpiry'} eq '0000-00-00') { |
718 |
if ( $borrower->{'dateexpiry'} eq '0000-00-00') { |
| 718 |
$issuingimpossible{EXPIRED} = 1; |
719 |
$issuingimpossible{EXPIRED} = 1; |
| 719 |
} else { |
720 |
} else { |
| 720 |
my @expirydate= split /-/,$borrower->{'dateexpiry'}; |
721 |
my @expirydate = split (/-/, $borrower->{'dateexpiry'}); |
| 721 |
if($expirydate[0]==0 || $expirydate[1]==0|| $expirydate[2]==0 || |
722 |
if ( $expirydate[0] == 0 |
| 722 |
Date_to_Days(Today) > Date_to_Days( @expirydate )) { |
723 |
|| $expirydate[1] == 0 |
| 723 |
$issuingimpossible{EXPIRED} = 1; |
724 |
|| $expirydate[2] == 0 |
|
|
725 |
|| Date_to_Days(Today) > Date_to_Days(@expirydate) ) { |
| 726 |
$issuingimpossible{EXPIRED} = 1; |
| 724 |
} |
727 |
} |
| 725 |
} |
728 |
} |
| 726 |
# |
729 |
# |
|
Lines 769-786
sub CanBookBeIssued {
Link Here
|
| 769 |
# |
772 |
# |
| 770 |
# JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS |
773 |
# JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS |
| 771 |
# |
774 |
# |
| 772 |
my ($current_loan_count, $max_loans_allowed) = TooMany( $borrower, $item->{biblionumber}, $item ); |
775 |
my @toomany = TooMany( $borrower, $item->{biblionumber}, $item ); |
| 773 |
# if TooMany max_loans_allowed returns 0 the user doesn't have permission to check out this book |
776 |
|
| 774 |
if ($max_loans_allowed eq 0) { |
777 |
if ( $toomany[0] == 1 && scalar(@toomany)<3) { |
| 775 |
$needsconfirmation{PATRON_CANT} = 1; |
778 |
$needsconfirmation{PATRON_CANT} = 1; |
| 776 |
} else { |
779 |
} elsif (scalar(@toomany)==3) { |
| 777 |
if($max_loans_allowed){ |
780 |
$needsconfirmation{TOO_MANY} = "$toomany[1] / $toomany[2]"; |
| 778 |
$needsconfirmation{TOO_MANY} = 1; |
|
|
| 779 |
$needsconfirmation{current_loan_count} = $current_loan_count; |
| 780 |
$needsconfirmation{max_loans_allowed} = $max_loans_allowed; |
| 781 |
} |
| 782 |
} |
781 |
} |
| 783 |
|
782 |
|
|
|
783 |
|
| 784 |
# |
784 |
# |
| 785 |
# ITEM CHECKING |
785 |
# ITEM CHECKING |
| 786 |
# |
786 |
# |
|
Lines 817-824
sub CanBookBeIssued {
Link Here
|
| 817 |
} |
817 |
} |
| 818 |
} |
818 |
} |
| 819 |
} |
819 |
} |
| 820 |
if ( $item->{'wthdrawn'} && $item->{'wthdrawn'} == 1 ) |
820 |
if ( $item->{'damaged'} && $item->{'damaged'} > 0 ){ |
| 821 |
{ |
821 |
$needsconfirmation{DAMAGED} = $item->{'damaged'}; |
|
|
822 |
my $fw = GetFrameworkCode($item->{biblionumber}); |
| 823 |
my $category = GetAuthValCode('items.damaged',$fw); |
| 824 |
my $authorizedvalues = GetAuthorisedValues($category, $item->{damaged}); |
| 825 |
|
| 826 |
foreach my $authvalue (@$authorizedvalues){ |
| 827 |
$needsconfirmation{DAMAGED} = $authvalue->{lib} if $authvalue->{'authorised_value'} eq $item->{'damaged'}; |
| 828 |
} |
| 829 |
|
| 830 |
} |
| 831 |
if ( $item->{'wthdrawn'} && $item->{'wthdrawn'} == 1 ) { |
| 822 |
$issuingimpossible{WTHDRAWN} = 1; |
832 |
$issuingimpossible{WTHDRAWN} = 1; |
| 823 |
} |
833 |
} |
| 824 |
if ( $item->{'restricted'} |
834 |
if ( $item->{'restricted'} |
|
Lines 826-840
sub CanBookBeIssued {
Link Here
|
| 826 |
{ |
836 |
{ |
| 827 |
$issuingimpossible{RESTRICTED} = 1; |
837 |
$issuingimpossible{RESTRICTED} = 1; |
| 828 |
} |
838 |
} |
|
|
839 |
my $userenv = C4::Context->userenv; |
| 840 |
my $branch=$userenv->{branch}; |
| 841 |
my $hbr= $item->{ C4::Context->preference("HomeOrHoldingBranch") }; |
| 829 |
if ( C4::Context->preference("IndependantBranches") ) { |
842 |
if ( C4::Context->preference("IndependantBranches") ) { |
| 830 |
my $userenv = C4::Context->userenv; |
|
|
| 831 |
if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) { |
843 |
if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) { |
| 832 |
$issuingimpossible{ITEMNOTSAMEBRANCH} = 1 |
844 |
$issuingimpossible{ITEMNOTSAMEBRANCH} = 1 |
| 833 |
if ( $item->{C4::Context->preference("HomeOrHoldingBranch")} ne $userenv->{branch} ); |
845 |
if ( $hbr ne $branch ); |
| 834 |
$needsconfirmation{BORRNOTSAMEBRANCH} = GetBranchName( $borrower->{'branchcode'} ) |
846 |
$needsconfirmation{BORRNOTSAMEBRANCH} = GetBranchName( $borrower->{'branchcode'} ) |
| 835 |
if ( $borrower->{'branchcode'} ne $userenv->{branch} ); |
847 |
if ( $borrower->{'branchcode'} ne $userenv->{branch} ); |
| 836 |
} |
848 |
} |
| 837 |
} |
849 |
} |
|
|
850 |
my $branchtransferfield=C4::Context->preference("BranchTransferLimitsType") eq "ccode" ? "ccode" : "itype"; |
| 851 |
if ( C4::Context->preference("UseBranchTransferLimits") |
| 852 |
and !IsBranchTransferAllowed( $branch, $hbr, $item->{ $branchtransferfield } ) ) { |
| 853 |
$needsconfirmation{BRANCH_TRANSFER_NOT_ALLOWED} = $hbr; |
| 854 |
} |
| 855 |
|
| 838 |
|
856 |
|
| 839 |
# |
857 |
# |
| 840 |
# CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER |
858 |
# CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER |
|
Lines 875-904
sub CanBookBeIssued {
Link Here
|
| 875 |
my ( $resborrower ) = C4::Members::GetMemberDetails( $resbor, 0 ); |
893 |
my ( $resborrower ) = C4::Members::GetMemberDetails( $resbor, 0 ); |
| 876 |
my $branches = GetBranches(); |
894 |
my $branches = GetBranches(); |
| 877 |
my $branchname = $branches->{ $res->{'branchcode'} }->{'branchname'}; |
895 |
my $branchname = $branches->{ $res->{'branchcode'} }->{'branchname'}; |
| 878 |
if ( $resbor ne $borrower->{'borrowernumber'} && $restype eq "Waiting" ) |
896 |
if( $resbor ne $borrower->{'borrowernumber'}){ |
| 879 |
{ |
897 |
if ( $restype eq "Waiting" ) { |
| 880 |
# The item is on reserve and waiting, but has been |
898 |
# The item is on reserve and waiting, but has been |
| 881 |
# reserved by some other patron. |
899 |
# reserved by some other patron. |
| 882 |
$needsconfirmation{RESERVE_WAITING} = 1; |
900 |
$needsconfirmation{RESERVE_WAITING} = |
| 883 |
$needsconfirmation{'resfirstname'} = $resborrower->{'firstname'}; |
901 |
"$resborrower->{'firstname'} $resborrower->{'surname'} ($resborrower->{'cardnumber'}, $branchname)"; |
| 884 |
$needsconfirmation{'ressurname'} = $resborrower->{'surname'}; |
902 |
} |
| 885 |
$needsconfirmation{'rescardnumber'} = $resborrower->{'cardnumber'}; |
903 |
elsif ( $restype eq "Reserved" ) { |
| 886 |
$needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'}; |
904 |
# The item is on reserve for someone else. |
| 887 |
$needsconfirmation{'resbranchname'} = $branchname; |
905 |
$needsconfirmation{RESERVED} = |
| 888 |
$needsconfirmation{'reswaitingdate'} = format_date($res->{'waitingdate'}); |
906 |
"$res->{'reservedate'} : $resborrower->{'firstname'} $resborrower->{'surname'} ($resborrower->{'cardnumber'})"; |
| 889 |
} |
907 |
} |
| 890 |
elsif ( $restype eq "Reserved" ) { |
|
|
| 891 |
# The item is on reserve for someone else. |
| 892 |
$needsconfirmation{RESERVED} = 1; |
| 893 |
$needsconfirmation{'resfirstname'} = $resborrower->{'firstname'}; |
| 894 |
$needsconfirmation{'ressurname'} = $resborrower->{'surname'}; |
| 895 |
$needsconfirmation{'rescardnumber'} = $resborrower->{'cardnumber'}; |
| 896 |
$needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'}; |
| 897 |
$needsconfirmation{'resbranchname'} = $branchname; |
| 898 |
$needsconfirmation{'resreservedate'} = format_date($res->{'reservedate'}); |
| 899 |
} |
908 |
} |
| 900 |
} |
909 |
} |
| 901 |
return ( \%issuingimpossible, \%needsconfirmation ); |
910 |
return ( \%issuingimpossible, \%needsconfirmation ); |
| 902 |
} |
911 |
} |
| 903 |
|
912 |
|
| 904 |
=head2 AddIssue |
913 |
=head2 AddIssue |
|
Lines 979-985
sub AddIssue {
Link Here
|
| 979 |
# who wants to borrow it now. mark it returned before issuing to the new borrower |
988 |
# who wants to borrow it now. mark it returned before issuing to the new borrower |
| 980 |
AddReturn( |
989 |
AddReturn( |
| 981 |
$item->{'barcode'}, |
990 |
$item->{'barcode'}, |
| 982 |
C4::Context->userenv->{'branch'} |
991 |
C4::Context->userenv->{'branch'}, |
|
|
992 |
undef, |
| 993 |
undef, |
| 994 |
1 |
| 983 |
); |
995 |
); |
| 984 |
} |
996 |
} |
| 985 |
|
997 |
|
|
Lines 1012-1018
sub AddIssue {
Link Here
|
| 1012 |
ModReserve(1, |
1024 |
ModReserve(1, |
| 1013 |
$res->{'biblionumber'}, |
1025 |
$res->{'biblionumber'}, |
| 1014 |
$res->{'borrowernumber'}, |
1026 |
$res->{'borrowernumber'}, |
| 1015 |
$res->{'branchcode'} |
1027 |
$res->{'branchcode'}, |
|
|
1028 |
undef, |
| 1029 |
$res->{'reservenumber'} |
| 1016 |
); |
1030 |
); |
| 1017 |
} |
1031 |
} |
| 1018 |
} |
1032 |
} |
|
Lines 1102-1111
sub AddIssue {
Link Here
|
| 1102 |
branch => $branch, |
1116 |
branch => $branch, |
| 1103 |
}); |
1117 |
}); |
| 1104 |
} |
1118 |
} |
|
|
1119 |
|
| 1120 |
logaction( "CIRCULATION", "ISSUE", $borrower->{'borrowernumber'}, $item->{'itemnumber'} ) |
| 1121 |
if C4::Context->preference("IssueLog"); |
| 1105 |
} |
1122 |
} |
| 1106 |
|
1123 |
|
| 1107 |
logaction("CIRCULATION", "ISSUE", $borrower->{'borrowernumber'}, $biblio->{'biblionumber'}) |
|
|
| 1108 |
if C4::Context->preference("IssueLog"); |
| 1109 |
} |
1124 |
} |
| 1110 |
return ($datedue); # not necessarily the same as when it came in! |
1125 |
return ($datedue); # not necessarily the same as when it came in! |
| 1111 |
} |
1126 |
} |
|
Lines 1120-1373
Get loan length for an itemtype, a borrower type and a branch
Link Here
|
| 1120 |
|
1135 |
|
| 1121 |
sub GetLoanLength { |
1136 |
sub GetLoanLength { |
| 1122 |
my ( $borrowertype, $itemtype, $branchcode ) = @_; |
1137 |
my ( $borrowertype, $itemtype, $branchcode ) = @_; |
| 1123 |
my $dbh = C4::Context->dbh; |
1138 |
my $loanlength=GetIssuingRule($borrowertype,$itemtype,$branchcode); |
| 1124 |
my $sth = |
1139 |
return $loanlength->{issuelength}; |
| 1125 |
$dbh->prepare( |
|
|
| 1126 |
"select issuelength from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null" |
| 1127 |
); |
| 1128 |
# warn "in get loan lenght $borrowertype $itemtype $branchcode "; |
| 1129 |
# try to find issuelength & return the 1st available. |
| 1130 |
# check with borrowertype, itemtype and branchcode, then without one of those parameters |
| 1131 |
$sth->execute( $borrowertype, $itemtype, $branchcode ); |
| 1132 |
my $loanlength = $sth->fetchrow_hashref; |
| 1133 |
return $loanlength->{issuelength} |
| 1134 |
if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; |
| 1135 |
|
| 1136 |
$sth->execute( $borrowertype, "*", $branchcode ); |
| 1137 |
$loanlength = $sth->fetchrow_hashref; |
| 1138 |
return $loanlength->{issuelength} |
| 1139 |
if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; |
| 1140 |
|
| 1141 |
$sth->execute( "*", $itemtype, $branchcode ); |
| 1142 |
$loanlength = $sth->fetchrow_hashref; |
| 1143 |
return $loanlength->{issuelength} |
| 1144 |
if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; |
| 1145 |
|
| 1146 |
$sth->execute( "*", "*", $branchcode ); |
| 1147 |
$loanlength = $sth->fetchrow_hashref; |
| 1148 |
return $loanlength->{issuelength} |
| 1149 |
if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; |
| 1150 |
|
| 1151 |
$sth->execute( $borrowertype, $itemtype, "*" ); |
| 1152 |
$loanlength = $sth->fetchrow_hashref; |
| 1153 |
return $loanlength->{issuelength} |
| 1154 |
if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; |
| 1155 |
|
| 1156 |
$sth->execute( $borrowertype, "*", "*" ); |
| 1157 |
$loanlength = $sth->fetchrow_hashref; |
| 1158 |
return $loanlength->{issuelength} |
| 1159 |
if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; |
| 1160 |
|
| 1161 |
$sth->execute( "*", $itemtype, "*" ); |
| 1162 |
$loanlength = $sth->fetchrow_hashref; |
| 1163 |
return $loanlength->{issuelength} |
| 1164 |
if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; |
| 1165 |
|
| 1166 |
$sth->execute( "*", "*", "*" ); |
| 1167 |
$loanlength = $sth->fetchrow_hashref; |
| 1168 |
return $loanlength->{issuelength} |
| 1169 |
if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; |
| 1170 |
|
| 1171 |
# if no rule is set => 21 days (hardcoded) |
| 1172 |
return 21; |
| 1173 |
} |
| 1174 |
|
| 1175 |
=head2 GetIssuingRule |
| 1176 |
|
| 1177 |
my $irule = &GetIssuingRule($borrowertype,$itemtype,branchcode) |
| 1178 |
|
| 1179 |
FIXME - This is a copy-paste of GetLoanLength |
| 1180 |
as a stop-gap. Do not wish to change API for GetLoanLength |
| 1181 |
this close to release, however, Overdues::GetIssuingRules is broken. |
| 1182 |
|
| 1183 |
Get the issuing rule for an itemtype, a borrower type and a branch |
| 1184 |
Returns a hashref from the issuingrules table. |
| 1185 |
|
| 1186 |
=cut |
| 1187 |
|
| 1188 |
sub GetIssuingRule { |
| 1189 |
my ( $borrowertype, $itemtype, $branchcode ) = @_; |
| 1190 |
my $dbh = C4::Context->dbh; |
| 1191 |
my $sth = $dbh->prepare( "select * from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null" ); |
| 1192 |
my $irule; |
| 1193 |
|
| 1194 |
$sth->execute( $borrowertype, $itemtype, $branchcode ); |
| 1195 |
$irule = $sth->fetchrow_hashref; |
| 1196 |
return $irule if defined($irule) ; |
| 1197 |
|
| 1198 |
$sth->execute( $borrowertype, "*", $branchcode ); |
| 1199 |
$irule = $sth->fetchrow_hashref; |
| 1200 |
return $irule if defined($irule) ; |
| 1201 |
|
| 1202 |
$sth->execute( "*", $itemtype, $branchcode ); |
| 1203 |
$irule = $sth->fetchrow_hashref; |
| 1204 |
return $irule if defined($irule) ; |
| 1205 |
|
| 1206 |
$sth->execute( "*", "*", $branchcode ); |
| 1207 |
$irule = $sth->fetchrow_hashref; |
| 1208 |
return $irule if defined($irule) ; |
| 1209 |
|
| 1210 |
$sth->execute( $borrowertype, $itemtype, "*" ); |
| 1211 |
$irule = $sth->fetchrow_hashref; |
| 1212 |
return $irule if defined($irule) ; |
| 1213 |
|
| 1214 |
$sth->execute( $borrowertype, "*", "*" ); |
| 1215 |
$irule = $sth->fetchrow_hashref; |
| 1216 |
return $irule if defined($irule) ; |
| 1217 |
|
| 1218 |
$sth->execute( "*", $itemtype, "*" ); |
| 1219 |
$irule = $sth->fetchrow_hashref; |
| 1220 |
return $irule if defined($irule) ; |
| 1221 |
|
| 1222 |
$sth->execute( "*", "*", "*" ); |
| 1223 |
$irule = $sth->fetchrow_hashref; |
| 1224 |
return $irule if defined($irule) ; |
| 1225 |
|
| 1226 |
# if no rule matches, |
| 1227 |
return undef; |
| 1228 |
} |
| 1229 |
|
| 1230 |
=head2 GetBranchBorrowerCircRule |
| 1231 |
|
| 1232 |
my $branch_cat_rule = GetBranchBorrowerCircRule($branchcode, $categorycode); |
| 1233 |
|
| 1234 |
Retrieves circulation rule attributes that apply to the given |
| 1235 |
branch and patron category, regardless of item type. |
| 1236 |
The return value is a hashref containing the following key: |
| 1237 |
|
| 1238 |
maxissueqty - maximum number of loans that a |
| 1239 |
patron of the given category can have at the given |
| 1240 |
branch. If the value is undef, no limit. |
| 1241 |
|
| 1242 |
This will first check for a specific branch and |
| 1243 |
category match from branch_borrower_circ_rules. |
| 1244 |
|
| 1245 |
If no rule is found, it will then check default_branch_circ_rules |
| 1246 |
(same branch, default category). If no rule is found, |
| 1247 |
it will then check default_borrower_circ_rules (default |
| 1248 |
branch, same category), then failing that, default_circ_rules |
| 1249 |
(default branch, default category). |
| 1250 |
|
| 1251 |
If no rule has been found in the database, it will default to |
| 1252 |
the buillt in rule: |
| 1253 |
|
| 1254 |
maxissueqty - undef |
| 1255 |
|
| 1256 |
C<$branchcode> and C<$categorycode> should contain the |
| 1257 |
literal branch code and patron category code, respectively - no |
| 1258 |
wildcards. |
| 1259 |
|
| 1260 |
=cut |
| 1261 |
|
| 1262 |
sub GetBranchBorrowerCircRule { |
| 1263 |
my $branchcode = shift; |
| 1264 |
my $categorycode = shift; |
| 1265 |
|
| 1266 |
my $branch_cat_query = "SELECT maxissueqty |
| 1267 |
FROM branch_borrower_circ_rules |
| 1268 |
WHERE branchcode = ? |
| 1269 |
AND categorycode = ?"; |
| 1270 |
my $dbh = C4::Context->dbh(); |
| 1271 |
my $sth = $dbh->prepare($branch_cat_query); |
| 1272 |
$sth->execute($branchcode, $categorycode); |
| 1273 |
my $result; |
| 1274 |
if ($result = $sth->fetchrow_hashref()) { |
| 1275 |
return $result; |
| 1276 |
} |
| 1277 |
|
| 1278 |
# try same branch, default borrower category |
| 1279 |
my $branch_query = "SELECT maxissueqty |
| 1280 |
FROM default_branch_circ_rules |
| 1281 |
WHERE branchcode = ?"; |
| 1282 |
$sth = $dbh->prepare($branch_query); |
| 1283 |
$sth->execute($branchcode); |
| 1284 |
if ($result = $sth->fetchrow_hashref()) { |
| 1285 |
return $result; |
| 1286 |
} |
| 1287 |
|
| 1288 |
# try default branch, same borrower category |
| 1289 |
my $category_query = "SELECT maxissueqty |
| 1290 |
FROM default_borrower_circ_rules |
| 1291 |
WHERE categorycode = ?"; |
| 1292 |
$sth = $dbh->prepare($category_query); |
| 1293 |
$sth->execute($categorycode); |
| 1294 |
if ($result = $sth->fetchrow_hashref()) { |
| 1295 |
return $result; |
| 1296 |
} |
| 1297 |
|
| 1298 |
# try default branch, default borrower category |
| 1299 |
my $default_query = "SELECT maxissueqty |
| 1300 |
FROM default_circ_rules"; |
| 1301 |
$sth = $dbh->prepare($default_query); |
| 1302 |
$sth->execute(); |
| 1303 |
if ($result = $sth->fetchrow_hashref()) { |
| 1304 |
return $result; |
| 1305 |
} |
| 1306 |
|
| 1307 |
# built-in default circulation rule |
| 1308 |
return { |
| 1309 |
maxissueqty => undef, |
| 1310 |
}; |
| 1311 |
} |
| 1312 |
|
| 1313 |
=head2 GetBranchItemRule |
| 1314 |
|
| 1315 |
my $branch_item_rule = GetBranchItemRule($branchcode, $itemtype); |
| 1316 |
|
| 1317 |
Retrieves circulation rule attributes that apply to the given |
| 1318 |
branch and item type, regardless of patron category. |
| 1319 |
|
| 1320 |
The return value is a hashref containing the following key: |
| 1321 |
|
| 1322 |
holdallowed => Hold policy for this branch and itemtype. Possible values: |
| 1323 |
0: No holds allowed. |
| 1324 |
1: Holds allowed only by patrons that have the same homebranch as the item. |
| 1325 |
2: Holds allowed from any patron. |
| 1326 |
|
| 1327 |
This searches branchitemrules in the following order: |
| 1328 |
|
| 1329 |
* Same branchcode and itemtype |
| 1330 |
* Same branchcode, itemtype '*' |
| 1331 |
* branchcode '*', same itemtype |
| 1332 |
* branchcode and itemtype '*' |
| 1333 |
|
| 1334 |
Neither C<$branchcode> nor C<$categorycode> should be '*'. |
| 1335 |
|
| 1336 |
=cut |
| 1337 |
|
| 1338 |
sub GetBranchItemRule { |
| 1339 |
my ( $branchcode, $itemtype ) = @_; |
| 1340 |
my $dbh = C4::Context->dbh(); |
| 1341 |
my $result = {}; |
| 1342 |
|
| 1343 |
my @attempts = ( |
| 1344 |
['SELECT holdallowed |
| 1345 |
FROM branch_item_rules |
| 1346 |
WHERE branchcode = ? |
| 1347 |
AND itemtype = ?', $branchcode, $itemtype], |
| 1348 |
['SELECT holdallowed |
| 1349 |
FROM default_branch_circ_rules |
| 1350 |
WHERE branchcode = ?', $branchcode], |
| 1351 |
['SELECT holdallowed |
| 1352 |
FROM default_branch_item_rules |
| 1353 |
WHERE itemtype = ?', $itemtype], |
| 1354 |
['SELECT holdallowed |
| 1355 |
FROM default_circ_rules'], |
| 1356 |
); |
| 1357 |
|
| 1358 |
foreach my $attempt (@attempts) { |
| 1359 |
my ($query, @bind_params) = @{$attempt}; |
| 1360 |
|
| 1361 |
# Since branch/category and branch/itemtype use the same per-branch |
| 1362 |
# defaults tables, we have to check that the key we want is set, not |
| 1363 |
# just that a row was returned |
| 1364 |
return $result if ( defined( $result->{'holdallowed'} = $dbh->selectrow_array( $query, {}, @bind_params ) ) ); |
| 1365 |
} |
| 1366 |
|
| 1367 |
# built-in default circulation rule |
| 1368 |
return { |
| 1369 |
holdallowed => 2, |
| 1370 |
}; |
| 1371 |
} |
1140 |
} |
| 1372 |
|
1141 |
|
| 1373 |
=head2 AddReturn |
1142 |
=head2 AddReturn |
|
Lines 1445-1452
patron who last borrowed the book.
Link Here
|
| 1445 |
=cut |
1214 |
=cut |
| 1446 |
|
1215 |
|
| 1447 |
sub AddReturn { |
1216 |
sub AddReturn { |
| 1448 |
my ( $barcode, $branch, $exemptfine, $dropbox ) = @_; |
1217 |
my ( $barcode, $branch, $exemptfine, $dropbox, $force) = @_; |
| 1449 |
if ($branch and not GetBranchDetail($branch)) { |
1218 |
if ( $branch and not GetBranchDetail($branch) ) { |
| 1450 |
warn "AddReturn error: branch '$branch' not found. Reverting to " . C4::Context->userenv->{'branch'}; |
1219 |
warn "AddReturn error: branch '$branch' not found. Reverting to " . C4::Context->userenv->{'branch'}; |
| 1451 |
undef $branch; |
1220 |
undef $branch; |
| 1452 |
} |
1221 |
} |
|
Lines 1490-1498
sub AddReturn {
Link Here
|
| 1490 |
my $branches = GetBranches(); # a potentially expensive call for a non-feature. |
1259 |
my $branches = GetBranches(); # a potentially expensive call for a non-feature. |
| 1491 |
$branches->{$hbr}->{PE} and $messages->{'IsPermanent'} = $hbr; |
1260 |
$branches->{$hbr}->{PE} and $messages->{'IsPermanent'} = $hbr; |
| 1492 |
} |
1261 |
} |
| 1493 |
|
1262 |
my $branchtransferfield=C4::Context->preference("BranchTransferLimitsType") eq "ccode" ? "ccode" : "itype"; |
|
|
1263 |
$debug && warn "$branch, $hbr, ",C4::Context->preference("BranchTransferLimitsType")," ,",$item->{ $branchtransferfield } ; |
| 1264 |
$debug && warn Dump($item); |
| 1265 |
$debug && warn IsBranchTransferAllowed( $branch, $hbr, $item->{ C4::Context->preference("BranchTransferLimitsType") } ); |
| 1494 |
# if indy branches and returning to different branch, refuse the return |
1266 |
# if indy branches and returning to different branch, refuse the return |
| 1495 |
if ($hbr ne $branch && C4::Context->preference("IndependantBranches")){ |
1267 |
if ( !$force && ($hbr ne $branch) |
|
|
1268 |
&& (C4::Context->preference("IndependantBranches") |
| 1269 |
or ( C4::Context->preference("UseBranchTransferLimits") |
| 1270 |
and !IsBranchTransferAllowed( $branch, $hbr, $item->{$branchtransferfield } ) ) |
| 1271 |
) |
| 1272 |
){ |
| 1496 |
$messages->{'Wrongbranch'} = { |
1273 |
$messages->{'Wrongbranch'} = { |
| 1497 |
Wrongbranch => $branch, |
1274 |
Wrongbranch => $branch, |
| 1498 |
Rightbranch => $hbr, |
1275 |
Rightbranch => $hbr, |
|
Lines 1503-1509
sub AddReturn {
Link Here
|
| 1503 |
# FIXME - even in an indy branches situation, there should |
1280 |
# FIXME - even in an indy branches situation, there should |
| 1504 |
# still be an option for the library to accept the item |
1281 |
# still be an option for the library to accept the item |
| 1505 |
# and transfer it to its owning library. |
1282 |
# and transfer it to its owning library. |
| 1506 |
return ( $doreturn, $messages, $issue, $borrower ); |
|
|
| 1507 |
} |
1283 |
} |
| 1508 |
|
1284 |
|
| 1509 |
if ( $item->{'wthdrawn'} ) { # book has been cancelled |
1285 |
if ( $item->{'wthdrawn'} ) { # book has been cancelled |
|
Lines 1514-1525
sub AddReturn {
Link Here
|
| 1514 |
# case of a return of document (deal with issues and holdingbranch) |
1290 |
# case of a return of document (deal with issues and holdingbranch) |
| 1515 |
if ($doreturn) { |
1291 |
if ($doreturn) { |
| 1516 |
$borrower or warn "AddReturn without current borrower"; |
1292 |
$borrower or warn "AddReturn without current borrower"; |
| 1517 |
my $circControlBranch; |
1293 |
my $circControlBranch; |
| 1518 |
if ($dropbox) { |
1294 |
if ($dropbox) { |
| 1519 |
# define circControlBranch only if dropbox mode is set |
1295 |
$circControlBranch = _GetCircControlBranch( $item, $borrower ); |
| 1520 |
# don't allow dropbox mode to create an invalid entry in issues (issuedate > today) |
1296 |
# don't allow dropbox mode to create an invalid entry in issues (issuedate > returndate) FIXME: actually checks eq, not gt |
| 1521 |
# FIXME: check issuedate > returndate, factoring in holidays |
1297 |
undef($dropbox) if ( $item->{'issuedate'} eq C4::Dates->today('iso') ); |
| 1522 |
$circControlBranch = _GetCircControlBranch($item,$borrower) unless ( $item->{'issuedate'} eq C4::Dates->today('iso') );; |
|
|
| 1523 |
} |
1298 |
} |
| 1524 |
|
1299 |
|
| 1525 |
if ($borrowernumber) { |
1300 |
if ($borrowernumber) { |
|
Lines 1527-1541
sub AddReturn {
Link Here
|
| 1527 |
$messages->{'WasReturned'} = 1; # FIXME is the "= 1" right? This could be the borrower hash. |
1302 |
$messages->{'WasReturned'} = 1; # FIXME is the "= 1" right? This could be the borrower hash. |
| 1528 |
} |
1303 |
} |
| 1529 |
|
1304 |
|
| 1530 |
ModItem({ onloan => undef }, $issue->{'biblionumber'}, $item->{'itemnumber'}); |
1305 |
ModItem( { renewals=>0, onloan => undef }, $issue->{'biblionumber'}, $item->{'itemnumber'} ); |
|
|
1306 |
# the holdingbranch is updated if the document is returned to another location. |
| 1307 |
# this is always done regardless of whether the item was on loan or not |
| 1308 |
if ( $item->{'holdingbranch'} ne $branch ) { |
| 1309 |
UpdateHoldingbranch( $branch, $item->{'itemnumber'} ); |
| 1310 |
$item->{'holdingbranch'} = $branch; # update item data holdingbranch too |
| 1311 |
} |
| 1531 |
} |
1312 |
} |
| 1532 |
|
1313 |
|
| 1533 |
# the holdingbranch is updated if the document is returned to another location. |
|
|
| 1534 |
# this is always done regardless of whether the item was on loan or not |
| 1535 |
if ($item->{'holdingbranch'} ne $branch) { |
| 1536 |
UpdateHoldingbranch($branch, $item->{'itemnumber'}); |
| 1537 |
$item->{'holdingbranch'} = $branch; # update item data holdingbranch too |
| 1538 |
} |
| 1539 |
ModDateLastSeen( $item->{'itemnumber'} ); |
1314 |
ModDateLastSeen( $item->{'itemnumber'} ); |
| 1540 |
|
1315 |
|
| 1541 |
# check if we have a transfer for this document |
1316 |
# check if we have a transfer for this document |
|
Lines 1562-1572
sub AddReturn {
Link Here
|
| 1562 |
_FixAccountForLostAndReturned($item->{'itemnumber'}, $borrowernumber, $barcode); # can tolerate undef $borrowernumber |
1337 |
_FixAccountForLostAndReturned($item->{'itemnumber'}, $borrowernumber, $barcode); # can tolerate undef $borrowernumber |
| 1563 |
$messages->{'WasLost'} = 1; |
1338 |
$messages->{'WasLost'} = 1; |
| 1564 |
} |
1339 |
} |
|
|
1340 |
if ($item->{'notforloan'}){ |
| 1341 |
$messages->{'NotForLoan'} = $item->{'notforloan'}; |
| 1342 |
} |
| 1343 |
if ($item->{'damaged'}){ |
| 1344 |
$messages->{'Damaged'} = $item->{'damaged'}; |
| 1345 |
} |
| 1565 |
|
1346 |
|
| 1566 |
# fix up the overdues in accounts... |
1347 |
if ($borrowernumber && $doreturn) { |
| 1567 |
if ($borrowernumber) { |
1348 |
# fix up the overdues in accounts... |
| 1568 |
my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox); |
1349 |
my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox); |
| 1569 |
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!"; # zero is OK, check defined |
1350 |
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!"; # zero is OK, check defined |
|
|
1351 |
|
| 1352 |
# fix fine days |
| 1353 |
my $debardate = _FixFineDaysOnReturn($borrower, $item, $issue->{date_due}); |
| 1354 |
$messages->{'Debarred'} = $debardate if($debardate); |
| 1355 |
|
| 1356 |
# get fines for the borrower |
| 1357 |
my $fineamount = C4::Overdues::GetFine($borrowernumber); |
| 1358 |
$messages->{'HaveFines'} = $fineamount if($fineamount); |
| 1359 |
|
| 1570 |
} |
1360 |
} |
| 1571 |
|
1361 |
|
| 1572 |
# find reserves..... |
1362 |
# find reserves..... |
|
Lines 1602-1621
sub AddReturn {
Link Here
|
| 1602 |
branch => $branch, |
1392 |
branch => $branch, |
| 1603 |
}); |
1393 |
}); |
| 1604 |
} |
1394 |
} |
| 1605 |
|
1395 |
|
| 1606 |
logaction("CIRCULATION", "RETURN", $borrowernumber, $item->{'biblionumber'}) |
1396 |
logaction( "CIRCULATION", "RETURN", $borrowernumber, $item->{'itemnumber'} ) |
| 1607 |
if C4::Context->preference("ReturnLog"); |
1397 |
if C4::Context->preference("ReturnLog"); |
| 1608 |
|
1398 |
|
| 1609 |
# FIXME: make this comment intelligible. |
1399 |
# FIXME: make this comment intelligible. |
| 1610 |
#adding message if holdingbranch is non equal a userenv branch to return the document to homebranch |
1400 |
#adding message if holdingbranch is non equal a userenv branch to return the document to homebranch |
| 1611 |
#we check, if we don't have reserv or transfert for this document, if not, return it to homebranch . |
1401 |
#we check, if we don't have reserv or transfert for this document, if not, return it to homebranch . |
| 1612 |
|
1402 |
|
| 1613 |
if ($doreturn and ($branch ne $hbr) and not $messages->{'WrongTransfer'} and ($validTransfert ne 1) ){ |
1403 |
if ( $doreturn and ( $branch ne $hbr ) and not $messages->{'WrongTransfer'} and ( $validTransfert ne 1 ) ) { |
| 1614 |
if ( C4::Context->preference("AutomaticItemReturn" ) or |
1404 |
if (C4::Context->preference("AutomaticItemReturn") |
| 1615 |
(C4::Context->preference("UseBranchTransferLimits") and |
1405 |
or ( C4::Context->preference("UseBranchTransferLimits") |
| 1616 |
! IsBranchTransferAllowed($branch, $hbr, $item->{C4::Context->preference("BranchTransferLimitsType")} ) |
1406 |
and !IsBranchTransferAllowed( $branch, $hbr, $item->{ $branchtransferfield } ) ) |
| 1617 |
)) { |
1407 |
) { |
| 1618 |
$debug and warn sprintf "about to call ModItemTransfer(%s, %s, %s)", $item->{'itemnumber'},$branch, $hbr; |
1408 |
$debug and warn sprintf "about to call ModItemTransfer(%s, %s, %s)", $item->{'itemnumber'}, $branch, $hbr; |
| 1619 |
$debug and warn "item: " . Dumper($item); |
1409 |
$debug and warn "item: " . Dumper($item); |
| 1620 |
ModItemTransfer($item->{'itemnumber'}, $branch, $hbr); |
1410 |
ModItemTransfer($item->{'itemnumber'}, $branch, $hbr); |
| 1621 |
$messages->{'WasTransfered'} = 1; |
1411 |
$messages->{'WasTransfered'} = 1; |
|
Lines 1690-1695
sub MarkIssueReturned {
Link Here
|
| 1690 |
$sth_del->execute($borrowernumber, $itemnumber); |
1480 |
$sth_del->execute($borrowernumber, $itemnumber); |
| 1691 |
} |
1481 |
} |
| 1692 |
|
1482 |
|
|
|
1483 |
=head2 _FixFineDaysOnReturn |
| 1484 |
|
| 1485 |
&_FixFineDaysOnReturn($borrower, $item, $datedue); |
| 1486 |
|
| 1487 |
C<$borrower> borrower hashref |
| 1488 |
|
| 1489 |
C<$item> item hashref |
| 1490 |
|
| 1491 |
C<$datedue> date due |
| 1492 |
|
| 1493 |
Internal function, called only by AddReturn that calculate and update the user fine days, and debars him |
| 1494 |
|
| 1495 |
=cut |
| 1496 |
|
| 1497 |
sub _FixFineDaysOnReturn { |
| 1498 |
my ($borrower, $item, $datedue) = @_; |
| 1499 |
|
| 1500 |
if($datedue){ |
| 1501 |
$datedue = C4::Dates->new($datedue,"iso"); |
| 1502 |
}else{ |
| 1503 |
return; |
| 1504 |
} |
| 1505 |
|
| 1506 |
my $branchcode =_GetCircControlBranch($item, $borrower); |
| 1507 |
my $calendar = C4::Calendar->new( branchcode => $branchcode ); |
| 1508 |
my $today = C4::Dates->new(); |
| 1509 |
|
| 1510 |
my $deltadays = $calendar->daysBetween($datedue, C4::Dates->new()); |
| 1511 |
|
| 1512 |
my $circcontrol = C4::Context::preference('CircControl'); |
| 1513 |
my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{itype}, $branchcode); |
| 1514 |
my $finedays = $issuingrule->{finedays}; |
| 1515 |
# exit if no finedays defined |
| 1516 |
return unless $finedays; |
| 1517 |
my $grace = $issuingrule->{firstremind}; |
| 1518 |
|
| 1519 |
if( $deltadays - $grace > 0){ |
| 1520 |
my @newdate = Add_Delta_Days(Today(), $deltadays * $finedays ); |
| 1521 |
my $isonewdate = join('-',@newdate); |
| 1522 |
my ($deby, $debm, $debd) = split(/-/,$borrower->{debarred}); |
| 1523 |
if(check_date($deby, $debm, $debd)){ |
| 1524 |
my @olddate = split(/-/, $borrower->{debarred}); |
| 1525 |
|
| 1526 |
if(Delta_Days(@olddate,@newdate) > 0){ |
| 1527 |
C4::Members::DebarMember($borrower->{borrowernumber}, $isonewdate); |
| 1528 |
return $isonewdate; |
| 1529 |
} |
| 1530 |
}else{ |
| 1531 |
C4::Members::DebarMember($borrower->{borrowernumber}, $isonewdate); |
| 1532 |
return $isonewdate; |
| 1533 |
} |
| 1534 |
} |
| 1535 |
} |
| 1536 |
|
| 1537 |
|
| 1693 |
=head2 _FixOverduesOnReturn |
1538 |
=head2 _FixOverduesOnReturn |
| 1694 |
|
1539 |
|
| 1695 |
&_FixOverduesOnReturn($brn,$itm, $exemptfine, $dropboxmode); |
1540 |
&_FixOverduesOnReturn($brn,$itm, $exemptfine, $dropboxmode); |
|
Lines 1864-1870
sub _GetCircControlBranch {
Link Here
|
| 1864 |
my $circcontrol = C4::Context->preference('CircControl'); |
1709 |
my $circcontrol = C4::Context->preference('CircControl'); |
| 1865 |
my $branch; |
1710 |
my $branch; |
| 1866 |
|
1711 |
|
| 1867 |
if ($circcontrol eq 'PickupLibrary') { |
1712 |
if ($circcontrol eq 'PickupLibrary' && C4::Context->userenv->{'branch'}) { |
| 1868 |
$branch= C4::Context->userenv->{'branch'}; |
1713 |
$branch= C4::Context->userenv->{'branch'}; |
| 1869 |
} elsif ($circcontrol eq 'PatronLibrary') { |
1714 |
} elsif ($circcontrol eq 'PatronLibrary') { |
| 1870 |
$branch=$borrower->{branchcode}; |
1715 |
$branch=$borrower->{branchcode}; |
|
Lines 1901-1907
sub GetItemIssue {
Link Here
|
| 1901 |
my ($itemnumber) = @_; |
1746 |
my ($itemnumber) = @_; |
| 1902 |
return unless $itemnumber; |
1747 |
return unless $itemnumber; |
| 1903 |
my $sth = C4::Context->dbh->prepare( |
1748 |
my $sth = C4::Context->dbh->prepare( |
| 1904 |
"SELECT * |
1749 |
"SELECT *, issues.renewals as 'issues.renewals' |
| 1905 |
FROM issues |
1750 |
FROM issues |
| 1906 |
LEFT JOIN items ON issues.itemnumber=items.itemnumber |
1751 |
LEFT JOIN items ON issues.itemnumber=items.itemnumber |
| 1907 |
WHERE issues.itemnumber=?"); |
1752 |
WHERE issues.itemnumber=?"); |
|
Lines 1972-1978
sub GetItemIssues {
Link Here
|
| 1972 |
} |
1817 |
} |
| 1973 |
my $results = $sth->fetchall_arrayref({}); |
1818 |
my $results = $sth->fetchall_arrayref({}); |
| 1974 |
foreach (@$results) { |
1819 |
foreach (@$results) { |
| 1975 |
$_->{'overdue'} = ($_->{'date_due'} lt $today) ? 1 : 0; |
1820 |
$_->{'overdue'} = ( $_->{'date_due'} lt $today && !defined($_->{return_date}) ) ? 1 : 0; |
| 1976 |
} |
1821 |
} |
| 1977 |
return $results; |
1822 |
return $results; |
| 1978 |
} |
1823 |
} |
|
Lines 2078-2146
already renewed the loan. $error will contain the reason the renewal can not pro
Link Here
|
| 2078 |
sub CanBookBeRenewed { |
1923 |
sub CanBookBeRenewed { |
| 2079 |
|
1924 |
|
| 2080 |
# check renewal status |
1925 |
# check renewal status |
| 2081 |
my ( $borrowernumber, $itemnumber, $override_limit ) = @_; |
1926 |
my ( $borrowernumber, $itemnumber ) = @_; |
| 2082 |
my $dbh = C4::Context->dbh; |
1927 |
my $dbh = C4::Context->dbh; |
| 2083 |
my $renews = 1; |
1928 |
my $renews = 1; |
| 2084 |
my $renewokay = 0; |
1929 |
my $renewokay = 1; |
| 2085 |
my $error; |
1930 |
my $error; |
| 2086 |
|
1931 |
|
| 2087 |
# Look in the issues table for this item, lent to this borrower, |
1932 |
# Look in the issues table for this item, lent to this borrower, |
| 2088 |
# and not yet returned. |
1933 |
# and not yet returned. |
| 2089 |
|
1934 |
|
| 2090 |
# Look in the issues table for this item, lent to this borrower, |
1935 |
# Look in the issues table for this item, lent to this borrower, |
| 2091 |
# and not yet returned. |
1936 |
# and not yet returned. |
| 2092 |
my %branch = ( |
1937 |
my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or return undef; |
| 2093 |
'ItemHomeLibrary' => 'items.homebranch', |
1938 |
my $item = GetItem($itemnumber) or return undef; |
| 2094 |
'PickupLibrary' => 'items.holdingbranch', |
1939 |
my $itemissue = GetItemIssue($itemnumber) or return undef; |
| 2095 |
'PatronLibrary' => 'borrowers.branchcode' |
1940 |
my $branchcode = _GetCircControlBranch($item, $borrower); |
| 2096 |
); |
1941 |
if ($itemissue->{'overdue'}){ |
| 2097 |
my $controlbranch = $branch{C4::Context->preference('CircControl')}; |
1942 |
$renewokay=0; |
| 2098 |
my $itype = C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype'; |
1943 |
$error->{message}='overdue'; |
|
|
1944 |
} |
| 2099 |
|
1945 |
|
| 2100 |
my $sthcount = $dbh->prepare(" |
1946 |
my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{itype}, $branchcode); |
| 2101 |
SELECT |
1947 |
|
| 2102 |
borrowers.categorycode, biblioitems.itemtype, issues.renewals, renewalsallowed, $controlbranch |
1948 |
if ( $issuingrule->{renewalsallowed} <= $itemissue->{'issues.renewals'} ) { |
| 2103 |
FROM issuingrules, |
1949 |
$renewokay=0; |
| 2104 |
issues |
1950 |
$error->{message} = "too_many"; |
| 2105 |
LEFT JOIN items USING (itemnumber) |
1951 |
} |
| 2106 |
LEFT JOIN borrowers USING (borrowernumber) |
|
|
| 2107 |
LEFT JOIN biblioitems USING (biblioitemnumber) |
| 2108 |
|
| 2109 |
WHERE |
| 2110 |
(issuingrules.categorycode = borrowers.categorycode OR issuingrules.categorycode = '*') |
| 2111 |
AND |
| 2112 |
(issuingrules.itemtype = $itype OR issuingrules.itemtype = '*') |
| 2113 |
AND |
| 2114 |
(issuingrules.branchcode = $controlbranch OR issuingrules.branchcode = '*') |
| 2115 |
AND |
| 2116 |
borrowernumber = ? |
| 2117 |
AND |
| 2118 |
itemnumber = ? |
| 2119 |
ORDER BY |
| 2120 |
issuingrules.categorycode desc, |
| 2121 |
issuingrules.itemtype desc, |
| 2122 |
issuingrules.branchcode desc |
| 2123 |
LIMIT 1; |
| 2124 |
"); |
| 2125 |
|
| 2126 |
$sthcount->execute( $borrowernumber, $itemnumber ); |
| 2127 |
if ( my $data1 = $sthcount->fetchrow_hashref ) { |
| 2128 |
|
| 2129 |
if ( ( $data1->{renewalsallowed} && $data1->{renewalsallowed} > $data1->{renewals} ) || $override_limit ) { |
| 2130 |
$renewokay = 1; |
| 2131 |
} |
| 2132 |
else { |
| 2133 |
$error="too_many"; |
| 2134 |
} |
| 2135 |
|
| 2136 |
my ( $resfound, $resrec ) = C4::Reserves::CheckReserves($itemnumber); |
| 2137 |
if ($resfound) { |
| 2138 |
$renewokay = 0; |
| 2139 |
$error="on_reserve" |
| 2140 |
} |
| 2141 |
|
1952 |
|
|
|
1953 |
my ( $resfound, $resrec ) = C4::Reserves::CheckReserves($itemnumber); |
| 1954 |
if ($resfound) { |
| 1955 |
$renewokay = 0; |
| 1956 |
$error->{message} = "on_reserve"; |
| 2142 |
} |
1957 |
} |
| 2143 |
return ($renewokay,$error); |
1958 |
$error->{renewals} = $itemissue->{'issues.renewals'}; |
|
|
1959 |
$error->{renewalsallowed}= $issuingrule->{renewalsallowed}; |
| 1960 |
|
| 1961 |
return ( $renewokay, $error ); |
| 2144 |
} |
1962 |
} |
| 2145 |
|
1963 |
|
| 2146 |
=head2 AddRenewal |
1964 |
=head2 AddRenewal |
|
Lines 2195-2216
sub AddRenewal {
Link Here
|
| 2195 |
# based on the value of the RenewalPeriodBase syspref. |
2013 |
# based on the value of the RenewalPeriodBase syspref. |
| 2196 |
unless ($datedue) { |
2014 |
unless ($datedue) { |
| 2197 |
|
2015 |
|
| 2198 |
my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or return undef; |
2016 |
my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or return undef; |
| 2199 |
my $loanlength = GetLoanLength( |
2017 |
my $branchcode = _GetCircControlBranch($item, $borrower); |
| 2200 |
$borrower->{'categorycode'}, |
2018 |
my $loanlength = GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode ); |
| 2201 |
(C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'} , |
2019 |
|
| 2202 |
$issuedata->{'branchcode'} ); # that's the circ control branch. |
2020 |
$datedue = |
|
|
2021 |
( C4::Context->preference('RenewalPeriodBase') eq 'date_due' ) |
| 2022 |
? C4::Dates->new( $issuedata->{date_due}, 'iso' ) |
| 2023 |
: C4::Dates->new(); |
| 2024 |
|
| 2025 |
my $itype = ( C4::Context->preference('item-level_itypes') ) ? $biblio->{'itype'} : $biblio->{'itemtype'}; |
| 2026 |
my $controlbranch = _GetCircControlBranch( $item, $borrower ); |
| 2027 |
my $renewalperiod = $loanlength->{renewalperiod} || GetLoanLength( $borrower->{'categorycode'}, $itype, $controlbranch ); |
| 2028 |
|
| 2029 |
$datedue = CalcDateDue( $datedue, $renewalperiod, $issuedata->{'branchcode'}, $borrower ); |
| 2203 |
|
2030 |
|
| 2204 |
$datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ? |
|
|
| 2205 |
C4::Dates->new($issuedata->{date_due}, 'iso') : |
| 2206 |
C4::Dates->new(); |
| 2207 |
$datedue = CalcDateDue($datedue,$loanlength,$issuedata->{'branchcode'},$borrower); |
| 2208 |
} |
2031 |
} |
| 2209 |
|
2032 |
|
| 2210 |
# Update the issues record to have the new due date, and a new count |
2033 |
# Update the issues record to have the new due date, and a new count |
| 2211 |
# of how many times it has been renewed. |
2034 |
# of how many times it has been renewed. |
| 2212 |
my $renews = $issuedata->{'renewals'} + 1; |
2035 |
my $renews = $issuedata->{'renewals'} + 1; |
| 2213 |
$sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ? |
2036 |
$sth = $dbh->prepare( |
|
|
2037 |
"UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ? |
| 2214 |
WHERE borrowernumber=? |
2038 |
WHERE borrowernumber=? |
| 2215 |
AND itemnumber=?" |
2039 |
AND itemnumber=?" |
| 2216 |
); |
2040 |
); |
|
Lines 2218-2225
sub AddRenewal {
Link Here
|
| 2218 |
$sth->finish; |
2042 |
$sth->finish; |
| 2219 |
|
2043 |
|
| 2220 |
# Update the renewal count on the item, and tell zebra to reindex |
2044 |
# Update the renewal count on the item, and tell zebra to reindex |
| 2221 |
$renews = $biblio->{'renewals'} + 1; |
2045 |
$renews = $item->{'renewals'} + 1; |
| 2222 |
ModItem({ renewals => $renews, onloan => $datedue->output('iso') }, $biblio->{'biblionumber'}, $itemnumber); |
2046 |
ModItem( { renewals => $renews, onloan => $datedue->output('iso') }, undef, $itemnumber ); |
| 2223 |
|
2047 |
|
| 2224 |
# Charge a new rental fee, if applicable? |
2048 |
# Charge a new rental fee, if applicable? |
| 2225 |
my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber ); |
2049 |
my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber ); |
|
Lines 2600-2614
sub CalcDateDue {
Link Here
|
| 2600 |
my ($startdate,$loanlength,$branch,$borrower) = @_; |
2424 |
my ($startdate,$loanlength,$branch,$borrower) = @_; |
| 2601 |
my $datedue; |
2425 |
my $datedue; |
| 2602 |
|
2426 |
|
| 2603 |
if(C4::Context->preference('useDaysMode') eq 'Days') { # ignoring calendar |
2427 |
my $calendar = C4::Calendar->new( branchcode => $branch ); |
| 2604 |
my $timedue = time + ($loanlength) * 86400; |
2428 |
$datedue = $calendar->addDate($startdate, $loanlength); |
| 2605 |
#FIXME - assumes now even though we take a startdate |
|
|
| 2606 |
my @datearr = localtime($timedue); |
| 2607 |
$datedue = C4::Dates->new( sprintf("%04d-%02d-%02d", 1900 + $datearr[5], $datearr[4] + 1, $datearr[3]), 'iso'); |
| 2608 |
} else { |
| 2609 |
my $calendar = C4::Calendar->new( branchcode => $branch ); |
| 2610 |
$datedue = $calendar->addDate($startdate, $loanlength); |
| 2611 |
} |
| 2612 |
|
2429 |
|
| 2613 |
# if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate |
2430 |
# if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate |
| 2614 |
if ( C4::Context->preference('ReturnBeforeExpiry') && $datedue->output('iso') gt $borrower->{dateexpiry} ) { |
2431 |
if ( C4::Context->preference('ReturnBeforeExpiry') && $datedue->output('iso') gt $borrower->{dateexpiry} ) { |
|
Lines 2818-2835
sub CreateBranchTransferLimit {
Link Here
|
| 2818 |
|
2635 |
|
| 2819 |
=head2 DeleteBranchTransferLimits |
2636 |
=head2 DeleteBranchTransferLimits |
| 2820 |
|
2637 |
|
| 2821 |
DeleteBranchTransferLimits(); |
2638 |
DeleteBranchTransferLimits($tobranch); |
| 2822 |
|
2639 |
|
| 2823 |
=cut |
2640 |
=cut |
| 2824 |
|
2641 |
|
| 2825 |
sub DeleteBranchTransferLimits { |
2642 |
sub DeleteBranchTransferLimits { |
| 2826 |
my $dbh = C4::Context->dbh; |
2643 |
my $branch = shift; |
| 2827 |
my $sth = $dbh->prepare("TRUNCATE TABLE branch_transfer_limits"); |
2644 |
my $dbh = C4::Context->dbh; |
| 2828 |
$sth->execute(); |
2645 |
my $sth = $dbh->prepare("DELETE FROM branch_transfer_limits WHERE toBranch = ?"); |
|
|
2646 |
$sth->execute($branch); |
| 2647 |
} |
| 2648 |
|
| 2649 |
sub GetOfflineOperations { |
| 2650 |
my $dbh = C4::Context->dbh; |
| 2651 |
my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE branchcode=? ORDER BY timestamp"); |
| 2652 |
$sth->execute(C4::Context->userenv->{'branch'}); |
| 2653 |
my $results = $sth->fetchall_arrayref({}); |
| 2654 |
$sth->finish; |
| 2655 |
return $results; |
| 2656 |
} |
| 2657 |
|
| 2658 |
sub GetOfflineOperation { |
| 2659 |
my $dbh = C4::Context->dbh; |
| 2660 |
my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE operationid=?"); |
| 2661 |
$sth->execute( shift ); |
| 2662 |
my $result = $sth->fetchrow_hashref; |
| 2663 |
$sth->finish; |
| 2664 |
return $result; |
| 2665 |
} |
| 2666 |
|
| 2667 |
sub AddOfflineOperation { |
| 2668 |
my $dbh = C4::Context->dbh; |
| 2669 |
warn Data::Dumper::Dumper(@_); |
| 2670 |
my $sth = $dbh->prepare("INSERT INTO pending_offline_operations VALUES('',?,?,?,?,?,?)"); |
| 2671 |
$sth->execute( @_ ); |
| 2672 |
return "Added."; |
| 2673 |
} |
| 2674 |
|
| 2675 |
sub DeleteOfflineOperation { |
| 2676 |
my $dbh = C4::Context->dbh; |
| 2677 |
my $sth = $dbh->prepare("DELETE FROM pending_offline_operations WHERE operationid=?"); |
| 2678 |
$sth->execute( shift ); |
| 2679 |
return "Deleted."; |
| 2680 |
} |
| 2681 |
|
| 2682 |
sub ProcessOfflineOperation { |
| 2683 |
my $operation = shift; |
| 2684 |
|
| 2685 |
my $report; |
| 2686 |
if ( $operation->{action} eq 'return' ) { |
| 2687 |
$report = ProcessOfflineReturn( $operation ); |
| 2688 |
} elsif ( $operation->{action} eq 'issue' ) { |
| 2689 |
$report = ProcessOfflineIssue( $operation ); |
| 2690 |
} |
| 2691 |
|
| 2692 |
DeleteOfflineOperation( $operation->{operationid} ) if $operation->{operationid}; |
| 2693 |
|
| 2694 |
return $report; |
| 2695 |
} |
| 2696 |
|
| 2697 |
sub ProcessOfflineReturn { |
| 2698 |
my $operation = shift; |
| 2699 |
|
| 2700 |
my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} ); |
| 2701 |
|
| 2702 |
if ( $itemnumber ) { |
| 2703 |
my $issue = GetOpenIssue( $itemnumber ); |
| 2704 |
if ( $issue ) { |
| 2705 |
MarkIssueReturned( |
| 2706 |
$issue->{borrowernumber}, |
| 2707 |
$itemnumber, |
| 2708 |
undef, |
| 2709 |
$operation->{timestamp}, |
| 2710 |
); |
| 2711 |
return "Success."; |
| 2712 |
} else { |
| 2713 |
return "Item not issued."; |
| 2714 |
} |
| 2715 |
} else { |
| 2716 |
return "Item not found."; |
| 2717 |
} |
| 2718 |
} |
| 2719 |
|
| 2720 |
sub ProcessOfflineIssue { |
| 2721 |
my $operation = shift; |
| 2722 |
|
| 2723 |
my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber |
| 2724 |
|
| 2725 |
if ( $borrower->{borrowernumber} ) { |
| 2726 |
my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} ); |
| 2727 |
my $issue = GetOpenIssue( $itemnumber ); |
| 2728 |
|
| 2729 |
if ( $issue and ( $issue->{borrowernumber} ne $borrower->{borrowernumber} ) ) { # Item already issued to another borrower, mark it returned |
| 2730 |
MarkIssueReturned( |
| 2731 |
$issue->{borrowernumber}, |
| 2732 |
$itemnumber, |
| 2733 |
undef, |
| 2734 |
$operation->{timestamp}, |
| 2735 |
); |
| 2736 |
} |
| 2737 |
AddIssue( |
| 2738 |
$borrower, |
| 2739 |
$operation->{'barcode'}, |
| 2740 |
undef, |
| 2741 |
1, |
| 2742 |
$operation->{timestamp}, |
| 2743 |
undef, |
| 2744 |
); |
| 2745 |
return "Success."; |
| 2746 |
} else { |
| 2747 |
return "Borrower not found."; |
| 2748 |
} |
| 2829 |
} |
2749 |
} |
| 2830 |
|
2750 |
|
| 2831 |
|
2751 |
|
| 2832 |
1; |
2752 |
1; |
| 2833 |
|
2753 |
|
| 2834 |
__END__ |
2754 |
__END__ |
| 2835 |
|
2755 |
|