Shelves wrap up - bugfix 1405, opac checkbox js fixed
[koha.git] / C4 / VirtualShelves.pm
1 # -*- tab-width: 8 -*-
2 # Please use 8-character tabs for this file (indents are every 4 characters)
3
4 package C4::VirtualShelves;
5
6
7 # Copyright 2000-2002 Katipo Communications
8 #
9 # This file is part of Koha.
10 #
11 # Koha is free software; you can redistribute it and/or modify it under the
12 # terms of the GNU General Public License as published by the Free Software
13 # Foundation; either version 2 of the License, or (at your option) any later
14 # version.
15 #
16 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
17 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License along with
21 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
22 # Suite 330, Boston, MA  02111-1307 USA
23
24 use strict;
25 use Carp;
26 use C4::Context;
27 use C4::Circulation;
28 use vars qw($VERSION @ISA @EXPORT);
29
30 BEGIN {
31         # set the version for version checking
32         $VERSION = 3.01;
33         require Exporter;
34         @ISA    = qw(Exporter);
35         @EXPORT = qw(
36         &GetShelves &GetShelfContents &GetShelf
37
38         &AddToShelf &AddToShelfFromBiblio &AddShelf
39
40         &ModShelf
41         &ShelfPossibleAction
42         &DelFromShelf &DelShelf
43         );
44 }
45
46 my $dbh = C4::Context->dbh;
47
48 =head1 NAME
49
50 C4::VirtualShelves - Functions for manipulating Koha virtual virtualshelves
51
52 =head1 SYNOPSIS
53
54   use C4::VirtualShelves;
55
56 =head1 DESCRIPTION
57
58 This module provides functions for manipulating virtual virtualshelves,
59 including creating and deleting virtualshelves, and adding and removing
60 items to and from virtualshelves.
61
62 =head1 FUNCTIONS
63
64 =over 2
65
66 =item GetShelves
67
68   $shelflist = &GetShelves($owner, $mincategory);
69   ($shelfnumber, $shelfhash) = each %{$shelflist};
70
71 Looks up the virtual virtualshelves, and returns a summary. C<$shelflist>
72 is a reference-to-hash. The keys are the virtualshelves numbers
73 (C<$shelfnumber>, above), and the values (C<$shelfhash>, above) are
74 themselves references-to-hash, with the following keys:
75
76 C<mincategory> : 2 if the list is for "look". 3 if the list is for "Select virtualshelves for adding a virtual".
77 virtualshelves of the owner are always selected, whatever the category
78
79 =over 4
80
81 =item C<$shelfhash-E<gt>{shelfname}>
82
83 A string. The name of the shelf.
84
85 =item C<$shelfhash-E<gt>{count}>
86
87 The number of virtuals on that virtualshelves.
88
89 =back
90
91 =cut
92
93 #'
94 # FIXME - Wouldn't it be more intuitive to return a list, rather than
95 # a reference-to-hash? The shelf number can be just another key in the
96 # hash.
97
98 sub GetShelves {
99     my ( $owner, $mincategory ) = @_;
100
101     my $query = qq(
102         SELECT virtualshelves.shelfnumber, virtualshelves.shelfname,owner,surname,firstname,virtualshelves.category,virtualshelves.sortfield,
103                count(virtualshelfcontents.biblionumber) as count
104         FROM   virtualshelves
105             LEFT JOIN   virtualshelfcontents ON virtualshelves.shelfnumber = virtualshelfcontents.shelfnumber
106             LEFT JOIN   borrowers ON virtualshelves.owner = borrowers.borrowernumber
107         WHERE  owner=? OR category>=?
108         GROUP BY virtualshelves.shelfnumber
109         ORDER BY virtualshelves.category, virtualshelves.shelfname, borrowers.firstname, borrowers.surname
110     );
111     my $sth = $dbh->prepare($query);
112     $sth->execute( $owner, $mincategory );
113     my %shelflist;
114     while (
115         my (
116             $shelfnumber, $shelfname, $owner, $surname,
117             $firstname,   $category,  $sortfield, $count
118         )
119         = $sth->fetchrow
120       )
121     {
122         $shelflist{$shelfnumber}->{'shelfname'} = $shelfname;
123         $shelflist{$shelfnumber}->{'count'}     = $count;
124         $shelflist{$shelfnumber}->{'sortfield'}     = $sortfield;
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 GetShelf
134
135   (shelfnumber,shelfname,owner,category) = &GetShelf($shelfnumber);
136
137 Looks up information about the contents of virtual virtualshelves number
138 C<$shelfnumber>
139
140 Returns the database's information on 'virtualshelves' table.
141
142 =cut
143
144 sub GetShelf {
145     my ($shelfnumber) = @_;
146     my $query = qq(
147         SELECT shelfnumber,shelfname,owner,category,sortfield
148         FROM   virtualshelves
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 virtualshelves number
161 C<$shelfnumber>.  Sorted by a field in the biblio table.  copyrightdate 
162 gives a desc sort.
163
164 Returns a reference-to-array, whose elements are references-to-hash,
165 as returned by C<C4::Biblio::GetBiblioFromItemNumber>.
166
167 Note: the notforloan status comes from the itemtype, and where it equals 0
168 it does not ensure that related items.notforloan status is likewise 0. The
169 caller has to check any items on their own, possibly with CanBookBeIssued
170 from C4::Circulation.
171
172 =cut
173
174 sub GetShelfContents {
175     my ( $shelfnumber ,$sortfield) = @_;
176     my $dbh=C4::Context->dbh();
177         if(!$sortfield) {
178                 my $sthsort = $dbh->prepare('select sortfield from virtualshelves where shelfnumber=?');
179                 $sthsort->execute($shelfnumber);
180                 ($sortfield) = $sthsort->fetchrow_array;
181         }
182     my $query =
183        " SELECT vc.biblionumber, vc.shelfnumber,
184                                 biblio.*, biblioitems.itemtype, itemtypes.*
185          FROM   virtualshelfcontents vc
186                  LEFT JOIN biblio      ON      vc.biblionumber =      biblio.biblionumber
187                  LEFT JOIN biblioitems ON  biblio.biblionumber = biblioitems.biblionumber
188                  LEFT JOIN itemtypes   ON biblioitems.itemtype = itemtypes.itemtype
189          WHERE  vc.shelfnumber=? ";
190         if($sortfield) {
191                 $query .= " ORDER BY `$sortfield` ";
192                 $query .= " DESC " if ($sortfield eq 'copyrightdate');
193         }
194     my $sth = $dbh->prepare($query);
195         $sth->execute($shelfnumber);
196         return $sth->fetchall_arrayref({});     
197         # Like the perldoc says,
198         # returns reference-to-array, where each element is reference-to-hash of the row:
199         #   like [ $sth->fetchrow_hashref(), $sth->fetchrow_hashref() ... ] 
200         # Suitable for use in TMPL_LOOP.
201         # See http://search.cpan.org/~timb/DBI-1.601/DBI.pm#fetchall_arrayref
202         # or newer, for your version of DBI.
203 }
204
205 =item AddShelf
206
207   $shelfnumber = &AddShelf( $shelfname, $owner, $category);
208
209 Creates a new virtual virtualshelves with name C<$shelfname>, owner C<$owner> and category
210 C<$category>.
211
212 Returns a code to know what's happen.
213     * -1 : if this virtualshelves already exist.
214     * $shelfnumber : if success.
215
216 =cut
217
218 sub AddShelf {
219     my ( $shelfname, $owner, $category ) = @_;
220     my $query = qq(
221         SELECT *
222         FROM   virtualshelves
223         WHERE  shelfname=? AND owner=?
224     );
225     my $sth = $dbh->prepare($query);
226     $sth->execute($shelfname,$owner);
227     ( $sth->rows ) and return (-1);
228     $query = qq(
229         INSERT INTO virtualshelves
230             (shelfname,owner,category)
231         VALUES (?,?,?)
232     );
233     $sth = $dbh->prepare($query);
234     $sth->execute( $shelfname, $owner, $category );
235     my $shelfnumber = $dbh->{'mysql_insertid'};
236     return ($shelfnumber);
237 }
238
239 =item AddToShelf
240
241   &AddToShelf($biblionumber, $shelfnumber);
242
243 Adds item number C<$biblionumber> to virtual virtualshelves number
244 C<$shelfnumber>, unless that item is already on that shelf.
245
246 =cut
247
248 #'
249 sub AddToShelf {
250     my ( $biblionumber, $shelfnumber ) = @_;
251     return unless $biblionumber;
252     my $query = qq(
253         SELECT *
254         FROM   virtualshelfcontents
255         WHERE  shelfnumber=? AND biblionumber=?
256     );
257     my $sth = $dbh->prepare($query);
258
259     $sth->execute( $shelfnumber, $biblionumber );
260     ($sth->rows) and return undef;      # already on shelf
261         $query = qq(
262                 INSERT INTO virtualshelfcontents
263                         (shelfnumber, biblionumber, flags)
264                 VALUES
265                         (?, ?, 0)
266         );
267         $sth = $dbh->prepare($query);
268         $sth->execute( $shelfnumber, $biblionumber );
269 }
270
271 =item AddToShelfFromBiblio
272  
273     &AddToShelfFromBiblio($biblionumber, $shelfnumber)
274
275     this function allow to add a virtual into the shelf number $shelfnumber
276     from biblionumber.
277
278 =cut
279
280 sub AddToShelfFromBiblio {
281     my ( $biblionumber, $shelfnumber ) = @_;
282     return unless $biblionumber;
283     my $query = qq(
284         SELECT *
285         FROM   virtualshelfcontents
286         WHERE  shelfnumber=? AND biblionumber=?
287     );
288     my $sth = $dbh->prepare($query);
289     $sth->execute( $shelfnumber, $biblionumber );
290     unless ( $sth->rows ) {
291         my $query =qq(
292             INSERT INTO virtualshelfcontents
293                 (shelfnumber, biblionumber, flags)
294             VALUES
295                 (?, ?, 0)
296         );
297         $sth = $dbh->prepare($query);
298         $sth->execute( $shelfnumber, $biblionumber );
299     }
300 }
301
302 =item ModShelf
303
304 ModShelf($shelfnumber, $shelfname, $owner, $category )
305
306 Modify the value into virtualshelves table with values given on input arg.
307
308 =cut
309
310 sub ModShelf {
311     my ( $shelfnumber, $shelfname, $owner, $category, $sortfield ) = @_;
312     my $query = qq(
313         UPDATE virtualshelves
314         SET    shelfname=?,owner=?,category=?,sortfield=?
315         WHERE  shelfnumber=?
316     );
317         my $sth = $dbh->prepare($query);
318     $sth->execute( $shelfname, $owner, $category, $sortfield, $shelfnumber );
319 }
320
321 =item ShelfPossibleAction
322
323 ShelfPossibleAction($loggedinuser, $shelfnumber, $action);
324
325 C<$loggedinuser,$shelfnumber,$action>
326
327 $action can be "view" or "manage".
328
329 Returns 1 if the user can do the $action in the $shelfnumber shelf.
330 Returns 0 otherwise.
331
332 =cut
333
334 sub ShelfPossibleAction {
335     my ( $user, $shelfnumber, $action ) = @_;
336     my $query = qq(
337         SELECT owner,category
338         FROM   virtualshelves
339         WHERE  shelfnumber=?
340     );
341     my $sth = $dbh->prepare($query);
342     $sth->execute($shelfnumber);
343     my ( $owner, $category ) = $sth->fetchrow;
344     return 1 if ($owner eq $user);
345     return 1 if ( $category >= 3);
346     return 1 if (($category >= 2) && $action eq 'view' );
347     return 0;
348 }
349
350 =item DelFromShelf
351
352   &DelFromShelf( $biblionumber, $shelfnumber);
353
354 Removes item number C<$biblionumber> from virtual virtualshelves number
355 C<$shelfnumber>. If the item wasn't on that virtualshelves to begin with,
356 nothing happens.
357
358 =cut
359
360 #'
361 sub DelFromShelf {
362     my ( $biblionumber, $shelfnumber ) = @_;
363     my $query = qq(
364         DELETE FROM virtualshelfcontents
365         WHERE  shelfnumber=? AND biblionumber=?
366     );
367     my $sth = $dbh->prepare($query);
368     $sth->execute( $shelfnumber, $biblionumber );
369 }
370
371 =item DelShelf (old version)
372
373   ($status, $msg) = &DelShelf($shelfnumber);
374
375 Deletes virtual virtualshelves number C<$shelfnumber>. The virtualshelves must
376 be empty.
377
378 Returns a two-element array, where C<$status> is 0 if the operation
379 was successful, or non-zero otherwise. C<$msg> is "Done" in case of
380 success, or an error message giving the reason for failure.
381
382 =item DelShelf (current version)
383
384   $Number = DelShelf($shelfnumber);
385
386 This function deletes the shelf number, and all of it's content.
387
388 =cut
389
390 sub DelShelf {
391         unless (@_) {
392                 carp "DelShelf called without valid argument (shelfnumber)";
393                 return undef;
394         }
395         my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?");
396         return $sth->execute(shift);
397 }
398
399 1;
400
401 __END__
402
403 =back
404
405 =head1 AUTHOR
406
407 Koha Developement team <info@koha.org>
408
409 =head1 SEE ALSO
410
411 C4::Circulation::Circ2(3)
412
413 =cut