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

(-)a/C4/Reserves.pm (-2 / +7 lines)
Lines 555-561 sub CanReserveBeCanceledFromOpac { Link Here
555
    my $reserve = Koha::Holds->find($reserve_id);
555
    my $reserve = Koha::Holds->find($reserve_id);
556
556
557
    return 0 unless $reserve->borrowernumber == $borrowernumber;
557
    return 0 unless $reserve->borrowernumber == $borrowernumber;
558
    return 0 if ( $reserve->found eq 'W' ) or ( $reserve->found eq 'T' );
558
    return 0 if ( $reserve->found && $reserve->found eq 'W' ) or ( $reserve->found && $reserve->found eq 'T' );
559
559
560
    return 1;
560
    return 1;
561
561
Lines 811-817 sub CheckReserves { Link Here
811
        my $priority = 10000000;
811
        my $priority = 10000000;
812
        foreach my $res (@reserves) {
812
        foreach my $res (@reserves) {
813
            #Before allocating to bib-level hold check if reserve respects hold rule, i.e. can patron category/item type combination allow reserves
813
            #Before allocating to bib-level hold check if reserve respects hold rule, i.e. can patron category/item type combination allow reserves
814
            my $checkreserve = Koha::Hold->check_if_existing_hold_matches_issuingrules( $res->{'borrowernumber'}, $itemnumber );
814
            my $checkreserve;
815
            if ( $item ){
816
                $checkreserve = Koha::Holds->find( $res->{reserve_id} )->matches_circulation_rules({ itemnumber => $item });
817
            } else {
818
                $checkreserve = Koha::Holds->find( $res->{reserve_id} )->matches_circulation_rules({ barcode => $barcode });
819
            }
815
            next unless ($checkreserve eq 'OK');
820
            next unless ($checkreserve eq 'OK');
816
821
817
            if ( $res->{'itemnumber'} && $res->{'itemnumber'} == $itemnumber && $res->{'priority'} == 0) {
822
            if ( $res->{'itemnumber'} && $res->{'itemnumber'} == $itemnumber && $res->{'priority'} == 0) {
(-)a/Koha/Hold.pm (-16 / +27 lines)
Lines 33-39 use Koha::Items; Link Here
33
use Koha::Libraries;
33
use Koha::Libraries;
34
use Koha::Old::Holds;
34
use Koha::Old::Holds;
35
use Koha::Calendar;
35
use Koha::Calendar;
36
37
use Koha::Exceptions::Hold;
36
use Koha::Exceptions::Hold;
38
37
39
use base qw(Koha::Object);
38
use base qw(Koha::Object);
Lines 337-377 sub is_suspended { Link Here
337
    return $self->suspend();
336
    return $self->suspend();
338
}
337
}
339
338
340
=head3 check_if_existing_hold_matches_issuingrules
339
=head3 matches_circulation_rules
341
340
342
my $checkreserve = Koha::Hold->check_if_existing_hold_matches_issuingrules($res->{'borrowernumber'}, $itemnumber );
341
    my $checkreserve = Koha::Hold->matches_circulation_rules({ itemnumber => $itemnumber });
342
    my $checkreserve = Koha::Hold->matches_circulation_rules({ barcode => $barcode });
343
343
344
Upon checking in an item of a bibliographic record with a biblio-level hold on it, check if a bib-level hold can be allocated to a patron based on the current values in the issuingrules table
344
Upon checking in an item of a bibliographic record with a biblio-level hold on it, check if a bib-level hold can be allocated to a patron based on the current values in the issuingrules table
345
345
346
Parameter is an attribute of the item that is being checked in
347
346
=cut
348
=cut
347
349
348
sub check_if_existing_hold_matches_issuingrules {
350
sub matches_circulation_rules {
349
    my ( $self, $borrowernumber, $itemnumber ) = @_;
351
    my ( $self, $params ) = @_;
350
352
351
    #Get patron and item objects
353
    #Get patron and item objects
352
    my $patron = Koha::Patrons->find( $borrowernumber );
354
    my $patron = $self->borrower;
353
    my $item = Koha::Items->find( $itemnumber );
355
    my $item = Koha::Items->find( $params->{itemnumber} );
354
    $item = $item->unblessed();
356
    if ( !defined $item ){
357
        $item = Koha::Items->find({ barcode => $params->{barcode} });
358
    }
355
359
356
    #Get branchcode
360
    #Get branchcode
357
    my $branchcode;
361
    my $branchcode;
358
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
362
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
359
363
    if ( $controlbranch eq "ItemHomeLibrary" && defined $item ) {
360
    if ( $controlbranch eq "ItemHomeLibrary" ) {
364
         $branchcode  = $item->homebranch;
361
         $branchcode  = $item->{homebranch};
365
    } else {
362
    }
363
    elsif ( $controlbranch eq "PatronLibrary" ) {
364
         $branchcode  = $patron->branchcode;
366
         $branchcode  = $patron->branchcode;
365
    }
367
    }
366
368
367
    my $issuingrule = Koha::IssuingRules->get_effective_issuing_rule({
369
    my $issuingrule = Koha::CirculationRules->get_effective_rules({
368
        branchcode => $branchcode,
370
        branchcode => $branchcode,
369
        categorycode => $patron->categorycode,
371
        categorycode => $patron->categorycode,
370
        itemtype => $item->{itype},
372
        itemtype => $item->effective_itemtype,
373
        rules => [
374
            'reservesallowed',
375
            'holds_per_record',
376
            'holds_per_day',
377
        ],
371
    });
378
    });
372
379
373
    #Check if the patron category/item type combination is valid
380
    #Check if the patron category/item type combination is valid
374
    if ( ($issuingrule->reservesallowed == 0 || $issuingrule->holds_per_record == 0 || $issuingrule->holds_per_day == 0 )) {
381
    if (
382
        ( defined $issuingrule->{reservesallowed} && $issuingrule->{reservesallowed} == 0 ) ||
383
        ( defined $issuingrule->{holds_per_record} && $issuingrule->{holds_per_record} == 0 ) ||
384
        ( defined $issuingrule->{holds_per_day} && $issuingrule->{holds_per_day} == 0 )
385
    ) {
375
        return 'InvalidHold';
386
        return 'InvalidHold';
376
    } else {
387
    } else {
377
        return 'OK';
388
        return 'OK';
(-)a/t/db_dependent/Hold.t (-89 / +146 lines)
Lines 28-34 use Koha::Holds; Link Here
28
use Koha::Item;
28
use Koha::Item;
29
use Koha::DateUtils;
29
use Koha::DateUtils;
30
use t::lib::TestBuilder;
30
use t::lib::TestBuilder;
31
use Koha::IssuingRules;
31
use Koha::CirculationRules;
32
use C4::Reserves;
32
33
33
use Test::More tests => 30;
34
use Test::More tests => 30;
34
use Test::Exception;
35
use Test::Exception;
Lines 272-370 subtest 'suspend() tests' => sub { Link Here
272
    $schema->storage->txn_rollback;
273
    $schema->storage->txn_rollback;
273
};
274
};
274
275
275
subtest "check_if_existing_hold_matches_issuingrules tests" => sub {
276
subtest "matches_circulation_rules tests" => sub {
276
    plan tests => 9;
277
    plan tests => 9;
277
278
278
    $schema->storage->txn_begin();
279
    $schema->storage->txn_begin();
279
280
280
    #Create test data
281
    #Create test data
281
    my $branchcode = $builder->build( { source => 'Branch' } )->{ branchcode };
282
    my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode };
282
    my $categorycode1 = $builder->build({ source => 'Category' })->{categorycode};
283
    my $categorycode = $builder->build({ source => 'Category' })->{ categorycode };
283
    my $categorycode2 = $builder->build({ source => 'Category' })->{categorycode};
284
    my $patron = $builder->build({ source => 'Borrower', value => { categorycode => $categorycode, branchcode => $branchcode }});
284
    my $patron1 = $builder->build({source => 'Borrower', value => { branchcode => $branchcode }});
285
    my $biblionumber = $builder->build({ source => 'Biblio' })->{biblionumber};
285
286
    my $itemtype1 = $builder->build({ source => 'Itemtype' })->{itemtype};
286
    my $item1 = $builder->build({ source => 'Item', value => { homebranch => $branchcode }});
287
    my $itemtype2 = $builder->build({ source => 'Itemtype' })->{itemtype};
287
    my $item2 = $builder->build({ source => 'Item', value => { homebranch => $branchcode }});
288
    my $item1 = $builder->build({ source => 'Item', value => { homebranch => $branchcode, biblionumber => $biblionumber, itype => $itemtype1 }});
288
289
    my $item2 = $builder->build({ source => 'Item', value => { homebranch => $branchcode, biblionumber => $biblionumber, itype => $itemtype2 }});
289
    my $itemtype1 = $item1->{'itype'};
290
290
    my $itemtype2 = $item2->{'itype'};
291
    Koha::CirculationRules->set_rules({
291
292
        branchcode => $branchcode,
292
    Koha::IssuingRules->delete;
293
        categorycode => $categorycode,
293
294
        itemtype => $itemtype1,
294
    #Get branchcode
295
        rules => {
295
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
296
            reservesallowed => 0,
296
297
            holds_per_record => 0,
297
    if ( $controlbranch eq "ItemHomeLibrary" ) {
298
            holds_per_day => 0,
298
       $branchcode  = $item->{homebranch};
299
        }
299
    }
300
    });
300
    elsif ( $controlbranch eq "PatronLibrary" ) {
301
301
       $branchcode  = $patron1->{branchcode};
302
    my $reserveid1 = AddReserve({
302
    }
303
        branchcode => $branchcode,
303
304
        borrowernumber => $patron->{borrowernumber},
304
    #Test all cases when the check_return
305
        biblionumber => $biblionumber,
305
    #check_if_existing_hold_matches_issuingrules() returns 'InvalidHold' when reservesallowed, holds_per_record and holds_per_day are all 0
306
    });
306
    my $rule1 = Koha::IssuingRule->new({
307
    my $reserve1 = Koha::Holds->find($reserveid1);
307
        branchcode =>  $branchcode,
308
308
        categorycode => $patron1->{'categorycode'},
309
    my $checkreserve1 = $reserve1->matches_circulation_rules({ itemnumber => $item1->{itemnumber} });
309
        itemtype => $item1->{'itype'},
310
    is( $checkreserve1, 'InvalidHold', 'Circulation rules disallow item being allocated to the hold' );
310
        reservesallowed => 0,
311
311
        holds_per_record => 0,
312
    #Confirm that when any of the 3 reserves-related circulaion rules fields (reservesallowed, holds_per_record, holds_per_day) are set to 0 then matches_circulation_rules returns 'InvalidHold' and so a newly returned item is not allocated to a specific bib-level reserve
312
        holds_per_day => 0,
313
313
    })->store;
314
    Koha::CirculationRules->set_rules({
314
    my $checkreserve1 = Koha::Hold->check_if_existing_hold_matches_issuingrules($patron1->{'borrowernumber'}, $item1->{'itemnumber'} );
315
        branchcode => $branchcode,
315
    is( $checkreserve1, 'InvalidHold', 'Allocating item1 to a bib-reserve is not allowed as the issuingrules reservesallowed, holds_per_record and holds_per_day is 0 for this patron category/itemtype combination' );
316
        categorycode => $categorycode,
316
317
        itemtype => $itemtype1,
317
    #Confirm that when any of the 4 reserves related issuingrules fields (reservesallowed, holds_per_record, holds_per_day) are set to 0 then check_if_existing_hold_matches_issuingrules() returns 'InvalidHold' and so a newly returned item is not allocated to a specific bib-level reserve
318
        rules => {
318
319
            reservesallowed => 0,
319
    #check_if_existing_hold_matches_issuingrules() returns 'InvalidHold' when reservesallowed is 0 for the patron category/itemtype combination
320
            holds_per_record => 1,
320
    $rule1->set({ reservesallowed => 0, holds_per_record => 1, holds_per_day => 1 })->store;
321
            holds_per_day => 1,
321
    my $checkreserve2 = Koha::Hold->check_if_existing_hold_matches_issuingrules($patron1->{'borrowernumber'}, $item1->{'itemnumber'} );
322
        }
322
    is( $checkreserve2, 'InvalidHold', 'Allocating item1 to a bib-reserve is not allowed as the issuingrules reservesallowed is 0 for this patron category/itemtype combination' );
323
    });
323
324
    my $checkreserve2 = $reserve1->matches_circulation_rules({ itemnumber => $item1->{itemnumber} });
324
    #Now change to reservesallowed = 1, holds_per_record = 0, holds_per_day = 1
325
    is( $checkreserve2, 'InvalidHold', 'Reserves allowed is 0' );
325
    $rule1->set({ reservesallowed => 1, holds_per_record => 0, holds_per_day => 1 })->store;
326
326
    my $checkreserve3 = Koha::Hold->check_if_existing_hold_matches_issuingrules($patron1->{'borrowernumber'}, $item1->{'itemnumber'} );
327
    Koha::CirculationRules->set_rules({
327
    is( $checkreserve3, 'InvalidHold', 'Allocating item1 to a bib-reserve is not allowed as the issuingrules holds_per_record is set to 0 for this patron category/itemtype combination' );
328
        branchcode => $branchcode,
328
329
        categorycode => $categorycode,
329
   #Now change to reservesallowed = 1, holds_per_record = 1, holds_per_day = 0
330
        itemtype => $itemtype1,
330
   $rule1->set({ reservesallowed => 1, holds_per_record => 1, holds_per_day => 0 })->store;
331
        rules => {
331
   my $checkreserve4 = Koha::Hold->check_if_existing_hold_matches_issuingrules($patron1->{'borrowernumber'}, $item1->{'itemnumber'} );
332
            reservesallowed => 1,
332
   is( $checkreserve4, 'InvalidHold', 'Allocating item1 to a bib-reserve is not allowed as the issuingrules holds_per_record is set to0 for this patron category/itemtype combination' );
333
            holds_per_record => 0,
333
334
            holds_per_day => 1,
334
   #Now change to reservesallowed = 1, holds_per_record = 1, holds_per_day = 1 and confirm 'OK' is returned
335
        }
335
   $rule1->set({ reservesallowed => 1, holds_per_record => 1, holds_per_day => 1 })->store;
336
    });
336
   my $checkreserve5 = Koha::Hold->check_if_existing_hold_matches_issuingrules($patron1->{'borrowernumber'}, $item1->{'itemnumber'} );
337
    my $checkreserve3 = $reserve1->matches_circulation_rules({ itemnumber => $item1->{itemnumber} });
337
   is( $checkreserve5, 'OK', 'Allocating item2 to a bib-reserve is allowed as there is no specific issuingrule for this patron category/itemtype combination and so we default to the all patron category/all item type rule which allows reserves' );
338
    is( $checkreserve3, 'InvalidHold', 'Holds per record is 0' );
338
339
339
   #Create a default rule (patron categories: ALL, itemtypes: ALL)
340
    Koha::CirculationRules->set_rules({
340
   my $rule3 = Koha::IssuingRule->new({
341
        branchcode => $branchcode,
341
       branchcode => $branchcode,
342
        categorycode => $categorycode,
342
       categorycode => '*',
343
        itemtype => $itemtype1,
343
       itemtype => '*',
344
        rules => {
344
       reservesallowed => 1,
345
            reservesallowed => 1,
345
       holds_per_record => 1,
346
            holds_per_record => 1,
346
       holds_per_day => 1,
347
            holds_per_day => 0,
347
    })->store;
348
        }
348
349
    });
349
    #Check that when no specific patron category/item type issuingrule combo exists we revert to using the default ALL categories/ALL
350
    my $checkreserve4 = $reserve1->matches_circulation_rules({ itemnumber => $item1->{itemnumber} });
350
    #itemtypes issuingrule. When generic rule is reservesallowed, holds_per_record and holds_per_day = 1 then 'OK' is returned
351
   is( $checkreserve4, 'InvalidHold', 'Holds per day is 0' );
351
    my $checkreserve6 = Koha::Hold->check_if_existing_hold_matches_issuingrules($patron1->{'borrowernumber'}, $item2->{'itemnumber'} );
352
352
    is( $checkreserve6, 'OK', 'Allocating item2 to a bib-reserve is allowed as there is no specific issuingrule for this patron category/itemtype combination and so we default to the all patron category/all item type rule which allows reserves' );
353
    Koha::CirculationRules->set_rules({
353
354
        branchcode => $branchcode,
354
    #When default rule is reservesallowed = 0, holds_per_record = 1, holds_per_day = 1 then 'InvalidHold is returned
355
        categorycode => $categorycode,
355
    $rule3->set({ reservesallowed => 0, holds_per_record => 1, holds_per_day => 1 })->store;
356
        itemtype => $itemtype1,
356
    my $checkreserve7 = Koha::Hold->check_if_existing_hold_matches_issuingrules($patron1->{'borrowernumber'}, $item2->{'itemnumber'} );
357
        rules => {
357
    is( $checkreserve7, 'InvalidHold', 'Allocating item2 to a bib-reserve is not allowed as there is no specific issuingrule for this patron category/itemtype combination and so we default to the all patron category/all item type rule which doesnt allows reserves as reservesallowed is 0' );
358
            reservesallowed => 1,
358
359
            holds_per_record => 1,
359
    #When default rule is reservesallowed = 1, holds_per_record = 0, holds_per_day = 1 then 'InvalidHold' is returned
360
            holds_per_day => 1,
360
    $rule3->set({ reservesallowed => 1, holds_per_record => 0, holds_per_day => 1 })->store;
361
        }
361
    my $checkreserve8 = Koha::Hold->check_if_existing_hold_matches_issuingrules($patron1->{'borrowernumber'}, $item2->{'itemnumber'} );
362
    });
362
    is( $checkreserve8, 'InvalidHold', 'Allocating item2 to a bib-reserve is not allowed as there is no specific issuingrule for this patron category/itemtype combination and so we default to the all patron category/all item type rule which doesnt allows reserves as holds_per_record is 0' );
363
    my $checkreserve5 = $reserve1->matches_circulation_rules({ itemnumber => $item1->{itemnumber} });
363
364
   is( $checkreserve5, 'OK', 'Hold is allowed, item allocated to hold' );
364
    #When default rule is reservesallowed = 1, holds_per_record = 1, holds_per_day = 0 then 'InvalidHold' is returned
365
365
    $rule3->set({ reservesallowed => 1, holds_per_record => 1, holds_per_day => 0 })->store;
366
    #Check that when no specific patron category/item type circulation rule combo exists we revert to using the default ALL categories/ALL
366
    my $checkreserve9 = Koha::Hold->check_if_existing_hold_matches_issuingrules($patron1->{'borrowernumber'}, $item2->{'itemnumber'} );
367
    my $reserveid2 = AddReserve({
367
    is( $checkreserve9, 'InvalidHold', 'Allocating item2 to a bib-reserve is not allowed as there is no specific issuingrule for this patron category/itemtype combination and so we default to the all patron category/all item type rule which doesnt allows reserves as holds_per_day is 0' );
368
        branchcode => $branchcode,
369
        borrowernumber => $patron->{borrowernumber},
370
        biblionumber => $biblionumber,
371
    });
372
    my $reserve2 = Koha::Holds->find($reserveid2);
373
374
    Koha::CirculationRules->set_rules({
375
        branchcode => undef,
376
        categorycode => undef,
377
        itemtype => undef,
378
        rules => {
379
            reservesallowed => 0,
380
            holds_per_record => 1,
381
            holds_per_day => 1,
382
        }
383
    });
384
    my $checkreserve6 = $reserve2->matches_circulation_rules({ itemnumber => $item2->{itemnumber} });
385
    is( $checkreserve6, 'InvalidHold', 'Reserves allowed is 0' );
386
387
    Koha::CirculationRules->set_rules({
388
        branchcode => undef,
389
        categorycode => undef,
390
        itemtype => undef,
391
        rules => {
392
            reservesallowed => 1,
393
            holds_per_record => 0,
394
            holds_per_day => 1,
395
        }
396
    });
397
    my $checkreserve7 = $reserve2->matches_circulation_rules({ itemnumber => $item2->{itemnumber} });
398
    is( $checkreserve7, 'InvalidHold', 'Holds per record is 0' );
399
400
    Koha::CirculationRules->set_rules({
401
        branchcode => undef,
402
        categorycode => undef,
403
        itemtype => undef,
404
        rules => {
405
            reservesallowed => 1,
406
            holds_per_record => 1,
407
            holds_per_day => 0,
408
        }
409
    });
410
    my $checkreserve8 = $reserve2->matches_circulation_rules({ itemnumber => $item2->{itemnumber} });
411
    is( $checkreserve8, 'InvalidHold', 'Holds per day is 0' );
412
413
    Koha::CirculationRules->set_rules({
414
        branchcode => undef,
415
        categorycode => undef,
416
        itemtype => undef,
417
        rules => {
418
            reservesallowed => 1,
419
            holds_per_record => 1,
420
            holds_per_day => 1,
421
        }
422
    });
423
    my $checkreserve9 = $reserve2->matches_circulation_rules({ itemnumber => $item2->{itemnumber} });
424
    is( $checkreserve9, 'OK', 'Hold is allowed, item allocated to hold' );
368
425
369
    $schema->storage->txn_rollback;
426
    $schema->storage->txn_rollback;
370
};
427
};
(-)a/t/db_dependent/Reserves.t (-61 / +126 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 65;
20
use Test::More tests => 67;
21
use Test::MockModule;
21
use Test::MockModule;
22
use Test::Warn;
22
use Test::Warn;
23
23
Lines 532-544 AddReserve( Link Here
532
        priority       => 1,
532
        priority       => 1,
533
    }
533
    }
534
);
534
);
535
535
my (undef, $canres, undef) = CheckReserves($item->itemnumber);
536
my (undef, $canres, undef) = CheckReserves($item->itemnumber);
536
537
537
is( CanReserveBeCanceledFromOpac(), undef,
538
is( CanReserveBeCanceledFromOpac(), undef,
538
    'CanReserveBeCanceledFromOpac should return undef if called without any parameter'
539
    'CanReserveBeCanceledFromOpac should return undef if called without any parameter'
539
);
540
);
540
is(
541
is(
541
    CanReserveBeCanceledFromOpac( $canres->{resserve_id} ),
542
    CanReserveBeCanceledFromOpac( $canres->{reserve_id} ),
542
    undef,
543
    undef,
543
    'CanReserveBeCanceledFromOpac should return undef if called without the reserve_id'
544
    'CanReserveBeCanceledFromOpac should return undef if called without the reserve_id'
544
);
545
);
Lines 727-793 MoveReserve( $item->itemnumber, $borrowernumber ); Link Here
727
is( $status, 'Reserved', 'MoveReserve did not fill future hold of 3 days');
728
is( $status, 'Reserved', 'MoveReserve did not fill future hold of 3 days');
728
$dbh->do('DELETE FROM reserves', undef, ($bibnum));
729
$dbh->do('DELETE FROM reserves', undef, ($bibnum));
729
730
730
731
#Test bug 23172. Check when returning an item that any patron category/item type combinations that forbid reservation are skipped over when allocating the item to a bib-level hold
731
732
$dbh->do('DELETE FROM circulation_rules');
732
733
734
735
#Test bug 23172. Check when returning an item that any patron category/item type combinations that forbid reservation are skipped over
736
#when allocating the item to a bib-level hold
737
$dbh->do('DELETE FROM issuingrules');
738
739
#Create two new patrons
740
my $patronnumcat1 = Koha::Patron->new({branchcode => $branch_1, categorycode => $category_1})->store->borrowernumber;
741
my $patronnumcat2 = Koha::Patron->new({branchcode => $branch_1, categorycode => $category_2})->store->borrowernumber;
742
743
#Create a new biblio record
744
my $bibnum3 = $builder->build_sample_biblio({frameworkcode => $frameworkcode})->biblionumber;
745
733
746
#Create a second item type
734
#Create a second item type
747
my $itemtype2 = $builder->build({ source => 'Itemtype', value => { notforloan => undef } } )->{itemtype};
735
my $itemtype2 = $builder->build({ source => 'Itemtype', value => { notforloan => undef } } )->{itemtype};
748
736
749
# Create an item from new itemtype
750
my ( $item_bibnum2, $item_bibitemnum2, $itemnumber2 ) = AddItem(
751
    {   homebranch    => $branch_1,
752
        holdingbranch => $branch_1,
753
        itype         => $itemtype2,
754
        barcode       => 'bug23172_CPL'
755
    },
756
    $bibnum3
757
);
758
759
#Make a general All patron category/all item type rule
737
#Make a general All patron category/all item type rule
760
$dbh->do(
738
Koha::CirculationRules->set_rules(
761
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_day, holds_per_record)
739
    {
762
      VALUES (?, ?, ?, ?, ?, ?)},
740
        branchcode   => undef,
763
    {},
741
        categorycode => undef,
764
    '*', '*', '*', 25, 1, 1
742
        itemtype     => undef,
743
        rules        => {
744
            reservesallowed => 25,
745
            holds_per_record => 1,
746
            holds_per_day => 1,
747
        }
748
    }
765
);
749
);
766
750
767
#When patron category = $category_1 and itemtype = $itemtype1 then reservesallowed, holds_per_day and holds_per_record are 0
751
#When patron category = $category_1 and itemtype = $itemtype2 then reservesallowed, holds_per_day and holds_per_record are 0
768
$dbh->do(
752
Koha::CirculationRules->set_rules(
769
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_day, holds_per_record)
753
    {
770
     VALUES (?, ?, ?, ?, ?, ?)},
754
        branchcode   => $branch_1,
771
    {},
755
        categorycode => $category_1,
772
    $category_1, $branch_1, $itemtype2, 0, 1, 1
756
        itemtype     => $itemtype2,
757
        rules        => {
758
            reservesallowed => 0,
759
            holds_per_record => 0,
760
            holds_per_day => 0,
761
        }
762
    }
773
);
763
);
774
764
775
#When patron category = $category_2 and itemtype = $itemtype2 then reservesallowed, holds_per_day and holds_per_record are 1
765
#When patron category = $category_2 and itemtype = $itemtype2 then reservesallowed, holds_per_day and holds_per_record are 1
776
$dbh->do(
766
Koha::CirculationRules->set_rules(
777
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_day, holds_per_record)
767
    {
778
     VALUES (?, ?, ?, ?, ?, ?)},
768
        branchcode   => $branch_1,
779
    {},
769
        categorycode => $category_2,
780
    $category_2, $branch_1, $itemtype2, 1, 1, 1
770
        itemtype     => $itemtype2,
771
        rules        => {
772
            reservesallowed => 1,
773
            holds_per_record => 1,
774
            holds_per_day => 1,
775
        }
776
    }
781
);
777
);
782
778
779
#When patron category = $category_1 and itemtype = $itemtype2 AND different branch, then reservesallowed, holds_per_day and holds_per_record are 0
780
Koha::CirculationRules->set_rules(
781
    {
782
        branchcode   => $branch_2,
783
        categorycode => $category_1,
784
        itemtype     => $itemtype2,
785
        rules        => {
786
            reservesallowed => 0,
787
            holds_per_record => 0,
788
            holds_per_day => 0,
789
        }
790
    }
791
);
792
793
#Create a new biblio record
794
my $bibnum3 = $builder->build_sample_biblio({frameworkcode => $frameworkcode})->biblionumber;
795
796
# Create an item from new itemtype
797
my $item2 = $builder->build_sample_item({
798
    homebranch => $branch_1,
799
    holdingbranch => $branch_1,
800
    itype => $itemtype2,
801
    barcode => 'bug23172_CPL',
802
    biblionumber => $bibnum3
803
});
804
805
#Create two new patrons
806
my $patronnumcat1 = Koha::Patron->new({branchcode => $branch_1, categorycode => $category_1})->store->borrowernumber;
807
my $patronnumcat2 = Koha::Patron->new({branchcode => $branch_1, categorycode => $category_2})->store->borrowernumber;
808
my $patronnumcat3 = Koha::Patron->new({branchcode => $branch_2, categorycode => $category_1})->store->borrowernumber;
809
783
#Remove existing reserves
810
#Remove existing reserves
784
$dbh->do("DELETE FROM reserves");
811
$dbh->do("DELETE FROM reserves");
785
812
786
#Create Bib-level hold for borrower who has a patron category of $category_2
787
my $reserveid2 = AddReserve($branch_1,  $patronnumcat2, $bibnum3);
788
789
#Bib-level hold for borrower who has a patron category of $category_1
813
#Bib-level hold for borrower who has a patron category of $category_1
790
my $reserveid1 = AddReserve($branch_1,  $patronnumcat1, $bibnum3 );
814
my $reserveid1 = AddReserve({
815
    branchcode => $branch_1,
816
    borrowernumber => $patronnumcat1,
817
    biblionumber => $bibnum3
818
});
819
820
#Create Bib-level hold for borrower who has a patron category of $category_2
821
my $reserveid2 = AddReserve({
822
    branchcode => $branch_1,
823
    borrowernumber => $patronnumcat2,
824
    biblionumber => $bibnum3
825
});
791
826
792
#Check bib-level hold priority and confirm hold made by patronnumcat1 (who fits into issuingrule with reserveallowed = 0) has first priority
827
#Check bib-level hold priority and confirm hold made by patronnumcat1 (who fits into issuingrule with reserveallowed = 0) has first priority
793
my $reserve1 = Koha::Holds->find($reserveid1);
828
my $reserve1 = Koha::Holds->find($reserveid1);
Lines 796-822 is( $reserve1->priority, 1, 'patronnumcat1 reserve is first priority'); Link Here
796
my $reserve2 = Koha::Holds->find($reserveid2);
831
my $reserve2 = Koha::Holds->find($reserveid2);
797
is( $reserve2->priority, 2, 'patronnumcat2 reserve is second priority');
832
is( $reserve2->priority, 2, 'patronnumcat2 reserve is second priority');
798
833
799
#Return the item
834
#Test with ReservesControlBranch system preference set to ItemHomeLibrary
835
t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary');
836
837
# Reserve 1 should be skipped because the circ rule for that patron's category does not allow reserves
800
(undef, $messages, undef, undef) = AddReturn('bug23172_CPL', $branch_1);
838
(undef, $messages, undef, undef) = AddReturn('bug23172_CPL', $branch_1);
801
839
802
#First priority hold is skipped as issuingrule is checked and the first hold does not respect issuingrules (as one of the three fields: reservesallowed, holds_per_day is 0) therefore not allocating item to this bib-level hold
840
#First priority hold is skipped as issuingrule is checked and the first hold does not respect issuingrules (as one of the three fields: reservesallowed, holds_per_day is 0) therefore not allocating item to this bib-level hold
803
is( $messages->{ResFound}->{borrowernumber}, $patronnumcat2,'Skip allocating item to first priority hold as it does not respect issuingrules instead allocate to next valid hold (bug 23172)');
841
is( $messages->{ResFound}->{borrowernumber}, $patronnumcat2,'First priority hold is skipped because circulation rules disallow holds for this patron category, so item is allocated to next hold.');
804
842
805
#Remove and re-add the issuing rule that prevented patronnumcat1 bib-level hold from being allocated upon item return making reservesallowed, holds_per_day and holds_per_record > 0
843
#Remove existing reserves
806
$dbh->do(q{DELETE FROM issuingrules WHERE categorycode = ? AND branchcode = ? AND itemtype = ?},
844
$dbh->do("DELETE FROM reserves");
807
        {},
845
808
        $category_1, $branch_1, $itemtype2
846
#Bib-level hold for borrower who has a patron category of $category_1
809
);
847
my $reserveid3 = AddReserve({
810
$dbh->do(
848
    branchcode => $branch_1,
811
   q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_day, holds_per_record)
849
    borrowernumber => $patronnumcat3,
812
    VALUES (?, ?, ?, ?, ?, ?)},
850
    biblionumber => $bibnum3
813
   {},
851
});
814
   $category_1, $branch_1, $itemtype2, 1, 1, 1
852
853
#Create Bib-level hold for borrower who has a patron category of $category_2
854
my $reserveid4 = AddReserve({
855
    branchcode => $branch_1,
856
    borrowernumber => $patronnumcat2,
857
    biblionumber => $bibnum3
858
});
859
860
#Test with ReservesControlBranch system preference set to PatronLibrary
861
t::lib::Mocks::mock_preference('ReservesControlBranch', 'PatronLibrary');
862
863
# Reserve 1 should be skipped because the circ rule for that patron's library does not allow reserves
864
(undef, $messages, undef, undef) = AddReturn('bug23172_CPL', $branch_1);
865
866
#First priority hold is skipped as issuingrule is checked and the first hold does not respect issuingrules (as one of the three fields: reservesallowed, holds_per_day is 0) therefore not allocating item to this bib-level hold
867
is( $messages->{ResFound}->{borrowernumber}, $patronnumcat2,'First priority hold is skipped because circulation rules disallow holds for this branch, so item is allocated to next hold.');
868
869
# Update the circulation rule that prevented patronnumcat3 bib-level hold from being allocated upon item return making reservesallowed, holds_per_day and holds_per_record > 0
870
Koha::CirculationRules->set_rules(
871
    {
872
        branchcode   => $branch_2,
873
        categorycode => $category_1,
874
        itemtype     => $itemtype2,
875
        rules        => {
876
            reservesallowed => 1,
877
            holds_per_record => 1,
878
            holds_per_day => 1,
879
        }
880
    }
815
);
881
);
816
882
817
#Return the item again and notice this time it is allocated to the bib-level hold made by patronnumcat1
883
#Return the item again and notice this time it is allocated to the bib-level hold made by patronnumcat1
818
(undef, $messages, undef, undef) = AddReturn('bug23172_CPL', $branch_1);
884
(undef, $messages, undef, undef) = AddReturn('bug23172_CPL', $branch_1);
819
is( $messages->{ResFound}->{borrowernumber}, $patronnumcat1,'Skip allocating item to first priority hold as it does not respect issuingrules instead allocate to next valid hold (bug 23172)');
885
is( $messages->{ResFound}->{borrowernumber}, $patronnumcat3,'Skip allocating item to first priority hold as it does not respect issuingrules instead allocate to next valid hold (bug 23172)');
820
886
821
$cache->clear_from_cache("MarcStructure-0-$frameworkcode");
887
$cache->clear_from_cache("MarcStructure-0-$frameworkcode");
822
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
888
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
823
- 

Return to bug 23172