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

(-)a/Koha/Hold.pm (+53 lines)
Lines 889-894 sub fill { Link Here
889
    return $self;
889
    return $self;
890
}
890
}
891
891
892
=head3 revert_waiting
893
894
    $hold->revert_waiting();
895
896
Reverts a 'waiting' hold back to a regular hold with a priority of 1.
897
898
=cut
899
900
sub revert_waiting {
901
    my ( $self, $params ) = @_;
902
903
    Koha::Exceptions::InvalidStatus->throw( invalid_status => 'hold_not_waiting' )
904
        unless $self->is_waiting;
905
906
    $self->_result->result_source->schema->txn_do(
907
        sub {
908
            my $original = C4::Context->preference('HoldsLog') ? $self->unblessed : undef;
909
910
            # Increment the priority of all other non-waiting
911
            # reserves for this bib record
912
            my $holds = Koha::Holds->search(
913
                {
914
                    biblionumber => $self->biblionumber,
915
                    priority     => { '>' => 0 }
916
                }
917
            )->update(
918
                { priority    => \'priority + 1' },
919
                { no_triggers => 1 }
920
            );
921
922
            ## Fix up the currently waiting reserve
923
            $self->set(
924
                {
925
                    priority       => 1,
926
                    found          => undef,
927
                    waitingdate    => undef,
928
                    expirationdate => $self->patron_expiration_date,
929
                    itemnumber     => $self->item_level_hold ? $self->itemnumber : undef,
930
                }
931
            )->store( { hold_reverted => 1 } );
932
933
            logaction( 'HOLDS', 'MODIFY', $self->id, $self, undef, $original )
934
                if C4::Context->preference('HoldsLog');
935
936
            C4::Reserves::_FixPriority( { biblionumber => $self->biblionumber } );
937
938
            Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue->new->enqueue( { biblio_ids => [ $self->biblionumber ] } )
939
                if C4::Context->preference('RealTimeHoldsQueue');
940
        }
941
    );
942
    return $self;
943
}
944
892
=head3 sub change_type
945
=head3 sub change_type
893
946
894
    $hold->change_type                # to record level
947
    $hold->change_type                # to record level
(-)a/t/db_dependent/Koha/Hold.t (-1 / +235 lines)
Lines 29-34 use t::lib::Mocks; Link Here
29
use t::lib::TestBuilder;
29
use t::lib::TestBuilder;
30
use t::lib::Mocks;
30
use t::lib::Mocks;
31
31
32
use C4::Reserves qw(AddReserve);
33
32
use Koha::ActionLogs;
34
use Koha::ActionLogs;
33
use Koha::DateUtils qw(dt_from_string);
35
use Koha::DateUtils qw(dt_from_string);
34
use Koha::Holds;
36
use Koha::Holds;
Lines 1259-1261 subtest 'strings_map() tests' => sub { Link Here
1259
1261
1260
    $schema->txn_rollback;
1262
    $schema->txn_rollback;
1261
};
1263
};
1262
- 
1264
1265
subtest 'revert_waiting() tests' => sub {
1266
1267
    plan tests => 3;
1268
1269
    subtest 'item-level holds tests' => sub {
1270
1271
        plan tests => 13;
1272
1273
        $schema->storage->txn_begin;
1274
1275
        my $item   = $builder->build_sample_item;
1276
        my $patron = $builder->build_object(
1277
            {
1278
                class => 'Koha::Patrons',
1279
                value => { branchcode => $item->homebranch }
1280
            }
1281
        );
1282
1283
        # Create item-level hold
1284
        my $hold = Koha::Holds->find(
1285
            AddReserve(
1286
                {
1287
                    branchcode     => $item->homebranch,
1288
                    borrowernumber => $patron->borrowernumber,
1289
                    biblionumber   => $item->biblionumber,
1290
                    priority       => 1,
1291
                    itemnumber     => $item->itemnumber,
1292
                }
1293
            )
1294
        );
1295
1296
        is( $hold->item_level_hold, 1, 'item_level_hold should be set when AddReserve is called with a specific item' );
1297
1298
        my $mock = Test::MockModule->new('Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue');
1299
        $mock->mock(
1300
            'enqueue',
1301
            sub {
1302
                my ( $self, $args ) = @_;
1303
                is_deeply(
1304
                    $args->{biblio_ids},
1305
                    [ $hold->biblionumber ],
1306
                    "AlterPriority triggers a holds queue update for the related biblio"
1307
                );
1308
            }
1309
        );
1310
1311
        t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 1 );
1312
        t::lib::Mocks::mock_preference( 'HoldsLog',           1 );
1313
1314
        # Mark it waiting
1315
        $hold->set_waiting();
1316
1317
        isnt( $hold->waitingdate, undef, "'waitingdate' set" );
1318
        is( $hold->priority, 0, "'priority' set to 0" );
1319
        ok( $hold->is_waiting, 'Hold set to waiting' );
1320
1321
        # Revert the waiting status
1322
        $hold->revert_waiting();
1323
1324
        is( $hold->waitingdate, undef, "'waitingdate' reset" );
1325
        ok( !$hold->is_waiting, 'Hold no longer set to waiting' );
1326
        is( $hold->priority, 1, "'priority' set to 1" );
1327
1328
        is(
1329
            $hold->itemnumber, $item->itemnumber,
1330
            'Itemnumber should not be removed when the waiting status is revert'
1331
        );
1332
1333
        my $log =
1334
            Koha::ActionLogs->search( { module => 'HOLDS', action => 'MODIFY', object => $hold->reserve_id } )->next;
1335
        my $expected = sprintf q{'timestamp' => '%s'}, $hold->timestamp;
1336
        like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1337
        my $log_count =
1338
            Koha::ActionLogs->search( { module => 'HOLDS', action => 'MODIFY', object => $hold->reserve_id } )->count;
1339
1340
        t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 0 );
1341
        t::lib::Mocks::mock_preference( 'HoldsLog',           0 );
1342
1343
        $hold->set_waiting();
1344
1345
        # Revert the waiting status, RealTimeHoldsQueue => shouldn't add a test
1346
        $hold->revert_waiting();
1347
1348
        my $log_count_after =
1349
            Koha::ActionLogs->search( { module => 'HOLDS', action => 'MODIFY', object => $hold->reserve_id } )->count;
1350
        is( $log_count, $log_count_after, "No logging is added for ->revert_waiting() when HoldsLog is disabled" );
1351
1352
        # Set as 'processing' to test the exception behavior
1353
        $hold->found('P');
1354
        throws_ok { $hold->revert_waiting() }
1355
        'Koha::Exceptions::InvalidStatus',
1356
            "Hold is not in 'waiting' status, exception thrown";
1357
1358
        is( $@->invalid_status, 'hold_not_waiting', "'invalid_status' set the right value" );
1359
1360
        $schema->storage->txn_rollback;
1361
    };
1362
1363
    subtest 'biblio-level hold tests' => sub {
1364
1365
        plan tests => 8;
1366
1367
        $schema->storage->txn_begin;
1368
1369
        my $item   = $builder->build_sample_item;
1370
        my $patron = $builder->build_object(
1371
            {
1372
                class => 'Koha::Patrons',
1373
                value => { branchcode => $item->homebranch }
1374
            }
1375
        );
1376
1377
        # Create biblio-level hold
1378
        my $hold = Koha::Holds->find(
1379
            AddReserve(
1380
                {
1381
                    branchcode     => $item->homebranch,
1382
                    borrowernumber => $patron->borrowernumber,
1383
                    biblionumber   => $item->biblionumber,
1384
                    priority       => 1,
1385
                }
1386
            )
1387
        );
1388
1389
        is(
1390
            $hold->item_level_hold, 0,
1391
            'item_level_hold should not be set when AddReserve is called without a specific item'
1392
        );
1393
1394
        # Mark it waiting
1395
        $hold->set( { itemnumber => $item->itemnumber } )->set_waiting();
1396
        $hold->set_waiting();
1397
1398
        isnt( $hold->waitingdate, undef, "'waitingdate' set" );
1399
        is( $hold->priority, 0, "'priority' set to 0" );
1400
        ok( $hold->is_waiting, 'Hold set to waiting' );
1401
1402
        # Revert the waiting status
1403
        $hold->revert_waiting();
1404
1405
        is( $hold->waitingdate, undef, "'waitingdate' reset" );
1406
        ok( !$hold->is_waiting, 'Hold no longer set to waiting' );
1407
        is( $hold->priority,   1,     "'priority' set to 1" );
1408
        is( $hold->itemnumber, undef, "'itemnumber' unset" );
1409
1410
        $schema->storage->txn_rollback;
1411
    };
1412
1413
    subtest 'priority shift tests' => sub {
1414
1415
        plan tests => 4;
1416
1417
        $schema->storage->txn_begin;
1418
1419
        # Create the items and patrons we need
1420
        my $library = $builder->build_object( { class => 'Koha::Libraries' } );
1421
        my $itype   = $builder->build_object( { class => "Koha::ItemTypes", value => { notforloan => 0 } } );
1422
        my $item    = $builder->build_sample_item(
1423
            {
1424
                itype   => $itype->itemtype,
1425
                library => $library->branchcode
1426
            }
1427
        );
1428
        my $patron_1 = $builder->build_object( { class => "Koha::Patrons" } );
1429
        my $patron_2 = $builder->build_object( { class => "Koha::Patrons" } );
1430
        my $patron_3 = $builder->build_object( { class => "Koha::Patrons" } );
1431
        my $patron_4 = $builder->build_object( { class => "Koha::Patrons" } );
1432
1433
        # Place a hold on the title for both patrons
1434
        my $hold = Koha::Holds->find(
1435
            C4::Reserves::AddReserve(
1436
                {
1437
                    branchcode     => $library->branchcode,
1438
                    borrowernumber => $patron_1->borrowernumber,
1439
                    biblionumber   => $item->biblionumber,
1440
                    priority       => 1,
1441
                    itemnumber     => $item->itemnumber,
1442
                }
1443
            )
1444
        );
1445
1446
        C4::Reserves::AddReserve(
1447
            {
1448
                branchcode     => $library->branchcode,
1449
                borrowernumber => $patron_2->borrowernumber,
1450
                biblionumber   => $item->biblionumber,
1451
                priority       => 1,
1452
                itemnumber     => $item->itemnumber,
1453
            }
1454
        );
1455
1456
        C4::Reserves::AddReserve(
1457
            {
1458
                branchcode     => $library->branchcode,
1459
                borrowernumber => $patron_3->borrowernumber,
1460
                biblionumber   => $item->biblionumber,
1461
                priority       => 1,
1462
                itemnumber     => $item->itemnumber,
1463
            }
1464
        );
1465
1466
        C4::Reserves::AddReserve(
1467
            {
1468
                branchcode     => $library->branchcode,
1469
                borrowernumber => $patron_4->borrowernumber,
1470
                biblionumber   => $item->biblionumber,
1471
                priority       => 1,
1472
                itemnumber     => $item->itemnumber,
1473
            }
1474
        );
1475
1476
        is( $item->biblio->holds->count, 4, '4 holds on the biblio' );
1477
1478
        $hold->set_waiting()->discard_changes();
1479
        is( $hold->priority, 0, "'priority' set to 0" );
1480
1481
        $hold->revert_waiting()->discard_changes();
1482
        is( $hold->priority, 1, "'priority' set to 1" );
1483
1484
        my $holds = $item->biblio->holds;
1485
        is_deeply(
1486
            [
1487
                $holds->next->priority, $holds->next->priority,
1488
                $holds->next->priority, $holds->next->priority,
1489
            ],
1490
            [ 1, 2, 3, 4 ],
1491
            'priorities have been reordered'
1492
        );
1493
1494
        $schema->storage->txn_rollback;
1495
    };
1496
};

Return to bug 40058