From 9931137fd6dfa1867c978f0b07244fdadb661da3 Mon Sep 17 00:00:00 2001 From: Matt Blenkinsop Date: Tue, 29 Oct 2024 16:48:28 +0000 Subject: [PATCH] Bug 38290: Add library group limit classes --- Koha/Acquisition/Bookseller.pm | 27 +++++- Koha/Acquisition/Booksellers.pm | 18 +++- Koha/Object/Limit/LibraryGroup.pm | 82 ++++++++++++++++ Koha/Objects/Limit/LibraryGroup.pm | 144 +++++++++++++++++++++++++++++ 4 files changed, 269 insertions(+), 2 deletions(-) create mode 100644 Koha/Object/Limit/LibraryGroup.pm create mode 100644 Koha/Objects/Limit/LibraryGroup.pm diff --git a/Koha/Acquisition/Bookseller.pm b/Koha/Acquisition/Bookseller.pm index 3ae36c13f0e..9273b735747 100644 --- a/Koha/Acquisition/Bookseller.pm +++ b/Koha/Acquisition/Bookseller.pm @@ -25,7 +25,7 @@ use Koha::Subscriptions; use C4::Contract qw( GetContracts ); -use base qw( Koha::Object::Mixin::AdditionalFields Koha::Object ); +use base qw( Koha::Object::Mixin::AdditionalFields Koha::Object Koha::Object::Limit::LibraryGroup ); =head1 NAME @@ -35,6 +35,18 @@ Koha::Acquisition::Bookseller Object class =head2 Class methods +=head3 store + +=cut + +sub store { + my ($self) = @_; + + $self->set_lib_group_visibility() if $self->lib_group_visibility; + $self = $self->SUPER::store(); + return $self; +} + =head3 baskets my $vendor = Koha::Acquisition::Booksellers->find( $id ); @@ -222,6 +234,19 @@ sub to_api_mapping { }; } +=head3 _library_group_visibility_parameters + +Configure library group limits + +=cut + +sub _library_group_visibility_parameters { + return { + class => "Aqbookseller", + visibility_column => "lib_group_visibility", + }; +} + =head2 Internal methods =head3 _type diff --git a/Koha/Acquisition/Booksellers.pm b/Koha/Acquisition/Booksellers.pm index 466270751db..50b7398a7a0 100644 --- a/Koha/Acquisition/Booksellers.pm +++ b/Koha/Acquisition/Booksellers.pm @@ -19,7 +19,7 @@ use Modern::Perl; use Koha::Acquisition::Bookseller; -use base qw( Koha::Object::Mixin::AdditionalFields Koha::Objects ); +use base qw( Koha::Objects Koha::Object::Mixin::AdditionalFields Koha::Objects::Limit::LibraryGroup ); =head1 NAME @@ -27,6 +27,22 @@ Koha::Acquisition::Booksellers object set class =head1 API +=head2 Class methods + +=head3 search + +=cut + +sub search { + my ( $self, $params, $attributes ) = @_; + + my $class = ref($self) ? ref($self) : $self; + + ( $params, $attributes ) = $self->define_library_group_limits( $params, $attributes ); + + return $self->SUPER::search( $params, $attributes ); +} + =head2 Internal methods =head3 _type (internal) diff --git a/Koha/Object/Limit/LibraryGroup.pm b/Koha/Object/Limit/LibraryGroup.pm new file mode 100644 index 00000000000..14502794427 --- /dev/null +++ b/Koha/Object/Limit/LibraryGroup.pm @@ -0,0 +1,82 @@ +package Koha::Object::Limit::LibraryGroup; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Koha::Database; +use Koha::Exceptions; + +use Try::Tiny qw( catch try ); + +=head1 NAME + +Koha::Object::Limit::LibraryGroup - Generic library group limit handling class + +=head1 SYNOPSIS + + use base qw(Koha::Object Koha::Object::Limit::LibraryGroup); + my $object = Koha::Object->new({ property1 => $property1, property2 => $property2, etc... } ); + +=head1 DESCRIPTION + +This class is provided as a generic way of handling library group limits for Koha::Object-based classes +in Koha. + +This class must always be subclassed. + +=head1 API + +=head2 Class Methods + +=cut + +=head3 lib_group_limits + +A method that can be used to embed or simply retrieve the library group limits for an object + +=cut + +sub lib_group_limits { + my ( $self ) = @_; + + my $lib_group_visibility = $self->lib_group_visibility; + return [] if !$lib_group_visibility; + + my @ids = grep(/[0-9]/, split(/\|/, $lib_group_visibility)); + + my @lib_groups = map { Koha::Library::Groups->find($_) } @ids; + + return \@lib_groups; +} + +=head3 set_lib_group_visibility + +A method that can be used to set the library group visibility for an object + +=cut + +sub set_lib_group_visibility { + my ( $self ) = @_; + + if ( $self->lib_group_visibility && $self->lib_group_visibility !~ /^\|.*\|$/ ) { + $self->lib_group_visibility( "|" . $self->lib_group_visibility . "|" ); + } + + return $self; +} + +1; diff --git a/Koha/Objects/Limit/LibraryGroup.pm b/Koha/Objects/Limit/LibraryGroup.pm new file mode 100644 index 00000000000..7e49819ef48 --- /dev/null +++ b/Koha/Objects/Limit/LibraryGroup.pm @@ -0,0 +1,144 @@ +package Koha::Objects::Limit::LibraryGroup; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use C4::Context; +use Koha::Database; + +=head1 NAME + +Koha::Objects::Limit::LibraryGroup - Generic library group limit handling class + +=head1 SYNOPSIS + + use base qw(Koha::Objects Koha::Objects::Limit::LibraryGroup); + my $objects = Koha::Objects->search_with_library_grouplimits( $params, $attributes, $library_group_id ); + +=head1 DESCRIPTION + +This class is provided as a generic way of handling library group limits for Koha::Objects-based classes +in Koha. + +This class must always be subclassed. + +=head1 API + +=head2 Class methods + +=cut + +=head3 define_library_group_limits + +my $results = $objects->define_library_group_limits( $params, $attributes, $library_group_id ); + +Wrapper method for searching objects with library limits, respecting those limits + +=cut + +sub define_library_group_limits { + my ( $self, $params, $attributes ) = @_; + + my $logged_in_branch = C4::Context->userenv()->{'branch'} || undef; + return ( $params, $attributes ) unless $logged_in_branch; + + my $lib_group_visibility_parameters = $self->object_class()->_library_group_visibility_parameters; + + my $library = Koha::Libraries->find($logged_in_branch); + return ( $params, $attributes ) unless $library; + + my $visibility_column = $lib_group_visibility_parameters->{visibility_column}; + my $library_group_limits_table = + Koha::Database->new->schema->resultset( $lib_group_visibility_parameters->{class} )->result_source->name; + + my $where = { + '-or' => [ + { "$visibility_column" => undef }, + ] + }; + + my @library_groups = $library->library_groups->as_list; + my @parent_ids; + + return ( $params, $attributes ) if scalar(@library_groups) == 0; + + foreach my $library_group (@library_groups) { + my $group_id = $library_group->id; + my $query = {}; + $query->{"$visibility_column"} = { "-like" => "%|$group_id|%" }; + push( @{ $where->{'-or'} }, $query ); + + _handle_parent_groups( + { + library_group => $library_group, where => $where, parent_ids => \@parent_ids, + visibility_column => $visibility_column + } + ); + } + + $params //= {}; + $attributes //= {}; + + if ( ref($params) eq 'ARRAY' ) { + foreach my $query (@$params) { + $query = { %$query, %$where }; + } + } else { + $params = { %$params, %$where }; + } + + return ( $params, $attributes ); +} + +=head3 _handle_parent_groups + +_handle_parent_groups( + { + library_group => $library_group, where => $where, parent_ids => \@parent_ids, + visibility_column => $visibility_column + } +); + +Recursively handles parent library groups to account for multiple sub groups + +=cut + +sub _handle_parent_groups { + my ($args) = @_; + + my $library_group = $args->{library_group}; + my $where = $args->{where}; + my $parent_ids = $args->{parent_ids}; + my $visibility_column = $args->{visibility_column}; + + my $parent = $library_group->parent; + if ( $parent && !grep( $_ eq $parent->id, @$parent_ids ) ) { + my $parent_query = {}; + my $parent_id = $parent->id; + push( @$parent_ids, $parent_id ); + $parent_query->{"$visibility_column"} = { "-like" => "%|$parent_id|%" }; + push( @{ $where->{'-or'} }, $parent_query ); + _handle_parent_groups( + { + library_group => $parent, where => $where, parent_ids => $parent_ids, + visibility_column => $visibility_column + } + ); + } +} + +1; -- 2.39.5 (Apple Git-154)