package C4::Branch; # This file is part of Koha. # # Koha is free software; you can redistribute it and/or modify it under the # terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. # # Koha is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, # Suite 330, Boston, MA 02111-1307 USA use strict; #use warnings; FIXME - Bug 2505 require Exporter; use C4::Context; use C4::Koha; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); BEGIN { # set the version for version checking $VERSION = 3.02; @ISA = qw(Exporter); @EXPORT = qw( &GetBranchCategory &GetBranchName &GetBranch &GetBranches &GetBranchesLoop &GetBranchDetail &get_branchinfos_of &ModBranch &CheckBranchCategorycode &GetBranchInfo &GetCategoryTypes &GetBranchCategories &GetBranchesInCategory &ModBranchCategoryInfo &DelBranch &DelBranchCategory &CheckCategoryUnique &mybranch ); @EXPORT_OK = qw( &onlymine &mybranch get_branch_code_from_name ); } =head1 NAME C4::Branch - Koha branch module =head1 SYNOPSIS use C4::Branch; =head1 DESCRIPTION The functions in this module deal with branches. =head1 FUNCTIONS =head2 GetBranches $branches = &GetBranches(); Returns informations about ALL branches, IndependantBranches Insensitive. GetBranchInfo() returns the same information without the problems of this function (namespace collision, mainly). Create a branch selector with the following code. =head3 in PERL SCRIPT my $branches = GetBranches; my @branchloop; foreach my $thisbranch (sort keys %$branches) { my $selected = 1 if $thisbranch eq $branch; my %row =(value => $thisbranch, selected => $selected, branchname => $branches->{$thisbranch}->{branchname}, ); push @branchloop, \%row; } =head3 in TEMPLATE =head4 Note that you often will want to just use GetBranchesLoop, for exactly the example above. =cut sub GetBranches { my ($onlymine)=@_; # returns a reference to a hash of references to ALL branches... my %branches; my $dbh = C4::Context->dbh; my $sth; my $query="SELECT * FROM branches"; my @bind_parameters; if ($onlymine && C4::Context->userenv && C4::Context->userenv->{branch}){ $query .= ' WHERE branchcode = ? '; push @bind_parameters, C4::Context->userenv->{branch}; } $query.=" ORDER BY branchname"; $sth = $dbh->prepare($query); $sth->execute( @bind_parameters ); my $nsth = $dbh->prepare( "SELECT categorycode FROM branchrelations WHERE branchcode = ?" ); # prepare once, outside while loop while ( my $branch = $sth->fetchrow_hashref ) { $nsth->execute( $branch->{'branchcode'} ); while ( my ($cat) = $nsth->fetchrow_array ) { # FIXME - This seems wrong. It ought to be # $branch->{categorycodes}{$cat} = 1; # otherwise, there's a namespace collision if there's a # category with the same name as a field in the 'branches' # table (i.e., don't create a category called "issuing"). # In addition, the current structure doesn't really allow # you to list the categories that a branch belongs to: # you'd have to list keys %$branch, and remove those keys # that aren't fields in the "branches" table. # $branch->{$cat} = 1; $branch->{category}{$cat} = 1; } $branches{ $branch->{'branchcode'} } = $branch; } return ( \%branches ); } sub onlymine { return C4::Context->preference('IndependantBranches') && C4::Context->userenv && C4::Context->userenv->{flags} %2 != 1 && C4::Context->userenv->{branch} ; } # always returns a string for OK comparison via "eq" or "ne" sub mybranch { C4::Context->userenv or return ''; return C4::Context->userenv->{branch} || ''; } sub GetBranchesLoop (;$$) { # since this is what most pages want anyway my $branch = @_ ? shift : mybranch(); # optional first argument is branchcode of "my branch", if preselection is wanted. my $onlymine = @_ ? shift : onlymine(); my $branches = GetBranches($onlymine); my @loop; foreach (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) { push @loop, { value => $_, selected => ($_ eq $branch) ? 1 : 0, branchname => $branches->{$_}->{branchname}, }; } return \@loop; } =head2 GetBranchName =cut sub GetBranchName { my ($branchcode) = @_; my $dbh = C4::Context->dbh; my $sth; $sth = $dbh->prepare("Select branchname from branches where branchcode=?"); $sth->execute($branchcode); my $branchname = $sth->fetchrow_array; $sth->finish; return ($branchname); } =head2 ModBranch $error = &ModBranch($newvalue); This function modify an existing branch C<$newvalue> is a ref to an array wich is containt all the column from branches table. =cut sub ModBranch { my ($data) = @_; my $dbh = C4::Context->dbh; if ($data->{add}) { my $query = " INSERT INTO branches (branchcode,branchname,branchaddress1, branchaddress2,branchaddress3,branchzip,branchcity, branchcountry,branchphone,branchfax,branchemail, branchurl,branchip,branchprinter,branchnotes) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; my $sth = $dbh->prepare($query); $sth->execute( $data->{'branchcode'}, $data->{'branchname'}, $data->{'branchaddress1'}, $data->{'branchaddress2'}, $data->{'branchaddress3'}, $data->{'branchzip'}, $data->{'branchcity'}, $data->{'branchcountry'}, $data->{'branchphone'}, $data->{'branchfax'}, $data->{'branchemail'}, $data->{'branchurl'}, $data->{'branchip'}, $data->{'branchprinter'}, $data->{'branchnotes'}, ); return 1 if $dbh->err; } else { my $query = " UPDATE branches SET branchname=?,branchaddress1=?, branchaddress2=?,branchaddress3=?,branchzip=?, branchcity=?,branchcountry=?,branchphone=?, branchfax=?,branchemail=?,branchurl=?,branchip=?, branchprinter=?,branchnotes=? WHERE branchcode=? "; my $sth = $dbh->prepare($query); $sth->execute( $data->{'branchname'}, $data->{'branchaddress1'}, $data->{'branchaddress2'}, $data->{'branchaddress3'}, $data->{'branchzip'}, $data->{'branchcity'}, $data->{'branchcountry'}, $data->{'branchphone'}, $data->{'branchfax'}, $data->{'branchemail'}, $data->{'branchurl'}, $data->{'branchip'}, $data->{'branchprinter'}, $data->{'branchnotes'}, $data->{'branchcode'}, ); } # sort out the categories.... my @checkedcats; my $cats = GetBranchCategory(); foreach my $cat (@$cats) { my $code = $cat->{'categorycode'}; if ( $data->{$code} ) { push( @checkedcats, $code ); } } my $branchcode = uc( $data->{'branchcode'} ); my $branch = GetBranchInfo($branchcode); $branch = $branch->[0]; my $branchcats = $branch->{'categories'}; my @addcats; my @removecats; foreach my $bcat (@$branchcats) { unless ( grep { /^$bcat$/ } @checkedcats ) { push( @removecats, $bcat ); } } foreach my $ccat (@checkedcats) { unless ( grep { /^$ccat$/ } @$branchcats ) { push( @addcats, $ccat ); } } foreach my $cat (@addcats) { my $sth = $dbh->prepare( "insert into branchrelations (branchcode, categorycode) values(?, ?)" ); $sth->execute( $branchcode, $cat ); $sth->finish; } foreach my $cat (@removecats) { my $sth = $dbh->prepare( "delete from branchrelations where branchcode=? and categorycode=?" ); $sth->execute( $branchcode, $cat ); $sth->finish; } } =head2 GetBranchCategory $results = GetBranchCategory($categorycode); C<$results> is an ref to an array. =cut sub GetBranchCategory { # returns a reference to an array of hashes containing branches, my ($catcode) = @_; my $dbh = C4::Context->dbh; my $sth; # print DEBUG "GetBranchCategory: entry: catcode=".cvs($catcode)."\n"; if ($catcode) { $sth = $dbh->prepare( "select * from branchcategories where categorycode = ?"); $sth->execute($catcode); } else { $sth = $dbh->prepare("Select * from branchcategories"); $sth->execute(); } my @results; while ( my $data = $sth->fetchrow_hashref ) { push( @results, $data ); } $sth->finish; # print DEBUG "GetBranchCategory: exit: returning ".cvs(\@results)."\n"; return \@results; } =head2 GetBranchCategories my $categories = GetBranchCategories($branchcode,$categorytype); Returns a list ref of anon hashrefs with keys eq columns of branchcategories table, i.e. categorycode, categorydescription, categorytype, categoryname. if $branchcode and/or $categorytype are passed, limit set to categories that $branchcode is a member of , and to $categorytype. =cut sub GetBranchCategories { my ($branchcode,$categorytype) = @_; my $dbh = C4::Context->dbh(); my $query = "SELECT c.* FROM branchcategories c"; my (@where, @bind); if($branchcode) { $query .= ",branchrelations r, branches b "; push @where, "c.categorycode=r.categorycode and r.branchcode=? "; push @bind , $branchcode; } if ($categorytype) { push @where, " c.categorytype=? "; push @bind, $categorytype; } $query .= " where " . join(" and ", @where) if(@where); $query .= " order by categorytype,c.categorycode"; my $sth=$dbh->prepare( $query); $sth->execute(@bind); my $branchcats = $sth->fetchall_arrayref({}); $sth->finish(); return( $branchcats ); } =head2 GetCategoryTypes $categorytypes = GetCategoryTypes; returns a list of category types. Currently these types are HARDCODED. type: 'searchdomain' defines a group of agencies that the calling library may search in. Other usage of agency categories falls under type: 'properties'. to allow for other uses of categories. The searchdomain bit may be better implemented as a separate module, but the categories were already here, and minimally used. =cut #TODO manage category types. rename possibly to 'agency domains' ? as borrowergroups are called categories. sub GetCategoryTypes() { return ( 'searchdomain','properties'); } =head2 GetBranch $branch = GetBranch( $query, $branches ); =cut sub GetBranch ($$) { my ( $query, $branches ) = @_; # get branch for this query from branches my $branch = $query->param('branch'); my %cookie = $query->cookie('userenv'); ($branch) || ($branch = $cookie{'branchname'}); ( $branches->{$branch} ) || ( $branch = ( keys %$branches )[0] ); return $branch; } =head2 GetBranchDetail $branch = &GetBranchDetail($branchcode); Given the branch code, the function returns a hashref for the corresponding row in the branches table. =cut sub GetBranchDetail { my ($branchcode) = shift or return; my $sth = C4::Context->dbh->prepare("SELECT * FROM branches WHERE branchcode = ?"); $sth->execute($branchcode); return $sth->fetchrow_hashref(); } =head2 get_branchinfos_of my $branchinfos_of = get_branchinfos_of(@branchcodes); Associates a list of branchcodes to the information of the branch, taken in branches table. Returns a href where keys are branchcodes and values are href where keys are branch information key. print 'branchname is ', $branchinfos_of->{$code}->{branchname}; =cut sub get_branchinfos_of { my @branchcodes = @_; my $query = ' SELECT branchcode, branchname FROM branches WHERE branchcode IN (' . join( ',', map( { "'" . $_ . "'" } @branchcodes ) ) . ') '; return C4::Koha::get_infos_of( $query, 'branchcode' ); } =head2 GetBranchesInCategory my $branches = GetBranchesInCategory($categorycode); Returns a href: keys %$branches eq (branchcode,branchname) . =cut sub GetBranchesInCategory($) { my ($categorycode) = @_; my @branches; my $dbh = C4::Context->dbh(); my $sth=$dbh->prepare( "SELECT b.branchcode FROM branchrelations r, branches b where r.branchcode=b.branchcode and r.categorycode=?"); $sth->execute($categorycode); while (my $branch = $sth->fetchrow) { push @branches, $branch; } $sth->finish(); return( \@branches ); } =head2 GetBranchInfo $results = GetBranchInfo($branchcode); returns C<$results>, a reference to an array of hashes containing branches. if $branchcode, just this branch, with associated categories. if ! $branchcode && $categorytype, all branches in the category. =cut sub GetBranchInfo { my ($branchcode,$categorytype) = @_; my $dbh = C4::Context->dbh; my $sth; if ($branchcode) { $sth = $dbh->prepare( "Select * from branches where branchcode = ? order by branchcode"); $sth->execute($branchcode); } else { $sth = $dbh->prepare("Select * from branches order by branchcode"); $sth->execute(); } my @results; while ( my $data = $sth->fetchrow_hashref ) { my @bind = ($data->{'branchcode'}); my $query= "select r.categorycode from branchrelations r"; $query .= ", branchcategories c " if($categorytype); $query .= " where branchcode=? "; if($categorytype) { $query .= " and c.categorytype=? and r.categorycode=c.categorycode"; push @bind, $categorytype; } my $nsth=$dbh->prepare($query); $nsth->execute( @bind ); my @cats = (); while ( my ($cat) = $nsth->fetchrow_array ) { push( @cats, $cat ); } $nsth->finish; $data->{'categories'} = \@cats; push( @results, $data ); } $sth->finish; return \@results; } =head2 DelBranch &DelBranch($branchcode); =cut sub DelBranch { my ($branchcode) = @_; my $dbh = C4::Context->dbh; my $sth = $dbh->prepare("delete from branches where branchcode = ?"); $sth->execute($branchcode); $sth->finish; } =head2 ModBranchCategoryInfo &ModBranchCategoryInfo($data); sets the data from the editbranch form, and writes to the database... =cut sub ModBranchCategoryInfo { my ($data) = @_; my $dbh = C4::Context->dbh; if ($data->{'add'}){ # we are doing an insert my $sth = $dbh->prepare("INSERT INTO branchcategories (categorycode,categoryname,codedescription,categorytype) VALUES (?,?,?,?)"); $sth->execute(uc( $data->{'categorycode'} ),$data->{'categoryname'}, $data->{'codedescription'},$data->{'categorytype'} ); $sth->finish(); } else { # modifying my $sth = $dbh->prepare("UPDATE branchcategories SET categoryname=?,codedescription=?,categorytype=? WHERE categorycode=?"); $sth->execute($data->{'categoryname'}, $data->{'codedescription'},$data->{'categorytype'},uc( $data->{'categorycode'} ) ); $sth->finish(); } } =head2 CheckCategoryUnique if (CheckCategoryUnique($categorycode)){ # do something } =cut sub CheckCategoryUnique { my $categorycode = shift; my $dbh = C4::Context->dbh; my $sth = $dbh->prepare("SELECT categorycode FROM branchcategories WHERE categorycode = ?"); $sth->execute(uc( $categorycode) ); if (my $data = $sth->fetchrow_hashref){ return 0; } else { return 1; } } =head2 DeleteBranchCategory DeleteBranchCategory($categorycode); =cut sub DelBranchCategory { my ($categorycode) = @_; my $dbh = C4::Context->dbh; my $sth = $dbh->prepare("delete from branchcategories where categorycode = ?"); $sth->execute($categorycode); $sth->finish; } =head2 CheckBranchCategorycode $number_rows_affected = CheckBranchCategorycode($categorycode); =cut sub CheckBranchCategorycode { # check to see if the branchcode is being used in the database somewhere.... my ($categorycode) = @_; my $dbh = C4::Context->dbh; my $sth = $dbh->prepare( "select count(*) from branchrelations where categorycode=?"); $sth->execute($categorycode); my ($total) = $sth->fetchrow_array; return $total; } sub get_branch_code_from_name { my @branch_name = @_; my $query = "SELECT branchcode FROM branches WHERE branchname=?;"; my $dbh = C4::Context->dbh(); my $sth = $dbh->prepare($query); $sth->execute(@branch_name); return $sth->fetchrow_array; } 1; __END__ =head1 AUTHOR Koha Development Team =cut