Bug 35211: Separate group holdings into individual tabs

Added SeparateHoldingsByGroup system preference
Adds new tabs to Holdings table if preference is enabled
Separates by library groups

Test Plan:
1. Apply patch, restart_all, updatedatabase
2. Koha Administration -> System preferences -> SeparateHoldingsByGroup
3. Change to "Separate holdings by library group in subsequent tabs..." and Save
4. Koha Administration -> Library Groups
5. Create multiple library groups and check the 'Use for staff search groups' box.
6. Add your logged in library to each group and other libraries to each group.
7. Do catalog searches where the location of the item is a library in a library group
8. Notice tabs in the Holdings table for each library group if it contains a library that has the item

Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Eric Garcia 2025-07-09 14:50:32 +00:00 committed by Lucas Gass
parent 39ca6bab0c
commit 08045c8009
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
6 changed files with 130 additions and 2 deletions

View File

@ -60,6 +60,8 @@ use Koha::Reviews;
use Koha::SearchEngine::Search;
use Koha::SearchEngine::QueryBuilder;
use Koha::Serial::Items;
use Koha::Library::Group;
use Koha::Library::Groups;
my $query = CGI->new();
@ -336,6 +338,51 @@ if ( C4::Context->preference('SeparateHoldings') ) {
$items_to_display->search( { $SeparateHoldingsBranch => { '!=' => C4::Context->userenv->{branch} } } )->count;
$template->param( other_holdings_count => $other_holdings_count );
}
if ( C4::Context->preference('SeparateHoldingsByGroup') ) {
my $branchcode = C4::Context->userenv->{branch};
my @all_search_groups = Koha::Library::Groups->get_search_groups( { interface => 'staff' } );
my @lib_groups;
my %branchcode_hash;
my %holdings_count;
foreach my $search_group (@all_search_groups) {
while ( my $group = $search_group->next ) {
my @all_libs = $group->all_libraries;
# Check if library is in group
if ( grep { $_->branchcode eq $branchcode } @all_libs ) {
# Get other libraries in group
my @other_libs = grep { $_->branchcode ne $branchcode } @all_libs;
my @libs_branchcodes;
foreach my $lib (@other_libs) {
push @libs_branchcodes, $lib->branchcode;
}
# Push logged in branchcode
push @libs_branchcodes, $branchcode;
# Build group branchcode hash
$branchcode_hash{ $group->id } = \@libs_branchcodes;
my $group_holdings_count =
$items_to_display->search( { homebranch => { '-in' => \@libs_branchcodes } } )->count;
$holdings_count{ $group->id } = $group_holdings_count;
push @lib_groups, $group;
}
}
}
$template->param(
lib_groups => \@lib_groups,
branchcodes => \%branchcode_hash,
holdings_count => \%holdings_count,
);
}
$template->param(
count => $all_items->count, # FIXME 'count' is used in catalog-strings.inc
# But it's not a meaningful variable, we should rename it there

View File

@ -0,0 +1,22 @@
use Modern::Perl;
use Koha::Installer::Output qw(say_warning say_success say_info);
return {
bug_number => "35211",
description => "",
up => sub {
my ($args) = @_;
my ( $dbh, $out ) = @$args{qw(dbh out)};
# Do you stuffs here
$dbh->do(
q{
INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
VALUES ('SeparateHoldingsByGroup',NULL,'','Separate current branch holdings and holdings from libraries in the same group','YesNo')
}
);
# Other information
say_success( $out, "Added new system preference 'SeparateHoldingsByGroup'" );
},
};

View File

@ -737,6 +737,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
('SendAllEmailsTo','',NULL,'All emails will be redirected to this email if it is not empty','free'),
('SeparateHoldings','0',NULL,'Separate current branch holdings from other holdings','YesNo'),
('SeparateHoldingsBranch','homebranch','homebranch|holdingbranch','Branch used to separate holdings','Choice'),
('SeparateHoldingsByGroup','0',NULL,'Separate current branch holdings and holdings from libraries in the same library groups','YesNo'),
('SerialsDefaultEmailAddress', '', NULL, 'Default email address used as reply-to for notices sent by the serials module.', 'Free'),
('SerialsDefaultReplyTo', '', NULL, 'Default email address that serials notices are sent from.', 'Free'),
('SerialsSearchResultsLimit', '', NULL, 'Serials search results limit', 'integer'),

View File

@ -296,6 +296,17 @@
holdings: "[% PROCESS 'build_table' tab="holdings" | collapse | $tojson %]",
otherholdings: "[% PROCESS 'build_table' tab="otherholdings" | collapse | $tojson %]",
};
const branchcodes = {
[% FOREACH key IN branchcodes.keys %]
"[% key | html %]": [
[% FOREACH code IN branchcodes.$key %]
"[% code | html %]"[% UNLESS loop.last %], [% END %]
[% END %]
][% UNLESS loop.last %], [% END %]
[% END %]
};
function build_items_table (tab_id, add_filters, dt_options, drawcallback) {
let table_dt;
@ -321,6 +332,19 @@
}
[% END %]
[% IF Koha.Preference('SeparateHoldingsByGroup') %]
if ( tab_id.includes('group_holdings') ) {
user_colvis[tab_id] = {};
items_table_settings[tab_id] = [% TablesSettings.GetTableSettings('catalogue', 'detail','otherholdings_table','json') | $raw %];
const id = tab_id.replace("group_holdings_", "");
let branch = '[% IF SeparateHoldingsBranch == 'homebranch' %]me.home_library_id[% ELSE %]me.holding_library_id[% END %]';
default_filters[branch] = branchcodes[id];
}
[% END %]
[% IF hidden_count %]
default_filters.lost_status = "0";
[% END %]

View File

@ -301,6 +301,12 @@ Cataloging:
homebranch: 'home library'
holdingbranch: 'holding library'
- "is the logged in user's library. The second tab will contain all other items."
-
- pref: SeparateHoldingsByGroup
choices:
1: Separate
0: "Don't separate"
- "holdings by library group in subsequent tabs that contain items whose home library is the logged in library branch."
-
- pref: AlwaysShowHoldingsTableFilters
choices:
@ -408,4 +414,4 @@ Cataloging:
- "<br/>"
- "All values of repeating tags and subfields will be printed with the given RIS tag."
- "<br/>"
- "Use of TY ( record type ) as a key will <em>replace</em> the default TY with the field value of your choosing."
- "Use of TY ( record type ) as a key will <em>replace</em> the default TY with the field value of your choosing."

View File

@ -337,6 +337,16 @@
<span>Holdings ([% items_to_display_count || 0 | html %])</span>
[% END %]
[% END %]
[% IF Koha.Preference('SeparateHoldingsByGroup') && lib_groups %]
[% FOREACH group IN lib_groups %]
[% IF ( holdings_count.${group.id} > 0 ) %]
[% WRAPPER tab_item tabname="group_holdings_" _ group.id %]
<span>[% group.title | html %] - Group ([% holdings_count.${group.id} | html %])</span>
[% END %]
[% END %]
[% END %]
[% END %]
[% IF Koha.Preference('EnableItemGroups') %]
[% WRAPPER tab_item tabname= "item_groups" %]
<span>Item groups</span>
@ -476,6 +486,16 @@
[% PROCESS items_table tab="otherholdings" %]
[% END # /tab_panel %]
[% END %]
[% IF Koha.Preference('SeparateHoldingsByGroup') && lib_groups %]
[% FOREACH group IN lib_groups %]
[% IF ( holdings_count.${group.id} > 0 ) %]
[% SET group_tab = "group_holdings_" _ group.id %]
[% WRAPPER tab_panel tabname=group_tab %]
[% PROCESS items_table tab=group_tab %]
[% END # /tab_panel %]
[% END %]
[% END %]
[% END %]
[% IF ( MARCNOTES ) %]
[% WRAPPER tab_panel tabname="description" %]
@ -1734,7 +1754,15 @@
var bundle_lost_value = [% Koha.Preference('BundleLostValue') | html %];
[% END %]
let items_tab_ids = [ 'holdings', 'otherholdings' ];
let items_tab_ids = [
'holdings',
'otherholdings'
[% IF Koha.Preference('SeparateHoldingsByGroup') && lib_groups %]
[% FOREACH group IN lib_groups %]
, 'group_holdings_[% group.id | html %]'
[% END %]
[% END %]
];
items_tab_ids.forEach( function( tab_id, index ) {
// Early return if the tab is not shown (ie. no table)