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

(-)a/C4/Circulation.pm (-16 / +36 lines)
Lines 483-498 sub TooMany { Link Here
483
483
484
        my $checkouts;
484
        my $checkouts;
485
        if ( $maxissueqty_rule->branchcode ) {
485
        if ( $maxissueqty_rule->branchcode ) {
486
            if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) {
486
            my $checkout_limit_scope = C4::Context->preference('CheckoutLimitScope') || 'branch_specific';
487
                $checkouts = $patron->checkouts->search( { 'me.branchcode' => $maxissueqty_rule->branchcode } );
487
            my $circ_control         = C4::Context->preference('CircControl');
488
            } elsif ( C4::Context->preference('CircControl') eq 'PatronLibrary' ) {
488
489
                $checkouts = $patron->checkouts; # if branch is the patron's home branch, then count all loans by patron
489
            if ( $checkout_limit_scope eq 'branch_specific'
490
                && ( $circ_control eq 'PickupLibrary' || $circ_control eq 'ItemHomeLibrary' ) )
491
            {
492
                # Use branch-specific counting for PickupLibrary and ItemHomeLibrary
493
                if ( $circ_control eq 'PickupLibrary' ) {
494
                    $checkouts = $patron->checkouts->search( { 'me.branchcode' => $maxissueqty_rule->branchcode } );
495
                } else {
496
                    my $branch_type = C4::Context->preference('HomeOrHoldingBranch') || 'homebranch';
497
                    $checkouts = $patron->checkouts->search( { "item.$branch_type" => $maxissueqty_rule->branchcode } );
498
                }
490
            } else {
499
            } else {
491
                my $branch_type = C4::Context->preference('HomeOrHoldingBranch') || 'homebranch';
500
492
                $checkouts = $patron->checkouts->search( { "item.$branch_type" => $maxissueqty_rule->branchcode } );
501
                # Default: count all patron checkouts (PatronLibrary behavior)
502
                $checkouts = $patron->checkouts;
493
            }
503
            }
494
        } else {
504
        } else {
495
            $checkouts = $patron->checkouts;     # if rule is not branch specific then count all loans by patron
505
            $checkouts = $patron->checkouts;    # if rule is not branch specific then count all loans by patron
496
        }
506
        }
497
        $checkouts = $checkouts->search( undef, { prefetch => 'item' } );
507
        $checkouts = $checkouts->search( undef, { prefetch => 'item' } );
498
508
Lines 590-605 sub TooMany { Link Here
590
        and $branch_borrower_circ_rule->{patron_maxissueqty} ne '' )
600
        and $branch_borrower_circ_rule->{patron_maxissueqty} ne '' )
591
    {
601
    {
592
        my $checkouts;
602
        my $checkouts;
593
        if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) {
603
        my $checkout_limit_scope = C4::Context->preference('CheckoutLimitScope') || 'branch_specific';
594
            $checkouts = $patron->checkouts->search( { 'me.branchcode' => $branch } );
604
        my $circ_control         = C4::Context->preference('CircControl');
595
        } elsif ( C4::Context->preference('CircControl') eq 'PatronLibrary' ) {
605
596
            $checkouts = $patron->checkouts;    # if branch is the patron's home branch, then count all loans by patron
606
        if ( $checkout_limit_scope eq 'branch_specific'
607
            && ( $circ_control eq 'PickupLibrary' || $circ_control eq 'ItemHomeLibrary' ) )
608
        {
609
            # Use branch-specific counting for PickupLibrary and ItemHomeLibrary
610
            if ( $circ_control eq 'PickupLibrary' ) {
611
                $checkouts = $patron->checkouts->search( { 'me.branchcode' => $branch } );
612
            } else {
613
                my $branch_type = C4::Context->preference('HomeOrHoldingBranch') || 'homebranch';
614
                $checkouts = $patron->checkouts->search(
615
                    { "item.$branch_type" => $branch },
616
                    { prefetch            => 'item' }
617
                );
618
            }
597
        } else {
619
        } else {
598
            my $branch_type = C4::Context->preference('HomeOrHoldingBranch') || 'homebranch';
620
599
            $checkouts = $patron->checkouts->search(
621
            # Default: count all patron checkouts (PatronLibrary behavior)
600
                { "item.$branch_type" => $branch },
622
            $checkouts = $patron->checkouts;
601
                { prefetch            => 'item' }
602
            );
603
        }
623
        }
604
624
605
        my $checkout_count               = $checkouts->count;
625
        my $checkout_count               = $checkouts->count;
(-)a/t/db_dependent/Circulation/TooMany.t (-2 / +121 lines)
Lines 16-22 Link Here
16
16
17
use Modern::Perl;
17
use Modern::Perl;
18
use Test::NoWarnings;
18
use Test::NoWarnings;
19
use Test::More tests => 12;
19
use Test::More tests => 13;
20
use C4::Context;
20
use C4::Context;
21
21
22
use C4::Members;
22
use C4::Members;
Lines 1225-1230 subtest 'HomeOrHoldingBranch is used' => sub { Link Here
1225
    teardown();
1225
    teardown();
1226
};
1226
};
1227
1227
1228
subtest 'CheckoutLimitScope system preference controls checkout counting' => sub {
1229
    plan tests => 12;
1230
1231
    t::lib::Mocks::mock_preference( 'item-level_itypes', 1 );
1232
1233
    my $branch1  = $builder->build( { source => 'Branch' } );
1234
    my $branch2  = $builder->build( { source => 'Branch' } );
1235
    my $category = $builder->build( { source => 'Category' } );
1236
    my $itemtype = $builder->build( { source => 'Itemtype', value => { notforloan => 0 } } );
1237
1238
    my $patron = $builder->build_object(
1239
        {
1240
            class => 'Koha::Patrons',
1241
            value => {
1242
                categorycode => $category->{categorycode},
1243
                branchcode   => $branch1->{branchcode},
1244
            }
1245
        }
1246
    );
1247
1248
    # Create items from different branches
1249
    my $item_branch1 = $builder->build_sample_item(
1250
        {
1251
            homebranch    => $branch1->{branchcode},
1252
            holdingbranch => $branch1->{branchcode},
1253
            itype         => $itemtype->{itemtype}
1254
        }
1255
    );
1256
1257
    my $item_branch2 = $builder->build_sample_item(
1258
        {
1259
            homebranch    => $branch2->{branchcode},
1260
            holdingbranch => $branch2->{branchcode},
1261
            itype         => $itemtype->{itemtype}
1262
        }
1263
    );
1264
1265
    # Set circulation rules for both branches
1266
    Koha::CirculationRules->set_rules(
1267
        {
1268
            branchcode   => $branch1->{branchcode},
1269
            categorycode => $category->{categorycode},
1270
            itemtype     => $itemtype->{itemtype},
1271
            rules        => {
1272
                maxissueqty => 1,
1273
            }
1274
        }
1275
    );
1276
1277
    Koha::CirculationRules->set_rules(
1278
        {
1279
            branchcode   => $branch2->{branchcode},
1280
            categorycode => $category->{categorycode},
1281
            itemtype     => $itemtype->{itemtype},
1282
            rules        => {
1283
                maxissueqty => 1,
1284
            }
1285
        }
1286
    );
1287
1288
    # Issue an item from branch1
1289
    t::lib::Mocks::mock_userenv( { branchcode => $branch1->{branchcode} } );
1290
    my $issue = C4::Circulation::AddIssue( $patron, $item_branch1->barcode, dt_from_string() );
1291
    ok( $issue, 'Item from branch1 issued successfully' );
1292
1293
    # Test PickupLibrary with CheckoutLimitScope = 'branch_specific' (default)
1294
    t::lib::Mocks::mock_preference( 'CircControl',        'PickupLibrary' );
1295
    t::lib::Mocks::mock_preference( 'CheckoutLimitScope', 'branch_specific' );
1296
1297
    # From branch1 - should count checkout made at branch1
1298
    my $data = C4::Circulation::TooMany( $patron, $item_branch1 );
1299
    ok( $data, 'TooMany should return limit exceeded when checking from same pickup library' );
1300
    is( $data->{count},  1,                    'Should count checkout made at this pickup library' );
1301
    is( $data->{reason}, 'TOO_MANY_CHECKOUTS', 'Correct reason returned' );
1302
1303
    # From branch2 - should not count checkout made at branch1
1304
    t::lib::Mocks::mock_userenv( { branchcode => $branch2->{branchcode} } );
1305
    $data = C4::Circulation::TooMany( $patron, $item_branch2 );
1306
    ok( !$data, 'TooMany should allow checkout when no checkouts from this pickup library' );
1307
1308
    # Test PickupLibrary with CheckoutLimitScope = 'all'
1309
    t::lib::Mocks::mock_preference( 'CheckoutLimitScope', 'all' );
1310
1311
    # Should count all patron checkouts regardless of pickup library
1312
    $data = C4::Circulation::TooMany( $patron, $item_branch2 );
1313
    ok( $data, 'TooMany should return limit exceeded when counting all checkouts' );
1314
    is( $data->{count}, 1, 'Should count all patron checkouts regardless of branch' );
1315
1316
    # Test ItemHomeLibrary with CheckoutLimitScope = 'all'
1317
    t::lib::Mocks::mock_preference( 'CircControl',        'ItemHomeLibrary' );
1318
    t::lib::Mocks::mock_preference( 'CheckoutLimitScope', 'all' );
1319
1320
    # Should count all patron checkouts regardless of item home library
1321
    $data = C4::Circulation::TooMany( $patron, $item_branch2 );
1322
    ok( $data, 'TooMany should return limit exceeded' );
1323
    is( $data->{count}, 1, 'Should count all patron checkouts' );
1324
1325
    # Test ItemHomeLibrary with CheckoutLimitScope = 'branch_specific'
1326
    t::lib::Mocks::mock_preference( 'CheckoutLimitScope', 'branch_specific' );
1327
1328
    # Item from branch2 - should not count checkout of item from branch1
1329
    $data = C4::Circulation::TooMany( $patron, $item_branch2 );
1330
    ok( !$data, 'TooMany should allow checkout when no items from this home library checked out' );
1331
1332
    # Item from branch1 - should count checkout of item from branch1
1333
    my $item_branch1_2 = $builder->build_sample_item(
1334
        {
1335
            homebranch    => $branch1->{branchcode},
1336
            holdingbranch => $branch1->{branchcode},
1337
            itype         => $itemtype->{itemtype}
1338
        }
1339
    );
1340
1341
    $data = C4::Circulation::TooMany( $patron, $item_branch1_2 );
1342
    ok( $data, 'TooMany should return limit exceeded when item from same home library already checked out' );
1343
    is( $data->{count}, 1, 'Should count checkout of item from same home library' );
1344
1345
    teardown();
1346
};
1347
1228
$schema->storage->txn_rollback;
1348
$schema->storage->txn_rollback;
1229
1349
1230
sub teardown {
1350
sub teardown {
1231
- 

Return to bug 27834