Lines 567-573
sub TooMany {
Link Here
|
567 |
|
567 |
|
568 |
=head2 CanBookBeIssued |
568 |
=head2 CanBookBeIssued |
569 |
|
569 |
|
570 |
( $issuingimpossible, $needsconfirmation, [ $alerts ] ) = CanBookBeIssued( $borrower, |
570 |
( $issuingimpossible, $needsconfirmation, [ $alerts ] ) = CanBookBeIssued( $patron, |
571 |
$barcode, $duedate, $inprocess, $ignore_reserves, $params ); |
571 |
$barcode, $duedate, $inprocess, $ignore_reserves, $params ); |
572 |
|
572 |
|
573 |
Check if a book can be issued. |
573 |
Check if a book can be issued. |
Lines 580-586
data is keyed in lower case!
Link Here
|
580 |
|
580 |
|
581 |
=over 4 |
581 |
=over 4 |
582 |
|
582 |
|
583 |
=item C<$borrower> hash with borrower informations (from Koha::Patron->unblessed) |
583 |
=item C<$patron> is a Koha::Patron |
584 |
|
584 |
|
585 |
=item C<$barcode> is the bar code of the book being issued. |
585 |
=item C<$barcode> is the bar code of the book being issued. |
586 |
|
586 |
|
Lines 671-677
if the borrower borrows to much things
Link Here
|
671 |
=cut |
671 |
=cut |
672 |
|
672 |
|
673 |
sub CanBookBeIssued { |
673 |
sub CanBookBeIssued { |
674 |
my ( $borrower, $barcode, $duedate, $inprocess, $ignore_reserves, $params ) = @_; |
674 |
my ( $patron, $barcode, $duedate, $inprocess, $ignore_reserves, $params ) = @_; |
675 |
my %needsconfirmation; # filled with problems that needs confirmations |
675 |
my %needsconfirmation; # filled with problems that needs confirmations |
676 |
my %issuingimpossible; # filled with problems that causes the issue to be IMPOSSIBLE |
676 |
my %issuingimpossible; # filled with problems that causes the issue to be IMPOSSIBLE |
677 |
my %alerts; # filled with messages that shouldn't stop issuing, but the librarian should be aware of. |
677 |
my %alerts; # filled with messages that shouldn't stop issuing, but the librarian should be aware of. |
Lines 685-690
sub CanBookBeIssued {
Link Here
|
685 |
my $biblioitem = GetBiblioItemData($item->{biblioitemnumber}); |
685 |
my $biblioitem = GetBiblioItemData($item->{biblioitemnumber}); |
686 |
$item->{'itemtype'}=$item->{'itype'}; |
686 |
$item->{'itemtype'}=$item->{'itype'}; |
687 |
my $dbh = C4::Context->dbh; |
687 |
my $dbh = C4::Context->dbh; |
|
|
688 |
my $patron_unblessed = $patron->unblessed; |
688 |
|
689 |
|
689 |
# MANDATORY CHECKS - unless item exists, nothing else matters |
690 |
# MANDATORY CHECKS - unless item exists, nothing else matters |
690 |
unless ( $item->{barcode} ) { |
691 |
unless ( $item->{barcode} ) { |
Lines 702-710
sub CanBookBeIssued {
Link Here
|
702 |
unless ( $duedate ) { |
703 |
unless ( $duedate ) { |
703 |
my $issuedate = $now->clone(); |
704 |
my $issuedate = $now->clone(); |
704 |
|
705 |
|
705 |
my $branch = _GetCircControlBranch($item,$borrower); |
706 |
my $branch = _GetCircControlBranch($item, $patron_unblessed); |
706 |
my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'}; |
707 |
my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'}; |
707 |
$duedate = CalcDateDue( $issuedate, $itype, $branch, $borrower ); |
708 |
$duedate = CalcDateDue( $issuedate, $itype, $branch, $patron_unblessed ); |
708 |
|
709 |
|
709 |
# Offline circ calls AddIssue directly, doesn't run through here |
710 |
# Offline circ calls AddIssue directly, doesn't run through here |
710 |
# So issuingimpossible should be ok. |
711 |
# So issuingimpossible should be ok. |
Lines 722-728
sub CanBookBeIssued {
Link Here
|
722 |
# |
723 |
# |
723 |
# BORROWER STATUS |
724 |
# BORROWER STATUS |
724 |
# |
725 |
# |
725 |
my $patron = Koha::Patrons->find( $borrower->{borrowernumber} ); |
|
|
726 |
if ( $patron->category->category_type eq 'X' && ( $item->{barcode} )) { |
726 |
if ( $patron->category->category_type eq 'X' && ( $item->{barcode} )) { |
727 |
# stats only borrower -- add entry to statistics table, and return issuingimpossible{STATS} = 1 . |
727 |
# stats only borrower -- add entry to statistics table, and return issuingimpossible{STATS} = 1 . |
728 |
&UpdateStats({ |
728 |
&UpdateStats({ |
Lines 730-743
sub CanBookBeIssued {
Link Here
|
730 |
type => 'localuse', |
730 |
type => 'localuse', |
731 |
itemnumber => $item->{'itemnumber'}, |
731 |
itemnumber => $item->{'itemnumber'}, |
732 |
itemtype => $item->{'itype'}, |
732 |
itemtype => $item->{'itype'}, |
733 |
borrowernumber => $borrower->{'borrowernumber'}, |
733 |
borrowernumber => $patron->borrowernumber, |
734 |
ccode => $item->{'ccode'}} |
734 |
ccode => $item->{'ccode'}} |
735 |
); |
735 |
); |
736 |
ModDateLastSeen( $item->{'itemnumber'} ); |
736 |
ModDateLastSeen( $item->{'itemnumber'} ); |
737 |
return( { STATS => 1 }, {}); |
737 |
return( { STATS => 1 }, {}); |
738 |
} |
738 |
} |
739 |
|
739 |
|
740 |
my $flags = C4::Members::patronflags( $borrower ); |
740 |
my $flags = C4::Members::patronflags( $patron_unblessed ); |
741 |
if ( ref $flags ) { |
741 |
if ( ref $flags ) { |
742 |
if ( $flags->{GNA} ) { |
742 |
if ( $flags->{GNA} ) { |
743 |
$issuingimpossible{GNA} = 1; |
743 |
$issuingimpossible{GNA} = 1; |
Lines 749-758
sub CanBookBeIssued {
Link Here
|
749 |
$issuingimpossible{DEBARRED} = 1; |
749 |
$issuingimpossible{DEBARRED} = 1; |
750 |
} |
750 |
} |
751 |
} |
751 |
} |
752 |
if ( !defined $borrower->{dateexpiry} || $borrower->{'dateexpiry'} eq '0000-00-00') { |
752 |
if ( !defined $patron->dateexpiry || $patron->dateexpiry eq '0000-00-00') { |
753 |
$issuingimpossible{EXPIRED} = 1; |
753 |
$issuingimpossible{EXPIRED} = 1; |
754 |
} else { |
754 |
} else { |
755 |
my $expiry_dt = dt_from_string( $borrower->{dateexpiry}, 'sql', 'floating' ); |
755 |
my $expiry_dt = dt_from_string( $patron->dateexpiry, 'sql', 'floating' ); |
756 |
$expiry_dt->truncate( to => 'day'); |
756 |
$expiry_dt->truncate( to => 'day'); |
757 |
my $today = $now->clone()->truncate(to => 'day'); |
757 |
my $today = $now->clone()->truncate(to => 'day'); |
758 |
$today->set_time_zone( 'floating' ); |
758 |
$today->set_time_zone( 'floating' ); |
Lines 767-773
sub CanBookBeIssued {
Link Here
|
767 |
|
767 |
|
768 |
# DEBTS |
768 |
# DEBTS |
769 |
my ($balance, $non_issue_charges, $other_charges) = |
769 |
my ($balance, $non_issue_charges, $other_charges) = |
770 |
C4::Members::GetMemberAccountBalance( $borrower->{'borrowernumber'} ); |
770 |
C4::Members::GetMemberAccountBalance( $patron->borrowernumber ); |
771 |
|
771 |
|
772 |
my $amountlimit = C4::Context->preference("noissuescharge"); |
772 |
my $amountlimit = C4::Context->preference("noissuescharge"); |
773 |
my $allowfineoverride = C4::Context->preference("AllowFineOverride"); |
773 |
my $allowfineoverride = C4::Context->preference("AllowFineOverride"); |
Lines 777-784
sub CanBookBeIssued {
Link Here
|
777 |
my $no_issues_charge_guarantees = C4::Context->preference("NoIssuesChargeGuarantees"); |
777 |
my $no_issues_charge_guarantees = C4::Context->preference("NoIssuesChargeGuarantees"); |
778 |
$no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees ); |
778 |
$no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees ); |
779 |
if ( defined $no_issues_charge_guarantees ) { |
779 |
if ( defined $no_issues_charge_guarantees ) { |
780 |
my $p = Koha::Patrons->find( $borrower->{borrowernumber} ); |
780 |
my @guarantees = $patron->guarantees(); |
781 |
my @guarantees = $p->guarantees(); |
|
|
782 |
my $guarantees_non_issues_charges; |
781 |
my $guarantees_non_issues_charges; |
783 |
foreach my $g ( @guarantees ) { |
782 |
foreach my $g ( @guarantees ) { |
784 |
my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id ); |
783 |
my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id ); |
Lines 817-823
sub CanBookBeIssued {
Link Here
|
817 |
$alerts{OTHER_CHARGES} = sprintf( "%.2f", $other_charges ); |
816 |
$alerts{OTHER_CHARGES} = sprintf( "%.2f", $other_charges ); |
818 |
} |
817 |
} |
819 |
|
818 |
|
820 |
$patron = Koha::Patrons->find( $borrower->{borrowernumber} ); |
819 |
$patron = Koha::Patrons->find( $patron->borrowernumber ); # FIXME Refetch just in case, to avoid regressions. But must not be needed |
821 |
if ( my $debarred_date = $patron->is_debarred ) { |
820 |
if ( my $debarred_date = $patron->is_debarred ) { |
822 |
# patron has accrued fine days or has a restriction. $count is a date |
821 |
# patron has accrued fine days or has a restriction. $count is a date |
823 |
if ($debarred_date eq '9999-12-31') { |
822 |
if ($debarred_date eq '9999-12-31') { |
Lines 839-845
sub CanBookBeIssued {
Link Here
|
839 |
# |
838 |
# |
840 |
# CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER |
839 |
# CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER |
841 |
# |
840 |
# |
842 |
if ( $issue && $issue->borrowernumber eq $borrower->{'borrowernumber'} ){ |
841 |
if ( $issue && $issue->borrowernumber eq $patron->borrowernumber ){ |
843 |
|
842 |
|
844 |
# Already issued to current borrower. |
843 |
# Already issued to current borrower. |
845 |
# If it is an on-site checkout if it can be switched to a normal checkout |
844 |
# If it is an on-site checkout if it can be switched to a normal checkout |
Lines 850-856
sub CanBookBeIssued {
Link Here
|
850 |
$messages{ONSITE_CHECKOUT_WILL_BE_SWITCHED} = 1; |
849 |
$messages{ONSITE_CHECKOUT_WILL_BE_SWITCHED} = 1; |
851 |
} else { |
850 |
} else { |
852 |
my ($CanBookBeRenewed,$renewerror) = CanBookBeRenewed( |
851 |
my ($CanBookBeRenewed,$renewerror) = CanBookBeRenewed( |
853 |
$borrower->{'borrowernumber'}, |
852 |
$patron->borrowernumber, |
854 |
$item->{'itemnumber'}, |
853 |
$item->{'itemnumber'}, |
855 |
); |
854 |
); |
856 |
if ( $CanBookBeRenewed == 0 ) { # no more renewals allowed |
855 |
if ( $CanBookBeRenewed == 0 ) { # no more renewals allowed |
Lines 892-899
sub CanBookBeIssued {
Link Here
|
892 |
C4::Context->preference('SwitchOnSiteCheckouts') |
891 |
C4::Context->preference('SwitchOnSiteCheckouts') |
893 |
and $issue |
892 |
and $issue |
894 |
and $issue->onsite_checkout |
893 |
and $issue->onsite_checkout |
895 |
and $issue->borrowernumber == $borrower->{'borrowernumber'} ? 1 : 0 ); |
894 |
and $issue->borrowernumber == $patron->borrowernumber ? 1 : 0 ); |
896 |
my $toomany = TooMany( $borrower, $item->{biblionumber}, $item, { onsite_checkout => $onsite_checkout, switch_onsite_checkout => $switch_onsite_checkout, } ); |
895 |
my $toomany = TooMany( $patron_unblessed, $item->{biblionumber}, $item, { onsite_checkout => $onsite_checkout, switch_onsite_checkout => $switch_onsite_checkout, } ); |
897 |
# if TooMany max_allowed returns 0 the user doesn't have permission to check out this book |
896 |
# if TooMany max_allowed returns 0 the user doesn't have permission to check out this book |
898 |
if ( $toomany && not exists $needsconfirmation{RENEW_ISSUE} ) { |
897 |
if ( $toomany && not exists $needsconfirmation{RENEW_ISSUE} ) { |
899 |
if ( $toomany->{max_allowed} == 0 ) { |
898 |
if ( $toomany->{max_allowed} == 0 ) { |
Lines 913-919
sub CanBookBeIssued {
Link Here
|
913 |
# |
912 |
# |
914 |
# CHECKPREVCHECKOUT: CHECK IF ITEM HAS EVER BEEN LENT TO PATRON |
913 |
# CHECKPREVCHECKOUT: CHECK IF ITEM HAS EVER BEEN LENT TO PATRON |
915 |
# |
914 |
# |
916 |
$patron = Koha::Patrons->find($borrower->{borrowernumber}); |
915 |
$patron = Koha::Patrons->find( $patron->borrowernumber ); # FIXME Refetch just in case, to avoid regressions. But must not be needed |
917 |
my $wants_check = $patron->wants_check_for_previous_checkout; |
916 |
my $wants_check = $patron->wants_check_for_previous_checkout; |
918 |
$needsconfirmation{PREVISSUE} = 1 |
917 |
$needsconfirmation{PREVISSUE} = 1 |
919 |
if ($wants_check and $patron->do_check_for_previous_checkout($item)); |
918 |
if ($wants_check and $patron->do_check_for_previous_checkout($item)); |
Lines 980-987
sub CanBookBeIssued {
Link Here
|
980 |
$issuingimpossible{ITEMNOTSAMEBRANCH} = 1; |
979 |
$issuingimpossible{ITEMNOTSAMEBRANCH} = 1; |
981 |
$issuingimpossible{'itemhomebranch'} = $item->{C4::Context->preference("HomeOrHoldingBranch")}; |
980 |
$issuingimpossible{'itemhomebranch'} = $item->{C4::Context->preference("HomeOrHoldingBranch")}; |
982 |
} |
981 |
} |
983 |
$needsconfirmation{BORRNOTSAMEBRANCH} = $borrower->{'branchcode'} |
982 |
$needsconfirmation{BORRNOTSAMEBRANCH} = $patron->branchcode |
984 |
if ( $borrower->{'branchcode'} ne $userenv->{branch} ); |
983 |
if ( $patron->branchcode ne $userenv->{branch} ); |
985 |
} |
984 |
} |
986 |
} |
985 |
} |
987 |
# |
986 |
# |
Lines 990-996
sub CanBookBeIssued {
Link Here
|
990 |
my $rentalConfirmation = C4::Context->preference("RentalFeesCheckoutConfirmation"); |
989 |
my $rentalConfirmation = C4::Context->preference("RentalFeesCheckoutConfirmation"); |
991 |
|
990 |
|
992 |
if ( $rentalConfirmation ){ |
991 |
if ( $rentalConfirmation ){ |
993 |
my ($rentalCharge) = GetIssuingCharges( $item->{'itemnumber'}, $borrower->{'borrowernumber'} ); |
992 |
my ($rentalCharge) = GetIssuingCharges( $item->{'itemnumber'}, $patron->borrowernumber ); |
994 |
if ( $rentalCharge > 0 ){ |
993 |
if ( $rentalCharge > 0 ){ |
995 |
$needsconfirmation{RENTALCHARGE} = $rentalCharge; |
994 |
$needsconfirmation{RENTALCHARGE} = $rentalCharge; |
996 |
} |
995 |
} |
Lines 1001-1007
sub CanBookBeIssued {
Link Here
|
1001 |
my ( $restype, $res ) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); |
1000 |
my ( $restype, $res ) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); |
1002 |
if ($restype) { |
1001 |
if ($restype) { |
1003 |
my $resbor = $res->{'borrowernumber'}; |
1002 |
my $resbor = $res->{'borrowernumber'}; |
1004 |
if ( $resbor ne $borrower->{'borrowernumber'} ) { |
1003 |
if ( $resbor ne $patron->borrowernumber ) { |
1005 |
my $patron = Koha::Patrons->find( $resbor ); |
1004 |
my $patron = Koha::Patrons->find( $resbor ); |
1006 |
if ( $restype eq "Waiting" ) |
1005 |
if ( $restype eq "Waiting" ) |
1007 |
{ |
1006 |
{ |
Lines 1031-1037
sub CanBookBeIssued {
Link Here
|
1031 |
|
1030 |
|
1032 |
## CHECK AGE RESTRICTION |
1031 |
## CHECK AGE RESTRICTION |
1033 |
my $agerestriction = $biblioitem->{'agerestriction'}; |
1032 |
my $agerestriction = $biblioitem->{'agerestriction'}; |
1034 |
my ($restriction_age, $daysToAgeRestriction) = GetAgeRestriction( $agerestriction, $borrower ); |
1033 |
my ($restriction_age, $daysToAgeRestriction) = GetAgeRestriction( $agerestriction, $patron->unblessed ); |
1035 |
if ( $daysToAgeRestriction && $daysToAgeRestriction > 0 ) { |
1034 |
if ( $daysToAgeRestriction && $daysToAgeRestriction > 0 ) { |
1036 |
if ( C4::Context->preference('AgeRestrictionOverride') ) { |
1035 |
if ( C4::Context->preference('AgeRestrictionOverride') ) { |
1037 |
$needsconfirmation{AGE_RESTRICTION} = "$agerestriction"; |
1036 |
$needsconfirmation{AGE_RESTRICTION} = "$agerestriction"; |
Lines 1043-1049
sub CanBookBeIssued {
Link Here
|
1043 |
|
1042 |
|
1044 |
## check for high holds decreasing loan period |
1043 |
## check for high holds decreasing loan period |
1045 |
if ( C4::Context->preference('decreaseLoanHighHolds') ) { |
1044 |
if ( C4::Context->preference('decreaseLoanHighHolds') ) { |
1046 |
my $check = checkHighHolds( $item, $borrower ); |
1045 |
my $check = checkHighHolds( $item, $patron_unblessed ); |
1047 |
|
1046 |
|
1048 |
if ( $check->{exceeded} ) { |
1047 |
if ( $check->{exceeded} ) { |
1049 |
if ($override_high_holds) { |
1048 |
if ($override_high_holds) { |
Lines 1076-1084
sub CanBookBeIssued {
Link Here
|
1076 |
require C4::Serials; |
1075 |
require C4::Serials; |
1077 |
my $is_a_subscription = C4::Serials::CountSubscriptionFromBiblionumber($biblionumber); |
1076 |
my $is_a_subscription = C4::Serials::CountSubscriptionFromBiblionumber($biblionumber); |
1078 |
unless ($is_a_subscription) { |
1077 |
unless ($is_a_subscription) { |
|
|
1078 |
# FIXME Should be $patron->checkouts($args); |
1079 |
my $checkouts = Koha::Checkouts->search( |
1079 |
my $checkouts = Koha::Checkouts->search( |
1080 |
{ |
1080 |
{ |
1081 |
borrowernumber => $borrower->{borrowernumber}, |
1081 |
borrowernumber => $patron->borrowernumber, |
1082 |
biblionumber => $biblionumber, |
1082 |
biblionumber => $biblionumber, |
1083 |
}, |
1083 |
}, |
1084 |
{ |
1084 |
{ |