b476eb440aeb49b03fe4f069c8c3313adaeb52d5
[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         my $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 DelShelf
322
323   ($status) = &DelShelf($shelfnumber);
324
325 Deletes virtual virtualshelves number C<$shelfnumber>. The virtualshelves must
326 be empty.
327
328 Returns a two-element array, where C<$status> is 0 if the operation
329 was successful, or non-zero otherwise. C<$msg> is "Done" in case of
330 success, or an error message giving the reason for failure.
331
332 =cut
333
334
335 =item ShelfPossibleAction
336
337 ShelfPossibleAction($loggedinuser, $shelfnumber, $action);
338
339 C<$loggedinuser,$shelfnumber,$action>
340
341 $action can be "view" or "manage".
342
343 Returns 1 if the user can do the $action in the $shelfnumber shelf.
344 Returns 0 otherwise.
345
346 =cut
347
348 sub ShelfPossibleAction {
349     my ( $user, $shelfnumber, $action ) = @_;
350     my $query = qq(
351         SELECT owner,category
352         FROM   virtualshelves
353         WHERE  shelfnumber=?
354     );
355     my $sth = $dbh->prepare($query);
356     $sth->execute($shelfnumber);
357     my ( $owner, $category ) = $sth->fetchrow;
358     return 1 if ($owner eq $user);
359     return 1 if ( $category >= 3);
360     return 1 if (($category >= 2) && $action eq 'view' );
361     return 0;
362 }
363
364 =item DelFromShelf
365
366   &DelFromShelf( $biblionumber, $shelfnumber);
367
368 Removes item number C<$biblionumber> from virtual virtualshelves number
369 C<$shelfnumber>. If the item wasn't on that virtualshelves to begin with,
370 nothing happens.
371
372 =cut
373
374 #'
375 sub DelFromShelf {
376     my ( $biblionumber, $shelfnumber ) = @_;
377     my $query = qq(
378         DELETE FROM virtualshelfcontents
379         WHERE  shelfnumber=? AND biblionumber=?
380     );
381     my $sth = $dbh->prepare($query);
382     $sth->execute( $shelfnumber, $biblionumber );
383 }
384
385 =head2 DelShelf
386
387   $Number = DelShelf($shelfnumber);
388
389     this function delete the shelf number, and all of it's content
390
391 =cut
392
393 #'
394 sub DelShelf {
395         unless (@_) {
396                 carp "DelShelf called without valid argument (shelfnumber)";
397                 return undef;
398         }
399         my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?");
400         return $sth->execute(shift);
401 }
402
403 1;
404
405 __END__
406
407 =back
408
409 =head1 AUTHOR
410
411 Koha Developement team <info@koha.org>
412
413 =head1 SEE ALSO
414
415 C4::Circulation::Circ2(3)
416
417 =cut