diff --git a/catalogue/detail.pl b/catalogue/detail.pl
index f8a1fe447e..cbe0b8abfa 100755
--- a/catalogue/detail.pl
+++ b/catalogue/detail.pl
@@ -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
diff --git a/installer/data/mysql/atomicupdate/bug_35211_separate_holdings_by_group.pl b/installer/data/mysql/atomicupdate/bug_35211_separate_holdings_by_group.pl
new file mode 100755
index 0000000000..bc41cec5c1
--- /dev/null
+++ b/installer/data/mysql/atomicupdate/bug_35211_separate_holdings_by_group.pl
@@ -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'" );
+ },
+};
diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql
index 5dd31ccbc4..034f48ed3f 100644
--- a/installer/data/mysql/mandatory/sysprefs.sql
+++ b/installer/data/mysql/mandatory/sysprefs.sql
@@ -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'),
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc
index d74198bdaf..569ee71189 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc
@@ -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 %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref
index 9c62cae068..33043ed714 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref
@@ -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:
- "
"
- "All values of repeating tags and subfields will be printed with the given RIS tag."
- "
"
- - "Use of TY ( record type ) as a key will replace the default TY with the field value of your choosing."
\ No newline at end of file
+ - "Use of TY ( record type ) as a key will replace the default TY with the field value of your choosing."
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt
index 061b5d39a1..8c678223aa 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt
@@ -337,6 +337,16 @@
Holdings ([% items_to_display_count || 0 | html %])
[% 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 %]
+ [% group.title | html %] - Group ([% holdings_count.${group.id} | html %])
+ [% END %]
+ [% END %]
+ [% END %]
+ [% END %]
+
[% IF Koha.Preference('EnableItemGroups') %]
[% WRAPPER tab_item tabname= "item_groups" %]
Item groups
@@ -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)