Lines 565-571
sub TooMany {
Link Here
|
565 |
|
565 |
|
566 |
=head2 CanBookBeIssued |
566 |
=head2 CanBookBeIssued |
567 |
|
567 |
|
568 |
( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $borrower, |
568 |
( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $patron, |
569 |
$barcode, $duedate, $inprocess, $ignore_reserves, $params ); |
569 |
$barcode, $duedate, $inprocess, $ignore_reserves, $params ); |
570 |
|
570 |
|
571 |
Check if a book can be issued. |
571 |
Check if a book can be issued. |
Lines 574-580
C<$issuingimpossible> and C<$needsconfirmation> are some hashref.
Link Here
|
574 |
|
574 |
|
575 |
=over 4 |
575 |
=over 4 |
576 |
|
576 |
|
577 |
=item C<$borrower> hash with borrower informations (from Koha::Patron->unblessed) |
577 |
=item C<$patron> is a Koha::Patron |
578 |
|
578 |
|
579 |
=item C<$barcode> is the bar code of the book being issued. |
579 |
=item C<$barcode> is the bar code of the book being issued. |
580 |
|
580 |
|
Lines 665-671
if the borrower borrows to much things
Link Here
|
665 |
=cut |
665 |
=cut |
666 |
|
666 |
|
667 |
sub CanBookBeIssued { |
667 |
sub CanBookBeIssued { |
668 |
my ( $borrower, $barcode, $duedate, $inprocess, $ignore_reserves, $params ) = @_; |
668 |
my ( $patron, $barcode, $duedate, $inprocess, $ignore_reserves, $params ) = @_; |
669 |
my %needsconfirmation; # filled with problems that needs confirmations |
669 |
my %needsconfirmation; # filled with problems that needs confirmations |
670 |
my %issuingimpossible; # filled with problems that causes the issue to be IMPOSSIBLE |
670 |
my %issuingimpossible; # filled with problems that causes the issue to be IMPOSSIBLE |
671 |
my %alerts; # filled with messages that shouldn't stop issuing, but the librarian should be aware of. |
671 |
my %alerts; # filled with messages that shouldn't stop issuing, but the librarian should be aware of. |
Lines 679-684
sub CanBookBeIssued {
Link Here
|
679 |
my $biblioitem = GetBiblioItemData($item->{biblioitemnumber}); |
679 |
my $biblioitem = GetBiblioItemData($item->{biblioitemnumber}); |
680 |
$item->{'itemtype'}=$item->{'itype'}; |
680 |
$item->{'itemtype'}=$item->{'itype'}; |
681 |
my $dbh = C4::Context->dbh; |
681 |
my $dbh = C4::Context->dbh; |
|
|
682 |
my $patron_unblessed = $patron->unblessed; |
682 |
|
683 |
|
683 |
# MANDATORY CHECKS - unless item exists, nothing else matters |
684 |
# MANDATORY CHECKS - unless item exists, nothing else matters |
684 |
unless ( $item->{barcode} ) { |
685 |
unless ( $item->{barcode} ) { |
Lines 696-704
sub CanBookBeIssued {
Link Here
|
696 |
unless ( $duedate ) { |
697 |
unless ( $duedate ) { |
697 |
my $issuedate = $now->clone(); |
698 |
my $issuedate = $now->clone(); |
698 |
|
699 |
|
699 |
my $branch = _GetCircControlBranch($item,$borrower); |
700 |
my $branch = _GetCircControlBranch($item, $patron_unblessed); |
700 |
my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'}; |
701 |
my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'}; |
701 |
$duedate = CalcDateDue( $issuedate, $itype, $branch, $borrower ); |
702 |
$duedate = CalcDateDue( $issuedate, $itype, $branch, $patron_unblessed ); |
702 |
|
703 |
|
703 |
# Offline circ calls AddIssue directly, doesn't run through here |
704 |
# Offline circ calls AddIssue directly, doesn't run through here |
704 |
# So issuingimpossible should be ok. |
705 |
# So issuingimpossible should be ok. |
Lines 716-722
sub CanBookBeIssued {
Link Here
|
716 |
# |
717 |
# |
717 |
# BORROWER STATUS |
718 |
# BORROWER STATUS |
718 |
# |
719 |
# |
719 |
my $patron = Koha::Patrons->find( $borrower->{borrowernumber} ); |
|
|
720 |
if ( $patron->category->category_type eq 'X' && ( $item->{barcode} )) { |
720 |
if ( $patron->category->category_type eq 'X' && ( $item->{barcode} )) { |
721 |
# stats only borrower -- add entry to statistics table, and return issuingimpossible{STATS} = 1 . |
721 |
# stats only borrower -- add entry to statistics table, and return issuingimpossible{STATS} = 1 . |
722 |
&UpdateStats({ |
722 |
&UpdateStats({ |
Lines 724-737
sub CanBookBeIssued {
Link Here
|
724 |
type => 'localuse', |
724 |
type => 'localuse', |
725 |
itemnumber => $item->{'itemnumber'}, |
725 |
itemnumber => $item->{'itemnumber'}, |
726 |
itemtype => $item->{'itype'}, |
726 |
itemtype => $item->{'itype'}, |
727 |
borrowernumber => $borrower->{'borrowernumber'}, |
727 |
borrowernumber => $patron->borrowernumber, |
728 |
ccode => $item->{'ccode'}} |
728 |
ccode => $item->{'ccode'}} |
729 |
); |
729 |
); |
730 |
ModDateLastSeen( $item->{'itemnumber'} ); |
730 |
ModDateLastSeen( $item->{'itemnumber'} ); |
731 |
return( { STATS => 1 }, {}); |
731 |
return( { STATS => 1 }, {}); |
732 |
} |
732 |
} |
733 |
|
733 |
|
734 |
my $flags = C4::Members::patronflags( $borrower ); |
734 |
my $flags = C4::Members::patronflags( $patron_unblessed ); |
735 |
if ( ref $flags ) { |
735 |
if ( ref $flags ) { |
736 |
if ( $flags->{GNA} ) { |
736 |
if ( $flags->{GNA} ) { |
737 |
$issuingimpossible{GNA} = 1; |
737 |
$issuingimpossible{GNA} = 1; |
Lines 743-752
sub CanBookBeIssued {
Link Here
|
743 |
$issuingimpossible{DEBARRED} = 1; |
743 |
$issuingimpossible{DEBARRED} = 1; |
744 |
} |
744 |
} |
745 |
} |
745 |
} |
746 |
if ( !defined $borrower->{dateexpiry} || $borrower->{'dateexpiry'} eq '0000-00-00') { |
746 |
if ( !defined $patron->dateexpiry || $patron->dateexpiry eq '0000-00-00') { |
747 |
$issuingimpossible{EXPIRED} = 1; |
747 |
$issuingimpossible{EXPIRED} = 1; |
748 |
} else { |
748 |
} else { |
749 |
my $expiry_dt = dt_from_string( $borrower->{dateexpiry}, 'sql', 'floating' ); |
749 |
my $expiry_dt = dt_from_string( $patron->dateexpiry, 'sql', 'floating' ); |
750 |
$expiry_dt->truncate( to => 'day'); |
750 |
$expiry_dt->truncate( to => 'day'); |
751 |
my $today = $now->clone()->truncate(to => 'day'); |
751 |
my $today = $now->clone()->truncate(to => 'day'); |
752 |
$today->set_time_zone( 'floating' ); |
752 |
$today->set_time_zone( 'floating' ); |
Lines 761-767
sub CanBookBeIssued {
Link Here
|
761 |
|
761 |
|
762 |
# DEBTS |
762 |
# DEBTS |
763 |
my ($balance, $non_issue_charges, $other_charges) = |
763 |
my ($balance, $non_issue_charges, $other_charges) = |
764 |
C4::Members::GetMemberAccountBalance( $borrower->{'borrowernumber'} ); |
764 |
C4::Members::GetMemberAccountBalance( $patron->borrowernumber ); |
765 |
|
765 |
|
766 |
my $amountlimit = C4::Context->preference("noissuescharge"); |
766 |
my $amountlimit = C4::Context->preference("noissuescharge"); |
767 |
my $allowfineoverride = C4::Context->preference("AllowFineOverride"); |
767 |
my $allowfineoverride = C4::Context->preference("AllowFineOverride"); |
Lines 771-778
sub CanBookBeIssued {
Link Here
|
771 |
my $no_issues_charge_guarantees = C4::Context->preference("NoIssuesChargeGuarantees"); |
771 |
my $no_issues_charge_guarantees = C4::Context->preference("NoIssuesChargeGuarantees"); |
772 |
$no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees ); |
772 |
$no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees ); |
773 |
if ( defined $no_issues_charge_guarantees ) { |
773 |
if ( defined $no_issues_charge_guarantees ) { |
774 |
my $p = Koha::Patrons->find( $borrower->{borrowernumber} ); |
774 |
my @guarantees = $patron->guarantees(); |
775 |
my @guarantees = $p->guarantees(); |
|
|
776 |
my $guarantees_non_issues_charges; |
775 |
my $guarantees_non_issues_charges; |
777 |
foreach my $g ( @guarantees ) { |
776 |
foreach my $g ( @guarantees ) { |
778 |
my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id ); |
777 |
my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id ); |
Lines 811-817
sub CanBookBeIssued {
Link Here
|
811 |
$alerts{OTHER_CHARGES} = sprintf( "%.2f", $other_charges ); |
810 |
$alerts{OTHER_CHARGES} = sprintf( "%.2f", $other_charges ); |
812 |
} |
811 |
} |
813 |
|
812 |
|
814 |
$patron = Koha::Patrons->find( $borrower->{borrowernumber} ); |
813 |
$patron = Koha::Patrons->find( $patron->borrowernumber ); # FIXME Refetch just in case, to avoid regressions. But must not be needed |
815 |
if ( my $debarred_date = $patron->is_debarred ) { |
814 |
if ( my $debarred_date = $patron->is_debarred ) { |
816 |
# patron has accrued fine days or has a restriction. $count is a date |
815 |
# patron has accrued fine days or has a restriction. $count is a date |
817 |
if ($debarred_date eq '9999-12-31') { |
816 |
if ($debarred_date eq '9999-12-31') { |
Lines 836-843
sub CanBookBeIssued {
Link Here
|
836 |
C4::Context->preference('SwitchOnSiteCheckouts') |
835 |
C4::Context->preference('SwitchOnSiteCheckouts') |
837 |
and $issue |
836 |
and $issue |
838 |
and $issue->onsite_checkout |
837 |
and $issue->onsite_checkout |
839 |
and $issue->borrowernumber == $borrower->{'borrowernumber'} ? 1 : 0 ); |
838 |
and $issue->borrowernumber == $patron->borrowernumber ? 1 : 0 ); |
840 |
my $toomany = TooMany( $borrower, $item->{biblionumber}, $item, { onsite_checkout => $onsite_checkout, switch_onsite_checkout => $switch_onsite_checkout, } ); |
839 |
my $toomany = TooMany( $patron_unblessed, $item->{biblionumber}, $item, { onsite_checkout => $onsite_checkout, switch_onsite_checkout => $switch_onsite_checkout, } ); |
841 |
# if TooMany max_allowed returns 0 the user doesn't have permission to check out this book |
840 |
# if TooMany max_allowed returns 0 the user doesn't have permission to check out this book |
842 |
if ( $toomany ) { |
841 |
if ( $toomany ) { |
843 |
if ( $toomany->{max_allowed} == 0 ) { |
842 |
if ( $toomany->{max_allowed} == 0 ) { |
Lines 857-863
sub CanBookBeIssued {
Link Here
|
857 |
# |
856 |
# |
858 |
# CHECKPREVCHECKOUT: CHECK IF ITEM HAS EVER BEEN LENT TO PATRON |
857 |
# CHECKPREVCHECKOUT: CHECK IF ITEM HAS EVER BEEN LENT TO PATRON |
859 |
# |
858 |
# |
860 |
$patron = Koha::Patrons->find($borrower->{borrowernumber}); |
859 |
$patron = Koha::Patrons->find( $patron->borrowernumber ); # FIXME Refetch just in case, to avoid regressions. But must not be needed |
861 |
my $wants_check = $patron->wants_check_for_previous_checkout; |
860 |
my $wants_check = $patron->wants_check_for_previous_checkout; |
862 |
$needsconfirmation{PREVISSUE} = 1 |
861 |
$needsconfirmation{PREVISSUE} = 1 |
863 |
if ($wants_check and $patron->do_check_for_previous_checkout($item)); |
862 |
if ($wants_check and $patron->do_check_for_previous_checkout($item)); |
Lines 924-931
sub CanBookBeIssued {
Link Here
|
924 |
$issuingimpossible{ITEMNOTSAMEBRANCH} = 1; |
923 |
$issuingimpossible{ITEMNOTSAMEBRANCH} = 1; |
925 |
$issuingimpossible{'itemhomebranch'} = $item->{C4::Context->preference("HomeOrHoldingBranch")}; |
924 |
$issuingimpossible{'itemhomebranch'} = $item->{C4::Context->preference("HomeOrHoldingBranch")}; |
926 |
} |
925 |
} |
927 |
$needsconfirmation{BORRNOTSAMEBRANCH} = $borrower->{'branchcode'} |
926 |
$needsconfirmation{BORRNOTSAMEBRANCH} = $patron->branchcode |
928 |
if ( $borrower->{'branchcode'} ne $userenv->{branch} ); |
927 |
if ( $patron->branchcode ne $userenv->{branch} ); |
929 |
} |
928 |
} |
930 |
} |
929 |
} |
931 |
# |
930 |
# |
Lines 934-940
sub CanBookBeIssued {
Link Here
|
934 |
my $rentalConfirmation = C4::Context->preference("RentalFeesCheckoutConfirmation"); |
933 |
my $rentalConfirmation = C4::Context->preference("RentalFeesCheckoutConfirmation"); |
935 |
|
934 |
|
936 |
if ( $rentalConfirmation ){ |
935 |
if ( $rentalConfirmation ){ |
937 |
my ($rentalCharge) = GetIssuingCharges( $item->{'itemnumber'}, $borrower->{'borrowernumber'} ); |
936 |
my ($rentalCharge) = GetIssuingCharges( $item->{'itemnumber'}, $patron->borrowernumber ); |
938 |
if ( $rentalCharge > 0 ){ |
937 |
if ( $rentalCharge > 0 ){ |
939 |
$needsconfirmation{RENTALCHARGE} = $rentalCharge; |
938 |
$needsconfirmation{RENTALCHARGE} = $rentalCharge; |
940 |
} |
939 |
} |
Lines 943-949
sub CanBookBeIssued {
Link Here
|
943 |
# |
942 |
# |
944 |
# CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER |
943 |
# CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER |
945 |
# |
944 |
# |
946 |
if ( $issue && $issue->borrowernumber eq $borrower->{'borrowernumber'} ){ |
945 |
if ( $issue && $issue->borrowernumber eq $patron->borrowernumber ){ |
947 |
|
946 |
|
948 |
# Already issued to current borrower. |
947 |
# Already issued to current borrower. |
949 |
# If it is an on-site checkout if it can be switched to a normal checkout |
948 |
# If it is an on-site checkout if it can be switched to a normal checkout |
Lines 954-960
sub CanBookBeIssued {
Link Here
|
954 |
$messages{ONSITE_CHECKOUT_WILL_BE_SWITCHED} = 1; |
953 |
$messages{ONSITE_CHECKOUT_WILL_BE_SWITCHED} = 1; |
955 |
} else { |
954 |
} else { |
956 |
my ($CanBookBeRenewed,$renewerror) = CanBookBeRenewed( |
955 |
my ($CanBookBeRenewed,$renewerror) = CanBookBeRenewed( |
957 |
$borrower->{'borrowernumber'}, |
956 |
$patron->borrowernumber, |
958 |
$item->{'itemnumber'}, |
957 |
$item->{'itemnumber'}, |
959 |
); |
958 |
); |
960 |
if ( $CanBookBeRenewed == 0 ) { # no more renewals allowed |
959 |
if ( $CanBookBeRenewed == 0 ) { # no more renewals allowed |
Lines 995-1001
sub CanBookBeIssued {
Link Here
|
995 |
my ( $restype, $res ) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); |
994 |
my ( $restype, $res ) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); |
996 |
if ($restype) { |
995 |
if ($restype) { |
997 |
my $resbor = $res->{'borrowernumber'}; |
996 |
my $resbor = $res->{'borrowernumber'}; |
998 |
if ( $resbor ne $borrower->{'borrowernumber'} ) { |
997 |
if ( $resbor ne $patron->borrowernumber ) { |
999 |
my $patron = Koha::Patrons->find( $resbor ); |
998 |
my $patron = Koha::Patrons->find( $resbor ); |
1000 |
if ( $restype eq "Waiting" ) |
999 |
if ( $restype eq "Waiting" ) |
1001 |
{ |
1000 |
{ |
Lines 1025-1031
sub CanBookBeIssued {
Link Here
|
1025 |
|
1024 |
|
1026 |
## CHECK AGE RESTRICTION |
1025 |
## CHECK AGE RESTRICTION |
1027 |
my $agerestriction = $biblioitem->{'agerestriction'}; |
1026 |
my $agerestriction = $biblioitem->{'agerestriction'}; |
1028 |
my ($restriction_age, $daysToAgeRestriction) = GetAgeRestriction( $agerestriction, $borrower ); |
1027 |
my ($restriction_age, $daysToAgeRestriction) = GetAgeRestriction( $agerestriction, $patron->unblessed ); |
1029 |
if ( $daysToAgeRestriction && $daysToAgeRestriction > 0 ) { |
1028 |
if ( $daysToAgeRestriction && $daysToAgeRestriction > 0 ) { |
1030 |
if ( C4::Context->preference('AgeRestrictionOverride') ) { |
1029 |
if ( C4::Context->preference('AgeRestrictionOverride') ) { |
1031 |
$needsconfirmation{AGE_RESTRICTION} = "$agerestriction"; |
1030 |
$needsconfirmation{AGE_RESTRICTION} = "$agerestriction"; |
Lines 1037-1043
sub CanBookBeIssued {
Link Here
|
1037 |
|
1036 |
|
1038 |
## check for high holds decreasing loan period |
1037 |
## check for high holds decreasing loan period |
1039 |
if ( C4::Context->preference('decreaseLoanHighHolds') ) { |
1038 |
if ( C4::Context->preference('decreaseLoanHighHolds') ) { |
1040 |
my $check = checkHighHolds( $item, $borrower ); |
1039 |
my $check = checkHighHolds( $item, $patron_unblessed ); |
1041 |
|
1040 |
|
1042 |
if ( $check->{exceeded} ) { |
1041 |
if ( $check->{exceeded} ) { |
1043 |
if ($override_high_holds) { |
1042 |
if ($override_high_holds) { |
Lines 1070-1078
sub CanBookBeIssued {
Link Here
|
1070 |
require C4::Serials; |
1069 |
require C4::Serials; |
1071 |
my $is_a_subscription = C4::Serials::CountSubscriptionFromBiblionumber($biblionumber); |
1070 |
my $is_a_subscription = C4::Serials::CountSubscriptionFromBiblionumber($biblionumber); |
1072 |
unless ($is_a_subscription) { |
1071 |
unless ($is_a_subscription) { |
|
|
1072 |
# FIXME Should be $patron->checkouts($args); |
1073 |
my $checkouts = Koha::Checkouts->search( |
1073 |
my $checkouts = Koha::Checkouts->search( |
1074 |
{ |
1074 |
{ |
1075 |
borrowernumber => $borrower->{borrowernumber}, |
1075 |
borrowernumber => $patron->borrowernumber, |
1076 |
biblionumber => $biblionumber, |
1076 |
biblionumber => $biblionumber, |
1077 |
}, |
1077 |
}, |
1078 |
{ |
1078 |
{ |