+ #
+ # CHECK AGE RESTRICTION
+ #
+
+ # get $marker from preferences. Could be something like "FSK|PEGI|Alter|Age:"
+ my $markers = C4::Context->preference('AgeRestrictionMarker' );
+ my $bibvalues = $biblioitem->{'agerestriction'};
+ if (($markers)&&($bibvalues))
+ {
+ # Split $bibvalues to something like FSK 16 or PEGI 6
+ my @values = split ' ', $bibvalues;
+
+ # Search first occurence of one of the markers
+ my @markers = split /\|/, $markers;
+ my $index = 0;
+ my $take = -1;
+ for my $value (@values) {
+ $index ++;
+ for my $marker (@markers) {
+ $marker =~ s/^\s+//; #remove leading spaces
+ $marker =~ s/\s+$//; #remove trailing spaces
+ if (uc($marker) eq uc($value)) {
+ $take = $index;
+ last;
+ }
+ }
+ if ($take > -1) {
+ last;
+ }
+ }
+ # Index points to the next value
+ my $restrictionyear = 0;
+ if (($take <= $#values) && ($take >= 0)){
+ $restrictionyear += $values[$take];
+ }
+
+ if ($restrictionyear > 0) {
+ if ( $borrower->{'dateofbirth'} ) {
+ my @alloweddate = split /-/,$borrower->{'dateofbirth'} ;
+ $alloweddate[0] += $restrictionyear;
+ #Prevent runime eror on leap year (invalid date)
+ if (($alloweddate[1] == 2) && ($alloweddate[2] == 29)) {
+ $alloweddate[2] = 28;
+ }
+
+ if ( Date_to_Days(Today) < Date_to_Days(@alloweddate) -1 ) {
+ if (C4::Context->preference('AgeRestrictionOverride' )) {
+ $needsconfirmation{AGE_RESTRICTION} = "$bibvalues";
+ }
+ else {
+ $issuingimpossible{AGE_RESTRICTION} = "$bibvalues";
+ }
+ }
+ }
+ }
+ }
+
+## check for high holds decreasing loan period
+ my $decrease_loan = C4::Context->preference('decreaseLoanHighHolds');
+ if ( $decrease_loan && $decrease_loan == 1 ) {
+ my ( $reserved, $num, $duration, $returndate ) =
+ checkHighHolds( $item, $borrower );
+
+ if ( $num >= C4::Context->preference('decreaseLoanHighHoldsValue') ) {
+ $needsconfirmation{HIGHHOLDS} = {
+ num_holds => $num,
+ duration => $duration,
+ returndate => output_pref($returndate),
+ };
+ }
+ }
+
+ return ( \%issuingimpossible, \%needsconfirmation, \%alerts );
+}
+
+=head2 CanBookBeReturned
+
+ ($returnallowed, $message) = CanBookBeReturned($item, $branch)
+
+Check whether the item can be returned to the provided branch
+
+=over 4
+
+=item C<$item> is a hash of item information as returned from GetItem
+
+=item C<$branch> is the branchcode where the return is taking place
+
+=back
+
+Returns:
+
+=over 4
+
+=item C<$returnallowed> is 0 or 1, corresponding to whether the return is allowed (1) or not (0)
+
+=item C<$message> is the branchcode where the item SHOULD be returned, if the return is not allowed
+
+=back
+
+=cut
+
+sub CanBookBeReturned {
+ my ($item, $branch) = @_;
+ my $allowreturntobranch = C4::Context->preference("AllowReturnToBranch") || 'anywhere';
+
+ # assume return is allowed to start
+ my $allowed = 1;
+ my $message;
+
+ # identify all cases where return is forbidden
+ if ($allowreturntobranch eq 'homebranch' && $branch ne $item->{'homebranch'}) {
+ $allowed = 0;
+ $message = $item->{'homebranch'};
+ } elsif ($allowreturntobranch eq 'holdingbranch' && $branch ne $item->{'holdingbranch'}) {
+ $allowed = 0;
+ $message = $item->{'holdingbranch'};
+ } elsif ($allowreturntobranch eq 'homeorholdingbranch' && $branch ne $item->{'homebranch'} && $branch ne $item->{'holdingbranch'}) {
+ $allowed = 0;
+ $message = $item->{'homebranch'}; # FIXME: choice of homebranch is arbitrary
+ }
+
+ return ($allowed, $message);
+}
+
+=head2 CheckHighHolds
+
+ used when syspref decreaseLoanHighHolds is active. Returns 1 or 0 to define whether the minimum value held in
+ decreaseLoanHighHoldsValue is exceeded, the total number of outstanding holds, the number of days the loan
+ has been decreased to (held in syspref decreaseLoanHighHoldsValue), and the new due date
+
+=cut
+
+sub checkHighHolds {
+ my ( $item, $borrower ) = @_;
+ my $biblio = GetBiblioFromItemNumber( $item->{itemnumber} );
+ my $branch = _GetCircControlBranch( $item, $borrower );
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare(
+'select count(borrowernumber) as num_holds from reserves where biblionumber=?'
+ );
+ $sth->execute( $item->{'biblionumber'} );
+ my ($holds) = $sth->fetchrow_array;
+ if ($holds) {
+ my $issuedate = DateTime->now( time_zone => C4::Context->tz() );
+
+ my $calendar = Koha::Calendar->new( branchcode => $branch );
+
+ my $itype =
+ ( C4::Context->preference('item-level_itypes') )
+ ? $biblio->{'itype'}
+ : $biblio->{'itemtype'};
+ my $orig_due =
+ C4::Circulation::CalcDateDue( $issuedate, $itype, $branch,
+ $borrower );
+
+ my $reduced_datedue =
+ $calendar->addDate( $issuedate,
+ C4::Context->preference('decreaseLoanHighHoldsDuration') );
+
+ if ( DateTime->compare( $reduced_datedue, $orig_due ) == -1 ) {
+ return ( 1, $holds,
+ C4::Context->preference('decreaseLoanHighHoldsDuration'),
+ $reduced_datedue );
+ }
+ }
+ return ( 0, 0, 0, undef );