Shelves consolidation to C4::VirtualShelves::Page. I can tell the consolidation
[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     unless ( $sth->rows ) {
261         # already on shelf
262         my $query = qq(
263             INSERT INTO virtualshelfcontents
264                 (shelfnumber, biblionumber, flags)
265             VALUES
266                 (?, ?, 0)
267         );
268         $sth = $dbh->prepare($query);
269         $sth->execute( $shelfnumber, $biblionumber );
270     }
271 }
272
273 =item AddToShelfFromBiblio
274  
275     &AddToShelfFromBiblio($biblionumber, $shelfnumber)
276
277     this function allow to add a virtual into the shelf number $shelfnumber
278     from biblionumber.
279
280 =cut
281
282 sub AddToShelfFromBiblio {
283     my ( $biblionumber, $shelfnumber ) = @_;
284     return unless $biblionumber;
285     my $query = qq(
286         SELECT *
287         FROM   virtualshelfcontents
288         WHERE  shelfnumber=? AND biblionumber=?
289     );
290     my $sth = $dbh->prepare($query);
291     $sth->execute( $shelfnumber, $biblionumber );
292     unless ( $sth->rows ) {
293         my $query =qq(
294             INSERT INTO virtualshelfcontents
295                 (shelfnumber, biblionumber, flags)
296             VALUES
297                 (?, ?, 0)
298         );
299         $sth = $dbh->prepare($query);
300         $sth->execute( $shelfnumber, $biblionumber );
301     }
302 }
303
304 =item ModShelf
305
306 ModShelf($shelfnumber, $shelfname, $owner, $category )
307
308 Modify the value into virtualshelves table with values given on input arg.
309
310 =cut
311
312 sub ModShelf {
313     my ( $shelfnumber, $shelfname, $owner, $category, $sortfield ) = @_;
314     my $query = qq(
315         UPDATE virtualshelves
316         SET    shelfname=?,owner=?,category=?,sortfield=?
317         WHERE  shelfnumber=?
318     );
319         my $sth = $dbh->prepare($query);
320     $sth->execute( $shelfname, $owner, $category, $sortfield, $shelfnumber );
321 }
322
323 =item DelShelf
324
325   ($status) = &DelShelf($shelfnumber);
326
327 Deletes virtual virtualshelves number C<$shelfnumber>. The virtualshelves must
328 be empty.
329
330 Returns a two-element array, where C<$status> is 0 if the operation
331 was successful, or non-zero otherwise. C<$msg> is "Done" in case of
332 success, or an error message giving the reason for failure.
333
334 =cut
335
336
337 =item ShelfPossibleAction
338
339 ShelfPossibleAction($loggedinuser, $shelfnumber, $action);
340
341 C<$loggedinuser,$shelfnumber,$action>
342
343 $action can be "view" or "manage".
344
345 Returns 1 if the user can do the $action in the $shelfnumber shelf.
346 Returns 0 otherwise.
347
348 =cut
349
350 sub ShelfPossibleAction {
351     my ( $user, $shelfnumber, $action ) = @_;
352     my $query = qq(
353         SELECT owner,category
354         FROM   virtualshelves
355         WHERE  shelfnumber=?
356     );
357     my $sth = $dbh->prepare($query);
358     $sth->execute($shelfnumber);
359     my ( $owner, $category ) = $sth->fetchrow;
360     return 1 if ($owner eq $user);
361     return 1 if ( $category >= 3);
362     return 1 if (($category >= 2) && $action eq 'view' );
363     return 0;
364 }
365
366 =item DelFromShelf
367
368   &DelFromShelf( $biblionumber, $shelfnumber);
369
370 Removes item number C<$biblionumber> from virtual virtualshelves number
371 C<$shelfnumber>. If the item wasn't on that virtualshelves to begin with,
372 nothing happens.
373
374 =cut
375
376 #'
377 sub DelFromShelf {
378     my ( $biblionumber, $shelfnumber ) = @_;
379     my $query = qq(
380         DELETE FROM virtualshelfcontents
381         WHERE  shelfnumber=? AND biblionumber=?
382     );
383     my $sth = $dbh->prepare($query);
384     $sth->execute( $shelfnumber, $biblionumber );
385 }
386
387 =head2 DelShelf
388
389   $Number = DelShelf($shelfnumber);
390
391     this function delete the shelf number, and all of it's content
392
393 =cut
394
395 #'
396 sub DelShelf {
397         unless (@_) {
398                 carp "DelShelf called without valid argument (shelfnumber)";
399                 return undef;
400         }
401         my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?");
402         return $sth->execute(shift);
403 }
404
405 1;
406
407 __END__
408
409 =back
410
411 =head1 AUTHOR
412
413 Koha Developement team <info@koha.org>
414
415 =head1 SEE ALSO
416
417 C4::Circulation::Circ2(3)
418
419 =cut