1 package Koha::Virtualshelf;
3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
21 use C4::Auth qw( haspermission );
25 use Koha::DateUtils qw( dt_from_string );
26 use Koha::Exceptions::Virtualshelf;
27 use Koha::Virtualshelfshare;
28 use Koha::Virtualshelfshares;
29 use Koha::Virtualshelfcontent;
30 use Koha::Virtualshelfcontents;
32 use base qw(Koha::Object);
36 Koha::Virtualshelf - Koha Virtualshelf Object class
47 unless ( $self->owner ) {
48 Koha::Exceptions::Virtualshelf::UseDbAdminAccount->throw;
51 unless ( $self->is_shelfname_valid ) {
52 Koha::Exceptions::Virtualshelf::DuplicateObject->throw;
55 $self->allow_change_from_owner( 1 )
56 unless defined $self->allow_change_from_owner;
57 $self->allow_change_from_others( 0 )
58 unless defined $self->allow_change_from_others;
59 $self->allow_change_from_staff( 0 )
60 unless defined $self->allow_change_from_staff;
62 $self->created_on( dt_from_string )
63 unless defined $self->created_on;
65 return $self->SUPER::store( $self );
75 return !$self->public;
78 sub is_shelfname_valid {
82 shelfname => $self->shelfname,
83 ( $self->shelfnumber ? ( "me.shelfnumber" => { '!=', $self->shelfnumber } ) : () ),
86 if ( $self->is_private and defined $self->owner ) {
87 $conditions->{-or} = {
88 "virtualshelfshares.borrowernumber" => $self->owner,
89 "me.owner" => $self->owner,
91 $conditions->{public} = 0;
93 elsif ( $self->is_private and not defined $self->owner ) {
94 $conditions->{owner} = undef;
95 $conditions->{public} = 0;
98 $conditions->{public} = 1;
101 my $count = Koha::Virtualshelves->search(
104 join => 'virtualshelfshares',
107 return $count ? 0 : 1;
112 my $rs = $self->{_result}->virtualshelfshares;
113 my $shares = Koha::Virtualshelfshares->_new_from_dbic( $rs );
119 my $rs = $self->{_result}->virtualshelfcontents;
120 my $contents = Koha::Virtualshelfcontents->_new_from_dbic( $rs );
125 my ( $self, $key ) = @_;
127 Koha::Exceptions::Virtualshelf::InvalidKeyOnSharing->throw;
129 Koha::Virtualshelfshare->new(
131 shelfnumber => $self->shelfnumber,
133 sharedate => dt_from_string,
140 return $self->get_shares->search(
142 borrowernumber => { '!=' => undef },
148 my ( $self, $borrowernumber ) = @_;
149 return unless $borrowernumber;
150 return $self->get_shares->search(
152 borrowernumber => $borrowernumber,
158 my ( $self, $borrowernumber ) = @_;
159 my $shelves = Koha::Virtualshelfshares->search(
161 shelfnumber => $self->shelfnumber,
162 borrowernumber => $borrowernumber,
165 return 0 unless $shelves->count;
167 # Only 1 share with 1 patron can exist
168 return $shelves->next->delete;
172 my ( $self, $biblionumber, $borrowernumber ) = @_;
173 return unless $biblionumber;
174 my $already_exists = $self->get_contents->search(
176 biblionumber => $biblionumber,
179 return if $already_exists;
182 my $patron = Koha::Patrons->find( $borrowernumber ) or return 0;
183 return 0 unless ( $self->owner == $borrowernumber && $self->allow_change_from_owner ) || ( $self->allow_change_from_staff && $patron->can_patron_change_staff_only_lists ) || $self->allow_change_from_others;
185 my $content = Koha::Virtualshelfcontent->new(
187 shelfnumber => $self->shelfnumber,
188 biblionumber => $biblionumber,
189 borrowernumber => $borrowernumber,
192 $self->lastmodified(dt_from_string);
199 my ( $self, $params ) = @_;
200 my $biblionumbers = $params->{biblionumbers} || [];
201 my $borrowernumber = $params->{borrowernumber};
202 return unless @$biblionumbers;
204 my $number_removed = 0;
205 my $patron = Koha::Patrons->find( $borrowernumber ) or return 0;
206 if( ( $self->owner == $borrowernumber && $self->allow_change_from_owner )
207 || ( $self->allow_change_from_staff && $patron->can_patron_change_staff_only_lists )
208 || $self->allow_change_from_others ) {
209 $number_removed += $self->get_contents->search({
210 biblionumber => $biblionumbers,
213 return $number_removed;
217 my ( $self, $borrowernumber ) = @_;
218 return 1 if $self->is_public;
219 return 0 unless $borrowernumber;
220 return 1 if $self->owner == $borrowernumber;
221 return $self->get_shares->search(
223 borrowernumber => $borrowernumber,
229 my ( $self, $borrowernumber ) = @_;
231 return 0 unless $borrowernumber;
232 return 1 if $self->owner == $borrowernumber;
234 my $patron = Koha::Patrons->find( $borrowernumber ) or return 0;
236 return 1 if $self->is_public and haspermission( $patron->userid, { lists => 'delete_public_lists' } );
242 my ( $self, $borrowernumber ) = @_;
244 if $borrowernumber and $self->owner == $borrowernumber;
246 my $patron = Koha::Patrons->find( $borrowernumber ) or return 0;
248 if $self->is_public and haspermission( $patron->userid, { lists => 'edit_public_lists' } );
252 sub can_biblios_be_added {
253 my ( $self, $borrowernumber ) = @_;
255 my $patron = Koha::Patrons->find( $borrowernumber ) or return 0;
258 and ( ( $self->owner == $borrowernumber && $self->allow_change_from_owner ) or ( $self->allow_change_from_staff && $patron->can_patron_change_staff_only_lists ) or $self->allow_change_from_others );
262 sub can_biblios_be_removed {
263 my ( $self, $borrowernumber ) = @_;
264 return $self->can_biblios_be_added( $borrowernumber );
265 # Same answer since bug 18228
268 =head3 cannot_be_transferred
270 $shelf->cannot_be_transferred({
271 by => $p1, to => $p2, interface => opac|intranet|undef,
272 # p1 and p2 are borrowernumbers
275 This routine has two main goals:
276 [1] Decide if patron may transfer a shared list to another
278 [2] Decide if staff member may transfer a public list.
280 If you pass interface, we'll check if it supports transfer too.
281 NOTE: The explicit passing is still more reliable than via context,
282 since we could switch interface after login in the same session.
284 Returns a true value (read: error_code) when not allowed.
285 The following error codes are possible:
286 unauthorized_transfer, missing_by_parameter, new_owner_not_found,
287 new_owner_has_no_share, missing_to_parameter.
288 Otherwise returns false (zero).
292 sub cannot_be_transferred {
293 my ( $self, $params ) = @_;
294 my $to = $params->{to};
295 my $by = $params->{by};
296 my $interface = $params->{interface};
298 # Check on interface: currently we don't support transfer shared on intranet, transfer public on OPAC
300 return 'unauthorized_transfer'
301 if ( $self->public && $interface eq 'opac' ) or
302 ( $self->is_private && $interface eq 'intranet' );
303 # is_private call is enough here, get_shares tested below
306 my $shares = $self->public ? undef : $self->get_shares->search({ borrowernumber => { '!=' => undef } });
307 return 'unauthorized_transfer' if $self->is_private && !$shares->count;
310 if( $self->public ) {
311 my $by_patron = Koha::Patrons->find($by);
312 return 'unauthorized_transfer'
313 if !$by_patron || !haspermission( $by_patron->userid, { lists => 'edit_public_lists' });
315 return 'unauthorized_transfer' if !$self->can_be_managed($by);
318 return 'missing_by_parameter';
322 if( !Koha::Patrons->find($to) ) {
323 return 'new_owner_not_found';
325 if( !$self->public && !$shares->search({ borrowernumber => $to })->count ) {
326 return 'new_owner_has_no_share';
329 return 'missing_to_parameter';
331 return 0; # serving as green light
334 =head2 Internal methods
341 return 'Virtualshelve';