View | Details | Raw Unified | Return to bug 32092
Collapse All | Expand All

(-)a/C4/Circulation.pm (-47 / +31 lines)
Lines 425-440 sub TooMany { Link Here
425
    my $branch = _GetCircControlBranch($item_object->unblessed,$borrower);
425
    my $branch = _GetCircControlBranch($item_object->unblessed,$borrower);
426
    my $type = $item_object->effective_itemtype;
426
    my $type = $item_object->effective_itemtype;
427
427
428
    my ($type_object, $parent_type, $parent_maxissueqty_rule);
428
    my $type_object = Koha::ItemTypes->find( $type );
429
    $type_object = Koha::ItemTypes->find( $type );
429
    my $parent_type = $type_object->parent_type if $type_object;
430
    $parent_type = $type_object->parent_type if $type_object;
431
    my $child_types = Koha::ItemTypes->search({ parent_type => $type });
430
    my $child_types = Koha::ItemTypes->search({ parent_type => $type });
432
    # Find any children if we are a parent_type;
431
    # Find any children if we are a parent_type;
433
432
434
    # given branch, patron category, and item type, determine
433
    # given branch, patron category, and item type, determine
435
    # applicable issuing rule
434
    # applicable issuing rule
436
435
437
    $parent_maxissueqty_rule = Koha::CirculationRules->get_effective_rule(
436
    # If the parent rule is for default type we discount it
437
    my $parent_maxissueqty;
438
    $parent_maxissueqty = Koha::CirculationRules->get_effective_rule_value(
438
        {
439
        {
439
            categorycode => $cat_borrower,
440
            categorycode => $cat_borrower,
440
            itemtype     => $parent_type,
441
            itemtype     => $parent_type,
Lines 442-451 sub TooMany { Link Here
442
            rule_name    => 'maxissueqty',
443
            rule_name    => 'maxissueqty',
443
        }
444
        }
444
    ) if $parent_type;
445
    ) if $parent_type;
445
    # If the parent rule is for default type we discount it
446
    $parent_maxissueqty_rule = undef if $parent_maxissueqty_rule && !defined $parent_maxissueqty_rule->itemtype;
447
446
448
    my $maxissueqty_rule = Koha::CirculationRules->get_effective_rule(
447
    my $maxissueqty = Koha::CirculationRules->get_effective_rule_value(
449
        {
448
        {
450
            categorycode => $cat_borrower,
449
            categorycode => $cat_borrower,
451
            itemtype     => $type,
450
            itemtype     => $type,
Lines 454-460 sub TooMany { Link Here
454
        }
453
        }
455
    );
454
    );
456
455
457
    my $maxonsiteissueqty_rule = Koha::CirculationRules->get_effective_rule(
456
    my $maxonsiteissueqty = Koha::CirculationRules->get_effective_rule_value(
458
        {
457
        {
459
            categorycode => $cat_borrower,
458
            categorycode => $cat_borrower,
460
            itemtype     => $type,
459
            itemtype     => $type,
Lines 468-485 sub TooMany { Link Here
468
    # if a rule is found and has a loan limit set, count
467
    # if a rule is found and has a loan limit set, count
469
    # how many loans the patron already has that meet that
468
    # how many loans the patron already has that meet that
470
    # rule
469
    # rule
471
    if (defined($maxissueqty_rule) and $maxissueqty_rule->rule_value ne "") {
470
    if (defined $maxissueqty and $maxissueqty ne "") {
472
471
473
        my $checkouts;
472
        my $checkouts;
474
        if ( $maxissueqty_rule->branchcode ) {
473
        if ( $branch ) {
475
            if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) {
474
            if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) {
476
                $checkouts = $patron->checkouts->search(
475
                $checkouts = $patron->checkouts->search(
477
                    { 'me.branchcode' => $maxissueqty_rule->branchcode } );
476
                    { 'me.branchcode' => $branch } );
478
            } elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') {
477
            } elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') {
479
                $checkouts = $patron->checkouts; # if branch is the patron's home branch, then count all loans by patron
478
                $checkouts = $patron->checkouts; # if branch is the patron's home branch, then count all loans by patron
480
            } else {
479
            } else {
481
                $checkouts = $patron->checkouts->search(
480
                $checkouts = $patron->checkouts->search(
482
                    { 'item.homebranch' => $maxissueqty_rule->branchcode } );
481
                    { 'item.homebranch' => $branch } );
483
            }
482
            }
484
        } else {
483
        } else {
485
            $checkouts = $patron->checkouts; # if rule is not branch specific then count all loans by patron
484
            $checkouts = $patron->checkouts; # if rule is not branch specific then count all loans by patron
Lines 487-509 sub TooMany { Link Here
487
        $checkouts = $checkouts->search(undef, { prefetch => 'item' });
486
        $checkouts = $checkouts->search(undef, { prefetch => 'item' });
488
487
489
        my $sum_checkouts;
488
        my $sum_checkouts;
490
        my $rule_itemtype = $maxissueqty_rule->itemtype;
491
489
492
        my @types;
490
        my @types;
493
        unless ( $rule_itemtype ) {
491
        unless ( $type ) {
494
            # matching rule has the default item type, so count only
492
            # matching rule has the default item type, so count only
495
            # those existing loans that don't fall under a more
493
            # those existing loans that don't fall under a more
496
            # specific rule
494
            # specific rule
497
            @types = Koha::CirculationRules->search(
495
            @types = Koha::CirculationRules->search(
498
                {
496
                {
499
                    branchcode => $maxissueqty_rule->branchcode,
497
                    branchcode => $branch,
500
                    categorycode => [ $maxissueqty_rule->categorycode, $cat_borrower ],
498
                    categorycode => $cat_borrower,
501
                    itemtype  => { '!=' => undef },
499
                    itemtype  => { '!=' => undef },
502
                    rule_name => 'maxissueqty'
500
                    rule_name => 'maxissueqty'
503
                }
501
                }
504
            )->get_column('itemtype');
502
            )->get_column('itemtype');
505
        } else {
503
        } else {
506
            if ( $parent_maxissueqty_rule ) {
504
            if ( $parent_maxissueqty ) {
507
                # if we have a parent item type then we count loans of the
505
                # if we have a parent item type then we count loans of the
508
                # specific item type or its siblings or parent
506
                # specific item type or its siblings or parent
509
                my $children = Koha::ItemTypes->search({ parent_type => $parent_type });
507
                my $children = Koha::ItemTypes->search({ parent_type => $parent_type });
Lines 522-528 sub TooMany { Link Here
522
        while ( my $c = $checkouts->next ) {
520
        while ( my $c = $checkouts->next ) {
523
            my $itemtype = $c->item->effective_itemtype;
521
            my $itemtype = $c->item->effective_itemtype;
524
522
525
            unless ( $rule_itemtype ) {
523
            unless ( $type ) {
526
                next if grep {$_ eq $itemtype} @types;
524
                next if grep {$_ eq $itemtype} @types;
527
            } else {
525
            } else {
528
                next unless grep {$_ eq $itemtype} @types;
526
                next unless grep {$_ eq $itemtype} @types;
Lines 541-560 sub TooMany { Link Here
541
            checkout_count               => $checkout_count,
539
            checkout_count               => $checkout_count,
542
            onsite_checkout_count        => $onsite_checkout_count,
540
            onsite_checkout_count        => $onsite_checkout_count,
543
            onsite_checkout              => $onsite_checkout,
541
            onsite_checkout              => $onsite_checkout,
544
            max_checkouts_allowed        => $maxissueqty_rule ? $maxissueqty_rule->rule_value : undef,
542
            max_checkouts_allowed        => $maxissueqty,,
545
            max_onsite_checkouts_allowed => $maxonsiteissueqty_rule ? $maxonsiteissueqty_rule->rule_value : undef,
543
            max_onsite_checkouts_allowed => $maxonsiteissueqty,
546
            switch_onsite_checkout       => $switch_onsite_checkout,
544
            switch_onsite_checkout       => $switch_onsite_checkout,
547
        };
545
        };
548
        # If parent rules exists
546
        # If parent rules exists
549
        if ( defined($parent_maxissueqty_rule) and defined($parent_maxissueqty_rule->rule_value) ){
547
        if ( defined $parent_maxissueqty ){
550
            $checkout_rules->{max_checkouts_allowed} = $parent_maxissueqty_rule ? $parent_maxissueqty_rule->rule_value : undef;
548
            $checkout_rules->{max_checkouts_allowed} = $parent_maxissueqty;
551
            my $qty_over = _check_max_qty($checkout_rules);
549
            my $qty_over = _check_max_qty($checkout_rules);
552
            return $qty_over if defined $qty_over;
550
            return $qty_over if defined $qty_over;
553
551
554
            # If the parent rule is less than or equal to the child, we only need check the parent
552
            # If the parent rule is less than or equal to the child, we only need check the parent
555
            if( $maxissueqty_rule->rule_value < $parent_maxissueqty_rule->rule_value && defined($maxissueqty_rule->itemtype) ) {
553
            if( $maxissueqty < $parent_maxissueqty && defined($type) ) {
556
                $checkout_rules->{checkout_count} = $checkout_count_type;
554
                $checkout_rules->{checkout_count} = $checkout_count_type;
557
                $checkout_rules->{max_checkouts_allowed} = $maxissueqty_rule ? $maxissueqty_rule->rule_value : undef;
555
                $checkout_rules->{max_checkouts_allowed} = $maxissueqty;
558
                my $qty_over = _check_max_qty($checkout_rules);
556
                my $qty_over = _check_max_qty($checkout_rules);
559
                return $qty_over if defined $qty_over;
557
                return $qty_over if defined $qty_over;
560
            }
558
            }
Lines 597-603 sub TooMany { Link Here
597
        return $qty_over if defined $qty_over;
595
        return $qty_over if defined $qty_over;
598
    }
596
    }
599
597
600
    if ( not defined( $maxissueqty_rule ) and not defined($branch_borrower_circ_rule->{patron_maxissueqty}) ) {
598
    unless ( defined $maxissueqty || defined $branch_borrower_circ_rule->{patron_maxissueqty} ) {
601
        return { reason => 'NO_RULE_DEFINED', max_allowed => 0 };
599
        return { reason => 'NO_RULE_DEFINED', max_allowed => 0 };
602
    }
600
    }
603
601
Lines 1889-1916 wildcards. Link Here
1889
1887
1890
sub GetBranchBorrowerCircRule {
1888
sub GetBranchBorrowerCircRule {
1891
    my ( $branchcode, $categorycode ) = @_;
1889
    my ( $branchcode, $categorycode ) = @_;
1892
1890
    return Koha::CirculationRules->get_effective_rules(
1893
    # Initialize default values
1891
        {
1894
    my $rules = {
1892
            categorycode => $categorycode,
1895
        patron_maxissueqty       => undef,
1893
            itemtype     => undef,
1896
        patron_maxonsiteissueqty => undef,
1894
            branchcode   => $branchcode,
1897
    };
1895
            rules => ['patron_maxissueqty', 'patron_maxonsiteissueqty']
1898
1896
        }
1899
    # Search for rules!
1897
    );
1900
    foreach my $rule_name (qw( patron_maxissueqty patron_maxonsiteissueqty )) {
1901
        my $rule = Koha::CirculationRules->get_effective_rule(
1902
            {
1903
                categorycode => $categorycode,
1904
                itemtype     => undef,
1905
                branchcode   => $branchcode,
1906
                rule_name    => $rule_name,
1907
            }
1908
        );
1909
1910
        $rules->{$rule_name} = $rule->rule_value if defined $rule;
1911
    }
1912
1913
    return $rules;
1914
}
1898
}
1915
1899
1916
=head2 GetBranchItemRule
1900
=head2 GetBranchItemRule
(-)a/C4/Reserves.pm (-54 / +42 lines)
Lines 329-335 See CanItemBeReserved() for possible return values. Link Here
329
329
330
=cut
330
=cut
331
331
332
sub CanBookBeReserved{
332
sub CanBookBeReserved {
333
    my ($borrowernumber, $biblionumber, $pickup_branchcode, $params) = @_;
333
    my ($borrowernumber, $biblionumber, $pickup_branchcode, $params) = @_;
334
334
335
    # Check that patron have not checked out this biblio (if AllowHoldsOnPatronsPossessions set)
335
    # Check that patron have not checked out this biblio (if AllowHoldsOnPatronsPossessions set)
Lines 342-357 sub CanBookBeReserved{ Link Here
342
342
343
        # biblio-level, item type-contrained
343
        # biblio-level, item type-contrained
344
        my $patron          = Koha::Patrons->find($borrowernumber);
344
        my $patron          = Koha::Patrons->find($borrowernumber);
345
        my $reservesallowed = Koha::CirculationRules->get_effective_rule(
345
        my $reservesallowed = Koha::CirculationRules->get_effective_rule_value(
346
            {
346
            {
347
                itemtype     => $params->{itemtype},
347
                itemtype     => $params->{itemtype},
348
                categorycode => $patron->categorycode,
348
                categorycode => $patron->categorycode,
349
                branchcode   => $pickup_branchcode,
349
                branchcode   => $pickup_branchcode,
350
                rule_name    => 'reservesallowed',
350
                rule_name    => 'reservesallowed',
351
            }
351
            }
352
        )->rule_value;
352
        );
353
353
354
        $reservesallowed = ( $reservesallowed eq '' ) ? undef : $reservesallowed;
354
        $reservesallowed = $reservesallowed eq '' ? undef : $reservesallowed;
355
355
356
        my $count = $patron->holds->search(
356
        my $count = $patron->holds->search(
357
            {
357
            {
Lines 423-429 sub CanItemBeReserved { Link Here
423
    my ( $patron, $item, $pickup_branchcode, $params ) = @_;
423
    my ( $patron, $item, $pickup_branchcode, $params ) = @_;
424
424
425
    my $dbh = C4::Context->dbh;
425
    my $dbh = C4::Context->dbh;
426
    my $ruleitemtype;    # itemtype of the matching issuing rule
426
    my $effective_itemtype = $item->effective_itemtype;
427
    my $allowedreserves  = 0; # Total number of holds allowed across all records, default to none
427
    my $allowedreserves  = 0; # Total number of holds allowed across all records, default to none
428
428
429
    # We check item branch if IndependentBranches is ON
429
    # We check item branch if IndependentBranches is ON
Lines 464-471 sub CanItemBeReserved { Link Here
464
    }
464
    }
465
465
466
    # check if a recall exists on this item from this borrower
466
    # check if a recall exists on this item from this borrower
467
    return { status => 'recall' }
467
    if (
468
      if $patron->recalls->filter_by_current->search({ item_id => $item->itemnumber })->count;
468
        C4::Context->preference('UseRecalls') &&
469
        $patron->recalls->filter_by_current->search({ item_id => $item->itemnumber })->count
470
    ) {
471
        return { status => 'recall' };
472
    }
469
473
470
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
474
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
471
475
Lines 482-512 sub CanItemBeReserved { Link Here
482
    }
486
    }
483
487
484
    # we retrieve rights
488
    # we retrieve rights
485
    if (
489
    #undefined is 0, blank is unlimited
486
        my $reservesallowed = Koha::CirculationRules->get_effective_rule({
490
    $allowedreserves = Koha::CirculationRules->get_effective_rule_value({
487
                itemtype     => $item->effective_itemtype,
491
        itemtype     => $effective_itemtype,
488
                categorycode => $borrower->{categorycode},
492
        categorycode => $borrower->{categorycode},
489
                branchcode   => $reserves_control_branch,
493
        branchcode   => $reserves_control_branch,
490
                rule_name    => 'reservesallowed',
494
        rule_name    => 'reservesallowed'
491
        })
495
    }) // 0;
492
    ) {
493
        $ruleitemtype     = $reservesallowed->itemtype;
494
        $allowedreserves  = $reservesallowed->rule_value // 0; #undefined is 0, blank is unlimited
495
    }
496
    else {
497
        $ruleitemtype = undef;
498
    }
499
496
500
    my $rights = Koha::CirculationRules->get_effective_rules({
497
    my $rights = Koha::CirculationRules->get_effective_rules({
501
        categorycode => $borrower->{'categorycode'},
498
        categorycode => $borrower->{'categorycode'},
502
        itemtype     => $item->effective_itemtype,
499
        itemtype     => $effective_itemtype,
503
        branchcode   => $reserves_control_branch,
500
        branchcode   => $reserves_control_branch,
504
        rules        => ['holds_per_record','holds_per_day']
501
        rules        => ['holds_per_record', 'holds_per_day']
505
    });
502
    });
506
    my $holds_per_record = $rights->{holds_per_record} // 1;
503
    my $holds_per_record = $rights->{holds_per_record} // 1;
507
    my $holds_per_day    = $rights->{holds_per_day};
504
    my $holds_per_day    = $rights->{holds_per_day};
508
505
509
    if (   defined $holds_per_record && $holds_per_record ne '' ){
506
    if ( defined $holds_per_record && $holds_per_record ne '' ){
510
        if ( $holds_per_record == 0 ) {
507
        if ( $holds_per_record == 0 ) {
511
            return { status => "noReservesAllowed" };
508
            return { status => "noReservesAllowed" };
512
        }
509
        }
Lines 531-538 sub CanItemBeReserved { Link Here
531
    }
528
    }
532
529
533
    # we check if it's ok or not
530
    # we check if it's ok or not
534
    if ( defined $allowedreserves && $allowedreserves ne '' ){
531
    if ( $allowedreserves ne '' ) {
535
        if( $allowedreserves == 0 ){
532
        if( $allowedreserves == 0 ) {
536
            return { status => 'noReservesAllowed' };
533
            return { status => 'noReservesAllowed' };
537
        }
534
        }
538
        if ( !$params->{ignore_hold_counts} ) {
535
        if ( !$params->{ignore_hold_counts} ) {
Lines 549-579 sub CanItemBeReserved { Link Here
549
546
550
            # If using item-level itypes, fall back to the record
547
            # If using item-level itypes, fall back to the record
551
            # level itemtype if the hold has no associated item
548
            # level itemtype if the hold has no associated item
552
            if ( defined $ruleitemtype ) {
549
            if ( C4::Context->preference('item-level_itypes') ) {
553
                if ( C4::Context->preference('item-level_itypes') ) {
550
                $querycount .= q{
554
                    $querycount .= q{
551
                    AND ( COALESCE( items.itype, biblioitems.itemtype ) = ?
555
                        AND ( COALESCE( items.itype, biblioitems.itemtype ) = ?
552
                    OR reserves.itemtype = ? )
556
                           OR reserves.itemtype = ? )
553
                };
557
                    };
558
                }
559
                else {
560
                    $querycount .= q{
561
                        AND ( biblioitems.itemtype = ?
562
                           OR reserves.itemtype = ? )
563
                    };
564
                }
565
            }
566
567
            my $sthcount = $dbh->prepare($querycount);
568
569
            if ( defined $ruleitemtype ) {
570
                $sthcount->execute( $patron->borrowernumber, $reserves_control_branch, $ruleitemtype, $ruleitemtype );
571
            }
554
            }
572
            else {
555
            else {
573
                $sthcount->execute( $patron->borrowernumber, $reserves_control_branch );
556
                $querycount .= q{
557
                    AND ( biblioitems.itemtype = ?
558
                    OR reserves.itemtype = ? )
559
                };
574
            }
560
            }
575
561
576
            my $reservecount = "0";
562
            my $sthcount = $dbh->prepare($querycount);
563
            $sthcount->execute( $patron->borrowernumber, $reserves_control_branch, $effective_itemtype, $effective_itemtype );
564
565
            my $reservecount = 0;
577
            if ( my $rowcount = $sthcount->fetchrow_hashref() ) {
566
            if ( my $rowcount = $sthcount->fetchrow_hashref() ) {
578
                $reservecount = $rowcount->{count};
567
                $reservecount = $rowcount->{count};
579
            }
568
            }
Lines 583-607 sub CanItemBeReserved { Link Here
583
    }
572
    }
584
573
585
    # Now we need to check hold limits by patron category
574
    # Now we need to check hold limits by patron category
586
    my $rule = Koha::CirculationRules->get_effective_rule(
575
    my $max_holds = Koha::CirculationRules->get_effective_rule_value(
587
        {
576
        {
588
            categorycode => $patron->categorycode,
577
            categorycode => $patron->categorycode,
589
            branchcode   => $reserves_control_branch,
578
            branchcode   => $reserves_control_branch,
590
            rule_name    => 'max_holds',
579
            rule_name    => 'max_holds',
591
        }
580
        }
592
    );
581
    );
593
    if (!$params->{ignore_hold_counts} && $rule && defined( $rule->rule_value ) && $rule->rule_value ne '' ) {
582
    if (!$params->{ignore_hold_counts} && defined $max_holds && $max_holds ne '' ) {
594
        my $total_holds_count = Koha::Holds->search(
583
        my $total_holds_count = Koha::Holds->search(
595
            {
584
            {
596
                borrowernumber => $patron->borrowernumber
585
                borrowernumber => $patron->borrowernumber
597
            }
586
            }
598
        )->count();
587
        )->count();
599
588
600
        return { status => 'tooManyReserves', limit => $rule->rule_value} if $total_holds_count >= $rule->rule_value;
589
        return { status => 'tooManyReserves', limit => $max_holds } if $total_holds_count >= $max_holds;
601
    }
590
    }
602
591
603
    my $branchitemrule =
592
    my $branchitemrule =
604
      C4::Circulation::GetBranchItemRule( $reserves_control_branch, $item->effective_itemtype );
593
      C4::Circulation::GetBranchItemRule( $reserves_control_branch, $effective_itemtype );
605
594
606
    if ( $branchitemrule->{holdallowed} eq 'not_allowed' ) {
595
    if ( $branchitemrule->{holdallowed} eq 'not_allowed' ) {
607
        return { status => 'notReservable' };
596
        return { status => 'notReservable' };
Lines 2358-2370 sub GetMaxPatronHoldsForRecord { Link Here
2358
2347
2359
        $branchcode = $item->homebranch if ( $controlbranch eq "ItemHomeLibrary" );
2348
        $branchcode = $item->homebranch if ( $controlbranch eq "ItemHomeLibrary" );
2360
2349
2361
        my $rule = Koha::CirculationRules->get_effective_rule({
2350
        my $holds_per_record = Koha::CirculationRules->get_effective_rule_value({
2362
            categorycode => $categorycode,
2351
            categorycode => $categorycode,
2363
            itemtype     => $itemtype,
2352
            itemtype     => $itemtype,
2364
            branchcode   => $branchcode,
2353
            branchcode   => $branchcode,
2365
            rule_name    => 'holds_per_record'
2354
            rule_name    => 'holds_per_record'
2366
        });
2355
        }) // 0;
2367
        my $holds_per_record = $rule ? $rule->rule_value : 0;
2368
        $max = $holds_per_record if $holds_per_record > $max;
2356
        $max = $holds_per_record if $holds_per_record > $max;
2369
    }
2357
    }
2370
2358
(-)a/Koha/Biblio.pm (-12 / +6 lines)
Lines 295-310 $borrower must be a Koha::Patron object Link Here
295
sub article_request_type {
295
sub article_request_type {
296
    my ( $self, $borrower ) = @_;
296
    my ( $self, $borrower ) = @_;
297
297
298
    return q{} unless $borrower;
298
    return unless $borrower;
299
299
300
    my $rule = $self->article_request_type_for_items( $borrower );
300
    my $type = $self->article_request_type_for_items( $borrower );
301
    return $rule if $rule;
301
    return $type if $type;
302
302
303
    # If the record has no items that are requestable, go by the record itemtype
303
    # If the record has no items that are requestable, go by the record itemtype
304
    $rule = $self->article_request_type_for_bib($borrower);
304
    return $self->article_request_type_for_bib($borrower);
305
    return $rule if $rule;
306
307
    return q{};
308
}
305
}
309
306
310
=head3 article_request_type_for_bib
307
=head3 article_request_type_for_bib
Lines 318-338 Returns the article request type 'yes', 'no', 'item_only', 'bib_only', for the g Link Here
318
sub article_request_type_for_bib {
315
sub article_request_type_for_bib {
319
    my ( $self, $borrower ) = @_;
316
    my ( $self, $borrower ) = @_;
320
317
321
    return q{} unless $borrower;
318
    return unless $borrower;
322
319
323
    my $borrowertype = $borrower->categorycode;
320
    my $borrowertype = $borrower->categorycode;
324
    my $itemtype     = $self->itemtype();
321
    my $itemtype     = $self->itemtype();
325
322
326
    my $rule = Koha::CirculationRules->get_effective_rule(
323
    return Koha::CirculationRules->get_effective_rule_value(
327
        {
324
        {
328
            rule_name    => 'article_requests',
325
            rule_name    => 'article_requests',
329
            categorycode => $borrowertype,
326
            categorycode => $borrowertype,
330
            itemtype     => $itemtype,
327
            itemtype     => $itemtype,
331
        }
328
        }
332
    );
329
    );
333
334
    return q{} unless $rule;
335
    return $rule->rule_value || q{}
336
}
330
}
337
331
338
=head3 article_request_type_for_items
332
=head3 article_request_type_for_items
(-)a/Koha/Charges/Fees.pm (-4 / +3 lines)
Lines 89-96 sub new { Link Here
89
sub accumulate_rentalcharge {
89
sub accumulate_rentalcharge {
90
    my ($self) = @_;
90
    my ($self) = @_;
91
91
92
    my $itemtype        = Koha::ItemTypes->find( $self->item->effective_itemtype );
92
    my $itemtype = Koha::ItemTypes->find( $self->item->effective_itemtype );
93
    my $lengthunit_rule = Koha::CirculationRules->get_effective_rule(
93
    my $units = Koha::CirculationRules->get_effective_rule_value(
94
        {
94
        {
95
            categorycode => $self->patron->categorycode,
95
            categorycode => $self->patron->categorycode,
96
            itemtype     => $itemtype->id,
96
            itemtype     => $itemtype->id,
Lines 98-106 sub accumulate_rentalcharge { Link Here
98
            rule_name    => 'lengthunit',
98
            rule_name    => 'lengthunit',
99
        }
99
        }
100
    );
100
    );
101
    return 0 unless $lengthunit_rule;
101
    return 0 unless $units;
102
102
103
    my $units = $lengthunit_rule->rule_value;
104
    my $rentalcharge_increment =
103
    my $rentalcharge_increment =
105
      ( $units eq 'days' )
104
      ( $units eq 'days' )
106
      ? $itemtype->rentalcharge_daily
105
      ? $itemtype->rentalcharge_daily
(-)a/Koha/CirculationRules.pm (-24 / +17 lines)
Lines 298-310 sub get_effective_rule_value { Link Here
298
    my $cache_key = sprintf "CircRules:%s:%s:%s:%s", $rule_name // q{},
298
    my $cache_key = sprintf "CircRules:%s:%s:%s:%s", $rule_name // q{},
299
      $categorycode // q{}, $branchcode // q{}, $itemtype // q{};
299
      $categorycode // q{}, $branchcode // q{}, $itemtype // q{};
300
300
301
    my $cached       = $memory_cache->get_from_cache($cache_key);
301
    my $value = $memory_cache->get_from_cache($cache_key);
302
    return $cached if $cached;
302
    unless (defined $value) {
303
303
        my $rule = $self->get_effective_rule($params);
304
    my $rule = $self->get_effective_rule($params);
304
        if ($rule) {
305
305
            $value = $rule->rule_value;
306
    my $value= $rule ? $rule->rule_value : undef;
306
        }
307
    $memory_cache->set_in_cache( $cache_key, $value );
307
        $value //= 'undef';
308
        $memory_cache->set_in_cache( $cache_key, $value );
309
    }
310
    return if $value eq 'undef';
308
    return $value;
311
    return $value;
309
}
312
}
310
313
Lines 492-498 sub get_opacitemholds_policy { Link Here
492
495
493
    return unless $item or $patron;
496
    return unless $item or $patron;
494
497
495
    my $rule = Koha::CirculationRules->get_effective_rule(
498
    return Koha::CirculationRules->get_effective_rule_value(
496
        {
499
        {
497
            categorycode => $patron->categorycode,
500
            categorycode => $patron->categorycode,
498
            itemtype     => $item->effective_itemtype,
501
            itemtype     => $item->effective_itemtype,
Lines 500-507 sub get_opacitemholds_policy { Link Here
500
            rule_name    => 'opacitemholds',
503
            rule_name    => 'opacitemholds',
501
        }
504
        }
502
    );
505
    );
503
504
    return $rule ? $rule->rule_value : undef;
505
}
506
}
506
507
507
=head3 get_onshelfholds_policy
508
=head3 get_onshelfholds_policy
Lines 515-529 sub get_onshelfholds_policy { Link Here
515
    my $item = $params->{item};
516
    my $item = $params->{item};
516
    my $itemtype = $item->effective_itemtype;
517
    my $itemtype = $item->effective_itemtype;
517
    my $patron = $params->{patron};
518
    my $patron = $params->{patron};
518
    my $rule = Koha::CirculationRules->get_effective_rule(
519
    return Koha::CirculationRules->get_effective_rule_value(
519
        {
520
        {
520
            categorycode => ( $patron ? $patron->categorycode : undef ),
521
            categorycode => ( $patron ? $patron->categorycode : undef ),
521
            itemtype     => $itemtype,
522
            itemtype     => $itemtype,
522
            branchcode   => $item->holdingbranch,
523
            branchcode   => $item->holdingbranch,
523
            rule_name    => 'onshelfholds',
524
            rule_name    => 'onshelfholds',
524
        }
525
        }
525
    );
526
    ) // 0;
526
    return $rule ? $rule->rule_value : 0;
527
}
527
}
528
528
529
=head3 get_lostreturn_policy
529
=head3 get_lostreturn_policy
Lines 560-573 sub get_lostreturn_policy { Link Here
560
560
561
    my $branch = $behaviour_mapping->{ $behaviour };
561
    my $branch = $behaviour_mapping->{ $behaviour };
562
562
563
    my $rule = Koha::CirculationRules->get_effective_rule(
563
    return Koha::CirculationRules->get_effective_rule_value(
564
        {
564
        {
565
            branchcode => $branch,
565
            branchcode => $branch,
566
            rule_name  => 'lostreturn',
566
            rule_name  => 'lostreturn',
567
        }
567
        }
568
    );
568
    ) // 'refund';
569
570
    return $rule ? $rule->rule_value : 'refund';
571
}
569
}
572
570
573
=head3 article_requestable_rules
571
=head3 article_requestable_rules
Lines 648-654 sub get_effective_daysmode { Link Here
648
    my $itemtype         = $params->{itemtype};
646
    my $itemtype         = $params->{itemtype};
649
    my $branchcode       = $params->{branchcode};
647
    my $branchcode       = $params->{branchcode};
650
648
651
    my $daysmode_rule = $class->get_effective_rule(
649
    my $daysmode = $class->get_effective_rule_value(
652
        {
650
        {
653
            categorycode => $categorycode,
651
            categorycode => $categorycode,
654
            itemtype     => $itemtype,
652
            itemtype     => $itemtype,
Lines 656-667 sub get_effective_daysmode { Link Here
656
            rule_name    => 'daysmode',
654
            rule_name    => 'daysmode',
657
        }
655
        }
658
    );
656
    );
659
657
    return $daysmode || C4::Context->preference('useDaysMode');
660
    return ( defined($daysmode_rule)
661
          and $daysmode_rule->rule_value ne '' )
662
      ? $daysmode_rule->rule_value
663
      : C4::Context->preference('useDaysMode');
664
665
}
658
}
666
659
667
660
(-)a/Koha/Item.pm (-4 / +1 lines)
Lines 828-834 sub article_request_type { Link Here
828
      :                                      undef;
828
      :                                      undef;
829
    my $borrowertype = $borrower->categorycode;
829
    my $borrowertype = $borrower->categorycode;
830
    my $itemtype = $self->effective_itemtype();
830
    my $itemtype = $self->effective_itemtype();
831
    my $rule = Koha::CirculationRules->get_effective_rule(
831
    return Koha::CirculationRules->get_effective_rule_value(
832
        {
832
        {
833
            rule_name    => 'article_requests',
833
            rule_name    => 'article_requests',
834
            categorycode => $borrowertype,
834
            categorycode => $borrowertype,
Lines 836-844 sub article_request_type { Link Here
836
            branchcode   => $branchcode
836
            branchcode   => $branchcode
837
        }
837
        }
838
    );
838
    );
839
840
    return q{} unless $rule;
841
    return $rule->rule_value || q{}
842
}
839
}
843
840
844
=head3 current_holds
841
=head3 current_holds
(-)a/Koha/Patron.pm (-7 / +3 lines)
Lines 1001-1007 sub can_request_article { Link Here
1001
1001
1002
    $library_id //= C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
1002
    $library_id //= C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
1003
1003
1004
    my $rule = Koha::CirculationRules->get_effective_rule(
1004
    my $limit = Koha::CirculationRules->get_effective_rule_value(
1005
        {
1005
        {
1006
            branchcode   => $library_id,
1006
            branchcode   => $library_id,
1007
            categorycode => $self->categorycode,
1007
            categorycode => $self->categorycode,
Lines 1009-1016 sub can_request_article { Link Here
1009
        }
1009
        }
1010
    );
1010
    );
1011
1011
1012
    my $limit = ($rule) ? $rule->rule_value : undef;
1013
1014
    return 1 unless defined $limit;
1012
    return 1 unless defined $limit;
1015
1013
1016
    my $count = Koha::ArticleRequests->search(
1014
    my $count = Koha::ArticleRequests->search(
Lines 1042-1056 sub article_request_fee { Link Here
1042
1040
1043
    $library_id //= C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
1041
    $library_id //= C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
1044
1042
1045
    my $rule = Koha::CirculationRules->get_effective_rule(
1043
    my $fee = Koha::CirculationRules->get_effective_rule_value(
1046
        {
1044
        {
1047
            branchcode   => $library_id,
1045
            branchcode   => $library_id,
1048
            categorycode => $self->categorycode,
1046
            categorycode => $self->categorycode,
1049
            rule_name    => 'article_request_fee'
1047
            rule_name    => 'article_request_fee'
1050
        }
1048
        }
1051
    );
1049
    ) + 0;
1052
1053
    my $fee = ($rule) ? $rule->rule_value + 0 : 0;
1054
1050
1055
    return $fee;
1051
    return $fee;
1056
}
1052
}
(-)a/Koha/REST/V1/Checkouts.pm (-3 / +3 lines)
Lines 216-234 sub allows_renewal { Link Here
216
        my $renewable = Mojo::JSON->false;
216
        my $renewable = Mojo::JSON->false;
217
        $renewable = Mojo::JSON->true if $can_renew;
217
        $renewable = Mojo::JSON->true if $can_renew;
218
218
219
        my $rule = Koha::CirculationRules->get_effective_rule(
219
        my $renewalsallowed = Koha::CirculationRules->get_effective_rule_value(
220
            {
220
            {
221
                categorycode => $checkout->patron->categorycode,
221
                categorycode => $checkout->patron->categorycode,
222
                itemtype     => $checkout->item->effective_itemtype,
222
                itemtype     => $checkout->item->effective_itemtype,
223
                branchcode   => $checkout->branchcode,
223
                branchcode   => $checkout->branchcode,
224
                rule_name    => 'renewalsallowed',
224
                rule_name    => 'renewalsallowed'
225
            }
225
            }
226
        );
226
        );
227
        return $c->render(
227
        return $c->render(
228
            status => 200,
228
            status => 200,
229
            openapi => {
229
            openapi => {
230
                allows_renewal => $renewable,
230
                allows_renewal => $renewable,
231
                max_renewals => $rule->rule_value,
231
                max_renewals => $renewalsallowed,
232
                current_renewals => $checkout->renewals_count,
232
                current_renewals => $checkout->renewals_count,
233
                unseen_renewals => $checkout->unseen_renewals,
233
                unseen_renewals => $checkout->unseen_renewals,
234
                error => $error
234
                error => $error
(-)a/Koha/Recall.pm (-6 / +4 lines)
Lines 115-127 sub checkout { Link Here
115
        my @items = Koha::Items->search({ biblionumber => $self->biblio_id })->as_list;
115
        my @items = Koha::Items->search({ biblionumber => $self->biblio_id })->as_list;
116
        my @itemnumbers;
116
        my @itemnumbers;
117
        foreach (@items) {
117
        foreach (@items) {
118
            my $recalls_allowed = Koha::CirculationRules->get_effective_rule({
118
            my $recalls_allowed = Koha::CirculationRules->get_effective_rule_value({
119
                branchcode => C4::Context->userenv->{'branch'},
119
                branchcode => C4::Context->userenv->{'branch'},
120
                categorycode => $self->patron->categorycode,
120
                categorycode => $self->patron->categorycode,
121
                itemtype => $_->effective_itemtype,
121
                itemtype => $_->effective_itemtype,
122
                rule_name => 'recalls_allowed',
122
                rule_name => 'recalls_allowed',
123
            });
123
            });
124
            if ( defined $recalls_allowed and $recalls_allowed->rule_value > 0 ) {
124
            if ( defined $recalls_allowed and $recalls_allowed > 0 ) {
125
                push ( @itemnumbers, $_->itemnumber );
125
                push ( @itemnumbers, $_->itemnumber );
126
            }
126
            }
127
        }
127
        }
Lines 261-274 sub calc_expirationdate { Link Here
261
        $branchcode = C4::Circulation::_GetCircControlBranch( $item->unblessed, $self->patron->unblessed );
261
        $branchcode = C4::Circulation::_GetCircControlBranch( $item->unblessed, $self->patron->unblessed );
262
    }
262
    }
263
263
264
    my $rule = Koha::CirculationRules->get_effective_rule({
264
    my $shelf_time = Koha::CirculationRules->get_effective_rule_value({
265
        categorycode => $self->patron->categorycode,
265
        categorycode => $self->patron->categorycode,
266
        branchcode => $branchcode,
266
        branchcode => $branchcode,
267
        itemtype => $item ? $item->effective_itemtype : undef,
267
        itemtype => $item ? $item->effective_itemtype : undef,
268
        rule_name => 'recall_shelf_time'
268
        rule_name => 'recall_shelf_time'
269
    });
269
    }) // C4::Context->preference('RecallsMaxPickUpDelay');
270
271
    my $shelf_time = defined $rule ? $rule->rule_value : C4::Context->preference('RecallsMaxPickUpDelay');
272
270
273
    my $expirationdate = dt_from_string->add( days => $shelf_time );
271
    my $expirationdate = dt_from_string->add( days => $shelf_time );
274
    return $expirationdate;
272
    return $expirationdate;
(-)a/Koha/Recalls.pm (-3 / +2 lines)
Lines 133-145 sub add_recall { Link Here
133
133
134
        # get checkout and adjust due date based on circulation rules
134
        # get checkout and adjust due date based on circulation rules
135
        my $checkout = $recall->checkout;
135
        my $checkout = $recall->checkout;
136
        my $recall_due_date_interval = Koha::CirculationRules->get_effective_rule({
136
        my $due_interval = Koha::CirculationRules->get_effective_rule_value({
137
            categorycode => $checkout->patron->categorycode,
137
            categorycode => $checkout->patron->categorycode,
138
            itemtype => $checkout->item->effective_itemtype,
138
            itemtype => $checkout->item->effective_itemtype,
139
            branchcode => $branchcode,
139
            branchcode => $branchcode,
140
            rule_name => 'recall_due_date_interval',
140
            rule_name => 'recall_due_date_interval',
141
        });
141
        }) // 5;
142
        my $due_interval = defined $recall_due_date_interval ? $recall_due_date_interval->rule_value : 5;
143
        my $timestamp = dt_from_string( $recall->timestamp );
142
        my $timestamp = dt_from_string( $recall->timestamp );
144
        my $due_date = $timestamp->add( days => $due_interval );
143
        my $due_date = $timestamp->add( days => $due_interval );
145
        $checkout->update({ date_due => $due_date });
144
        $checkout->update({ date_due => $due_date });
(-)a/Koha/Template/Plugin/CirculationRules.pm (-4 / +1 lines)
Lines 46-52 sub Get { Link Here
46
    $categorycode = undef if $categorycode eq q{} or $categorycode eq q{*};
46
    $categorycode = undef if $categorycode eq q{} or $categorycode eq q{*};
47
    $itemtype     = undef if $itemtype eq q{}     or $itemtype  eq q{*};
47
    $itemtype     = undef if $itemtype eq q{}     or $itemtype  eq q{*};
48
48
49
    my $rule = Koha::CirculationRules->get_effective_rule(
49
    return Koha::CirculationRules->get_effective_rule_value(
50
        {
50
        {
51
            branchcode   => $branchcode,
51
            branchcode   => $branchcode,
52
            categorycode => $categorycode,
52
            categorycode => $categorycode,
Lines 54-61 sub Get { Link Here
54
            rule_name    => $rule_name,
54
            rule_name    => $rule_name,
55
        }
55
        }
56
    );
56
    );
57
58
    return $rule->rule_value if $rule;
59
}
57
}
60
58
61
=head3 Search
59
=head3 Search
62
- 

Return to bug 32092