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

(-)a/C4/Circulation.pm (-3 / +4 lines)
Lines 1347-1352 Check whether the item can be returned to the provided branch Link Here
1347
1347
1348
=item C<$branch> is the branchcode where the return is taking place
1348
=item C<$branch> is the branchcode where the return is taking place
1349
1349
1350
=item C<$transferbranch> the branch where the book should be transferred after return, if the transfer is impossible, the book will be prevented from returning.
1351
1350
=back
1352
=back
1351
1353
1352
Returns:
1354
Returns:
Lines 1365-1375 sub CanBookBeReturned { Link Here
1365
    my ($item, $returnbranch, $transferbranch) = @_;
1367
    my ($item, $returnbranch, $transferbranch) = @_;
1366
    my $allowreturntobranch = C4::Context->preference("AllowReturnToBranch") || 'anywhere';
1368
    my $allowreturntobranch = C4::Context->preference("AllowReturnToBranch") || 'anywhere';
1367
1369
1368
    # assume return is allowed to start
1369
    my $allowed = 1;
1370
    my $allowed = 1;
1370
    my $message;
1371
    my $message;
1371
1372
1372
    # identify all cases where return is forbidden
1373
    # Refuse check-in if it does not respect AllowReturnToBranch rules
1373
    if ($allowreturntobranch eq 'homebranch' && $returnbranch ne $item->homebranch) {
1374
    if ($allowreturntobranch eq 'homebranch' && $returnbranch ne $item->homebranch) {
1374
        $allowed = 0;
1375
        $allowed = 0;
1375
        $message = $item->homebranch;
1376
        $message = $item->homebranch;
Lines 1381-1387 sub CanBookBeReturned { Link Here
1381
        $message = $item->homebranch; # FIXME: choice of homebranch is arbitrary
1382
        $message = $item->homebranch; # FIXME: choice of homebranch is arbitrary
1382
    }
1383
    }
1383
1384
1384
    # identify cases where transfer rules prohibit return
1385
    # Refuse check-in if book cannot be transferred to $transferbranch due to transfer limits
1385
    if ( defined($transferbranch) && $allowed ) {
1386
    if ( defined($transferbranch) && $allowed ) {
1386
        my $from_library = Koha::Libraries->find($returnbranch);
1387
        my $from_library = Koha::Libraries->find($returnbranch);
1387
        my $to_library   = Koha::Libraries->find($transferbranch);
1388
        my $to_library   = Koha::Libraries->find($transferbranch);
(-)a/t/db_dependent/Circulation.t (-46 / +162 lines)
Lines 18-24 Link Here
18
use Modern::Perl;
18
use Modern::Perl;
19
use utf8;
19
use utf8;
20
20
21
use Test::More tests => 76;
21
use Test::More tests => 77;
22
use Test::Exception;
22
use Test::Exception;
23
use Test::MockModule;
23
use Test::MockModule;
24
use Test::Deep qw( cmp_deeply );
24
use Test::Deep qw( cmp_deeply );
Lines 2600-2606 subtest 'CanBookBeIssued + Koha::Patron->is_debarred|has_overdues' => sub { Link Here
2600
    is( $error->{USERBLOCKEDNOENDDATE},    '9999-12-31', 'USERBLOCKEDNOENDDATE should be 9999-12-31 for unlimited debarments' );
2600
    is( $error->{USERBLOCKEDNOENDDATE},    '9999-12-31', 'USERBLOCKEDNOENDDATE should be 9999-12-31 for unlimited debarments' );
2601
};
2601
};
2602
2602
2603
2604
subtest 'CanBookBeReturned + UseBranchTransfertLimits + CirculationRules' => sub {
2603
subtest 'CanBookBeReturned + UseBranchTransfertLimits + CirculationRules' => sub {
2605
    plan tests => 22;
2604
    plan tests => 22;
2606
    t::lib::Mocks::mock_preference( 'UseBranchTransferLimits', '1' );
2605
    t::lib::Mocks::mock_preference( 'UseBranchTransferLimits', '1' );
Lines 2608-2614 subtest 'CanBookBeReturned + UseBranchTransfertLimits + CirculationRules' => sub Link Here
2608
    my $homebranch    = $builder->build( { source => 'Branch' } );
2607
    my $homebranch    = $builder->build( { source => 'Branch' } );
2609
    my $holdingbranch = $builder->build( { source => 'Branch' } );
2608
    my $holdingbranch = $builder->build( { source => 'Branch' } );
2610
    my $returnbranch  = $builder->build( { source => 'Branch' } );
2609
    my $returnbranch  = $builder->build( { source => 'Branch' } );
2611
    my $patron        = $builder->build_object( { class => 'Koha::Patrons', value => { categorycode => $patron_category->{categorycode} } } );
2610
    my $patron        = $builder->build_object(
2611
        { class => 'Koha::Patrons', value => { categorycode => $patron_category->{categorycode} } } );
2612
2612
2613
    my $item = $builder->build_sample_item(
2613
    my $item = $builder->build_sample_item(
2614
        {
2614
        {
Lines 2623-2670 subtest 'CanBookBeReturned + UseBranchTransfertLimits + CirculationRules' => sub Link Here
2623
2623
2624
    # Attempt returns at returnbranch
2624
    # Attempt returns at returnbranch
2625
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'homebranch' );
2625
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'homebranch' );
2626
    my ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode});
2626
    my ( $allowed, $message ) = C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode} );
2627
    is ( 0 , $allowed , 'Prevent return where returnbranch != homebranch');
2627
    is( 0,                         $allowed, 'Prevent return where returnbranch != homebranch' );
2628
    is ( $homebranch->{branchcode} , $message , 'Redirect to homebranch');
2628
    is( $homebranch->{branchcode}, $message, 'Redirect to homebranch' );
2629
2629
2630
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'holdingbranch' );
2630
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'holdingbranch' );
2631
    ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode});
2631
    ( $allowed, $message ) = C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode} );
2632
    is ( 0 , $allowed , 'Prevent return where returnbranch != holdingbranch');
2632
    is( 0,                            $allowed, 'Prevent return where returnbranch != holdingbranch' );
2633
    is ( $holdingbranch->{branchcode} , $message , 'Redirect to holdingbranch');
2633
    is( $holdingbranch->{branchcode}, $message, 'Redirect to holdingbranch' );
2634
2634
2635
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'homeorholdingbranch' );
2635
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'homeorholdingbranch' );
2636
    ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode});
2636
    ( $allowed, $message ) = C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode} );
2637
    is ( 0 , $allowed , 'Prevent return where returnbranch != homebranch or holdingbranch');
2637
    is( 0,                         $allowed, 'Prevent return where returnbranch != homebranch or holdingbranch' );
2638
    is ( $homebranch->{branchcode} , $message , 'Redirect to homebranch');
2638
    is( $homebranch->{branchcode}, $message, 'Redirect to homebranch' );
2639
2639
2640
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2640
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2641
    ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode});
2641
    ( $allowed, $message ) = C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode} );
2642
    is ( 1 , $allowed , 'with AllowReturnToBranch = anywhere and no limits return to returnbranch is allowed');
2642
    is( 1,     $allowed, 'with AllowReturnToBranch = anywhere and no limits return to returnbranch is allowed' );
2643
    is ( undef , $message , 'without limits provides no message');
2643
    is( undef, $message, 'without limits provides no message' );
2644
2644
2645
    # Set limit (Holding -> Return denied)
2645
    # Set limit (Holding -> Return denied)
2646
    diag("Transfer limit: Holding -> Return");
2646
    diag("Transfer limit: Holding -> Return");
2647
    t::lib::Mocks::mock_preference( 'BranchTransferLimitsType', 'itemtype' );
2647
    t::lib::Mocks::mock_preference( 'BranchTransferLimitsType', 'itemtype' );
2648
    my $limit = Koha::Item::Transfer::Limit->new({
2648
    my $limit = Koha::Item::Transfer::Limit->new(
2649
        toBranch   => $returnbranch->{branchcode},
2649
        {
2650
        fromBranch => $holdingbranch->{branchcode},
2650
            toBranch   => $returnbranch->{branchcode},
2651
        itemtype   => $item->effective_itemtype,
2651
            fromBranch => $holdingbranch->{branchcode},
2652
    })->store();
2652
            itemtype   => $item->effective_itemtype,
2653
        }
2654
    )->store();
2653
2655
2654
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2656
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2655
    ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode});
2657
    ( $allowed, $message ) = C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode} );
2656
    is ( 1 , $allowed , 'Allow return where transferbranch is not passed');
2658
    is( 1,     $allowed, 'Allow return where transferbranch is not passed' );
2657
    is ( undef , $message , 'without limits provides no message');
2659
    is( undef, $message, 'without limits provides no message' );
2658
2660
2659
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2661
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2660
    ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode}, $homebranch->{branchcode});
2662
    ( $allowed, $message ) =
2661
    is ( 1 , $allowed , 'Allow return where there is no transfer limit between returnbranch and homebranch');
2663
        C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode}, $homebranch->{branchcode} );
2662
    is ( undef , $message , 'without limits provides no message');
2664
    is( 1,     $allowed, 'Allow return where there is no transfer limit between returnbranch and homebranch' );
2665
    is( undef, $message, 'without limits provides no message' );
2663
2666
2664
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2667
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2665
    ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode}, $holdingbranch->{branchcode});
2668
    ( $allowed, $message ) =
2666
    is ( 1 , $allowed , 'Allow return where there is no transfer limit between returnbranch and holdingbranch');
2669
        C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode}, $holdingbranch->{branchcode} );
2667
    is ( undef , $message , 'without limits provides no message');
2670
    is( 1,     $allowed, 'Allow return where there is no transfer limit between returnbranch and holdingbranch' );
2671
    is( undef, $message, 'without limits provides no message' );
2668
2672
2669
    # Set limit ( Return -> Home denied)
2673
    # Set limit ( Return -> Home denied)
2670
    diag("Transfer limit: Return -> Home");
2674
    diag("Transfer limit: Return -> Home");
Lines 2676-2690 subtest 'CanBookBeReturned + UseBranchTransfertLimits + CirculationRules' => sub Link Here
2676
    )->store()->discard_changes;
2680
    )->store()->discard_changes;
2677
2681
2678
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2682
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2679
    ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode}, $homebranch->{branchcode});
2683
    ( $allowed, $message ) =
2680
    is ( 0 , $allowed , 'Prevent return where returnbranch cannot transfer to homebranch');
2684
        C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode}, $homebranch->{branchcode} );
2681
    is ( $homebranch->{branchcode} , $message , 'Redirect to homebranch');
2685
    is( 0,                         $allowed, 'Prevent return where returnbranch cannot transfer to homebranch' );
2686
    is( $homebranch->{branchcode}, $message, 'Redirect to homebranch' );
2682
2687
2683
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2688
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2684
    ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode}, $holdingbranch->{branchcode});
2689
    ( $allowed, $message ) =
2685
    is ( 1 , $allowed , 'Allow return where there is no transfer limit between returnbranch and holdingbranch');
2690
        C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode}, $holdingbranch->{branchcode} );
2686
    is ( undef , $message , 'without limits provides no message');
2691
    is( 1,     $allowed, 'Allow return where there is no transfer limit between returnbranch and holdingbranch' );
2687
 
2692
    is( undef, $message, 'without limits provides no message' );
2693
2688
    # Set limit ( Return -> Holding denied)
2694
    # Set limit ( Return -> Holding denied)
2689
    diag("Transfer limit: Return -> Holding");
2695
    diag("Transfer limit: Return -> Holding");
2690
2696
Lines 2697-2712 subtest 'CanBookBeReturned + UseBranchTransfertLimits + CirculationRules' => sub Link Here
2697
    )->store()->discard_changes;
2703
    )->store()->discard_changes;
2698
2704
2699
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2705
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2700
    ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode}, $homebranch->{branchcode});
2706
    ( $allowed, $message ) =
2701
    is ( 1 , $allowed , 'Allow return where there is no transfer limit between returnbranch and homebranch');
2707
        C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode}, $homebranch->{branchcode} );
2702
    is ( undef , $message , 'without limits provides no message');
2708
    is( 1,     $allowed, 'Allow return where there is no transfer limit between returnbranch and homebranch' );
2709
    is( undef, $message, 'without limits provides no message' );
2703
2710
2704
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2711
    t::lib::Mocks::mock_preference( 'AllowReturnToBranch', 'anywhere' );
2705
    ($allowed, $message) = C4::Circulation::CanBookBeReturned($item, $returnbranch->{branchcode}, $holdingbranch->{branchcode});
2712
    ( $allowed, $message ) =
2706
    is ( 0 , $allowed , 'Prevent return where returnbranch cannot transfer to holdingbranch');
2713
        C4::Circulation::CanBookBeReturned( $item, $returnbranch->{branchcode}, $holdingbranch->{branchcode} );
2707
    is ( $holdingbranch->{branchcode} , $message , 'Redirect to holdingbranch');
2714
    is( 0,                            $allowed, 'Prevent return where returnbranch cannot transfer to holdingbranch' );
2715
    is( $holdingbranch->{branchcode}, $message, 'Redirect to holdingbranch' );
2708
};
2716
};
2709
2717
2718
subtest 'AddReturn + TransferLimits' => sub {
2719
    plan tests => 3;
2720
2721
    ########################################################################
2722
    #
2723
    # Prepare test
2724
    #
2725
    ########################################################################
2726
2727
    my $patron        = $builder->build_object( { class => 'Koha::Patrons' } );
2728
    my $homebranch    = $builder->build( { source => 'Branch' } );
2729
    my $holdingbranch = $builder->build( { source => 'Branch' } );
2730
    my $returnbranch  = $builder->build( { source => 'Branch' } );
2731
    my $item          = $builder->build_sample_item(
2732
        {
2733
            homebranch    => $homebranch->{branchcode},
2734
            holdingbranch => $holdingbranch->{branchcode},
2735
        }
2736
    );
2737
2738
    # Default circulation rules
2739
    Koha::CirculationRules->set_rules(
2740
        {
2741
            categorycode => undef,
2742
            branchcode   => undef,
2743
            itemtype     => $item->itype,
2744
            rules        => {
2745
                maxissueqty     => 1,
2746
                reservesallowed => 25,
2747
                issuelength     => 7,
2748
                lengthunit      => 'days',
2749
                renewalsallowed => 5,
2750
                renewalperiod   => 7,
2751
                norenewalbefore => undef,
2752
                auto_renew      => 0,
2753
                fine            => .10,
2754
                chargeperiod    => 1,
2755
            }
2756
        }
2757
    );
2758
    t::lib::Mocks::mock_userenv( { branchcode => $holdingbranch->{branchcode} } );
2759
2760
    # Each transfer from returnbranch is forbidden
2761
    my $limit = Koha::Item::Transfer::Limit->new(
2762
        {
2763
            fromBranch => $returnbranch->{branchcode},
2764
            toBranch   => $holdingbranch->{branchcode},
2765
            itemtype   => $item->effective_itemtype,
2766
        }
2767
    )->store();
2768
    my $limit2 = Koha::Item::Transfer::Limit->new(
2769
        {
2770
            fromBranch => $returnbranch->{branchcode},
2771
            toBranch   => $homebranch->{branchcode},
2772
            itemtype   => $item->effective_itemtype,
2773
        }
2774
    )->store();
2775
2776
    ########################################################################
2777
    #
2778
    # Begin test
2779
    #
2780
    # Each transfer is forbidden by transfer limits
2781
    # Checkin must be forbidden except if there is no transfer to perform
2782
    #
2783
    ########################################################################
2784
2785
    # Case 1: There is a transfer to to do homebranch
2786
    Koha::CirculationRules->set_rules(
2787
        {
2788
            branchcode => undef,
2789
            itemtype   => undef,
2790
            rules      => {
2791
                returnbranch => 'homebranch',
2792
            },
2793
        }
2794
    );
2795
    my $issue = AddIssue( $patron, $item->barcode );
2796
    my ( $doreturn, $messages, $iteminfo, $borrowerinfo ) = AddReturn( $item->barcode, $returnbranch->{branchcode} );
2797
    is( $doreturn, 0, "Item cannot be returned if there is a transfer to do" );
2798
2799
    # Case 2: There is a transfer to do to holdingbranch
2800
    Koha::CirculationRules->set_rules(
2801
        {
2802
            branchcode => undef,
2803
            itemtype   => undef,
2804
            rules      => {
2805
                returnbranch => 'holdingbranch',
2806
            },
2807
        }
2808
    );
2809
    $issue->delete;
2810
    $item->holdingbranch( $holdingbranch->{branchcode} )->store();
2811
    $issue = AddIssue( $patron, $item->barcode );
2812
    ( $doreturn, $messages, $iteminfo, $borrowerinfo ) = AddReturn( $item->barcode, $returnbranch->{branchcode} );
2813
    is( $doreturn, 0, "Item cannot be returned if there is a transfer to do (item is floating)" );
2814
2815
    # Case 3: There is no transfer to do
2816
    Koha::CirculationRules->set_rules(
2817
        {
2818
            branchcode => undef,
2819
            itemtype   => undef,
2820
            rules      => {
2821
                returnbranch => 'noreturn',
2822
            },
2823
        }
2824
    );
2825
    $issue->delete;
2826
    $issue = AddIssue( $patron, $item->barcode );
2827
    ( $doreturn, $messages, $iteminfo, $borrowerinfo ) = AddReturn( $item->barcode, $returnbranch->{branchcode} );
2828
    is( $doreturn, 1, "Item cannot be returned if there is a transfer to do" );
2829
};
2710
2830
2711
subtest 'Statistic patrons "X"' => sub {
2831
subtest 'Statistic patrons "X"' => sub {
2712
    plan tests => 15;
2832
    plan tests => 15;
Lines 2795-2805 subtest 'Statistic patrons "X"' => sub { Link Here
2795
        Koha::Statistics->search( { itemnumber => $item_4->itemnumber } )->count, 3,
2915
        Koha::Statistics->search( { itemnumber => $item_4->itemnumber } )->count, 3,
2796
        'Issue, return, and localuse should be recorded in statistics table for item 4.'
2916
        'Issue, return, and localuse should be recorded in statistics table for item 4.'
2797
    );
2917
    );
2798
2799
    # TODO There are other tests to provide here
2800
};
2918
};
2801
2919
2802
2803
subtest "Bug 27753 - Add AutoClaimReturnStatusOnCheckin" => sub {
2920
subtest "Bug 27753 - Add AutoClaimReturnStatusOnCheckin" => sub {
2804
    plan tests => 8;
2921
    plan tests => 8;
2805
2922
2806
- 

Return to bug 7376