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

(-)a/C4/Circulation.pm (-19 / +32 lines)
Lines 482-498 sub TooMany { Link Here
482
    if ( defined($maxissueqty_rule) and $maxissueqty_rule->rule_value ne "" ) {
482
    if ( defined($maxissueqty_rule) and $maxissueqty_rule->rule_value ne "" ) {
483
483
484
        my $checkouts;
484
        my $checkouts;
485
        if ( $maxissueqty_rule->branchcode ) {
485
        my $checkout_limit_scope = C4::Context->preference('CircControlCheckoutLimitScope') || 'all';
486
            if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) {
486
        if ( $checkout_limit_scope eq 'checkout'
487
                $checkouts = $patron->checkouts->search( { 'me.branchcode' => $maxissueqty_rule->branchcode } );
487
            and ( C4::Context->userenv and C4::Context->userenv->{'branch'} ) )
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
490
            } else {
490
            # Count only checkouts made at this pickup library
491
                my $branch_type = C4::Context->preference('HomeOrHoldingBranch') || 'homebranch';
491
            my $pickup_branch = C4::Context->userenv->{'branch'};
492
                $checkouts = $patron->checkouts->search( { "item.$branch_type" => $maxissueqty_rule->branchcode } );
492
            $checkouts = $patron->checkouts->search( { 'me.branchcode' => $pickup_branch } );
493
            }
493
        } elsif ( $checkout_limit_scope eq 'item' ) {
494
495
            # Count only checkouts of items from this items library (follows HomeOrHoldingBranch)
496
            my $branch_type = C4::Context->preference('HomeOrHoldingBranch') || 'homebranch';
497
            $checkouts = $patron->checkouts->search( { "item.$branch_type" => $item->$branch_type } );
494
        } else {
498
        } else {
495
            $checkouts = $patron->checkouts;     # if rule is not branch specific then count all loans by patron
499
500
            # Default 'all': count all patron checkouts across all libraries
501
            $checkouts = $patron->checkouts;    # if rule is not branch specific then count all loans by patron
496
        }
502
        }
497
        $checkouts = $checkouts->search( undef, { prefetch => 'item' } );
503
        $checkouts = $checkouts->search( undef, { prefetch => 'item' } );
498
504
Lines 590-606 sub TooMany { Link Here
590
        and $branch_borrower_circ_rule->{patron_maxissueqty} ne '' )
596
        and $branch_borrower_circ_rule->{patron_maxissueqty} ne '' )
591
    {
597
    {
592
        my $checkouts;
598
        my $checkouts;
593
        if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) {
599
        my $checkout_limit_scope = C4::Context->preference('CircControlCheckoutLimitScope') || 'all';
594
            $checkouts = $patron->checkouts->search( { 'me.branchcode' => $branch } );
600
        if ( $checkout_limit_scope eq 'checkout'
595
        } elsif ( C4::Context->preference('CircControl') eq 'PatronLibrary' ) {
601
            and ( C4::Context->userenv and C4::Context->userenv->{'branch'} ) )
596
            $checkouts = $patron->checkouts;    # if branch is the patron's home branch, then count all loans by patron
602
        {
597
        } else {
603
            # Count only checkouts made at this pickup library
604
            my $pickup_branch = C4::Context->userenv->{'branch'};
605
            $checkouts = $patron->checkouts->search( { 'me.branchcode' => $pickup_branch } );
606
        } elsif ( $checkout_limit_scope eq 'item' ) {
607
608
            # Count only checkouts of items from this library (follows HomeOrHoldingBranch)
598
            my $branch_type = C4::Context->preference('HomeOrHoldingBranch') || 'homebranch';
609
            my $branch_type = C4::Context->preference('HomeOrHoldingBranch') || 'homebranch';
599
            $checkouts = $patron->checkouts->search(
610
            $checkouts = $patron->checkouts->search( { "item.$branch_type" => $item->$branch_type } );
600
                { "item.$branch_type" => $branch },
611
        } else {
601
                { prefetch            => 'item' }
612
602
            );
613
            # Default 'all': count all patron checkouts across all libraries
614
            $checkouts = $patron->checkouts;
603
        }
615
        }
616
        $checkouts = $checkouts->search( undef, { prefetch => 'item' } );
604
617
605
        my $checkout_count               = $checkouts->count;
618
        my $checkout_count               = $checkouts->count;
606
        my $onsite_checkout_count        = $checkouts->search( { onsite_checkout => 1 } )->count;
619
        my $onsite_checkout_count        = $checkouts->search( { onsite_checkout => 1 } )->count;
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (+8 lines)
Lines 312-317 Circulation: Link Here
312
                  homebranch: the item's home library (homebranch)
312
                  homebranch: the item's home library (homebranch)
313
                  holdingbranch: the item's holding library (holdingbranch)
313
                  holdingbranch: the item's holding library (holdingbranch)
314
            - .
314
            - .
315
        -
316
            - Calculate total issues for maxIssue limits using
317
            - pref: CircControlCheckoutLimitScope
318
              type: choice
319
              choices:
320
                  all: all patron checkouts across all libraries.
321
                  item: only checkouts of items from the same library as the item being checked out (follows HomeOrHoldingBranch preference).
322
                  checkout: only checkouts made at the same library as the current checkout.
315
        -
323
        -
316
            - Allow items to be checked in
324
            - Allow items to be checked in
317
            - pref: AllowReturnToBranch
325
            - pref: AllowReturnToBranch
(-)a/t/db_dependent/Circulation/TooMany.t (-6 / +357 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 => 15;
20
use C4::Context;
20
use C4::Context;
21
21
22
use C4::Members;
22
use C4::Members;
Lines 562-568 subtest '1 BranchBorrowerCircRule exist: 1 CO allowed, 1 OSCO allowed' => sub { Link Here
562
subtest 'General vs specific rules limit quantity correctly' => sub {
562
subtest 'General vs specific rules limit quantity correctly' => sub {
563
    plan tests => 18;
563
    plan tests => 18;
564
564
565
    t::lib::Mocks::mock_preference( 'CircControl', 'ItemHomeLibrary' );
565
    t::lib::Mocks::mock_preference( 'CircControl',                   'ItemHomeLibrary' );
566
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'item' );
566
    my $branch   = $builder->build( { source => 'Branch', } );
567
    my $branch   = $builder->build( { source => 'Branch', } );
567
    my $category = $builder->build( { source => 'Category', } );
568
    my $category = $builder->build( { source => 'Category', } );
568
    my $itemtype = $builder->build(
569
    my $itemtype = $builder->build(
Lines 695-701 subtest 'General vs specific rules limit quantity correctly' => sub { Link Here
695
    );
696
    );
696
697
697
    # If circcontrol is PatronLibrary we count all the patron's loan, regardless of branch
698
    # If circcontrol is PatronLibrary we count all the patron's loan, regardless of branch
698
    t::lib::Mocks::mock_preference( 'CircControl', 'PatronLibrary' );
699
    t::lib::Mocks::mock_preference( 'CircControl',                   'PatronLibrary' );
700
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'all' );
699
    $data = C4::Circulation::TooMany( $patron, $branch_item );
701
    $data = C4::Circulation::TooMany( $patron, $branch_item );
700
    $rule = delete $data->{circulation_rule};
702
    $rule = delete $data->{circulation_rule};
701
    is( ref $rule, 'Koha::CirculationRule', 'Circulation rule was returned' );
703
    is( ref $rule, 'Koha::CirculationRule', 'Circulation rule was returned' );
Lines 708-714 subtest 'General vs specific rules limit quantity correctly' => sub { Link Here
708
        },
710
        },
709
        'We are allowed one from the branch specifically, but have one'
711
        'We are allowed one from the branch specifically, but have one'
710
    );
712
    );
711
    t::lib::Mocks::mock_preference( 'CircControl', 'ItemHomeLibrary' );
713
    t::lib::Mocks::mock_preference( 'CircControl',                   'ItemHomeLibrary' );
714
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'item' );
712
715
713
    $issue = C4::Circulation::AddIssue( $patron, $branch_item->barcode, dt_from_string() );
716
    $issue = C4::Circulation::AddIssue( $patron, $branch_item->barcode, dt_from_string() );
714
717
Lines 735-740 subtest 'General vs specific rules limit quantity correctly' => sub { Link Here
735
    );
738
    );
736
739
737
    # Now we make another from a different branch
740
    # Now we make another from a different branch
741
    # Switch to 'all' scope to test general rules counting all checkouts
742
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'all' );
738
    my $item_2 = $builder->build_sample_item(
743
    my $item_2 = $builder->build_sample_item(
739
        {
744
        {
740
            itype => $itemtype->{itemtype},
745
            itype => $itemtype->{itemtype},
Lines 794-800 subtest 'General vs specific rules limit quantity correctly' => sub { Link Here
794
        'We are only allowed one for general rule, and have two total (no rule for specific branch)'
799
        'We are only allowed one for general rule, and have two total (no rule for specific branch)'
795
    );
800
    );
796
801
797
    # Set a branch specific rule for new branch
802
    # Set a branch specific rule for new branch and use 'checkout' scope
803
    # With PickupLibrary CircControl, we want to count checkouts made at this branch
804
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'checkout' );
798
    Koha::CirculationRules->set_rules(
805
    Koha::CirculationRules->set_rules(
799
        {
806
        {
800
            branchcode   => $branch2->{branchcode},
807
            branchcode   => $branch2->{branchcode},
Lines 1225-1230 subtest 'HomeOrHoldingBranch is used' => sub { Link Here
1225
    teardown();
1232
    teardown();
1226
};
1233
};
1227
1234
1235
subtest 'CircControlCheckoutLimitScope system preference controls checkout counting' => sub {
1236
    plan tests => 12;
1237
1238
    t::lib::Mocks::mock_preference( 'item-level_itypes', 1 );
1239
1240
    my $branch1  = $builder->build( { source => 'Branch' } );
1241
    my $branch2  = $builder->build( { source => 'Branch' } );
1242
    my $category = $builder->build( { source => 'Category' } );
1243
    my $itemtype = $builder->build( { source => 'Itemtype', value => { notforloan => 0 } } );
1244
1245
    my $patron = $builder->build_object(
1246
        {
1247
            class => 'Koha::Patrons',
1248
            value => {
1249
                categorycode => $category->{categorycode},
1250
                branchcode   => $branch1->{branchcode},
1251
            }
1252
        }
1253
    );
1254
1255
    # Create items from different branches
1256
    my $item_branch1 = $builder->build_sample_item(
1257
        {
1258
            homebranch    => $branch1->{branchcode},
1259
            holdingbranch => $branch1->{branchcode},
1260
            itype         => $itemtype->{itemtype}
1261
        }
1262
    );
1263
1264
    my $item_branch2 = $builder->build_sample_item(
1265
        {
1266
            homebranch    => $branch2->{branchcode},
1267
            holdingbranch => $branch2->{branchcode},
1268
            itype         => $itemtype->{itemtype}
1269
        }
1270
    );
1271
1272
    # Set circulation rules for both branches
1273
    Koha::CirculationRules->set_rules(
1274
        {
1275
            branchcode   => $branch1->{branchcode},
1276
            categorycode => $category->{categorycode},
1277
            itemtype     => $itemtype->{itemtype},
1278
            rules        => {
1279
                maxissueqty => 1,
1280
            }
1281
        }
1282
    );
1283
1284
    Koha::CirculationRules->set_rules(
1285
        {
1286
            branchcode   => $branch2->{branchcode},
1287
            categorycode => $category->{categorycode},
1288
            itemtype     => $itemtype->{itemtype},
1289
            rules        => {
1290
                maxissueqty => 1,
1291
            }
1292
        }
1293
    );
1294
1295
    # Issue an item from branch1
1296
    t::lib::Mocks::mock_userenv( { branchcode => $branch1->{branchcode} } );
1297
    my $issue = C4::Circulation::AddIssue( $patron, $item_branch1->barcode, dt_from_string() );
1298
    ok( $issue, 'Item from branch1 issued successfully' );
1299
1300
    # Test with CircControlCheckoutLimitScope = 'checkout'
1301
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'checkout' );
1302
1303
    # From branch1 - should count checkout made at branch1
1304
    my $data = C4::Circulation::TooMany( $patron, $item_branch1 );
1305
    ok( $data, 'TooMany should return limit exceeded when checking from same pickup library' );
1306
    is( $data->{count},  1,                    'Should count checkout made at this pickup library' );
1307
    is( $data->{reason}, 'TOO_MANY_CHECKOUTS', 'Correct reason returned' );
1308
1309
    # From branch2 - should not count checkout made at branch1
1310
    t::lib::Mocks::mock_userenv( { branchcode => $branch2->{branchcode} } );
1311
    $data = C4::Circulation::TooMany( $patron, $item_branch2 );
1312
    ok( !$data, 'TooMany should allow checkout when no checkouts from this pickup library' );
1313
1314
    # Test with CircControlCheckoutLimitScope = 'all'
1315
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'all' );
1316
1317
    # Should count all patron checkouts regardless of pickup library
1318
    $data = C4::Circulation::TooMany( $patron, $item_branch2 );
1319
    ok( $data, 'TooMany should return limit exceeded when counting all checkouts' );
1320
    is( $data->{count}, 1, 'Should count all patron checkouts regardless of branch' );
1321
1322
    # Test with CircControlCheckoutLimitScope = 'all' from branch1
1323
    t::lib::Mocks::mock_userenv( { branchcode => $branch1->{branchcode} } );
1324
    $data = C4::Circulation::TooMany( $patron, $item_branch2 );
1325
    ok( $data, 'TooMany should return limit exceeded' );
1326
    is( $data->{count}, 1, 'Should count all patron checkouts' );
1327
1328
    # Test with CircControlCheckoutLimitScope = 'item'
1329
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'item' );
1330
1331
    # Item from branch2 - should not count checkout of item from branch1
1332
    $data = C4::Circulation::TooMany( $patron, $item_branch2 );
1333
    ok( !$data, 'TooMany should allow checkout when no items from this home library checked out' );
1334
1335
    # Item from branch1 - should count checkout of item from branch1
1336
    my $item_branch1_2 = $builder->build_sample_item(
1337
        {
1338
            homebranch    => $branch1->{branchcode},
1339
            holdingbranch => $branch1->{branchcode},
1340
            itype         => $itemtype->{itemtype}
1341
        }
1342
    );
1343
1344
    $data = C4::Circulation::TooMany( $patron, $item_branch1_2 );
1345
    ok( $data, 'TooMany should return limit exceeded when item from same home library already checked out' );
1346
    is( $data->{count}, 1, 'Should count checkout of item from same home library' );
1347
1348
    teardown();
1349
};
1350
1351
subtest 'CircControlCheckoutLimitScope with HomeOrHoldingBranch preference' => sub {
1352
    plan tests => 8;
1353
1354
    t::lib::Mocks::mock_preference( 'item-level_itypes', 1 );
1355
    t::lib::Mocks::mock_preference( 'CircControl',       'ItemHomeLibrary' );
1356
1357
    my $branch1  = $builder->build( { source => 'Branch' } );
1358
    my $branch2  = $builder->build( { source => 'Branch' } );
1359
    my $category = $builder->build( { source => 'Category' } );
1360
    my $itemtype = $builder->build( { source => 'Itemtype', value => { notforloan => 0 } } );
1361
1362
    my $patron = $builder->build_object(
1363
        {
1364
            class => 'Koha::Patrons',
1365
            value => {
1366
                categorycode => $category->{categorycode},
1367
                branchcode   => $branch1->{branchcode},
1368
            }
1369
        }
1370
    );
1371
1372
    # Create an item with different home and holding branches
1373
    my $item_home1_holding2 = $builder->build_sample_item(
1374
        {
1375
            homebranch    => $branch1->{branchcode},
1376
            holdingbranch => $branch2->{branchcode},
1377
            itype         => $itemtype->{itemtype}
1378
        }
1379
    );
1380
1381
    my $item_home2_holding1 = $builder->build_sample_item(
1382
        {
1383
            homebranch    => $branch2->{branchcode},
1384
            holdingbranch => $branch1->{branchcode},
1385
            itype         => $itemtype->{itemtype}
1386
        }
1387
    );
1388
1389
    # Set circulation rules for both branches
1390
    Koha::CirculationRules->set_rules(
1391
        {
1392
            branchcode   => $branch1->{branchcode},
1393
            categorycode => $category->{categorycode},
1394
            itemtype     => $itemtype->{itemtype},
1395
            rules        => {
1396
                maxissueqty => 1,
1397
            }
1398
        }
1399
    );
1400
1401
    Koha::CirculationRules->set_rules(
1402
        {
1403
            branchcode   => $branch2->{branchcode},
1404
            categorycode => $category->{categorycode},
1405
            itemtype     => $itemtype->{itemtype},
1406
            rules        => {
1407
                maxissueqty => 1,
1408
            }
1409
        }
1410
    );
1411
1412
    # Test with scope='item' and HomeOrHoldingBranch='homebranch'
1413
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'item' );
1414
    t::lib::Mocks::mock_preference( 'HomeOrHoldingBranch',           'homebranch' );
1415
    t::lib::Mocks::mock_userenv( { branchcode => $branch1->{branchcode} } );
1416
1417
    # Check out item with homebranch=branch1
1418
    my $issue = C4::Circulation::AddIssue( $patron, $item_home1_holding2->barcode, dt_from_string() );
1419
    ok( $issue, 'Item with homebranch=branch1 issued successfully' );
1420
1421
    # Reload item to get updated holdingbranch (AddIssue may change it)
1422
    $item_home1_holding2->discard_changes;
1423
1424
    # Try to check out another item with homebranch=branch1
1425
    my $item_home1_2 = $builder->build_sample_item(
1426
        {
1427
            homebranch    => $branch1->{branchcode},
1428
            holdingbranch => $branch1->{branchcode},
1429
            itype         => $itemtype->{itemtype}
1430
        }
1431
    );
1432
1433
    my $data = C4::Circulation::TooMany( $patron, $item_home1_2 );
1434
    ok( $data, 'TooMany should block checkout of another item from same homebranch' );
1435
    is( $data->{count}, 1, 'Should count 1 checkout with same homebranch' );
1436
1437
    # Try to check out item with different homebranch (branch2)
1438
    $data = C4::Circulation::TooMany( $patron, $item_home2_holding1 );
1439
    ok( !$data, 'TooMany should allow checkout of item from different homebranch' );
1440
1441
    # Now test with HomeOrHoldingBranch='holdingbranch'
1442
    t::lib::Mocks::mock_preference( 'HomeOrHoldingBranch', 'holdingbranch' );
1443
1444
    # After checkout, the item's holdingbranch may have been updated to the checkout library
1445
    # Get the current holdingbranch from the checked-out item
1446
    my $checked_out_holdingbranch = $item_home1_holding2->holdingbranch;
1447
1448
    # Try to check out another item with the same holdingbranch
1449
    my $item_holding_same = $builder->build_sample_item(
1450
        {
1451
            homebranch    => $branch2->{branchcode},
1452
            holdingbranch => $checked_out_holdingbranch,
1453
            itype         => $itemtype->{itemtype}
1454
        }
1455
    );
1456
1457
    $data = C4::Circulation::TooMany( $patron, $item_holding_same );
1458
    ok( $data, 'TooMany should block checkout of another item from same holdingbranch' );
1459
    is( $data->{count}, 1, 'Should count 1 checkout with same holdingbranch' );
1460
1461
    # Try to check out item with different holdingbranch
1462
    my $different_holdingbranch =
1463
        $checked_out_holdingbranch eq $branch1->{branchcode} ? $branch2->{branchcode} : $branch1->{branchcode};
1464
    my $item_holding_different = $builder->build_sample_item(
1465
        {
1466
            homebranch    => $branch1->{branchcode},
1467
            holdingbranch => $different_holdingbranch,
1468
            itype         => $itemtype->{itemtype}
1469
        }
1470
    );
1471
1472
    $data = C4::Circulation::TooMany( $patron, $item_holding_different );
1473
    ok( !$data, 'TooMany should allow checkout of item from different holdingbranch' );
1474
1475
    # Verify that we're actually using holdingbranch not homebranch
1476
    # item_home1_2 has homebranch=branch1, verify its holdingbranch determines the result
1477
    $data = C4::Circulation::TooMany( $patron, $item_home1_2 );
1478
    if ( $item_home1_2->holdingbranch eq $checked_out_holdingbranch ) {
1479
        ok( $data, 'Item with same holdingbranch should be blocked' );
1480
    } else {
1481
        ok( !$data, 'Item with different holdingbranch should be allowed' );
1482
    }
1483
1484
    teardown();
1485
};
1486
1487
subtest 'CircControlCheckoutLimitScope with patron_maxissueqty' => sub {
1488
    plan tests => 9;
1489
1490
    t::lib::Mocks::mock_preference( 'item-level_itypes', 1 );
1491
1492
    my $branch1  = $builder->build( { source => 'Branch' } );
1493
    my $branch2  = $builder->build( { source => 'Branch' } );
1494
    my $category = $builder->build( { source => 'Category' } );
1495
    my $itemtype = $builder->build( { source => 'Itemtype', value => { notforloan => 0 } } );
1496
1497
    my $patron = $builder->build_object(
1498
        {
1499
            class => 'Koha::Patrons',
1500
            value => {
1501
                categorycode => $category->{categorycode},
1502
                branchcode   => $branch1->{branchcode},
1503
            }
1504
        }
1505
    );
1506
1507
    # Create items from different branches
1508
    my $item_branch1 = $builder->build_sample_item(
1509
        {
1510
            homebranch    => $branch1->{branchcode},
1511
            holdingbranch => $branch1->{branchcode},
1512
            itype         => $itemtype->{itemtype}
1513
        }
1514
    );
1515
1516
    my $item_branch2 = $builder->build_sample_item(
1517
        {
1518
            homebranch    => $branch2->{branchcode},
1519
            holdingbranch => $branch2->{branchcode},
1520
            itype         => $itemtype->{itemtype}
1521
        }
1522
    );
1523
1524
    # Set patron_maxissueqty rules for both branches
1525
    Koha::CirculationRules->set_rules(
1526
        {
1527
            branchcode   => $branch1->{branchcode},
1528
            categorycode => $category->{categorycode},
1529
            rules        => {
1530
                patron_maxissueqty => 1,
1531
            }
1532
        }
1533
    );
1534
1535
    Koha::CirculationRules->set_rules(
1536
        {
1537
            branchcode   => $branch2->{branchcode},
1538
            categorycode => $category->{categorycode},
1539
            rules        => {
1540
                patron_maxissueqty => 1,
1541
            }
1542
        }
1543
    );
1544
1545
    # Issue an item from branch1
1546
    t::lib::Mocks::mock_userenv( { branchcode => $branch1->{branchcode} } );
1547
    my $issue = C4::Circulation::AddIssue( $patron, $item_branch1->barcode, dt_from_string() );
1548
    ok( $issue, 'Item from branch1 issued successfully' );
1549
1550
    # Test with scope='all' - should count all checkouts
1551
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'all' );
1552
    my $data = C4::Circulation::TooMany( $patron, $item_branch1 );
1553
    ok( $data, 'patron_maxissueqty with scope=all should count all checkouts' );
1554
    is( $data->{count}, 1, 'Should count 1 checkout total' );
1555
1556
    # Test with scope='item' - should count items from same branch
1557
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'item' );
1558
    $data = C4::Circulation::TooMany( $patron, $item_branch1 );
1559
    ok( $data, 'patron_maxissueqty with scope=item should count items from same branch' );
1560
    is( $data->{count}, 1, 'Should count 1 checkout from branch1' );
1561
1562
    # Item from different branch should be allowed with scope='item'
1563
    $data = C4::Circulation::TooMany( $patron, $item_branch2 );
1564
    ok( !$data, 'patron_maxissueqty with scope=item should allow item from different branch' );
1565
1566
    # Test with scope='checkout' - should count checkouts made at same location
1567
    t::lib::Mocks::mock_preference( 'CircControlCheckoutLimitScope', 'checkout' );
1568
    $data = C4::Circulation::TooMany( $patron, $item_branch1 );
1569
    ok( $data, 'patron_maxissueqty with scope=checkout should count checkouts made here' );
1570
    is( $data->{count}, 1, 'Should count 1 checkout made at branch1' );
1571
1572
    # From different branch should be allowed with scope='checkout'
1573
    t::lib::Mocks::mock_userenv( { branchcode => $branch2->{branchcode} } );
1574
    $data = C4::Circulation::TooMany( $patron, $item_branch2 );
1575
    ok( !$data, 'patron_maxissueqty with scope=checkout should allow checkout from different branch' );
1576
1577
    teardown();
1578
};
1579
1228
$schema->storage->txn_rollback;
1580
$schema->storage->txn_rollback;
1229
1581
1230
sub teardown {
1582
sub teardown {
1231
- 

Return to bug 27834