@@ -, +, @@ --- C4/Reserves.pm | 2 +- Koha/Biblio.pm | 31 ++++++++++++++ .../prog/en/modules/reserve/request.tt | 27 +++++++++--- koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss | 1 + .../opac-tmpl/bootstrap/en/modules/opac-reserve.tt | 50 ++++++++++++++++++++-- opac/opac-reserve.pl | 25 +++++++++-- reserve/request.pl | 26 +++++++++++ t/db_dependent/Reserves/MultiplePerRecord.t | 20 ++++++++- 8 files changed, 167 insertions(+), 15 deletions(-) --- a/C4/Reserves.pm +++ a/C4/Reserves.pm @@ -4,6 +4,7 @@ package C4::Reserves; # 2006 SAN Ouest Provence # 2007-2010 BibLibre Paul POULAIN # 2011 Catalyst IT +# 2018 Catalyst IT # # This file is part of Koha. # @@ -275,7 +276,6 @@ See CanItemBeReserved() for possible return values. sub CanBookBeReserved{ my ($borrowernumber, $biblionumber, $pickup_branchcode) = @_; - my @itemnumbers = Koha::Items->search({ biblionumber => $biblionumber})->get_column("itemnumber"); #get items linked via host records my @hostitems = get_hostitemnumbers_of($biblionumber); --- a/Koha/Biblio.pm +++ a/Koha/Biblio.pm @@ -425,6 +425,37 @@ sub has_items_waiting_or_intransit { return 0; } +=head3 allowed_holds + + my $holds_allowed_on_record_today = $biblio->allowed_holds( $patron_obj ); + + Calculates and returns the number of item-level holds a borrower is allowed to place on the record on a single day. + +=cut + +sub allowed_holds { + my ( $self, $patron ) = @_; + + my $controlbranch = C4::Context->preference('ReservesControlBranch'); + + my $categorycode = $patron->categorycode; + my $branchcode; + $branchcode = $patron->branchcode if ( $controlbranch eq "PatronLibrary" ); + + my $holds_allowed = 0; + foreach my $item ( $self->items()->as_list() ) { + my $itemtype = $item->effective_itemtype(); + $branchcode = $item->homebranch if ( $controlbranch eq "ItemHomeLibrary" ); + + my $rule = C4::Reserves::GetHoldRule( $categorycode, $itemtype, $branchcode ); + my $holds_per_day = $rule ? $rule->{holds_per_day} : 0; + if ( $holds_per_day ) { + $holds_allowed = $holds_per_day if $holds_per_day > $holds_allowed; + } + } + return $holds_allowed; +} + =head3 type =cut --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -248,7 +248,7 @@ [% IF remaining_holds_for_record > 1 %]
  • - +
  • [% ELSE %] @@ -670,9 +670,12 @@ [% END %][% END %][% END %] }; var MSG_NO_ITEMS_AVAILABLE = _("A hold cannot be requested on any of these items."); - var MSG_EXCEEDED_HOLDS_PER_RECORD = _("Patron has exceeded the number of holds for this record."); + var MSG_EXCEEDED_HOLDS_PER_RECORD = _("Patron reached the maximum number of holds for this record."); + var MSG_EXCEEDED_HOLDS_PER_DAY = _("Patron reached the maximum number of holds allowed today."); + var MSG_EXCEEDED_MAXRESERVES_SYSPREF = _("Patron reached the maximum number of holds allowed at once"); var remainingHolds = "[% remaining_holds_for_record | html %]"; - + var remainingHoldsToday = "[% remaining_holds_allowed_today | html %]"; + var maxreserves = "[% maxreserves | html %]"; $(document).ready(function() { function ToggleHoldsToPlace() { if ( $("#requestany").prop('checked') ) { @@ -685,7 +688,6 @@ $("#requestany").on('change', function(){ ToggleHoldsToPlace(); }); - [% IF AutoResumeSuspendedHolds %] $(".suspend_until_datepicker, .datepickerfrom, .datepickerto").datepicker("option", "minDate", 1); [% END %] @@ -807,8 +809,23 @@ } else { $("#requestany").prop("checked",true); } - if (remainingHolds - numchecked < 0) { + if (remainingHolds - numchecked <= 0) { alert(MSG_EXCEEDED_HOLDS_PER_RECORD); + [% IF !(Koha.Preference('AllowHoldPolicyOverride')) %] + $('input[name=checkitem]:not(:checked)').attr('disabled', 'disabled'); + [% END %] + } + if (remainingHoldsToday - numchecked <= 0) { + alert(MSG_EXCEEDED_HOLDS_PER_DAY); + [% IF !(Koha.Preference('AllowHoldPolicyOverride')) %] + $('input[name=checkitem]:not(:checked)').attr('disabled', 'disabled'); + [% END %] + } + if (maxreserves - numchecked <= 0) { + alert(MSG_EXCEEDED_MAXRESERVES_SYSPREF); + [% IF !(Koha.Preference('AllowHoldPolicyOverride')) %] + $('input[name=checkitem]:not(:checked)').attr('disabled', 'disabled'); + [% END %] } }); var prev_rank_request; --- a/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss +++ a/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss @@ -3004,6 +3004,7 @@ button.closebtn { .hold-options { clear: both; + width: auto; } .toggle-hold-options { --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt +++ a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt @@ -151,6 +151,7 @@ [% FOREACH bibitemloo IN bibitemloop %]
    +

    [% IF ( bibitemloo.holdable ) %] @@ -298,8 +299,10 @@ [% END # / IF OpacHoldNotes %] + [% IF bibitemloo.itemholdable %]

    + [% END # / IF bibitemloo.itemholdable %] [% IF bibitemloo.remaining_holds_for_record > 1 %] @@ -321,7 +326,7 @@