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

(-)a/C4/Circulation.pm (-66 / +148 lines)
Lines 373-381 sub transferbook { Link Here
373
373
374
374
375
sub TooMany {
375
sub TooMany {
376
    my $borrower        = shift;
376
    my $borrower = shift;
377
    my $biblionumber = shift;
377
    my $biblionumber = shift;
378
	my $item		= shift;
378
    my $item = shift;
379
    my $params = shift;
379
    my $params = shift;
380
    my $onsite_checkout = $params->{onsite_checkout} || 0;
380
    my $onsite_checkout = $params->{onsite_checkout} || 0;
381
    my $switch_onsite_checkout = $params->{switch_onsite_checkout} || 0;
381
    my $switch_onsite_checkout = $params->{switch_onsite_checkout} || 0;
Lines 388-395 sub TooMany { Link Here
388
  			? $item->{'itype'}         # item-level
388
  			? $item->{'itype'}         # item-level
389
			: $item->{'itemtype'};     # biblio-level
389
			: $item->{'itemtype'};     # biblio-level
390
 
390
 
391
    my ($type_object, $parent_type, $parent_maxissueqty_rule);
392
    $type_object = Koha::ItemTypes->find( $type );
393
    $parent_type = $type_object->parent_type if $type_object;
394
    my $child_types = Koha::ItemTypes->search( parent_type => $type );
395
    # Find any children if we are a parent_type;
396
391
    # given branch, patron category, and item type, determine
397
    # given branch, patron category, and item type, determine
392
    # applicable issuing rule
398
    # applicable issuing rule
399
400
    $parent_maxissueqty_rule = Koha::CirculationRules->get_effective_rule(
401
        {
402
            categorycode => $cat_borrower,
403
            itemtype     => $parent_type,
404
            branchcode   => $branch,
405
            rule_name    => 'maxissueqty',
406
        }
407
    ) if $parent_type;
408
    # If the parent rule is for default type we discount it
409
    $parent_maxissueqty_rule = undef if $parent_maxissueqty_rule && $parent_maxissueqty_rule->itemtype eq '*';
410
393
    my $maxissueqty_rule = Koha::CirculationRules->get_effective_rule(
411
    my $maxissueqty_rule = Koha::CirculationRules->get_effective_rule(
394
        {
412
        {
395
            categorycode => $cat_borrower,
413
            categorycode => $cat_borrower,
Lines 398-403 sub TooMany { Link Here
398
            rule_name    => 'maxissueqty',
416
            rule_name    => 'maxissueqty',
399
        }
417
        }
400
    );
418
    );
419
420
401
    my $maxonsiteissueqty_rule = Koha::CirculationRules->get_effective_rule(
421
    my $maxonsiteissueqty_rule = Koha::CirculationRules->get_effective_rule(
402
        {
422
        {
403
            categorycode => $cat_borrower,
423
            categorycode => $cat_borrower,
Lines 412-420 sub TooMany { Link Here
412
    # how many loans the patron already has that meet that
432
    # how many loans the patron already has that meet that
413
    # rule
433
    # rule
414
    if (defined($maxissueqty_rule) and defined($maxissueqty_rule->rule_value)) {
434
    if (defined($maxissueqty_rule) and defined($maxissueqty_rule->rule_value)) {
435
415
        my @bind_params;
436
        my @bind_params;
416
        my $count_query = q|
437
        my $count_query = "";
417
            SELECT COUNT(*) AS total, COALESCE(SUM(onsite_checkout), 0) AS onsite_checkouts
438
439
        if (C4::Context->preference('item-level_itypes')) {
440
            $count_query .= q|SELECT COALESCE( SUM( IF(items.itype = '| .$type . q|',1,0) ), 0) as type_total, COUNT(*) AS total, COALESCE(SUM(onsite_checkout), 0) AS onsite_checkouts|;
441
        } else{
442
            $count_query .= q|SELECT COALESCE(SUM( IF(biblioitems.itype = '| .$type . q|',1,0) ), 0) as type_total, COUNT(*) AS total, COALESCE(SUM(onsite_checkout), 0) AS onsite_checkouts|;
443
        }
444
445
        $count_query .= q|
418
            FROM issues
446
            FROM issues
419
            JOIN items USING (itemnumber)
447
            JOIN items USING (itemnumber)
420
        |;
448
        |;
Lines 444-458 sub TooMany { Link Here
444
            push @bind_params, $maxissueqty_rule->categorycode;
472
            push @bind_params, $maxissueqty_rule->categorycode;
445
            push @bind_params, $cat_borrower;
473
            push @bind_params, $cat_borrower;
446
        } else {
474
        } else {
447
            # rule has specific item type, so count loans of that
475
            my @types;
448
            # specific item type
476
            if ( $parent_maxissueqty_rule ) {
477
            # if we have a parent item type then we count loans of the
478
            # specific item type or its siblings or parent
479
                push @types, $parent_type;
480
                my $children = Koha::ItemTypes->search({ parent_type => $parent_type });
481
                while ( my $child = $children->next ){
482
                    push @types, $child->itemtype;
483
                }
484
            } elsif ( $child_types ) {
485
            # If we are a parent type, we need to count all child types and our own type
486
                while ( my $child = $child_types->next ){
487
                    push @types, $child->itemtype;
488
                }
489
                push @types, $type; # And don't forget to count our own types
490
            } else { push @types, $type; } # Otherwise only count the specific itemtype
491
            my $types_param = ( '?,' ) x @types;
492
            $types_param =~ s/,$//;
449
            if (C4::Context->preference('item-level_itypes')) {
493
            if (C4::Context->preference('item-level_itypes')) {
450
                $count_query .= " WHERE items.itype = ? ";
494
                $count_query .= " WHERE items.itype IN (" . $types_param . ")";
451
            } else { 
495
            } else { 
452
                $count_query .= " JOIN  biblioitems USING (biblionumber) 
496
                $count_query .= " JOIN  biblioitems USING (biblionumber) 
453
                                  WHERE biblioitems.itemtype= ? ";
497
                                  WHERE biblioitems.itemtype IN (" . $types_param . ")";
454
            }
498
            }
455
            push @bind_params, $type;
499
            push @bind_params, @types;
456
        }
500
        }
457
501
458
        $count_query .= " AND borrowernumber = ? ";
502
        $count_query .= " AND borrowernumber = ? ";
Lines 470-507 sub TooMany { Link Here
470
            }
514
            }
471
        }
515
        }
472
516
473
        my ( $checkout_count, $onsite_checkout_count ) = $dbh->selectrow_array( $count_query, {}, @bind_params );
517
        my ( $checkout_count_type, $checkout_count, $onsite_checkout_count ) = $dbh->selectrow_array( $count_query, {}, @bind_params );
474
518
475
        my $max_checkouts_allowed = $maxissueqty_rule ? $maxissueqty_rule->rule_value : undef;
476
        my $max_onsite_checkouts_allowed = $maxonsiteissueqty_rule ? $maxonsiteissueqty_rule->rule_value : undef;
519
        my $max_onsite_checkouts_allowed = $maxonsiteissueqty_rule ? $maxonsiteissueqty_rule->rule_value : undef;
477
520
478
        if ( $onsite_checkout and defined $max_onsite_checkouts_allowed ) {
521
        # If parent rules exists
479
            if ( $onsite_checkout_count >= $max_onsite_checkouts_allowed )  {
522
        if ( defined($parent_maxissueqty_rule) and defined($parent_maxissueqty_rule->rule_value) ){
480
                return {
523
            my $max_checkouts_allowed = $parent_maxissueqty_rule->rule_value;
481
                    reason => 'TOO_MANY_ONSITE_CHECKOUTS',
524
482
                    count => $onsite_checkout_count,
525
            my $qty_over = _check_max_qty({
483
                    max_allowed => $max_onsite_checkouts_allowed,
526
                checkout_count => $checkout_count,
484
                }
527
                onsite_checkout_count => $onsite_checkout_count,
485
            }
528
                onsite_checkout => $onsite_checkout,
486
        }
529
                max_checkouts_allowed => $max_checkouts_allowed,
487
        if ( C4::Context->preference('ConsiderOnSiteCheckoutsAsNormalCheckouts') ) {
530
                max_onsite_checkouts_allowed => $max_onsite_checkouts_allowed,
488
            my $delta = $switch_onsite_checkout ? 1 : 0;
531
                switch_onsite_checkout       => $switch_onsite_checkout
489
            if ( $checkout_count >= $max_checkouts_allowed + $delta ) {
532
            });
490
                return {
533
            return $qty_over if defined $qty_over;
491
                    reason => 'TOO_MANY_CHECKOUTS',
534
492
                    count => $checkout_count,
535
493
                    max_allowed => $max_checkouts_allowed,
536
           # If the parent rule is less than or equal to the child, we only need check the parent
494
                };
537
           if( $maxissueqty_rule->rule_value < $parent_maxissueqty_rule->rule_value && defined($maxissueqty_rule->itemtype) ) {
495
            }
538
               my $max_checkouts_allowed = $maxissueqty_rule->rule_value;
496
        } elsif ( not $onsite_checkout ) {
539
               my $qty_over = _check_max_qty({
497
            if ( $checkout_count - $onsite_checkout_count >= $max_checkouts_allowed )  {
540
                   checkout_count => $checkout_count_type,
498
                return {
541
                   onsite_checkout_count => $onsite_checkout_count,
499
                    reason => 'TOO_MANY_CHECKOUTS',
542
                   onsite_checkout => $onsite_checkout,
500
                    count => $checkout_count - $onsite_checkout_count,
543
                   max_checkouts_allowed => $max_checkouts_allowed,
501
                    max_allowed => $max_checkouts_allowed,
544
                   max_onsite_checkouts_allowed => $max_onsite_checkouts_allowed,
502
                };
545
                   switch_onsite_checkout       => $switch_onsite_checkout
503
            }
546
               });
547
               return $qty_over if defined $qty_over;
548
           }
549
550
        } else {
551
            my $max_checkouts_allowed = $maxissueqty_rule->rule_value;
552
            my $qty_over = _check_max_qty({
553
                checkout_count => $checkout_count,
554
                onsite_checkout_count => $onsite_checkout_count,
555
                onsite_checkout => $onsite_checkout,
556
                max_checkouts_allowed => $max_checkouts_allowed,
557
                max_onsite_checkouts_allowed => $max_onsite_checkouts_allowed,
558
                switch_onsite_checkout       => $switch_onsite_checkout
559
            });
560
            return $qty_over if defined $qty_over;
504
        }
561
        }
562
563
505
    }
564
    }
506
565
507
    # Now count total loans against the limit for the branch
566
    # Now count total loans against the limit for the branch
Lines 527-561 sub TooMany { Link Here
527
        }
586
        }
528
        my ( $checkout_count, $onsite_checkout_count ) = $dbh->selectrow_array( $branch_count_query, {}, @bind_params );
587
        my ( $checkout_count, $onsite_checkout_count ) = $dbh->selectrow_array( $branch_count_query, {}, @bind_params );
529
        my $max_checkouts_allowed = $branch_borrower_circ_rule->{patron_maxissueqty};
588
        my $max_checkouts_allowed = $branch_borrower_circ_rule->{patron_maxissueqty};
530
        my $max_onsite_checkouts_allowed = $branch_borrower_circ_rule->{patron_maxonsiteissueqty};
589
        my $max_onsite_checkouts_allowed = $branch_borrower_circ_rule->{patron_maxonsiteissueqty} || undef;
531
590
532
        if ( $onsite_checkout and $max_onsite_checkouts_allowed ne '' ) {
591
        my $qty_over = _check_max_qty({
533
            if ( $onsite_checkout_count >= $max_onsite_checkouts_allowed )  {
592
            checkout_count => $checkout_count,
534
                return {
593
            onsite_checkout_count => $onsite_checkout_count,
535
                    reason => 'TOO_MANY_ONSITE_CHECKOUTS',
594
            onsite_checkout => $onsite_checkout,
536
                    count => $onsite_checkout_count,
595
            max_checkouts_allowed => $max_checkouts_allowed,
537
                    max_allowed => $max_onsite_checkouts_allowed,
596
            max_onsite_checkouts_allowed => $max_onsite_checkouts_allowed,
538
                }
597
            switch_onsite_checkout       => $switch_onsite_checkout
539
            }
598
        });
540
        }
599
        return $qty_over if defined $qty_over;
541
        if ( C4::Context->preference('ConsiderOnSiteCheckoutsAsNormalCheckouts') ) {
600
542
            my $delta = $switch_onsite_checkout ? 1 : 0;
543
            if ( $checkout_count >= $max_checkouts_allowed + $delta ) {
544
                return {
545
                    reason => 'TOO_MANY_CHECKOUTS',
546
                    count => $checkout_count,
547
                    max_allowed => $max_checkouts_allowed,
548
                };
549
            }
550
        } elsif ( not $onsite_checkout ) {
551
            if ( $checkout_count - $onsite_checkout_count >= $max_checkouts_allowed )  {
552
                return {
553
                    reason => 'TOO_MANY_CHECKOUTS',
554
                    count => $checkout_count - $onsite_checkout_count,
555
                    max_allowed => $max_checkouts_allowed,
556
                };
557
            }
558
        }
559
    }
601
    }
560
602
561
    if ( not defined( $maxissueqty_rule ) and not defined($branch_borrower_circ_rule->{patron_maxissueqty}) ) {
603
    if ( not defined( $maxissueqty_rule ) and not defined($branch_borrower_circ_rule->{patron_maxissueqty}) ) {
Lines 566-571 sub TooMany { Link Here
566
    return;
608
    return;
567
}
609
}
568
610
611
sub _check_max_qty {
612
    my $params = shift;
613
    my $checkout_count = $params->{checkout_count};
614
    my $onsite_checkout_count = $params->{onsite_checkout_count};
615
    my $onsite_checkout = $params->{onsite_checkout};
616
    my $max_checkouts_allowed = $params->{max_checkouts_allowed};
617
    my $max_onsite_checkouts_allowed = $params->{max_onsite_checkouts_allowed};
618
    my $switch_onsite_checkout = $params->{switch_onsite_checkout};
619
620
    if ( $onsite_checkout and defined $max_onsite_checkouts_allowed ) {
621
        if ( $onsite_checkout_count >= $max_onsite_checkouts_allowed )  {
622
            return {
623
                reason => 'TOO_MANY_ONSITE_CHECKOUTS',
624
                count => $onsite_checkout_count,
625
                max_allowed => $max_onsite_checkouts_allowed,
626
            }
627
        }
628
    }
629
    if ( C4::Context->preference('ConsiderOnSiteCheckoutsAsNormalCheckouts') ) {
630
        my $delta = $switch_onsite_checkout ? 1 : 0;
631
        if ( $checkout_count >= $max_checkouts_allowed + $delta ) {
632
            return {
633
                reason => 'TOO_MANY_CHECKOUTS',
634
                count => $checkout_count,
635
                max_allowed => $max_checkouts_allowed,
636
            };
637
        }
638
    } elsif ( not $onsite_checkout ) {
639
        if ( $checkout_count - $onsite_checkout_count >= $max_checkouts_allowed )  {
640
            return {
641
                reason => 'TOO_MANY_CHECKOUTS',
642
                count => $checkout_count - $onsite_checkout_count,
643
                max_allowed => $max_checkouts_allowed,
644
            };
645
        }
646
    }
647
648
    return;
649
}
650
569
=head2 CanBookBeIssued
651
=head2 CanBookBeIssued
570
652
571
  ( $issuingimpossible, $needsconfirmation, [ $alerts ] ) =  CanBookBeIssued( $patron,
653
  ( $issuingimpossible, $needsconfirmation, [ $alerts ] ) =  CanBookBeIssued( $patron,
(-)a/t/db_dependent/Circulation/TooMany.t (-2 / +232 lines)
Lines 15-21 Link Here
15
# with Koha; if not, see <http://www.gnu.org/licenses>.
15
# with Koha; if not, see <http://www.gnu.org/licenses>.
16
16
17
use Modern::Perl;
17
use Modern::Perl;
18
use Test::More tests => 8;
18
use Test::More tests => 9;
19
use C4::Context;
19
use C4::Context;
20
20
21
use C4::Members;
21
use C4::Members;
Lines 659-665 subtest 'General vs specific rules limit quantity correctly' => sub { Link Here
659
        'We are allowed one from the branch specifically now'
659
        'We are allowed one from the branch specifically now'
660
    );
660
    );
661
661
662
};
663
664
subtest 'itemtype group tests' => sub {
665
    plan tests => 13;
666
667
    t::lib::Mocks::mock_preference('CircControl', 'ItemHomeLibrary');
668
    my $rule = $builder->build({
669
        source => 'Issuingrule',
670
        value => {
671
            categorycode => '*',
672
            itemtype     => '*',
673
            branchcode   => '*',
674
            issuelength  => 1,
675
            firstremind  => 1,        # 1 day of grace
676
            finedays     => 2,        # 2 days of fine per day of overdue
677
            lengthunit   => 'days',
678
        }
679
    });
680
681
    my $parent_itype = $builder->build({
682
        source=>'Itemtype',
683
        value => {
684
            parent_type => undef,
685
            rentalcharge => undef,
686
            rentalcharge_daily => undef,
687
            rentalcharge_hourly => undef,
688
            notforloan => 0,
689
        }
690
    });
691
    my $child_itype_1 = $builder->build({
692
        source=>'Itemtype',
693
        value => {
694
            parent_type => $parent_itype->{itemtype},
695
            rentalcharge => 0,
696
            rentalcharge_daily => 0,
697
            rentalcharge_hourly => 0,
698
            notforloan => 0,
699
        }
700
    });
701
    my $child_itype_2 = $builder->build({
702
        source=>'Itemtype',
703
        value => {
704
            parent_type => $parent_itype->{itemtype},
705
            rentalcharge => 0,
706
            rentalcharge_daily => 0,
707
            rentalcharge_hourly => 0,
708
            notforloan => 0,
709
        }
710
    });
711
712
    my $branch = $builder->build({source => 'Branch',});
713
    my $category = $builder->build({source => 'Category',});
714
    my $patron = $builder->build({
715
        source => 'Borrower',
716
        value => {
717
            categorycode => $category->{categorycode},
718
            branchcode => $branch->{branchcode},
719
        },
720
    });
721
    my $item = $builder->build_sample_item({
722
        homebranch=>$branch->{branchcode},
723
        holdingbranch=>$branch->{branchcode},
724
        itype=>$child_itype_1->{itemtype}
725
    });
726
727
    my $all_iq_rule = $builder->build({
728
        source=>'CirculationRule',
729
        value => {
730
            branchcode   => $branch->{branchcode},
731
            categorycode => $category->{categorycode},
732
            itemtype     => undef,
733
            rule_name    => 'maxissueqty',
734
            rule_value   => 1
735
        }
736
    });
737
    is(
738
        C4::Circulation::TooMany( $patron, $item->biblionumber, $item->unblessed ),
739
        undef,
740
        'Checkout allowed, using all rule of 1'
741
    );
742
743
    #Checkout an item
744
    my $issue = C4::Circulation::AddIssue( $patron, $item->barcode, dt_from_string() );
745
    like( $issue->issue_id, qr|^\d+$|, 'The issue should have been inserted' );
746
    #Patron has 1 checkout of child itype1
747
748
    my $parent_iq_rule = $builder->build({
749
        source=>'CirculationRule',
750
        value => {
751
            branchcode   => $branch->{branchcode},
752
            categorycode => $category->{categorycode},
753
            itemtype     => $parent_itype->{itemtype},
754
            rule_name    => 'maxissueqty',
755
            rule_value   => 2
756
        }
757
    });
758
759
    is(
760
        C4::Circulation::TooMany( $patron, $item->biblionumber, $item->unblessed ),
761
        undef,
762
        'Checkout allowed, using parent type rule of 2'
763
    );
764
765
    my $child1_iq_rule = $builder->build_object({
766
        class=>'Koha::CirculationRules',
767
        value => {
768
            branchcode   => $branch->{branchcode},
769
            categorycode => $category->{categorycode},
770
            itemtype     => $child_itype_1->{itemtype},
771
            rule_name    => 'maxissueqty',
772
            rule_value   => 1
773
        }
774
    });
775
776
    is_deeply(
777
        C4::Circulation::TooMany( $patron, $item->biblionumber, $item->unblessed ),
778
        {
779
            reason => 'TOO_MANY_CHECKOUTS',
780
            count => 1,
781
            max_allowed => 1,
782
        },
783
        'Checkout not allowed, using specific type rule of 1'
784
    );
785
786
    my $item_1 = $builder->build_sample_item({
787
        homebranch=>$branch->{branchcode},
788
        holdingbranch=>$branch->{branchcode},
789
        itype=>$child_itype_2->{itemtype}
790
    });
791
792
    my $child2_iq_rule = $builder->build({
793
        source=>'CirculationRule',
794
        value => {
795
            branchcode   => $branch->{branchcode},
796
            categorycode => $category->{categorycode},
797
            itemtype     => $child_itype_2->{itemtype},
798
            rule_name    => 'maxissueqty',
799
            rule_value   => 3
800
        }
801
    });
802
803
    is(
804
        C4::Circulation::TooMany( $patron, $item_1->biblionumber, $item_1->unblessed ),
805
        undef,
806
        'Checkout allowed'
807
    );
808
809
    #checkout an item
810
    $issue = C4::Circulation::AddIssue( $patron, $item_1->barcode, dt_from_string());
811
    like( $issue->issue_id, qr|^\d+$|, 'the issue should have been inserted' );
812
    #patron has 1 checkout of childitype1 and 1 checkout of childitype2
813
814
    is_deeply(
815
        C4::Circulation::TooMany( $patron, $item->biblionumber, $item->unblessed ),
816
        {
817
            reason => 'TOO_MANY_CHECKOUTS',
818
            count => 2,
819
            max_allowed => 2,
820
        },
821
        'Checkout not allowed, using parent type rule of 2, checkout of sibling itemtype counted'
822
    );
823
824
    my $parent_item = $builder->build_sample_item({
825
        homebranch=>$branch->{branchcode},
826
        holdingbranch=>$branch->{branchcode},
827
        itype=>$parent_itype->{itemtype}
828
    });
829
830
    is_deeply(
831
        C4::Circulation::TooMany( $patron, $parent_item->biblionumber, $parent_item->unblessed ),
832
        {
833
            reason => 'TOO_MANY_CHECKOUTS',
834
            count => 2,
835
            max_allowed => 2,
836
        },
837
        'Checkout not allowed, using parent type rule of 2, checkout of child itemtypes counted'
838
    );
839
840
841
    #increase parent type to greater than specific
842
    my $circ_rule_object = Koha::CirculationRules->find( $parent_iq_rule->{id} );
843
    $circ_rule_object->rule_value(4)->store();
844
845
    is(
846
        C4::Circulation::TooMany( $patron, $item->biblionumber, $item_1->unblessed ),
847
        undef,
848
        'Checkout allowed, using specific type rule of 3'
849
    );
850
851
    my $item_2 = $builder->build_sample_item({
852
        homebranch=>$branch->{branchcode},
853
        holdingbranch=>$branch->{branchcode},
854
        itype=>$child_itype_2->{itemtype}
855
    });
856
    #checkout an item
857
    $issue = C4::Circulation::AddIssue( $patron, $item_2->barcode, dt_from_string(), undef, undef, undef );
858
    like( $issue->issue_id, qr|^\d+$|, 'the issue should have been inserted' );
859
    #patron has 1 checkoout of childitype1 and 2 of childitype2
662
860
861
    is(
862
        C4::Circulation::TooMany( $patron, $item_2->biblionumber, $item_2->unblessed ),
863
        undef,
864
        'Checkout allowed, using specific type rule of 3, checkout of sibling itemtype not counted'
865
    );
866
867
    $child1_iq_rule->rule_value(2)->store(); #Allow 2 checkouts for child type 1
868
869
    my $item_3 = $builder->build_sample_item({
870
        homebranch=>$branch->{branchcode},
871
        holdingbranch=>$branch->{branchcode},
872
        itype=>$child_itype_1->{itemtype}
873
    });
874
    my $item_4 = $builder->build_sample_item({
875
        homebranch=>$branch->{branchcode},
876
        holdingbranch=>$branch->{branchcode},
877
        itype=>$child_itype_2->{itemtype}
878
    });
879
880
    #checkout an item
881
    $issue = C4::Circulation::AddIssue( $patron, $item_4->barcode, dt_from_string(), undef, undef, undef );
882
    like( $issue->issue_id, qr|^\d+$|, 'the issue should have been inserted' );
883
    #patron has 1 checkout of childitype 1 and 3 of childitype2
884
885
    is_deeply(
886
        C4::Circulation::TooMany( $patron, $item_3->biblionumber, $item_3->unblessed ),
887
        {
888
            reason => 'TOO_MANY_CHECKOUTS',
889
            max_allowed => 4,
890
            count => 4,
891
        },
892
        'Checkout not allowed, using specific type rule of 2, checkout of sibling itemtype not counted, but parent rule (4) prevents another'
893
    );
663
894
664
};
895
};
665
896
666
- 

Return to bug 21946