Allow all argument forms to GetBranchesLoops.
[koha.git] / C4 / Branch.pm
1 package C4::Branch;
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 2 of the License, or (at your option) any later
8 # version.
9 #
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along with
15 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
16 # Suite 330, Boston, MA  02111-1307 USA
17
18
19 use strict;
20 require Exporter;
21 use C4::Context;
22 use C4::Koha;
23
24 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
25
26 BEGIN {
27         # set the version for version checking
28         $VERSION = 3.01;
29         @ISA    = qw(Exporter);
30         @EXPORT = qw(
31                 &GetBranchCategory
32                 &GetBranchName
33                 &GetBranch
34                 &GetBranches
35                 &GetBranchesLoop
36                 &GetBranchDetail
37                 &get_branchinfos_of
38                 &ModBranch
39                 &CheckBranchCategorycode
40                 &GetBranchInfo
41                 &GetCategoryTypes
42                 &GetBranchCategories
43                 &GetBranchesInCategory
44                 &ModBranchCategoryInfo
45                 &DelBranch
46                 &DelBranchCategory
47         );
48 }
49
50 =head1 NAME
51
52 C4::Branch - Koha branch module
53
54 =head1 SYNOPSIS
55
56 use C4::Branch;
57
58 =head1 DESCRIPTION
59
60 The functions in this module deal with branches.
61
62 =head1 FUNCTIONS
63
64 =head2 GetBranches
65
66   $branches = &GetBranches();
67   returns informations about ALL branches.
68   Create a branch selector with the following code
69   IndependantBranches Insensitive...
70   GetBranchInfo() returns the same information without the problems of this function 
71   (namespace collision, mainly).  You should probably use that, and replace GetBranches()
72   with GetBranchInfo() where you see it in the code.
73   
74 =head3 in PERL SCRIPT
75
76 my $branches = GetBranches;
77 my @branchloop;
78 foreach my $thisbranch (keys %$branches) {
79     my $selected = 1 if $thisbranch eq $branch;
80     my %row =(value => $thisbranch,
81                 selected => $selected,
82                 branchname => $branches->{$thisbranch}->{'branchname'},
83             );
84     push @branchloop, \%row;
85 }
86
87 =head3 in TEMPLATE
88             <select name="branch">
89                 <option value="">Default</option>
90             <!-- TMPL_LOOP name="branchloop" -->
91                 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="branchname" --></option>
92             <!-- /TMPL_LOOP -->
93             </select>
94
95 =cut
96
97 sub GetBranches {
98     my ($onlymine)=@_;
99     # returns a reference to a hash of references to ALL branches...
100     my %branches;
101     my $dbh = C4::Context->dbh;
102     my $sth;
103     my $query="SELECT * FROM branches";
104     my @bind_parameters;
105     if ($onlymine && C4::Context->userenv && C4::Context->userenv->{branch}){
106       $query .= ' WHERE branchcode = ? ';
107       push @bind_parameters, C4::Context->userenv->{branch};
108     }
109         $query.=" ORDER BY branchname";
110     $sth = $dbh->prepare($query);
111     $sth->execute( @bind_parameters );
112     while ( my $branch = $sth->fetchrow_hashref ) {
113         my $nsth =
114           $dbh->prepare(
115             "SELECT categorycode FROM branchrelations WHERE branchcode = ?");
116         $nsth->execute( $branch->{'branchcode'} );
117         while ( my ($cat) = $nsth->fetchrow_array ) {
118
119             # FIXME - This seems wrong. It ought to be
120             # $branch->{categorycodes}{$cat} = 1;
121             # otherwise, there's a namespace collision if there's a
122             # category with the same name as a field in the 'branches'
123             # table (i.e., don't create a category called "issuing").
124             # In addition, the current structure doesn't really allow
125             # you to list the categories that a branch belongs to:
126             # you'd have to list keys %$branch, and remove those keys
127             # that aren't fields in the "branches" table.
128          #   $branch->{$cat} = 1;
129             $branch->{category}{$cat} = 1;
130         }
131         $branches{ $branch->{'branchcode'} } = $branch;
132     }
133     return ( \%branches );
134 }
135
136 sub GetBranchesLoop (;$$) {  # since this is what most pages want anyway
137     my $branch   = @_ ? shift : '';     # optional first argument is branchcode of "my branch", if preselection is wanted.
138     my $onlymine = @_ ? shift : C4::Context->preference("IndependantBranches");
139     my $branches = GetBranches($onlymine);
140     my @loop;
141     foreach (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) {
142         push @loop, {
143             value => $_,
144             selected => ($_ eq $branch) ? 1 : 0, 
145             branchname => $branches->{$_}->{branchname},
146         };
147     }
148     return \@loop;
149 }
150
151 =head2 GetBranchName
152
153 =cut
154
155 sub GetBranchName {
156     my ($branchcode) = @_;
157     my $dbh = C4::Context->dbh;
158     my $sth;
159     $sth = $dbh->prepare("Select branchname from branches where branchcode=?");
160     $sth->execute($branchcode);
161     my $branchname = $sth->fetchrow_array;
162     $sth->finish;
163     return ($branchname);
164 }
165
166 =head2 ModBranch
167
168 &ModBranch($newvalue);
169
170 This function modify an existing branches.
171
172 C<$newvalue> is a ref to an array wich is containt all the column from branches table.
173
174 =cut
175
176 sub ModBranch {
177     my ($data) = @_;
178     
179     my $dbh    = C4::Context->dbh;
180     if ($data->{add}) {
181         my $query  = "
182             INSERT INTO branches
183             (branchcode,branchname,branchaddress1,
184             branchaddress2,branchaddress3,branchphone,
185             branchfax,branchemail,branchip,branchprinter)
186             VALUES (?,?,?,?,?,?,?,?,?,?)
187         ";
188         my $sth    = $dbh->prepare($query);
189         $sth->execute(
190             $data->{'branchcode'},       $data->{'branchname'},
191             $data->{'branchaddress1'},   $data->{'branchaddress2'},
192             $data->{'branchaddress3'},   $data->{'branchphone'},
193             $data->{'branchfax'},        $data->{'branchemail'},
194             $data->{'branchip'},         $data->{'branchprinter'},
195         );
196     } else {
197         my $query  = "
198             UPDATE branches
199             SET branchname=?,branchaddress1=?,
200                 branchaddress2=?,branchaddress3=?,branchphone=?,
201                 branchfax=?,branchemail=?,branchip=?,branchprinter=?
202             WHERE branchcode=?
203         ";
204         my $sth    = $dbh->prepare($query);
205         $sth->execute(
206             $data->{'branchname'},
207             $data->{'branchaddress1'},   $data->{'branchaddress2'},
208             $data->{'branchaddress3'},   $data->{'branchphone'},
209             $data->{'branchfax'},        $data->{'branchemail'},
210             $data->{'branchip'},         $data->{'branchprinter'},
211             $data->{'branchcode'},
212         );
213     }
214     # sort out the categories....
215     my @checkedcats;
216     my $cats = GetBranchCategory();
217     foreach my $cat (@$cats) {
218         my $code = $cat->{'categorycode'};
219         if ( $data->{$code} ) {
220             push( @checkedcats, $code );
221         }
222     }
223     my $branchcode = uc( $data->{'branchcode'} );
224     my $branch     = GetBranchInfo($branchcode);
225     $branch = $branch->[0];
226     my $branchcats = $branch->{'categories'};
227     my @addcats;
228     my @removecats;
229     foreach my $bcat (@$branchcats) {
230
231         unless ( grep { /^$bcat$/ } @checkedcats ) {
232             push( @removecats, $bcat );
233         }
234     }
235     foreach my $ccat (@checkedcats) {
236         unless ( grep { /^$ccat$/ } @$branchcats ) {
237             push( @addcats, $ccat );
238         }
239     }
240     foreach my $cat (@addcats) {
241         my $sth =
242           $dbh->prepare(
243 "insert into branchrelations (branchcode, categorycode) values(?, ?)"
244           );
245         $sth->execute( $branchcode, $cat );
246         $sth->finish;
247     }
248     foreach my $cat (@removecats) {
249         my $sth =
250           $dbh->prepare(
251             "delete from branchrelations where branchcode=? and categorycode=?"
252           );
253         $sth->execute( $branchcode, $cat );
254         $sth->finish;
255     }
256 }
257
258 =head2 GetBranchCategory
259
260 $results = GetBranchCategory($categorycode);
261
262 C<$results> is an ref to an array.
263
264 =cut
265
266 sub GetBranchCategory {
267
268     # returns a reference to an array of hashes containing branches,
269     my ($catcode) = @_;
270     my $dbh = C4::Context->dbh;
271     my $sth;
272
273     #    print DEBUG "GetBranchCategory: entry: catcode=".cvs($catcode)."\n";
274     if ($catcode) {
275         $sth =
276           $dbh->prepare(
277             "select * from branchcategories where categorycode = ?");
278         $sth->execute($catcode);
279     }
280     else {
281         $sth = $dbh->prepare("Select * from branchcategories");
282         $sth->execute();
283     }
284     my @results;
285     while ( my $data = $sth->fetchrow_hashref ) {
286         push( @results, $data );
287     }
288     $sth->finish;
289
290     #    print DEBUG "GetBranchCategory: exit: returning ".cvs(\@results)."\n";
291     return \@results;
292 }
293
294 =head2 GetBranchCategories
295
296   my $categories = GetBranchCategories($branchcode,$categorytype);
297
298 Returns a list ref of anon hashrefs with keys eq columns of branchcategories table,
299 i.e. categorycode, categorydescription, categorytype, categoryname.
300 if $branchcode and/or $categorytype are passed, limit set to categories that
301 $branchcode is a member of , and to $categorytype.
302
303 =cut
304
305 sub GetBranchCategories {
306     my ($branchcode,$categorytype) = @_;
307         my $dbh = C4::Context->dbh();
308         my $query = "SELECT c.* FROM branchcategories c";
309         my (@where, @bind);
310         if($branchcode) {
311                 $query .= ",branchrelations r, branches b ";
312                 push @where, "c.categorycode=r.categorycode and r.branchcode=? ";  
313                 push @bind , $branchcode;
314         }
315         if ($categorytype) {
316                 push @where, " c.categorytype=? ";
317                 push @bind, $categorytype;
318         }
319         $query .= " where " . join(" and ", @where) if(@where);
320         $query .= " order by categorytype,c.categorycode";
321         my $sth=$dbh->prepare( $query);
322         $sth->execute(@bind);
323         
324         my $branchcats = $sth->fetchall_arrayref({});
325         $sth->finish();
326         return( $branchcats );
327 }
328
329 =head2 GetCategoryTypes
330
331 $categorytypes = GetCategoryTypes;
332 returns a list of category types.
333 Currently these types are HARDCODED.
334 type: 'searchdomain' defines a group of agencies that the calling library may search in.
335 Other usage of agency categories falls under type: 'properties'.
336         to allow for other uses of categories.
337 The searchdomain bit may be better implemented as a separate module, but
338 the categories were already here, and minimally used.
339 =cut
340
341         #TODO  manage category types.  rename possibly to 'agency domains' ? as borrowergroups are called categories.
342 sub GetCategoryTypes() {
343         return ( 'searchdomain','properties');
344 }
345
346 =head2 GetBranch
347
348 $branch = GetBranch( $query, $branches );
349
350 =cut
351
352 sub GetBranch ($$) {
353     my ( $query, $branches ) = @_;    # get branch for this query from branches
354     my $branch = $query->param('branch');
355     my %cookie = $query->cookie('userenv');
356     ($branch)                || ($branch = $cookie{'branchname'});
357     ( $branches->{$branch} ) || ( $branch = ( keys %$branches )[0] );
358     return $branch;
359 }
360
361 =head2 GetBranchDetail
362
363   $branchname = &GetBranchDetail($branchcode);
364
365 Given the branch code, the function returns the corresponding
366 branch name for a comprehensive information display
367
368 =cut
369
370 sub GetBranchDetail {
371     my ($branchcode) = @_;
372     my $dbh = C4::Context->dbh;
373     my $sth = $dbh->prepare("SELECT * FROM branches WHERE branchcode = ?");
374     $sth->execute($branchcode);
375     my $branchname = $sth->fetchrow_hashref();
376     $sth->finish();
377     return $branchname;
378 }
379
380 =head2 get_branchinfos_of
381
382   my $branchinfos_of = get_branchinfos_of(@branchcodes);
383
384 Associates a list of branchcodes to the information of the branch, taken in
385 branches table.
386
387 Returns a href where keys are branchcodes and values are href where keys are
388 branch information key.
389
390   print 'branchname is ', $branchinfos_of->{$code}->{branchname};
391
392 =cut
393
394 sub get_branchinfos_of {
395     my @branchcodes = @_;
396
397     my $query = '
398     SELECT branchcode,
399        branchname
400     FROM branches
401     WHERE branchcode IN ('
402       . join( ',', map( { "'" . $_ . "'" } @branchcodes ) ) . ')
403 ';
404     return C4::Koha::get_infos_of( $query, 'branchcode' );
405 }
406
407
408 =head2 GetBranchesInCategory
409
410   my $branches = GetBranchesInCategory($categorycode);
411
412 Returns a href:  keys %$branches eq (branchcode,branchname) .
413
414 =cut
415
416 sub GetBranchesInCategory($) {
417     my ($categorycode) = @_;
418         my @branches;
419         my $dbh = C4::Context->dbh();
420         my $sth=$dbh->prepare( "SELECT b.branchcode FROM branchrelations r, branches b 
421                                                         where r.branchcode=b.branchcode and r.categorycode=?");
422     $sth->execute($categorycode);
423         while (my $branch = $sth->fetchrow) {
424                 push @branches, $branch;
425         }
426         $sth->finish();
427         return( \@branches );
428 }
429
430 =head2 GetBranchInfo
431
432 $results = GetBranchInfo($branchcode);
433
434 returns C<$results>, a reference to an array of hashes containing branches.
435 if $branchcode, just this branch, with associated categories.
436 if ! $branchcode && $categorytype, all branches in the category.
437 =cut
438
439 sub GetBranchInfo {
440     my ($branchcode,$categorytype) = @_;
441     my $dbh = C4::Context->dbh;
442     my $sth;
443
444
445         if ($branchcode) {
446         $sth =
447           $dbh->prepare(
448             "Select * from branches where branchcode = ? order by branchcode");
449         $sth->execute($branchcode);
450     }
451     else {
452         $sth = $dbh->prepare("Select * from branches order by branchcode");
453         $sth->execute();
454     }
455     my @results;
456     while ( my $data = $sth->fetchrow_hashref ) {
457                 my @bind = ($data->{'branchcode'});
458         my $query= "select r.categorycode from branchrelations r";
459                 $query .= ", branchcategories c " if($categorytype);
460                 $query .= " where  branchcode=? ";
461                 if($categorytype) { 
462                         $query .= " and c.categorytype=? and r.categorycode=c.categorycode";
463                         push @bind, $categorytype;
464                 }
465         my $nsth=$dbh->prepare($query);
466                 $nsth->execute( @bind );
467         my @cats = ();
468         while ( my ($cat) = $nsth->fetchrow_array ) {
469             push( @cats, $cat );
470         }
471         $nsth->finish;
472         $data->{'categories'} = \@cats;
473         push( @results, $data );
474     }
475     $sth->finish;
476     return \@results;
477 }
478
479 =head2 DelBranch
480
481 &DelBranch($branchcode);
482
483 =cut
484
485 sub DelBranch {
486     my ($branchcode) = @_;
487     my $dbh = C4::Context->dbh;
488     my $sth = $dbh->prepare("delete from branches where branchcode = ?");
489     $sth->execute($branchcode);
490     $sth->finish;
491 }
492
493 =head2 ModBranchCategoryInfo
494
495 &ModBranchCategoryInfo($data);
496 sets the data from the editbranch form, and writes to the database...
497
498 =cut
499
500 sub ModBranchCategoryInfo {
501     my ($data) = @_;
502     my $dbh    = C4::Context->dbh;
503         if ($data->{'add'}){
504                 # we are doing an insert
505                 my $sth   = $dbh->prepare("INSERT INTO branchcategories (categorycode,categoryname,codedescription,categorytype) VALUES (?,?,?,?)");
506                 $sth->execute(uc( $data->{'categorycode'} ),$data->{'categoryname'}, $data->{'codedescription'},$data->{'categorytype'} );
507                 $sth->finish();         
508         }
509         else {
510                 # modifying
511                 my $sth = $dbh->prepare("UPDATE branchcategories SET categoryname=?,codedescription=?,categorytype=? WHERE categorycode=?");
512                 $sth->execute($data->{'categoryname'}, $data->{'codedescription'},$data->{'categorytype'},uc( $data->{'categorycode'} ) );
513                 $sth->finish();
514         }
515 }
516
517 =head2 DeleteBranchCategory
518
519 DeleteBranchCategory($categorycode);
520
521 =cut
522
523 sub DelBranchCategory {
524     my ($categorycode) = @_;
525     my $dbh = C4::Context->dbh;
526     my $sth = $dbh->prepare("delete from branchcategories where categorycode = ?");
527     $sth->execute($categorycode);
528     $sth->finish;
529 }
530
531 =head2 CheckBranchCategorycode
532
533 $number_rows_affected = CheckBranchCategorycode($categorycode);
534
535 =cut
536
537 sub CheckBranchCategorycode {
538
539     # check to see if the branchcode is being used in the database somewhere....
540     my ($categorycode) = @_;
541     my $dbh            = C4::Context->dbh;
542     my $sth            =
543       $dbh->prepare(
544         "select count(*) from branchrelations where categorycode=?");
545     $sth->execute($categorycode);
546     my ($total) = $sth->fetchrow_array;
547     return $total;
548 }
549
550 1;
551 __END__
552
553 =head1 AUTHOR
554
555 Koha Developement team <info@koha.org>
556
557 =cut