add security for the item barcode
[koha.git] / C4 / BookShelves.pm
1 # -*- tab-width: 8 -*-
2 # Please use 8-character tabs for this file (indents are every 4 characters)
3
4 package C4::BookShelves;
5
6 # $Id$
7
8 # Copyright 2000-2002 Katipo Communications
9 #
10 # This file is part of Koha.
11 #
12 # Koha is free software; you can redistribute it and/or modify it under the
13 # terms of the GNU General Public License as published by the Free Software
14 # Foundation; either version 2 of the License, or (at your option) any later
15 # version.
16 #
17 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License along with
22 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23 # Suite 330, Boston, MA  02111-1307 USA
24
25 use strict;
26 require Exporter;
27 use C4::Context;
28 use C4::Circulation;
29 use vars qw($VERSION @ISA @EXPORT);
30
31 # set the version for version checking
32 $VERSION = do { my @v = '$Revision$' =~ /\d+/g; shift(@v) . "." . join( "_", map { sprintf "%03d", $_ } @v ); };
33
34 =head1 NAME
35
36 C4::BookShelves - Functions for manipulating Koha virtual bookshelves
37
38 =head1 SYNOPSIS
39
40   use C4::BookShelves;
41
42 =head1 DESCRIPTION
43
44 This module provides functions for manipulating virtual bookshelves,
45 including creating and deleting bookshelves, and adding and removing
46 items to and from bookshelves.
47
48 =head1 FUNCTIONS
49
50 =over 2
51
52 =cut
53
54 @ISA    = qw(Exporter);
55 @EXPORT = qw(
56         &GetShelves &GetShelfContents &GetShelf
57
58         &AddToShelf &AddToShelfFromBiblio &AddShelf
59
60         &ModShelf
61         &ShelfPossibleAction
62         &DelFromShelf &DelShelf
63 );
64
65 my $dbh = C4::Context->dbh;
66
67 =item GetShelves
68
69   $shelflist = &GetShelves($owner, $mincategory);
70   ($shelfnumber, $shelfhash) = each %{$shelflist};
71
72 Looks up the virtual bookshelves, and returns a summary. C<$shelflist>
73 is a reference-to-hash. The keys are the bookshelf numbers
74 (C<$shelfnumber>, above), and the values (C<$shelfhash>, above) are
75 themselves references-to-hash, with the following keys:
76
77 C<mincategory> : 2 if the list is for "look". 3 if the list is for "Select bookshelf for adding a book".
78 bookshelves of the owner are always selected, whatever the category
79
80 =over 4
81
82 =item C<$shelfhash-E<gt>{shelfname}>
83
84 A string. The name of the shelf.
85
86 =item C<$shelfhash-E<gt>{count}>
87
88 The number of books on that bookshelf.
89
90 =back
91
92 =cut
93
94 #'
95 # FIXME - Wouldn't it be more intuitive to return a list, rather than
96 # a reference-to-hash? The shelf number can be just another key in the
97 # hash.
98
99 sub GetShelves {
100     my ( $owner, $mincategory ) = @_;
101
102     my $query = qq(
103         SELECT bookshelf.shelfnumber, bookshelf.shelfname,owner,surname,firstname,bookshelf.category,
104                count(shelfcontents.itemnumber) as count
105         FROM   bookshelf
106             LEFT JOIN   shelfcontents ON bookshelf.shelfnumber = shelfcontents.shelfnumber
107             LEFT JOIN   borrowers ON bookshelf.owner = borrowers.borrowernumber
108         WHERE  owner=? OR category>=?
109         GROUP BY bookshelf.shelfnumber
110         ORDER BY bookshelf.category, bookshelf.shelfname, borrowers.firstname, borrowers.surname
111     );
112     my $sth = $dbh->prepare($query);
113     $sth->execute( $owner, $mincategory );
114     my %shelflist;
115     while (
116         my (
117             $shelfnumber, $shelfname, $owner, $surname,
118             $firstname,   $category,  $count
119         )
120         = $sth->fetchrow
121       )
122     {
123         $shelflist{$shelfnumber}->{'shelfname'} = $shelfname;
124         $shelflist{$shelfnumber}->{'count'}     = $count;
125         $shelflist{$shelfnumber}->{'category'}  = $category;
126         $shelflist{$shelfnumber}->{'owner'}     = $owner;
127         $shelflist{$shelfnumber}->{'surname'}     = $surname;
128         $shelflist{$shelfnumber}->{'firstname'}   = $firstname;
129     }
130     return ( \%shelflist );
131 }
132
133 =item GetShef
134
135   (shelfnumber,shelfname,owner,category) = &GetShelf($shelfnumber);
136
137 Looks up information about the contents of virtual bookshelf number
138 C<$shelfnumber>
139
140 Returns the database's information on 'bookshelf' table.
141
142 =cut
143
144 sub GetShelf {
145     my ($shelfnumber) = @_;
146     my $query = qq(
147         SELECT shelfnumber,shelfname,owner,category
148         FROM   bookshelf
149         WHERE  shelfnumber=?
150     );
151     my $sth = $dbh->prepare($query);
152     $sth->execute($shelfnumber);
153     return $sth->fetchrow;
154 }
155
156 =item GetShelfContents
157
158   $itemlist = &GetShelfContents($shelfnumber);
159
160 Looks up information about the contents of virtual bookshelf number
161 C<$shelfnumber>.
162
163 Returns a reference-to-array, whose elements are references-to-hash,
164 as returned by C<C4::Biblio::GetBiblioFromItemNumber>.
165
166 =cut
167
168 #'
169 sub GetShelfContents {
170     my ( $shelfnumber ) = @_;
171     my @itemlist;
172     my $query =
173        " SELECT itemnumber
174          FROM   shelfcontents
175          WHERE  shelfnumber=?
176          ORDER BY itemnumber
177        ";
178     my $sth = $dbh->prepare($query);
179     $sth->execute($shelfnumber);
180     my $sth2 = $dbh->prepare("
181         SELECT biblio.*,biblioitems.* FROM items 
182             LEFT JOIN biblio on items.biblionumber=biblio.biblionumber
183             LEFT JOIN biblioitems on items.biblionumber=biblioitems.biblionumber
184         WHERE items.itemnumber=?"
185     );
186     while ( my ($itemnumber) = $sth->fetchrow ) {
187         $sth2->execute($itemnumber);
188         my $item = $sth2->fetchrow_hashref;
189         $item->{'itemnumber'}=$itemnumber;
190         push( @itemlist, $item );
191     }
192     return ( \@itemlist );
193 }
194
195 =item AddShelf
196
197   $shelfnumber = &AddShelf( $shelfname, $owner, $category);
198
199 Creates a new virtual bookshelf with name C<$shelfname>, owner C<$owner> and category
200 C<$category>.
201
202 Returns a code to know what's happen.
203     * -1 : if this bookshelf already exist.
204     * $shelfnumber : if success.
205
206 =cut
207
208 sub AddShelf {
209     my ( $shelfname, $owner, $category ) = @_;
210     my $query = qq(
211         SELECT *
212         FROM   bookshelf
213         WHERE  shelfname=? AND owner=?
214     );
215     my $sth = $dbh->prepare($query);
216     $sth->execute($shelfname,$owner);
217     if ( $sth->rows ) {
218         return (-1);
219     }
220     else {
221         my $query = qq(
222             INSERT INTO bookshelf
223                 (shelfname,owner,category)
224             VALUES (?,?,?)
225         );
226         $sth = $dbh->prepare($query);
227         $sth->execute( $shelfname, $owner, $category );
228         my $shelfnumber = $dbh->{'mysql_insertid'};
229         return ($shelfnumber);
230     }
231 }
232
233 =item AddToShelf
234
235   &AddToShelf($itemnumber, $shelfnumber);
236
237 Adds item number C<$itemnumber> to virtual bookshelf number
238 C<$shelfnumber>, unless that item is already on that shelf.
239
240 =cut
241
242 #'
243 sub AddToShelf {
244     my ( $itemnumber, $shelfnumber ) = @_;
245     return unless $itemnumber;
246     my $query = qq(
247         SELECT *
248         FROM   shelfcontents
249         WHERE  shelfnumber=? AND itemnumber=?
250     );
251     my $sth = $dbh->prepare($query);
252
253     $sth->execute( $shelfnumber, $itemnumber );
254     unless ( $sth->rows ) {
255         # already on shelf
256         my $query = qq(
257             INSERT INTO shelfcontents
258                 (shelfnumber, itemnumber, flags)
259             VALUES
260                 (?, ?, 0)
261         );
262         $sth = $dbh->prepare($query);
263         $sth->execute( $shelfnumber, $itemnumber );
264     }
265 }
266
267 =item AddToShelfFromBiblio
268  
269     &AddToShelfFromBiblio($biblionumber, $shelfnumber)
270
271     this function allow to add a book into the shelf number $shelfnumber
272     from biblionumber.
273
274 =cut
275
276 sub AddToShelfFromBiblio {
277     my ( $biblionumber, $shelfnumber ) = @_;
278     return unless $biblionumber;
279     my $query = qq(
280         SELECT itemnumber
281         FROM   items
282         WHERE  biblionumber=?
283     );
284     my $sth = $dbh->prepare($query);
285     $sth->execute($biblionumber);
286     my ($itemnumber) = $sth->fetchrow;
287     $query = qq(
288         SELECT *
289         FROM   shelfcontents
290         WHERE  shelfnumber=? AND itemnumber=?
291     );
292     $sth = $dbh->prepare($query);
293     $sth->execute( $shelfnumber, $itemnumber );
294     unless ( $sth->rows ) {
295         # "already on shelf";
296         my $query =qq(
297             INSERT INTO shelfcontents
298                 (shelfnumber, itemnumber, flags)
299             VALUES
300                 (?, ?, 0)
301         );
302         $sth = $dbh->prepare($query);
303         $sth->execute( $shelfnumber, $itemnumber );
304     }
305 }
306
307 =item ModShelf
308
309 ModShelf($shelfnumber, $shelfname, $owner, $category )
310
311 Modify the value into bookshelf table with values given on input arg.
312
313 =cut
314
315 sub ModShelf {
316     my ( $shelfnumber, $shelfname, $owner, $category ) = @_;
317     my $query = qq(
318         UPDATE bookshelf
319         SET    shelfname=?,owner=?,category=?
320         WHERE  shelfnumber=?
321     );
322     my $sth = $dbh->prepare($query);
323     $sth->execute( $shelfname, $owner, $category, $shelfnumber );
324 }
325
326 =item DelShelf
327
328   ($status) = &DelShelf($shelfnumber);
329
330 Deletes virtual bookshelf number C<$shelfnumber>. The bookshelf must
331 be empty.
332
333 Returns a two-element array, where C<$status> is 0 if the operation
334 was successful, or non-zero otherwise. C<$msg> is "Done" in case of
335 success, or an error message giving the reason for failure.
336
337 =cut
338
339
340 =item ShelfPossibleAction
341
342 ShelfPossibleAction($loggedinuser, $shelfnumber, $action);
343
344 C<$loggedinuser,$shelfnumber,$action>
345
346 $action can be "view" or "manage".
347
348 Returns 1 if the user can do the $action in the $shelfnumber shelf.
349 Returns 0 otherwise.
350
351 =cut
352
353 sub ShelfPossibleAction {
354     my ( $user, $shelfnumber, $action ) = @_;
355     my $query = qq(
356         SELECT owner,category
357         FROM   bookshelf
358         WHERE  shelfnumber=?
359     );
360     my $sth = $dbh->prepare($query);
361     $sth->execute($shelfnumber);
362     my ( $owner, $category ) = $sth->fetchrow;
363     return 1 if (($category >= 3 or $owner eq $user) && $action eq 'manage' );
364     return 1 if (($category >= 2 or $owner eq $user) && $action eq 'view' );
365     return 0;
366 }
367
368 =item DelFromShelf
369
370   &DelFromShelf( $itemnumber, $shelfnumber);
371
372 Removes item number C<$itemnumber> from virtual bookshelf number
373 C<$shelfnumber>. If the item wasn't on that bookshelf to begin with,
374 nothing happens.
375
376 =cut
377
378 #'
379 sub DelFromShelf {
380     my ( $itemnumber, $shelfnumber ) = @_;
381     my $query = qq(
382         DELETE FROM shelfcontents
383         WHERE  shelfnumber=? AND itemnumber=?
384     );
385     my $sth = $dbh->prepare($query);
386     $sth->execute( $shelfnumber, $itemnumber );
387 }
388
389 =head2 DelShelf
390
391   $Number = DelShelf($shelfnumber);
392
393     this function delete the shelf number, and all of it's content
394
395 =cut
396
397 #'
398 sub DelShelf {
399     my ( $shelfnumber ) = @_;
400         my $sth = $dbh->prepare("DELETE FROM bookshelf WHERE shelfnumber=?");
401         $sth->execute($shelfnumber);
402         return 0;
403 }
404
405 END { }    # module clean-up code here (global destructor)
406
407 1;
408
409 __END__
410
411 =back
412
413 =head1 AUTHOR
414
415 Koha Developement team <info@koha.org>
416
417 =head1 SEE ALSO
418
419 C4::Circulation::Circ2(3)
420
421 =cut
422
423 #
424 # $Log$
425 # Revision 1.21  2007/04/04 16:46:22  tipaul
426 # HUGE COMMIT : code cleaning circulation.
427 #
428 # some stuff to do, i'll write a mail on koha-devel NOW !
429 #
430 # Revision 1.20  2007/03/09 14:31:47  tipaul
431 # rel_3_0 moved to HEAD
432 #
433 # Revision 1.15.8.10  2007/01/25 13:18:15  tipaul
434 # checking that a bookshelf with the same name AND OWNER does not exist before creating it
435 #
436 # Revision 1.15.8.9  2006/12/15 17:37:52  toins
437 # removing a function used only once.
438 #
439 # Revision 1.15.8.8  2006/12/14 17:22:55  toins
440 # bookshelves work perfectly with mod_perl and are cleaned.
441 #
442 # Revision 1.15.8.7  2006/12/13 19:46:41  hdl
443 # Some bug fixing.
444 #
445 # Revision 1.15.8.6  2006/12/11 17:10:06  toins
446 # fixing some bugs on bookshelves.
447 #
448 # Revision 1.15.8.5  2006/12/07 16:45:43  toins
449 # removing warn compilation. (perl -wc)
450 #
451 # Revision 1.15.8.4  2006/11/23 09:05:01  tipaul
452 # enable removal of a bookshelf even if there are items inside
453 #
454 # Revision 1.15.8.3  2006/10/30 09:50:20  tipaul
455 # removing getiteminformations (using direct SQL, as we are in a .pm, so it's "legal")
456 #
457 # Revision 1.15.8.2  2006/08/31 16:03:52  toins
458 # Add Pod to DelShelf
459 #
460 # Revision 1.15.8.1  2006/08/30 15:59:14  toins
461 # Code cleaned according to coding guide lines.
462 #
463 # Revision 1.15  2004/12/16 11:30:58  tipaul
464 # adding bookshelf features :
465 # * create bookshelf on the fly
466 # * modify a bookshelf name & status
467 #
468 # Revision 1.14  2004/12/15 17:28:23  tipaul
469 # adding bookshelf features :
470 # * create bookshelf on the fly
471 # * modify a bookshelf (this being not finished, will commit the rest soon)