X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FReserves.pm;h=77880dc737e87642fdc05832bf06227c18ec775d;hb=3f7b2fa41898f59ce39d1725f8dfe6001095f796;hp=16ad20df779b617bf566fb7de41e06eea3dfc377;hpb=27b2b0bb95053e8a4a5a1a0e7eb3ba2f2c7f9dce;p=koha.git diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 16ad20df77..77880dc737 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -48,6 +48,8 @@ use Koha::IssuingRules; use Koha::Items; use Koha::ItemTypes; use Koha::Patrons; +use Koha::CirculationRules; +use Koha::Account::Lines; use List::MoreUtils qw( firstidx any ); use Carp; @@ -265,7 +267,7 @@ sub AddReserve { =head2 CanBookBeReserved - $canReserve = &CanBookBeReserved($borrowernumber, $biblionumber) + $canReserve = &CanBookBeReserved($borrowernumber, $biblionumber, $branchcode) if ($canReserve eq 'OK') { #We can reserve this Item! } See CanItemBeReserved() for possible return values. @@ -273,64 +275,68 @@ See CanItemBeReserved() for possible return values. =cut sub CanBookBeReserved{ - my ($borrowernumber, $biblionumber) = @_; + my ($borrowernumber, $biblionumber, $pickup_branchcode) = @_; - my $items = GetItemnumbersForBiblio($biblionumber); + my @itemnumbers = Koha::Items->search({ biblionumber => $biblionumber})->get_column("itemnumber"); #get items linked via host records my @hostitems = get_hostitemnumbers_of($biblionumber); if (@hostitems){ - push (@$items,@hostitems); + push (@itemnumbers, @hostitems); } my $canReserve; - foreach my $item (@$items) { - $canReserve = CanItemBeReserved( $borrowernumber, $item ); - return 'OK' if $canReserve eq 'OK'; + foreach my $itemnumber (@itemnumbers) { + $canReserve = CanItemBeReserved( $borrowernumber, $itemnumber, $pickup_branchcode ); + return { status => 'OK' } if $canReserve->{status} eq 'OK'; } return $canReserve; } =head2 CanItemBeReserved - $canReserve = &CanItemBeReserved($borrowernumber, $itemnumber) - if ($canReserve eq 'OK') { #We can reserve this Item! } + $canReserve = &CanItemBeReserved($borrowernumber, $itemnumber, $branchcode) + if ($canReserve->{status} eq 'OK') { #We can reserve this Item! } -@RETURNS OK, if the Item can be reserved. - ageRestricted, if the Item is age restricted for this borrower. - damaged, if the Item is damaged. - cannotReserveFromOtherBranches, if syspref 'canreservefromotherbranches' is OK. - tooManyReserves, if the borrower has exceeded his maximum reserve amount. - notReservable, if holds on this item are not allowed +@RETURNS { status => OK }, if the Item can be reserved. + { status => ageRestricted }, if the Item is age restricted for this borrower. + { status => damaged }, if the Item is damaged. + { status => cannotReserveFromOtherBranches }, if syspref 'canreservefromotherbranches' is OK. + { status => tooManyReserves, limit => $limit }, if the borrower has exceeded their maximum reserve amount. + { status => notReservable }, if holds on this item are not allowed + { status => libraryNotFound }, if given branchcode is not an existing library + { status => libraryNotPickupLocation }, if given branchcode is not configured to be a pickup location + { status => cannotBeTransferred }, if branch transfer limit applies on given item and branchcode =cut sub CanItemBeReserved { - my ( $borrowernumber, $itemnumber ) = @_; + my ( $borrowernumber, $itemnumber, $pickup_branchcode ) = @_; my $dbh = C4::Context->dbh; my $ruleitemtype; # itemtype of the matching issuing rule my $allowedreserves = 0; # Total number of holds allowed across all records my $holds_per_record = 1; # Total number of holds allowed for this one given record + my $holds_per_day; # Default to unlimited # we retrieve borrowers and items informations # # item->{itype} will come for biblioitems if necessery - my $item = GetItem($itemnumber); + my $item = C4::Items::GetItem($itemnumber); my $biblio = Koha::Biblios->find( $item->{biblionumber} ); my $patron = Koha::Patrons->find( $borrowernumber ); my $borrower = $patron->unblessed; # If an item is damaged and we don't allow holds on damaged items, we can stop right here - return 'damaged' + return { status =>'damaged' } if ( $item->{damaged} && !C4::Context->preference('AllowHoldsOnDamagedItems') ); # Check for the age restriction my ( $ageRestriction, $daysToAgeRestriction ) = C4::Circulation::GetAgeRestriction( $biblio->biblioitem->agerestriction, $borrower ); - return 'ageRestricted' if $daysToAgeRestriction && $daysToAgeRestriction > 0; + return { status => 'ageRestricted' } if $daysToAgeRestriction && $daysToAgeRestriction > 0; # Check that the patron doesn't have an item level hold on this item already - return 'itemAlreadyOnHold' + return { status =>'itemAlreadyOnHold' } if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count(); my $controlbranch = C4::Context->preference('ReservesControlBranch'); @@ -361,6 +367,7 @@ sub CanItemBeReserved { $ruleitemtype = $rights->{itemtype}; $allowedreserves = $rights->{reservesallowed}; $holds_per_record = $rights->{holds_per_record}; + $holds_per_day = $rights->{holds_per_day}; } else { $ruleitemtype = '*'; @@ -375,7 +382,19 @@ sub CanItemBeReserved { } ); if ( $holds->count() >= $holds_per_record ) { - return "tooManyHoldsForThisRecord"; + return { status => "tooManyHoldsForThisRecord", limit => $holds_per_record }; + } + + my $today_holds = Koha::Holds->search({ + borrowernumber => $borrowernumber, + reservedate => dt_from_string->date + }); + + if ( defined $holds_per_day && + ( ( $holds_per_day > 0 && $today_holds->count() >= $holds_per_day ) + or ( $holds_per_day == 0 ) ) + ) { + return { status => 'tooManyReservesToday', limit => $holds_per_day }; } # we retrieve count @@ -406,30 +425,25 @@ sub CanItemBeReserved { # we check if it's ok or not if ( $reservecount >= $allowedreserves ) { - return 'tooManyReserves'; + return { status => 'tooManyReserves', limit => $allowedreserves }; } # Now we need to check hold limits by patron category - my $schema = Koha::Database->new()->schema(); - my $rule = $schema->resultset('BranchBorrowerCircRule')->find( + my $rule = Koha::CirculationRules->get_effective_rule( { - branchcode => $branchcode, categorycode => $borrower->{categorycode}, + branchcode => $branchcode, + rule_name => 'max_holds', } ); - $rule ||= $schema->resultset('DefaultBorrowerCircRule')->find( - { - categorycode => $borrower->{categorycode} - } - ); - if ( $rule && defined $rule->max_holds ) { + if ( $rule && defined( $rule->rule_value ) && $rule->rule_value ne '' ) { my $total_holds_count = Koha::Holds->search( { borrowernumber => $borrower->{borrowernumber} } )->count(); - return 'tooManyReserves' if $total_holds_count >= $rule->max_holds; + return { status => 'tooManyReserves', limit => $rule->rule_value} if $total_holds_count >= $rule->rule_value; } my $circ_control_branch = @@ -438,13 +452,13 @@ sub CanItemBeReserved { C4::Circulation::GetBranchItemRule( $circ_control_branch, $item->itype ); if ( $branchitemrule->{holdallowed} == 0 ) { - return 'notReservable'; + return { status => 'notReservable' }; } if ( $branchitemrule->{holdallowed} == 1 && $borrower->{branchcode} ne $item->homebranch ) { - return 'cannotReserveFromOtherBranches'; + return { status => 'cannotReserveFromOtherBranches' }; } # If reservecount is ok, we check item branch if IndependentBranches is ON @@ -454,11 +468,27 @@ sub CanItemBeReserved { { my $itembranch = $item->homebranch; if ( $itembranch ne $borrower->{branchcode} ) { - return 'cannotReserveFromOtherBranches'; + return { status => 'cannotReserveFromOtherBranches' }; + } + } + + if ($pickup_branchcode) { + my $destination = Koha::Libraries->find({ + branchcode => $pickup_branchcode, + }); + + unless ($destination) { + return { status => 'libraryNotFound' }; + } + unless ($destination->pickup_location) { + return { status => 'libraryNotPickupLocation' }; + } + unless ($item->can_be_transferred({ to => $destination })) { + return 'cannotBeTransferred'; } } - return 'OK'; + return { status => 'OK' }; } =head2 CanReserveBeCanceledFromOpac @@ -542,13 +572,24 @@ sub GetOtherReserves { sub ChargeReserveFee { my ( $borrowernumber, $fee, $title ) = @_; - return if !$fee || $fee==0; # the last test is needed to include 0.00 - my $accquery = qq{ -INSERT INTO accountlines ( borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding ) VALUES (?, ?, NOW(), ?, ?, 'Res', ?) - }; - my $dbh = C4::Context->dbh; - my $nextacctno = &getnextacctno( $borrowernumber ); - $dbh->do( $accquery, undef, ( $borrowernumber, $nextacctno, $fee, "Reserve Charge - $title", $fee ) ); + + return if !$fee || $fee == 0; # the last test is needed to include 0.00 + + my $branchcode = C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef; + my $nextacctno = C4::Accounts::getnextacctno($borrowernumber); + + Koha::Account::Line->new( + { + borrowernumber => $borrowernumber, + accountno => $nextacctno, + date => dt_from_string(), + amount => $fee, + description => "Reserve Charge - $title", + accounttype => 'Res', + amountoutstanding => $fee, + branchcode => $branchcode + } + )->store(); } =head2 GetReserveFee @@ -1211,7 +1252,7 @@ sub _get_itype { =head2 AlterPriority - AlterPriority( $where, $reserve_id ); + AlterPriority( $where, $reserve_id, $prev_priority, $next_priority, $first_priority, $last_priority ); This function changes a reserve's priority up, down, to the top, or to the bottom. Input: $where is 'up', 'down', 'top' or 'bottom'. Biblionumber, Date reserve was placed @@ -1219,7 +1260,7 @@ Input: $where is 'up', 'down', 'top' or 'bottom'. Biblionumber, Date reserve was =cut sub AlterPriority { - my ( $where, $reserve_id ) = @_; + my ( $where, $reserve_id, $prev_priority, $next_priority, $first_priority, $last_priority ) = @_; my $hold = Koha::Holds->find( $reserve_id ); return unless $hold; @@ -1229,21 +1270,18 @@ sub AlterPriority { return; } - if ( $where eq 'up' || $where eq 'down' ) { - - my $priority = $hold->priority; - $priority = $where eq 'up' ? $priority - 1 : $priority + 1; - _FixPriority({ reserve_id => $reserve_id, rank => $priority }) - + if ( $where eq 'up' ) { + return unless $prev_priority; + _FixPriority({ reserve_id => $reserve_id, rank => $prev_priority }) + } elsif ( $where eq 'down' ) { + return unless $next_priority; + _FixPriority({ reserve_id => $reserve_id, rank => $next_priority }) } elsif ( $where eq 'top' ) { - - _FixPriority({ reserve_id => $reserve_id, rank => '1' }) - + _FixPriority({ reserve_id => $reserve_id, rank => $first_priority }) } elsif ( $where eq 'bottom' ) { - - _FixPriority({ reserve_id => $reserve_id, rank => '999999' }); - + _FixPriority({ reserve_id => $reserve_id, rank => $last_priority }); } + # FIXME Should return the new priority } @@ -2115,7 +2153,7 @@ sub GetHoldRule { my $sth = $dbh->prepare( q{ - SELECT categorycode, itemtype, branchcode, reservesallowed, holds_per_record + SELECT categorycode, itemtype, branchcode, reservesallowed, holds_per_record, holds_per_day FROM issuingrules WHERE (categorycode in (?,'*') ) AND (itemtype IN (?,'*'))