Bugzilla – Attachment 121941 Details for
Bug 15565
Place multiple item-level holds at once for the same record
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 15565: Work in progress, calculating holds remaining
Bug-15565-Work-in-progress-calculating-holds-remai.patch (text/plain), 13.97 KB, created by
Aleisha Amohia
on 2021-06-15 01:50:46 UTC
(
hide
)
Description:
Bug 15565: Work in progress, calculating holds remaining
Filename:
MIME Type:
Creator:
Aleisha Amohia
Created:
2021-06-15 01:50:46 UTC
Size:
13.97 KB
patch
obsolete
>From 81b072736a39c9a067f5a168d4202df47f0f15e4 Mon Sep 17 00:00:00 2001 >From: Aleisha Amohia <aleishaamohia@hotmail.com> >Date: Tue, 15 Jun 2021 13:49:47 +1200 >Subject: [PATCH] Bug 15565: Work in progress, calculating holds remaining > >Not ready for testing! >--- > Koha/Holds.pm | 135 ++++++++++++++++++++++++++++++ > t/db_dependent/Koha/Holds.t | 195 +++++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 329 insertions(+), 1 deletion(-) > >diff --git a/Koha/Holds.pm b/Koha/Holds.pm >index 296f99cb0a..dd9abf8805 100644 >--- a/Koha/Holds.pm >+++ b/Koha/Holds.pm >@@ -153,6 +153,141 @@ sub get_items_that_can_fill { > ); > } > >+=head3 remaining_holds_total >+ >+ my $remaining_holds_total = Koha::Holds->remaining_holds_total({ patron => $patron, biblio => $biblio }); >+ >+Calculates and returns the number of remaining holds a borrower is allowed to place. >+This will be firstly based on the maxreserves system preference, the secondly the reservesallowed circulation rules >+ >+=cut >+ >+sub remaining_holds_total { >+ my ( $self, $params ) = @_; >+ >+ unless ( $params->{patron} ) { >+ # no patron was passed >+ return 0; >+ } >+ >+ my $current_holds_count = $params->{patron}->holds->count; >+ my $holds_allowed_total = C4::Context->preference('maxreserves'); >+ if ( $holds_allowed_total and $current_holds_count >= $holds_allowed_total ) { >+ # patron has more holds than maxreserves system preference >+ return 0; >+ } >+ >+ my $branchcode = C4::Context->preference('ReservesControlBranch'); >+ if ( $params->{biblio} ) { >+ # iterate through every item attached to this biblio. >+ # get the highest reservesallowed value out of these item types. >+ my @items = Koha::Items->search({ biblionumber => $params->{biblio}->biblionumber }); >+ foreach my $item ( @items ) { >+ my $reservesallowed = Koha::CirculationRules->get_effective_rule({ >+ rule_name => 'reservesallowed', >+ categorycode => $params->{patron}->categorycode, >+ itemtype => $item->itemtype, >+ branchcode => $branchcode, >+ }); >+ if ( $reservesallowed and $reservesallowed->rule_value and $reservesallowed->rule_value < $holds_allowed_total ) { >+ # use the lowest value >+ $holds_allowed_total = $reservesallowed->rule_value; >+ } >+ } >+ } else { >+ my $reservesallowed = Koha::CirculationRules->get_effective_rule({ >+ rule_name => 'reservesallowed', >+ categorycode => $params->{patron}->categorycode, >+ itemtype => undef, >+ branchcode => $branchcode, >+ }); >+ if ( $reservesallowed and $reservesallowed->rule_value and $reservesallowed->rule_value < $holds_allowed_total ) { >+ # use the lowest value >+ $holds_allowed_total = $reservesallowed->rule_value; >+ } >+ } >+ my $remaining_holds_count = $holds_allowed_total - $current_holds_count; >+ return $remaining_holds_count; >+} >+ >+=head3 remaining_holds_record >+ >+ my $remaining_holds_record = Koha::Holds->remaining_holds_record({ patron => $patron, biblio => $biblio }); >+ >+Calculates and returns the number of remaining holds a borrower is allowed to place per record. >+This will be based on the holds_per_record circulation rules >+ >+=cut >+ >+sub remaining_holds_record { >+ my ( $self, $params ) = @_; >+ >+ unless ( $params->{patron} or $params->{biblio} ) { >+ # no patron or biblio was passed >+ return 0; >+ } >+ >+ my $current_holds_count = $self->search({ borrowernumber => $params->{patron}->borrowernumber, biblionumber => $params->{biblio}->biblionumber })->count; >+ my $holds_allowed_per_record = 0; >+ >+ my $branchcode = C4::Context->preference('ReservesControlBranch'); >+ my @items = Koha::Items->search({ biblionumber => $params->{biblio}->biblionumber }); >+ foreach my $item ( @items ) { >+ my $holds_per_record = Koha::CirculationRules->get_effective_rule({ >+ rule_name => 'holds_per_record', >+ categorycode => $params->{patron}->categorycode, >+ itemtype => $item->itemtype, >+ branchcode => $branchcode, >+ }); >+ if ( $holds_per_record and $holds_per_record->rule_value and $holds_per_record->rule_value < $holds_allowed_per_record ) { >+ # use the lowest value >+ $holds_allowed_per_record = $holds_per_record->rule_value; >+ } >+ } >+ >+ my $remaining_holds_count = $holds_allowed_per_record - $current_holds_count; >+ return $remaining_holds_count; >+} >+ >+=head3 remaining_holds_today >+ >+ my $remaining_holds_today = Koha::Holds->remaining_holds_today({ patron => $patron, biblio => $biblio }); >+ >+Calculates and returns the number of remaining holds a borrower is allowed to place today. >+This will be based on the holds_per_day circulation rules >+ >+=cut >+ >+sub remaining_holds_today { >+ my ( $self, $params ) = @_; >+ >+ unless ( $params->{patron} or $params->{biblio} ) { >+ # no patron or biblio was passed >+ return 0; >+ } >+ >+ my $current_holds_count = $self->search({ borrowernumber => $params->{patron}->borrowernumber, reservedate => dt_from_string->date })->count; >+ my $holds_allowed_per_day = 0; >+ >+ my $branchcode = C4::Context->preference('ReservesControlBranch'); >+ my @items = Koha::Items->search({ biblionumber => $params->{biblio}->biblionumber }); >+ foreach my $item ( @items ) { >+ my $holds_per_day = Koha::CirculationRules->get_effective_rule({ >+ rule_name => 'holds_per_day', >+ categorycode => $params->{patron}->categorycode, >+ itemtype => $item->itemtype, >+ branchcode => $branchcode, >+ }); >+ if ( $holds_per_day and $holds_per_day->rule_value and $holds_per_day->rule_value < $holds_allowed_per_day ) { >+ # use the lowest value >+ $holds_allowed_per_day = $holds_per_day->rule_value; >+ } >+ } >+ >+ my $remaining_holds_count = $holds_allowed_per_day - $current_holds_count; >+ return $remaining_holds_count; >+} >+ > =head3 type > > =cut >diff --git a/t/db_dependent/Koha/Holds.t b/t/db_dependent/Koha/Holds.t >index 7d19a132f1..b977175bb3 100755 >--- a/t/db_dependent/Koha/Holds.t >+++ b/t/db_dependent/Koha/Holds.t >@@ -19,7 +19,7 @@ > > use Modern::Perl; > >-use Test::More tests => 6; >+use Test::More tests => 9; > use Test::Warn; > > use C4::Circulation; >@@ -500,6 +500,199 @@ subtest 'get_items_that_can_fill' => sub { > > }; > >+subtest 'remaining_holds_total' => sub { >+ plan tests => 3; >+ >+ my $biblio = $builder->build_sample_biblio; >+ my $itype_1 = $builder->build_object({ class => 'Koha::ItemTypes' }); >+ my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, itype => $itype_1->itemtype }); >+ my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, itype => $itype_1->itemtype }); >+ my $item_3 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, itype => $itype_1->itemtype }); >+ my $patron_1 = $builder->build_object({ class => 'Koha::Patrons' }); >+ >+ t::lib::Mocks::mock_userenv({ patron => $patron_1 }); >+ t::lib::Mocks::mock_preference('maxreserves', 4); >+ Koha::CirculationRules->set_rules({ >+ itemtype => $itype_1->itemtype, >+ branchcode => undef, >+ categorycode => $patron_1->categorycode, >+ rules => { >+ reservesallowed => 5, >+ }, >+ }); >+ >+ my $reserve_id_1 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => $item_1->itemnumber, >+ } >+ ); >+ >+ my $reserve_id_2 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => $item_2->itemnumber, >+ } >+ ); >+ >+ my $reserve_id_3 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => $item_3->itemnumber, >+ } >+ ); >+ >+ my $reserve_id_4 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => undef, >+ } >+ ); >+ >+ my $remaining_holds_total = Koha::Holds->remaining_holds_total; >+ is( $remaining_holds_total, 0, "No patron was passed to calculate their holds" ); >+ >+ $remaining_holds_total = Koha::Holds->remaining_holds_total({ patron => $patron_1, biblio => $biblio }); >+ is( $remaining_holds_total, 0, "Patron has reached maxreserves system preference maximum holds" ); >+ >+ t::lib::Mocks::mock_preference('maxreserves', 5); >+ >+ $remaining_holds_total = Koha::Holds->remaining_holds_total({ patron => $patron_1, biblio => $biblio }); >+ is( $remaining_holds_total, 1, "Patron has one more allowed hold based on reservesallowed circulation rule" ); >+}; >+ >+subtest 'remaining_holds_record' => sub { >+ plan tests => 3; >+ >+ my $biblio = $builder->build_sample_biblio; >+ my $itype_1 = $builder->build_object({ class => 'Koha::ItemTypes' }); >+ my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, itype => $itype_1->itemtype }); >+ my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, itype => $itype_1->itemtype }); >+ my $item_3 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, itype => $itype_1->itemtype }); >+ my $patron_1 = $builder->build_object({ class => 'Koha::Patrons' }); >+ >+ t::lib::Mocks::mock_userenv({ patron => $patron_1 }); >+ t::lib::Mocks::mock_preference('maxreserves', 10); >+ Koha::CirculationRules->set_rules({ >+ itemtype => $itype_1->itemtype, >+ branchcode => undef, >+ categorycode => $patron_1->categorycode, >+ rules => { >+ holds_per_record => 3, >+ }, >+ }); >+ >+ my $reserve_id_1 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => $item_1->itemnumber, >+ } >+ ); >+ >+ my $reserve_id_2 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => $item_2->itemnumber, >+ } >+ ); >+ >+ my $reserve_id_3 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => $item_3->itemnumber, >+ } >+ ); >+ >+ my $remaining_holds_record = Koha::Holds->remaining_holds_record; >+ is( $remaining_holds_record, 0, "No patron or biblio passed" ); >+ >+ $remaining_holds_record = Koha::Holds->remaining_holds_record({ patron => $patron_1, biblio => $biblio }); >+ is( $remaining_holds_record, 0, "Patron has reached holds_per_record circulation rule maximum holds" ); >+ >+ Koha::Holds->find( $reserve_id_3 )->delete; >+ >+ $remaining_holds_record = Koha::Holds->remaining_holds_record({ patron => $patron_1, biblio => $biblio }); >+ is( $remaining_holds_record, 1, "Patron has one more allowed hold on this record based on reservesallowed circulation rule" ); >+}; >+ >+subtest 'remaining_holds_today' => sub { >+ plan tests => 3; >+ >+ my $biblio = $builder->build_sample_biblio; >+ my $itype_1 = $builder->build_object({ class => 'Koha::ItemTypes' }); >+ my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, itype => $itype_1->itemtype }); >+ my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, itype => $itype_1->itemtype }); >+ my $item_3 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, itype => $itype_1->itemtype }); >+ my $patron_1 = $builder->build_object({ class => 'Koha::Patrons' }); >+ >+ t::lib::Mocks::mock_userenv({ patron => $patron_1 }); >+ t::lib::Mocks::mock_preference('maxreserves', 10); >+ Koha::CirculationRules->set_rules({ >+ itemtype => $itype_1->itemtype, >+ branchcode => undef, >+ categorycode => $patron_1->categorycode, >+ rules => { >+ holds_per_day => 5, >+ }, >+ }); >+ >+ my $reserve_id_1 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => $item_1->itemnumber, >+ } >+ ); >+ >+ my $reserve_id_2 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => $item_2->itemnumber, >+ } >+ ); >+ >+ my $reserve_id_3 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => $item_3->itemnumber, >+ } >+ ); >+ >+ my $reserve_id_4 = C4::Reserves::AddReserve( >+ { >+ borrowernumber => $patron_1->borrowernumber, >+ biblionumber => $biblio->biblionumber, >+ priority => 1, >+ itemnumber => undef, >+ } >+ ); >+ >+ my $remaining_holds_total = Koha::Holds->remaining_holds_today; >+ is( $remaining_holds_total, 0, "No patron was passed to calculate their holds" ); >+ >+ $remaining_holds_total = Koha::Holds->remaining_holds_today({ patron => $patron_1, biblio => $biblio }); >+ is( $remaining_holds_total, 1, "Patron has one more allowed hold based on holds_per_day circulation rule" ); >+}; >+ > $schema->storage->txn_rollback; > > 1; >-- >2.11.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 15565
:
47527
|
47551
|
47552
|
50068
|
50069
|
50392
|
50393
|
56229
|
56230
|
56231
|
56232
|
56458
|
56510
|
56511
|
56512
|
56513
|
56514
|
56515
|
56517
|
56518
|
56519
|
56520
|
56521
|
56522
|
56523
|
56524
|
61244
|
61245
|
61246
|
61247
|
61248
|
61576
|
61577
|
61578
|
61579
|
61580
|
64590
|
64591
|
64592
|
64593
|
64594
|
66594
|
66595
|
66596
|
66597
|
66598
|
68759
|
68760
|
68761
|
68762
|
68763
|
71643
|
71644
|
71645
|
71646
|
71647
|
71648
|
72644
|
72645
|
72646
|
72647
|
72648
|
72649
|
78242
|
78243
|
78244
|
78245
|
78246
|
78247
|
78248
|
78266
|
78305
|
78417
|
78418
|
78419
|
78420
|
78421
|
78422
|
78423
|
78424
|
78425
|
78426
|
78712
|
78713
|
78714
|
78715
|
78716
|
78717
|
78718
|
78719
|
78720
|
78815
|
78816
|
78817
|
78818
|
78819
|
78820
|
78821
|
78822
|
78823
|
81419
|
81420
|
81421
|
81422
|
81423
|
81424
|
81425
|
81426
|
81427
|
81431
|
81449
|
81570
|
81571
|
81572
|
81573
|
81574
|
81575
|
81576
|
81577
|
81578
|
81579
|
81580
|
81581
|
82205
|
82206
|
82207
|
82208
|
82209
|
82210
|
82211
|
82212
|
82213
|
82214
|
82215
|
82216
|
82220
|
82221
|
83331
|
83332
|
83333
|
83334
|
83335
|
83336
|
83337
|
83338
|
83339
|
83340
|
83341
|
83342
|
83378
|
83380
|
83381
|
84541
|
84542
|
84543
|
84544
|
84545
|
84546
|
84547
|
84548
|
84549
|
84550
|
84551
|
84552
|
84553
|
87979
|
87980
|
87981
|
87982
|
87983
|
87984
|
87985
|
87986
|
87987
|
87988
|
87989
|
87990
|
87991
|
117128
|
117129
|
117130
|
117131
|
117132
|
117133
|
120365
|
120366
|
120367
|
120639
|
120640
|
120641
|
121941
|
122098
|
162071
|
162072
|
162073
|
162074
|
163052
|
163053
|
163054
|
163055
|
163092
|
163093
|
166005
|
166006
|
166007
|
166008
|
166009