From 11b7a990a88b1a69a6ff421e01f0062752c902b1 Mon Sep 17 00:00:00 2001 From: Emmi Takkinen Date: Wed, 8 Sep 2021 08:58:14 +0300 Subject: [PATCH 3/4] Bug 9525: Add option to define float groups and rules for float Bug 22284 introduced ability to create hold groups. We should have ability to create float groups in same manner. This patch adds checkbox "Is local float group" to group creation feature and new return policy "Item floats by librarygroup". To test: 1. Add new float group and some libraries to it. 2. From circulation and fine rules, set default return policy as "Item floats by library group". 3. Check out an item for a patron. 4. Set library as one that belongs in the same float group. 5. Check in the item. => Observe that notice for transfer doesn't pop up. 6. Check out again. 7. This time set library as one that doen's belong in the same float group. 8. Check in. => Observe that notice for transfer pops up. Experiment this feature by changing return policy per library, item type etc. Also prove t/db_dependent/Koha/Libraries.t Sponsored-by: Koha-Suomi Oy Signed-off-by: Lisette Scheer --- C4/Circulation.pm | 13 +++++- Koha/Library.pm | 42 +++++++++++++++++++ admin/library_groups.pl | 4 ++ circ/returns.pl | 6 ++- .../prog/en/modules/admin/library_groups.tt | 27 ++++++++++-- .../prog/en/modules/admin/smart-rules.tt | 10 +++++ t/db_dependent/Koha/Libraries.t | 32 ++++++++++++++ 7 files changed, 127 insertions(+), 7 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index aa858a855b..7c2e6dc5a5 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2099,8 +2099,19 @@ sub AddReturn { # full item data, but no borrowernumber or checkout info (no issue) my $hbr = Koha::CirculationRules->get_return_branch_policy($item); + # check if returnbranch and homebranch belong to the same float group + my $validate_float = Koha::Libraries->find( $item->homebranch )->validate_float_sibling({ branchcode => $branch }); # get the proper branch to which to return the item - my $returnbranch = $hbr ne 'noreturn' ? $item->$hbr : $branch; + my $returnbranch; + if($hbr eq 'noreturn'){ + $returnbranch = $branch; + }elsif($hbr eq 'returnbylibrarygroup'){ + # if library isn't in same the float group, transfer item to homebranch + $hbr = 'homebranch'; + $returnbranch = $validate_float ? $branch : $item->$hbr; + }else{ + $returnbranch = $item->$hbr; + } # if $hbr was "noreturn" or any other non-item table value, then it should 'float' (i.e. stay at this branch) my $transfer_trigger = $hbr eq 'homebranch' ? 'ReturnToHome' : $hbr eq 'holdingbranch' ? 'ReturnToHolding' : undef; diff --git a/Koha/Library.pm b/Koha/Library.pm index 20db2ca632..68b76d6051 100644 --- a/Koha/Library.pm +++ b/Koha/Library.pm @@ -333,6 +333,48 @@ sub opac_info { }); } +=head3 get_float_group_libraries + +Return all libraries belonging to the same float group + +=cut + +sub get_float_libraries { + my ( $self ) = @_; + + my $library_groups = $self->library_groups; + my @float_libraries; + + while ( my $library_group = $library_groups->next ) { + my $root = Koha::Library::Groups->get_root_ancestor({id => $library_group->id}); + if($root->ft_local_float_group) { + push @float_libraries, $root->all_libraries; + } + } + + my %seen; + @float_libraries = + grep { !$seen{ $_->id }++ } @float_libraries; + + return Koha::Libraries->search({ branchcode => { '-in' => [ keys %seen ] } }); +} + +=head3 validate_float_sibling + +Return if given library is a valid float group member + +=cut + +sub validate_float_sibling { + my ( $self, $params ) = @_; + + return 1 if $params->{branchcode} eq $self->id; + + my $branchcode = $params->{branchcode}; + return $self->get_float_libraries->search( { branchcode => $branchcode } ) + ->count > 0; +} + =head2 Internal methods =head3 _type diff --git a/admin/library_groups.pl b/admin/library_groups.pl index 5284a881f4..b0ab345b01 100755 --- a/admin/library_groups.pl +++ b/admin/library_groups.pl @@ -50,6 +50,7 @@ if ( $action eq 'add' ) { my $ft_search_groups_opac = $cgi->param('ft_search_groups_opac') || 0; my $ft_search_groups_staff = $cgi->param('ft_search_groups_staff') || 0; my $ft_local_hold_group = $cgi->param('ft_local_hold_group') || 0; + my $ft_local_float_group = $cgi->param('ft_local_float_group') || 0; if ( !$branchcode && Koha::Library::Groups->search( { title => $title } )->count() ) { $template->param( error_duplicate_title => $title ); @@ -65,6 +66,7 @@ if ( $action eq 'add' ) { ft_search_groups_opac => $ft_search_groups_opac, ft_search_groups_staff => $ft_search_groups_staff, ft_local_hold_group => $ft_local_hold_group, + ft_local_float_group => $ft_local_float_group, branchcode => $branchcode, } )->store(); @@ -85,6 +87,7 @@ elsif ( $action eq 'edit' ) { my $ft_search_groups_opac = $cgi->param('ft_search_groups_opac') || 0; my $ft_search_groups_staff = $cgi->param('ft_search_groups_staff') || 0; my $ft_local_hold_group = $cgi->param('ft_local_hold_group') || 0; + my $ft_local_float_group = $cgi->param('ft_local_float_group') || 0; if ($id) { my $group = Koha::Library::Groups->find($id); @@ -97,6 +100,7 @@ elsif ( $action eq 'edit' ) { ft_search_groups_opac => $ft_search_groups_opac, ft_search_groups_staff => $ft_search_groups_staff, ft_local_hold_group => $ft_local_hold_group, + ft_local_float_group => $ft_local_float_group, } )->store(); diff --git a/circ/returns.pl b/circ/returns.pl index 2c2bea8aa8..04b23bcb8c 100755 --- a/circ/returns.pl +++ b/circ/returns.pl @@ -298,8 +298,10 @@ if ($barcode) { # make sure return branch respects home branch circulation rules, default to homebranch my $hbr = Koha::CirculationRules->get_return_branch_policy($item); - $returnbranch = $hbr ne 'noreturn' ? $item->$hbr : $userenv_branch; # can be noreturn, homebranch or holdingbranch - + my $validate_float = Koha::Libraries->find( $item->homebranch )->validate_float_sibling({ branchcode => $userenv_branch }); + # get the proper branch to which to return the item + # if library isn't in same the float group, transfer item to homelibrary + $returnbranch = $hbr eq 'noreturn' ? $userenv_branch : $hbr eq 'returnbylibrarygroup' ? $validate_float ? $userenv_branch : $item->homebranch : $item->$hbr; my $materials = $item->materials; my $descriptions = Koha::AuthorisedValues->get_description_by_koha_field({frameworkcode => '', kohafield =>'items.materials', authorised_value => $materials }); $materials = $descriptions->{lib} // $materials; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/library_groups.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/library_groups.tt index 02742b5ab8..f37e6e8503 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/library_groups.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/library_groups.tt @@ -152,6 +152,12 @@ Is local hold group

+

+ +

@@ -216,6 +222,12 @@ Is local hold group

+

+ +

@@ -296,7 +308,8 @@ var ft_search_groups_opac = $(this).data('groupFt_search_groups_opac'); var ft_search_groups_staff = $(this).data('groupFt_search_groups_staff'); var ft_local_hold_group = $(this).data('groupFt_local_hold_group'); - edit_group( id, parent_id, title, description, ft_hide_patron_info, ft_search_groups_opac, ft_search_groups_staff, ft_local_hold_group ); + var ft_local_float_group = $(this).data('groupFt_local_float_group'); + edit_group( id, parent_id, title, description, ft_hide_patron_info, ft_search_groups_opac, ft_search_groups_staff, ft_local_hold_group, ft_local_float_group ); }); $('.delete-group').on('click', function(e) { @@ -332,6 +345,7 @@ $('#add-group-modal-ft_search_groups_opac').prop('checked', false); $('#add-group-modal-ft_search_groups_staff').prop('checked', false); $('#add-group-modal-ft_local_hold_group').prop('checked', false); + $('#add-group-modal-ft_local_float_group').prop('checked', false); if ( parent_id ) { $('#root-group-features-add').hide(); } else { @@ -341,22 +355,24 @@ } - function edit_group( id, parent_id, title, description, ft_hide_patron_info, ft_search_groups_opac, ft_search_groups_staff, ft_local_hold_group ) { + function edit_group( id, parent_id, title, description, ft_hide_patron_info, ft_search_groups_opac, ft_search_groups_staff, ft_local_hold_group, ft_local_float_group ) { $('#edit-group-modal-id').val( id ); $('#edit-group-modal-title').val( title ); $('#edit-group-modal-description').val( description ); - + console.log(ft_local_float_group); if ( parent_id ) { $('#edit-group-modal-ft_hide_patron_info').prop('checked', false); $('#edit-group-modal-ft_search_groups_opac').prop('checked', false); $('#edit-group-modal-ft_search_groups_staff').prop('checked', false); $('#edit-group-modal-ft_local_hold_group').prop('checked', false); + $('#edit-group-modal-ft_local_float_group').prop('checked', false); $('#root-group-features-edit').hide(); } else { $('#edit-group-modal-ft_hide_patron_info').prop('checked', ft_hide_patron_info ? true : false ); $('#edit-group-modal-ft_search_groups_opac').prop('checked', ft_search_groups_opac ? true : false ); $('#edit-group-modal-ft_search_groups_staff').prop('checked', ft_search_groups_staff ? true : false ); $('#edit-group-modal-ft_local_hold_group').prop('checked', ft_local_hold_group ? true : false ); + $('#edit-group-modal-ft_local_float_group').prop('checked', ft_local_float_group ? true : false ); $('#root-group-features-edit').show(); } @@ -412,6 +428,9 @@ [% IF group.ft_local_hold_group %]
  • Is local hold group
  • [% END %] + [% IF group.ft_local_float_group %] +
  • Is local float group
  • + [% END %] [% END %] @@ -429,7 +448,7 @@
  • - + Edit
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt index 593b9dab8e..d3e58b1d54 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt @@ -773,6 +773,13 @@ [% END %] Item floats + [% IF returnbranch.rule_value == 'returnbylibrarygroup' %] + @@ -1325,6 +1332,8 @@ Item returns to issuing branch [% ELSIF returnbranch == 'noreturn' %] Item floats + [% ELSIF returnbranch == 'returnbylibrarygroup'%] + Item floats by library group [% END %] @@ -1377,6 +1386,7 @@ + diff --git a/t/db_dependent/Koha/Libraries.t b/t/db_dependent/Koha/Libraries.t index 86c68fd5c7..419dcbf0da 100755 --- a/t/db_dependent/Koha/Libraries.t +++ b/t/db_dependent/Koha/Libraries.t @@ -331,6 +331,38 @@ subtest 'get_hold_libraries and validate_hold_sibling' => sub { }; +subtest 'get_float_libraries and validate_float_sibling' => sub { + + plan tests => 4; + + $schema->storage->txn_begin; + + my $library1 = $builder->build_object({ class => 'Koha::Libraries' }); + my $library2 = $builder->build_object({ class => 'Koha::Libraries' }); + my $library3 = $builder->build_object({ class => 'Koha::Libraries' }); + my $library4 = $builder->build_object({ class => 'Koha::Libraries' }); + + my $root1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } ); + my $root2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } ); + # Float group 1 + $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library1->branchcode } } ); + $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library2->branchcode } } ); + # Float group 2 + $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library3->branchcode } } ); + $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library4->branchcode } } ); + + my @libraries1 = $library1->get_float_libraries(); + is(scalar @libraries1, '2', '1st float group contains 2 libraries'); + + my @libraries2 = $library3->get_float_libraries(); + is(scalar @libraries2, '2', '2nd float group also contains 2 libraries'); + + ok($library1->validate_float_sibling({ branchcode => $library2->branchcode }), "Library1 and library2 belong in to the same float group."); + ok($library3->validate_float_sibling({ branchcode => $library4->branchcode }), "Library3 and library5 belong in to the same float group."); + + $schema->storage->txn_rollback; +}; + subtest 'outgoing_transfers' => sub { plan tests => 3; -- 2.34.1