@@ -, +, @@ LibA LibB LibC LibD LibE LibF LibG LibH LibA but instead of being limited to just your library, you should have access to everything within your library group. Example: Try to edit an item. If the item is owned by a library in your group, you should be able to edit it. --- C4/Acquisition.pm | 16 +- C4/Branch.pm | 98 +++++++++- C4/Circulation.pm | 11 +- C4/Items.pm | 44 +++-- C4/Letters.pm | 2 +- C4/Members.pm | 109 ++++++----- C4/Serials.pm | 111 +++++++---- C4/Suggestions.pm | 40 +++-- acqui/basket.pl | 27 ++- admin/branches.pl | 50 ++---- catalogue/moredetail.pl | 15 +- cataloguing/additem.pl | 13 +- circ/circulation-home.pl | 5 +- circ/pendingreserves.pl | 5 +- circ/reserveratios.pl | 6 +- installer/data/mysql/kohastructure.sql | 2 +- installer/data/mysql/updatedatabase.pl | 14 ++- .../prog/en/modules/admin/branches.tt | 206 +++++++++++++------- members/deletemem.pl | 12 +- 19 files changed, 521 insertions(+), 265 deletions(-) --- a/C4/Acquisition.pm +++ a/C4/Acquisition.pm @@ -876,9 +876,8 @@ sub GetPendingOrders { my $userenv = C4::Context->userenv; if ( C4::Context->preference("IndependentBranches") ) { if ( ($userenv) && ( $userenv->{flags} != 1 ) ) { - $strsth .= " AND (borrowers.branchcode = ? - or borrowers.branchcode = '')"; - push @query_params, $userenv->{branch}; + my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); + $strsth .= qq{ AND (borrowers.branchcode IN ( $branches ) OR borrowers.branchcode = '') }; } } if ($supplierid) { @@ -1740,7 +1739,8 @@ sub GetParcel { if ( C4::Context->preference("IndependentBranches") ) { my $userenv = C4::Context->userenv; if ( ($userenv) && ( $userenv->{flags} != 1 ) ) { - $strsth .= " and (borrowers.branchcode = ? + my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); + $strsth .= " and (borrowers.branchcode IN ( $branches ) or borrowers.branchcode = '')"; push @query_params, $userenv->{branch}; } @@ -1959,8 +1959,8 @@ sub GetLateOrders { if (C4::Context->preference("IndependentBranches") && C4::Context->userenv && C4::Context->userenv->{flags} != 1 ) { - $from .= ' AND borrowers.branchcode LIKE ? '; - push @query_params, C4::Context->userenv->{branch}; + my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); + $from .= qq{ AND borrowers.branchcode IN ( $branches ) }; } my $query = "$select $from $having\nORDER BY latesince, basketno, borrowers.branchcode, supplier"; $debug and print STDERR "GetLateOrders query: $query\nGetLateOrders args: " . join(" ",@query_params); @@ -2129,8 +2129,8 @@ sub GetHistory { if ( C4::Context->preference("IndependentBranches") ) { my $userenv = C4::Context->userenv; if ( $userenv && ($userenv->{flags} || 0) != 1 ) { - $query .= " AND (borrowers.branchcode = ? OR borrowers.branchcode ='' ) "; - push @query_params, $userenv->{branch}; + my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); + $query .= qq{ AND ( borrowers.branchcode = ? OR borrowers.branchcode IN ( $branches ) ) }; } } $query .= " ORDER BY id"; --- a/C4/Branch.pm +++ a/C4/Branch.pm @@ -19,6 +19,7 @@ package C4::Branch; use strict; #use warnings; FIXME - Bug 2505 require Exporter; +use Carp; use C4::Context; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @@ -42,6 +43,7 @@ BEGIN { &GetBranchCategories &GetBranchesInCategory &ModBranchCategoryInfo + &GetIndependentGroupModificationRights &DelBranch &DelBranchCategory &CheckCategoryUnique @@ -110,8 +112,8 @@ sub GetBranches { 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}; + my $branches = GetIndependentGroupModificationRights({ stringify => 1 }); + $query .= qq{ WHERE branchcode IN ( $branches ) }; } $query.=" ORDER BY branchname"; $sth = $dbh->prepare($query); @@ -299,16 +301,12 @@ 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( + $sth = $dbh->prepare( "select * from branchcategories where categorycode = ?"); $sth->execute($catcode); } @@ -316,14 +314,14 @@ sub GetBranchCategory { $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; + return wantarray() ? @results : \@results; } =head2 GetBranchCategories @@ -391,7 +389,7 @@ the categories were already here, and minimally used. #TODO manage category types. rename possibly to 'agency domains' ? as borrowergroups are called categories. sub GetCategoryTypes { - return ( 'searchdomain','properties'); + return ( 'searchdomain','independent_groups'); } =head2 GetBranch @@ -447,6 +445,86 @@ sub GetBranchesInCategory { return( \@branches ); } +=head2 GetIndependentGroupModificationRights + + GetIndependentGroupModificationRights( + { + branch => $this_branch, + for => $other_branch, + stringify => 1, + } + ); + + Returns a list of branches this branch shares a common + independent group with. + + If 'branch' is not provided, it will be looked up via + C4::Context->userenv->{branch}. + + If 'for' is provided, the lookup is limited to that branch. + + If called in a list context, returns a list of + branchcodes ( including $this_branch ). + + If called in a scalar context, it returns + a count of matching branchcodes. Returns 1 if + + If stringify param is passed, the return value will + be a string of the comma delimited branchcodes. This + is useful for "branchcode IN $branchcodes" clauses + in SQL queries. + + $this_branch and $other_branch are equal for efficiency. + + So you can write: + my @branches = GetIndependentGroupModificationRights(); + or something like: + if ( GetIndependentGroupModificationRights( { for => $other_branch } ) ) { do_stuff(); } + +=cut + +sub GetIndependentGroupModificationRights { + my ($params) = @_; + + my $this_branch = $params->{branch}; + my $other_branch = $params->{for}; + my $stringify = $params->{stringify}; + + $this_branch ||= C4::Context->userenv->{branch}; + + carp("No branch found!") unless ($this_branch); + + return 1 if ( $this_branch eq $other_branch ); + + my $sql = q{ + SELECT DISTINCT(branchcode) + FROM branchrelations + JOIN branchcategories USING ( categorycode ) + WHERE categorycode IN ( + SELECT categorycode + FROM branchrelations + WHERE branchcode = ? + ) + AND branchcategories.categorytype = 'independent_group' + }; + + my @params; + push( @params, $this_branch ); + + if ($other_branch) { + $sql .= q{ AND branchcode = ? }; + push( @params, $other_branch ); + } + + my $dbh = C4::Context->dbh; + my @branchcodes = @{ $dbh->selectcol_arrayref( $sql, {}, @params ) }; + + return join( ',', map { qq{'$_'} } ( @branchcodes, $this_branch ) ) + if ($stringify); + + return wantarray() ? ( @branchcodes, $this_branch ) : scalar(@branchcodes); +} + =head2 GetBranchInfo $results = GetBranchInfo($branchcode); --- a/C4/Circulation.pm +++ a/C4/Circulation.pm @@ -890,8 +890,15 @@ sub CanBookBeIssued { if ( C4::Context->preference("IndependentBranches") ) { unless ( C4::Context->IsSuperLibrarian() ) { $issuingimpossible{ITEMNOTSAMEBRANCH} = 1 - if ( $item->{C4::Context->preference("HomeOrHoldingBranch")} ne $userenv->{branch} ); - $needsconfirmation{BORRNOTSAMEBRANCH} = GetBranchName( $borrower->{'branchcode'} ) + unless ( + GetIndependentGroupModificationRights( + { + for => $item->{ C4::Context->preference("HomeOrHoldingBranch") } + } + ) + ); + $needsconfirmation{BORRNOTSAMEBRANCH} = + GetBranchName( $borrower->{'branchcode'} ) if ( $borrower->{'branchcode'} ne $userenv->{branch} ); } } --- a/C4/Items.pm +++ a/C4/Items.pm @@ -32,6 +32,7 @@ use C4::Log; use List::MoreUtils qw/any/; use Data::Dumper; # used as part of logging item record changes, not just for # debugging; so please don't remove this +use C4::Branch qw/GetIndependentGroupModificationRights/; use vars qw($VERSION @ISA @EXPORT); @@ -1247,18 +1248,22 @@ sub GetItemsInfo { my $datedue = ''; $isth->execute( $data->{'itemnumber'} ); if ( my $idata = $isth->fetchrow_hashref ) { - $data->{borrowernumber} = $idata->{borrowernumber}; - $data->{cardnumber} = $idata->{cardnumber}; - $data->{surname} = $idata->{surname}; - $data->{firstname} = $idata->{firstname}; + $data->{borrowernumber} = $idata->{borrowernumber}; + $data->{cardnumber} = $idata->{cardnumber}; + $data->{surname} = $idata->{surname}; + $data->{firstname} = $idata->{firstname}; $data->{lastreneweddate} = $idata->{lastreneweddate}; - $datedue = $idata->{'date_due'}; - if (C4::Context->preference("IndependentBranches")){ - my $userenv = C4::Context->userenv; - unless ( C4::Context->IsSuperLibrarian() ) { - $data->{'NOTSAMEBRANCH'} = 1 if ($idata->{'bcode'} ne $userenv->{branch}); - } - } + $datedue = $idata->{'date_due'}; + + if ( C4::Context->preference("IndependentBranches") ) { + unless ( + C4::Context->IsSuperLibrarian() + || GetIndependentGroupModificationRights( { for => $idata->{'bcode'} } ) + ) + { + $data->{'NOTSAMEBRANCH'} = 1; + } + } } if ( $data->{'serial'}) { $ssth->execute($data->{'itemnumber'}) ; @@ -2210,12 +2215,18 @@ sub DelItemCheck { my $item = GetItem($itemnumber); my $onloan=$sth->fetchrow; - if ($onloan){ - $error = "book_on_loan" + if ($onloan) { + $error = "book_on_loan"; } - elsif ( !( C4::Context->userenv->{flags} & 1 ) + elsif ( + !( C4::Context->userenv->{flags} & 1 ) and C4::Context->preference("IndependentBranches") - and ( C4::Context->userenv->{branch} ne $item->{'homebranch'} ) ) + and GetIndependentGroupModificationRights( + { + for => $item->{ C4::Context->preference("HomeOrHoldingBranch") } + } + ) + ) { $error = "not_same_branch"; } @@ -2691,7 +2702,8 @@ sub PrepareItemrecordDisplay { if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) { if ( ( C4::Context->preference("IndependentBranches") ) && !C4::Context->IsSuperLibrarian() ) { - my $sth = $dbh->prepare( "SELECT branchcode,branchname FROM branches WHERE branchcode = ? ORDER BY branchname" ); + my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); + my $sth = $dbh->prepare( "SELECT branchcode,branchname FROM branches WHERE branchcode IN ( $branches ) ORDER BY branchname" ); $sth->execute( C4::Context->userenv->{branch} ); push @authorised_values, "" unless ( $tagslib->{$tag}->{$subfield}->{mandatory} ); --- a/C4/Letters.pm +++ a/C4/Letters.pm @@ -126,7 +126,7 @@ our %letter; sub getletter { my ( $module, $code, $branchcode ) = @_; - $branchcode ||= ''; + $branchcode ||= q{}; if ( C4::Context->preference('IndependentBranches') and $branchcode --- a/C4/Members.pm +++ a/C4/Members.pm @@ -40,7 +40,7 @@ use DateTime; use DateTime::Format::DateParse; use Koha::DateUtils; use Text::Unaccent qw( unac_string ); - +use C4::Branch qw( GetIndependentGroupModificationRights ); our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug); BEGIN { @@ -199,6 +199,7 @@ sub _express_member_find { sub Search { my ( $filter, $orderby, $limit, $columns_out, $search_on_fields, $searchtype ) = @_; + warn "C4::Members::Search"; my $search_string; my $found_borrower; @@ -257,24 +258,22 @@ sub Search { # Mentioning for the reference if ( C4::Context->preference("IndependentBranches") ) { # && !$showallbranches){ - if ( my $userenv = C4::Context->userenv ) { - my $branch = $userenv->{'branch'}; - if ( !C4::Context->IsSuperLibrarian() && $branch ){ - if (my $fr = ref $filter) { - if ( $fr eq "HASH" ) { - $filter->{branchcode} = $branch; - } - else { - foreach (@$filter) { - $_ = { '' => $_ } unless ref $_; - $_->{branchcode} = $branch; - } - } + unless ( C4::Context->IsSuperLibrarian() ){ + my @branches = GetIndependentGroupModificationRights(); + if ( my $fr = ref $filter ) { + if ( $fr eq "HASH" ) { + $filter->{branchcode} = \@branches; } else { - $filter = { '' => $filter, branchcode => $branch }; + foreach (@$filter) { + $_ = { '' => $_ } unless ref $_; + $_->{branchcode} = \@branches; + } } - } + } + else { + $filter = { '' => $filter, branchcode => \@branches }; + } } } @@ -2041,13 +2040,14 @@ sub GetBorrowersToExpunge { my $filterdate = $params->{'not_borrowered_since'}; my $filterexpiry = $params->{'expired_before'}; my $filtercategory = $params->{'category_code'}; - my $filterbranch = $params->{'branchcode'} || - ((C4::Context->preference('IndependentBranches') - && C4::Context->userenv - && !C4::Context->IsSuperLibrarian() - && C4::Context->userenv->{branch}) - ? C4::Context->userenv->{branch} - : ""); + my $filterbranch = $params->{'branchcode'}; + my @filterbranches = + ( C4::Context->preference('IndependentBranches') + && C4::Context->userenv + && !C4::Context->IsSuperLibrarian() + && C4::Context->userenv->{branch} ) + ? GetIndependentGroupModificationRights() + : ($filterbranch); my $dbh = C4::Context->dbh; my $query = " @@ -2062,9 +2062,10 @@ sub GetBorrowersToExpunge { AND borrowernumber NOT IN (SELECT guarantorid FROM borrowers WHERE guarantorid IS NOT NULL AND guarantorid <> 0) "; my @query_params; - if ( $filterbranch && $filterbranch ne "" ) { - $query.= " AND borrowers.branchcode = ? "; - push( @query_params, $filterbranch ); + if ( @filterbranches ) { + my $placeholders = join( ',', ('?') x @filterbranches ); + $query.= " AND borrowers.branchcode IN ( $placeholders )"; + push( @query_params, @filterbranches ); } if ( $filterexpiry ) { $query .= " AND dateexpiry < ? "; @@ -2107,13 +2108,16 @@ I<$result> is a ref to an array which all elements are a hasref. =cut sub GetBorrowersWhoHaveNeverBorrowed { - my $filterbranch = shift || - ((C4::Context->preference('IndependentBranches') - && C4::Context->userenv - && !C4::Context->IsSuperLibrarian() - && C4::Context->userenv->{branch}) - ? C4::Context->userenv->{branch} - : ""); + my $filterbranch = shift; + + my @filterbranches = + ( C4::Context->preference('IndependentBranches') + && C4::Context->userenv + && !C4::Context->IsSuperLibrarian() + && C4::Context->userenv->{branch} ) + ? GetIndependentGroupModificationRights() + : ($filterbranch); + my $dbh = C4::Context->dbh; my $query = " SELECT borrowers.borrowernumber,max(timestamp) as latestissue @@ -2121,10 +2125,12 @@ sub GetBorrowersWhoHaveNeverBorrowed { LEFT JOIN issues ON borrowers.borrowernumber = issues.borrowernumber WHERE issues.borrowernumber IS NULL "; + my @query_params; - if ($filterbranch && $filterbranch ne ""){ - $query.=" AND borrowers.branchcode= ?"; - push @query_params,$filterbranch; + if (@filterbranches) { + my $placeholders = join( ',', ('?') x @filterbranches ); + $query .= " AND borrowers.branchcode IN ( $placeholders ) "; + push( @query_params, @filterbranches ); } warn $query if $debug; @@ -2157,25 +2163,32 @@ This hashref is containt the number of time this borrowers has borrowed before I sub GetBorrowersWithIssuesHistoryOlderThan { my $dbh = C4::Context->dbh; my $date = shift ||POSIX::strftime("%Y-%m-%d",localtime()); - my $filterbranch = shift || - ((C4::Context->preference('IndependentBranches') - && C4::Context->userenv - && !C4::Context->IsSuperLibrarian() - && C4::Context->userenv->{branch}) - ? C4::Context->userenv->{branch} - : ""); + my $filterbranch = shift; + + my @filterbranches = + ( C4::Context->preference('IndependentBranches') + && C4::Context->userenv + && !C4::Context->IsSuperLibrarian() + && C4::Context->userenv->{branch} ) + ? GetIndependentGroupModificationRights() + : ($filterbranch); + my $query = " SELECT count(borrowernumber) as n,borrowernumber FROM old_issues WHERE returndate < ? AND borrowernumber IS NOT NULL "; + my @query_params; - push @query_params, $date; - if ($filterbranch){ - $query.=" AND branchcode = ?"; - push @query_params, $filterbranch; - } + push( @query_params, $date ); + + if (@filterbranches) { + my $placeholders = join( ',', ('?') x @filterbranches ); + $query .= " AND branchcode IN ( $placeholders ) "; + push( @query_params, @filterbranches ); + } + $query.=" GROUP BY borrowernumber "; warn $query if $debug; my $sth = $dbh->prepare($query); --- a/C4/Serials.pm +++ a/C4/Serials.pm @@ -215,13 +215,20 @@ sub GetSerialInformation { my ($serialid) = @_; my $dbh = C4::Context->dbh; my $query = qq| - SELECT serial.*, serial.notes as sernotes, serial.status as serstatus,subscription.*,subscription.subscriptionid as subsid |; + SELECT serial.*, + serial.notes as sernotes, + serial.status as serstatus, + subscription.*, + subscription.subscriptionid as subsid + |; if ( C4::Context->preference('IndependentBranches') && C4::Context->userenv - && C4::Context->userenv->{'flags'} != 1 + && C4::Context->userenv->{'flags'} % 2 != 1 && C4::Context->userenv->{'branch'} ) { - $query .= " - , ((subscription.branchcode <>\"" . C4::Context->userenv->{'branch'} . "\") and subscription.branchcode <>\"\" and subscription.branchcode IS NOT NULL) as cannotedit "; + my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); + $query .= qq| + , ( ( subscription.branchcode NOT IN ( $branches ) ) AND subscription.branchcode <> '' AND subscription.branchcode IS NOT NULL ) AS cannotedit + |; } $query .= qq| FROM serial LEFT JOIN subscription ON subscription.subscriptionid=serial.subscriptionid @@ -315,33 +322,36 @@ subscription, subscriptionhistory, aqbooksellers.name, biblio.title sub GetSubscription { my ($subscriptionid) = @_; my $dbh = C4::Context->dbh; - my $query = qq( + + my $query = qq| SELECT subscription.*, subscriptionhistory.*, aqbooksellers.name AS aqbooksellername, biblio.title AS bibliotitle, - subscription.biblionumber as bibnum); + subscription.biblionumber as bibnum + |; + if ( C4::Context->preference('IndependentBranches') && C4::Context->userenv - && C4::Context->userenv->{'flags'} != 1 - && C4::Context->userenv->{'branch'} ) { - $query .= " - , ((subscription.branchcode <>\"" . C4::Context->userenv->{'branch'} . "\") and subscription.branchcode <>\"\" and subscription.branchcode IS NOT NULL) as cannotedit "; + && C4::Context->userenv->{'flags'} % 2 != 1 + && C4::Context->userenv->{'branch'} ) + { + my $branches = + GetIndependentGroupModificationRights( { stringify => 1 } ); + + $query .= qq| + , ( ( subscription.branchcode NOT IN ( $branches ) ) AND subscription.branchcode <> '' AND subscription.branchcode IS NOT NULL ) AS cannotedit + |; } - $query .= qq( + + $query .= qq| FROM subscription LEFT JOIN subscriptionhistory ON subscription.subscriptionid=subscriptionhistory.subscriptionid LEFT JOIN aqbooksellers ON subscription.aqbooksellerid=aqbooksellers.id LEFT JOIN biblio ON biblio.biblionumber=subscription.biblionumber WHERE subscription.subscriptionid = ? - ); + |; - # if (C4::Context->preference('IndependentBranches') && - # C4::Context->userenv && - # C4::Context->userenv->{'flags'} != 1){ - # # $debug and warn "flags: ".C4::Context->userenv->{'flags'}; - # $query.=" AND subscription.branchcode IN ('".C4::Context->userenv->{'branch'}."',\"\")"; - # } $debug and warn "query : $query\nsubsid :$subscriptionid"; my $sth = $dbh->prepare($query); $sth->execute($subscriptionid); @@ -358,8 +368,10 @@ sub GetSubscription { sub GetFullSubscription { my ($subscriptionid) = @_; my $dbh = C4::Context->dbh; - my $query = qq| - SELECT serial.serialid, + + my $query = qq| + SELECT + serial.serialid, serial.serialseq, serial.planneddate, serial.publisheddate, @@ -369,14 +381,22 @@ sub GetFullSubscription { aqbooksellers.name as aqbooksellername, biblio.title as bibliotitle, subscription.branchcode AS branchcode, - subscription.subscriptionid AS subscriptionid |; + subscription.subscriptionid AS subscriptionid + |; + if ( C4::Context->preference('IndependentBranches') && C4::Context->userenv - && C4::Context->userenv->{'flags'} != 1 - && C4::Context->userenv->{'branch'} ) { - $query .= " - , ((subscription.branchcode <>\"" . C4::Context->userenv->{'branch'} . "\") and subscription.branchcode <>\"\" and subscription.branchcode IS NOT NULL) as cannotedit "; + && C4::Context->userenv->{'flags'} % 2 != 1 + && C4::Context->userenv->{'branch'} ) + { + my $branches = + GetIndependentGroupModificationRights( { stringify => 1 } ); + + $query .= qq| + , ( ( subscription.branchcode NOT IN ( $branches ) ) AND subscription.branchcode <> '' AND subscription.branchcode IS NOT NULL ) AS cannotedit + |; } + $query .= qq| FROM serial LEFT JOIN subscription ON @@ -489,13 +509,16 @@ sub GetSubscriptionsFromBiblionumber { $subs->{ "periodicity" . $subs->{periodicity} } = 1; $subs->{ "numberpattern" . $subs->{numberpattern} } = 1; $subs->{ "status" . $subs->{'status'} } = 1; - $subs->{'cannotedit'} = - ( C4::Context->preference('IndependentBranches') + $subs->{'cannotedit'} = ( + C4::Context->preference('IndependentBranches') && C4::Context->userenv && !C4::Context->IsSuperLibrarian() && C4::Context->userenv->{branch} && $subs->{branchcode} - && ( C4::Context->userenv->{branch} ne $subs->{branchcode} ) ); + && GetIndependentGroupModificationRights( + { for => $subs->{branchcode} } + ) + ); if ( $subs->{enddate} eq '0000-00-00' ) { $subs->{enddate} = ''; @@ -519,8 +542,10 @@ sub GetSubscriptionsFromBiblionumber { sub GetFullSubscriptionsFromBiblionumber { my ($biblionumber) = @_; my $dbh = C4::Context->dbh; - my $query = qq| - SELECT serial.serialid, + + my $query = qq| + SELECT + serial.serialid, serial.serialseq, serial.planneddate, serial.publisheddate, @@ -529,13 +554,20 @@ sub GetFullSubscriptionsFromBiblionumber { year(IF(serial.publisheddate="00-00-0000",serial.planneddate,serial.publisheddate)) as year, biblio.title as bibliotitle, subscription.branchcode AS branchcode, - subscription.subscriptionid AS subscriptionid|; + subscription.subscriptionid AS subscriptionid + |; + if ( C4::Context->preference('IndependentBranches') && C4::Context->userenv && C4::Context->userenv->{'flags'} != 1 - && C4::Context->userenv->{'branch'} ) { - $query .= " - , ((subscription.branchcode <>\"" . C4::Context->userenv->{'branch'} . "\") and subscription.branchcode <>\"\" and subscription.branchcode IS NOT NULL) as cannotedit "; + && C4::Context->userenv->{'branch'} ) + { + my $branches = + GetIndependentGroupModificationRights( { stringify => 1 } ); + + $query .= qq| + , ( ( subscription.branchcode NOT IN ( $branches ) ) AND subscription.branchcode <> '' AND subscription.branchcode IS NOT NULL ) AS cannotedit + |; } $query .= qq| @@ -629,13 +661,16 @@ sub GetSubscriptions { my @results; while ( my $line = $sth->fetchrow_hashref ) { - $line->{'cannotedit'} = - ( C4::Context->preference('IndependentBranches') + $line->{'cannotedit'} = ( + C4::Context->preference('IndependentBranches') && C4::Context->userenv - && !C4:Context->IsSuperLibrarian() + && !C4::Context->IsSuperLibrarian() && C4::Context->userenv->{branch} && $line->{branchcode} - && ( C4::Context->userenv->{branch} ne $line->{branchcode} ) ); + && GetIndependentGroupModificationRights( + { for => $line->{branchcode} } + ) + ); push @results, $line; } return @results; --- a/C4/Suggestions.pm +++ a/C4/Suggestions.pm @@ -32,6 +32,7 @@ use C4::Letters; use List::MoreUtils qw(any); use C4::Dates qw(format_date_in_iso); use base qw(Exporter); +use C4::Branch qw(GetIndependentGroupModificationRights); our $VERSION = 3.07.00.049; our @EXPORT = qw( @@ -137,10 +138,11 @@ sub SearchSuggestion { if ($userenv) { if ( !C4::Context->IsSuperLibrarian() && !$suggestion->{branchcode} ) { - push @sql_params, $$userenv{branch}; - push @query, q{ - AND (suggestions.branchcode=? OR suggestions.branchcode='') - }; + my $branches = + GetIndependentGroupModificationRights( { stringify => 1 } ); + push ( @query, qq{ + AND (suggestions.branchcode IN ( $branches ) OR suggestions.branchcode='') + } ); } } } else { @@ -340,13 +342,20 @@ sub GetSuggestionByStatus { # filter on branch if ( C4::Context->preference("IndependentBranches") || $branchcode ) { - my $userenv = C4::Context->userenv; - if ($userenv) { - unless ( C4::Context->IsSuperLibrarian() ) { - push @sql_params, $userenv->{branch}; - $query .= q{ AND (U1.branchcode = ? OR U1.branchcode ='') }; - } + + if ( C4::Context->userenv + && C4::Context->preference("IndependentBranches") + && !C4::Context->IsSuperLibrarian() ) + { + + my $branches = + GetIndependentGroupModificationRights( { stringify => 1 } ); + + $query .= qq{ + AND (U1.branchcode IN ( $branches ) OR U1.branchcode ='') + }; } + if ($branchcode) { push @sql_params, $branchcode; $query .= q{ AND (U1.branchcode = ? OR U1.branchcode ='') }; @@ -392,12 +401,19 @@ sub CountSuggestion { if ( C4::Context->preference("IndependentBranches") && !C4::Context->IsSuperLibrarian() ) { - my $query = q{ + my $branches = + GetIndependentGroupModificationRights( { stringify => 1 } ); + + my $query = qq{ SELECT count(*) FROM suggestions LEFT JOIN borrowers ON borrowers.borrowernumber=suggestions.suggestedby WHERE STATUS=? - AND (borrowers.branchcode='' OR borrowers.branchcode=?) + AND ( + borrowers.branchcode IN ( $branches ) + OR + borrowers.branchcode=? + ) }; $sth = $dbh->prepare($query); $sth->execute( $status, $userenv->{branch} ); --- a/acqui/basket.pl +++ a/acqui/basket.pl @@ -105,11 +105,17 @@ if ( $op eq 'delete_confirm' ) { $template->param( delete_confirm => 1 ); if ( C4::Context->preference("IndependentBranches") ) { my $userenv = C4::Context->userenv; - unless ( $userenv->{flags} == 1 ) { - my $validtest = ( $basket->{creationdate} eq '' ) - || ( $userenv->{branch} eq $basket->{branch} ) + if ( $userenv->{flags} % 2 != 1 ) { + my $validtest = + ( $basket->{creationdate} eq '' ) || ( $userenv->{branch} eq '' ) - || ( $basket->{branch} eq '' ); + || ( $basket->{branch} eq '' ) + || ( + GetIndependentGroupModificationRights( + { for => $basket->{branch} } + ) + ); + unless ($validtest) { print $query->redirect("../mainpage.pl"); exit 1; @@ -194,11 +200,16 @@ if ( $op eq 'delete_confirm' ) { # get librarian branch... if ( C4::Context->preference("IndependentBranches") ) { my $userenv = C4::Context->userenv; - unless ( $userenv->{flags} == 1 ) { - my $validtest = ( $basket->{creationdate} eq '' ) - || ( $userenv->{branch} eq $basket->{branch} ) + if ( $userenv->{flags} % 2 != 1 ) { + my $validtest = + ( $basket->{creationdate} eq '' ) || ( $userenv->{branch} eq '' ) - || ( $basket->{branch} eq '' ); + || ( $basket->{branch} eq '' ) + || ( + GetIndependentGroupModificationRights( + { for => $basket->{branch} } + ) + ); unless ($validtest) { print $query->redirect("../mainpage.pl"); exit 1; --- a/admin/branches.pl +++ a/admin/branches.pl @@ -260,13 +260,14 @@ sub editbranchform { my $catinfo = GetBranchCategory(); my @categoryloop = (); + my $branch_categories; foreach my $cat (@$catinfo) { my $checked; my $tmp = quotemeta( $cat->{'categorycode'} ); if ( grep { /^$tmp$/ } @{ $data->{'categories'} } ) { $checked = 1; } - push @categoryloop, { + $branch_categories->{ $cat->{categorytype} }->{ $cat->{'categorycode'} } = { categoryname => $cat->{'categoryname'}, categorycode => $cat->{'categorycode'}, categorytype => $cat->{'categorytype'}, @@ -274,7 +275,7 @@ sub editbranchform { checked => $checked, }; } - $innertemplate->param( categoryloop => \@categoryloop ); + $innertemplate->param( branch_categories => $branch_categories ); for my $obsolete ( 'categoryname', 'categorycode', 'codedescription' ) { $innertemplate->param( @@ -283,26 +284,12 @@ sub editbranchform { } sub editcatform { - - # prepares the edit form... my ($categorycode,$innertemplate) = @_; - # warn "cat : $categorycode"; - my @cats; - my $data; if ($categorycode) { - my $data = GetBranchCategory($categorycode); - $data = $data->[0]; $innertemplate->param( - categorycode => $data->{'categorycode'}, - categoryname => $data->{'categoryname'}, - codedescription => $data->{'codedescription'}, - show_in_pulldown => $data->{'show_in_pulldown'}, + category => @{ GetBranchCategory($categorycode) }[0], ); } - for my $ctype (GetCategoryTypes()) { - push @cats , { type => $ctype , selected => ($data->{'categorytype'} and $data->{'categorytype'} eq $ctype) }; - } - $innertemplate->param(categorytype => \@cats); } sub branchinfotable { @@ -373,25 +360,20 @@ sub branchinfotable { push @loop_data, \%row; } - my @branchcategories = (); - for my $ctype ( GetCategoryTypes() ) { - my $catinfo = GetBranchCategories(undef,$ctype); - my @categories; - foreach my $cat (@$catinfo) { - push @categories, { - categoryname => $cat->{'categoryname'}, - categorycode => $cat->{'categorycode'}, - codedescription => $cat->{'codedescription'}, - categorytype => $cat->{'categorytype'}, - }; - } - push @branchcategories, { categorytype => $ctype , $ctype => 1 , catloop => ( @categories ? \@categories : undef) }; - } + + my $catinfo = GetBranchCategories(); + my $categories; + foreach my $cat (@$catinfo) { + $categories->{ $cat->{categorytype} }->{ $cat->{'categorycode'} } = { + categoryname => $cat->{'categoryname'}, + codedescription => $cat->{'codedescription'}, + }; + } + $innertemplate->param( - branches => \@loop_data, - branchcategories => \@branchcategories + branches => \@loop_data, + branch_categories => $categories ); - } sub _branch_to_template { --- a/catalogue/moredetail.pl +++ a/catalogue/moredetail.pl @@ -172,13 +172,20 @@ foreach my $item (@items){ $item->{status_advisory} = 1; } - if (C4::Context->preference("IndependentBranches")) { - #verifying rights + if ( C4::Context->preference("IndependentBranches") ) { + my $userenv = C4::Context->userenv(); - unless (($userenv->{'flags'} == 1) or ($userenv->{'branch'} eq $item->{'homebranch'})) { - $item->{'nomod'}=1; + unless ( + $userenv->{'flags'} % 2 != 1 + || GetIndependentGroupModificationRights( + { for => $item->{'homebranch'} } + ) + ) + { + $item->{'nomod'} = 1; } } + $item->{'homebranchname'} = GetBranchName($item->{'homebranch'}); $item->{'holdingbranchname'} = GetBranchName($item->{'holdingbranch'}); if ($item->{'datedue'}) { --- a/cataloguing/additem.pl +++ a/cataloguing/additem.pl @@ -689,10 +689,19 @@ foreach my $field (@fields) { || $subfieldvalue; } - if (($field->tag eq $branchtagfield) && ($subfieldcode eq $branchtagsubfield) && C4::Context->preference("IndependentBranches")) { + if ( $field->tag eq $branchtagfield + && $subfieldcode eq $branchtagsubfield + && C4::Context->preference("IndependentBranches") ) + { #verifying rights my $userenv = C4::Context->userenv(); - unless (($userenv->{'flags'} == 1) or (($userenv->{'branch'} eq $subfieldvalue))){ + unless ( + $userenv->{'flags'} % 2 == 1 + || GetIndependentGroupModificationRights( + { for => $subfieldvalue } + ) + ) + { $this_row{'nomod'} = 1; } } --- a/circ/circulation-home.pl +++ a/circ/circulation-home.pl @@ -23,6 +23,7 @@ use C4::Auth; use C4::Output; use C4::Context; use C4::Koha; +use C4::Branch qw/GetIndependentGroupModificationRights/; my $query = new CGI; my ($template, $loggedinuser, $cookie, $flags) @@ -38,7 +39,9 @@ my $fa = getframeworkinfo('FA'); $template->param( fast_cataloging => 1 ) if (defined $fa); # Checking if the transfer page needs to be displayed -$template->param( display_transfer => 1 ) if ( ($flags->{'superlibrarian'} == 1) || (C4::Context->preference("IndependentBranches") == 0) ); +$template->param( display_transfer => 1 ) + if ( $flags->{'superlibrarian'} == 1 + || scalar GetIndependentGroupModificationRights() ); output_html_with_http_headers $query, $cookie, $template->output; --- a/circ/pendingreserves.pl +++ a/circ/pendingreserves.pl @@ -32,6 +32,7 @@ use C4::Auth; use C4::Dates qw/format_date format_date_in_iso/; use C4::Debug; use Date::Calc qw/Today Add_Delta_YMD/; +use C4::Branch qw/GetIndependentGroupModificationRights/; my $input = new CGI; my $startdate=$input->param('from'); @@ -152,8 +153,8 @@ if ( $run_report ) { if (C4::Context->preference('IndependentBranches')){ - $strsth .= " AND items.holdingbranch=? "; - push @query_params, C4::Context->userenv->{'branch'}; + my @branches = GetIndependentGroupModificationRights( { stringify => 1 } ); + $strsth .= " AND items.holdingbranch IN ( $branches ) "; } $strsth .= " GROUP BY reserves.biblionumber ORDER BY biblio.title "; --- a/circ/reserveratios.pl +++ a/circ/reserveratios.pl @@ -113,9 +113,9 @@ my $strsth = $sqldatewhere "; -if (C4::Context->preference('IndependentBranches')){ - $strsth .= " AND items.holdingbranch=? "; - push @query_params, C4::Context->userenv->{'branch'}; +if ( C4::Context->preference('IndependentBranches') ) { + my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); + $strsth .= " AND items.holdingbranch IN ( $branches ) "; } $strsth .= " GROUP BY reserves.biblionumber ORDER BY reservecount DESC"; --- a/installer/data/mysql/kohastructure.sql +++ a/installer/data/mysql/kohastructure.sql @@ -340,7 +340,7 @@ CREATE TABLE `branchcategories` ( -- information related to library/branch group `categorycode` varchar(10) NOT NULL default '', -- unique identifier for the library/branch group `categoryname` varchar(32), -- name of the library/branch group `codedescription` mediumtext, -- longer description of the library/branch group - `categorytype` varchar(16), -- says whether this is a search group or a properties group + `categorytype` ENUM( 'searchdomain', 'independent_group' ) NULL DEFAULT NULL, -- says whether this is a search group or an independent group `show_in_pulldown` tinyint(1) NOT NULL DEFAULT '0', -- says this group should be in the opac libararies pulldown if it is enabled PRIMARY KEY (`categorycode`), KEY `show_in_pulldown` (`show_in_pulldown`) --- a/installer/data/mysql/updatedatabase.pl +++ a/installer/data/mysql/updatedatabase.pl @@ -6938,7 +6938,19 @@ $DBversion = "3.13.00.002"; if ( CheckVersion($DBversion) ) { $dbh->do("UPDATE systempreferences SET variable = 'IndependentBranches' WHERE variable = 'IndependantBranches'"); print "Upgrade to $DBversion done (Bug 10080 - Change system pref IndependantBranches to IndependentBranches)\n"; - SetVersion ($DBversion); + SetVersion ($DBversion); +} + +$DBversion = "3.11.00.XXX"; +if ( CheckVersion($DBversion) ) { + $dbh->do(q{ + ALTER TABLE branchcategories + CHANGE categorytype categorytype + ENUM( 'searchdomain', 'independent_group' ) + NULL DEFAULT NULL + }); + print "Upgrade to $DBversion done (Remove branch property groups, add independent groups)\n"; + SetVersion ($DBversion); } $DBversion = '3.13.00.003'; --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt @@ -103,20 +103,46 @@ tinyMCE.init({ - [% IF ( categoryloop ) %]
Group(s): -
    - [% FOREACH categoryloo IN categoryloop %] -
  1. - [% IF ( categoryloo.checked ) %] - - [% ELSE %] - - [% END %] - [% categoryloo.codedescription %] -
  2. - [% END %] -
-
[% END %] + + [% IF ( branch_categories ) %] +
+ Group(s): +
    +
    + Search domain + [% FOREACH bc IN branch_categories.searchdomain %] +
  1. + + [% IF ( bc.value.checked ) %] + + [% ELSE %] + + [% END %] + [% bc.value.codedescription %] +
  2. + [% END %] +
    +
+
    +
    + Independent library groups + [% FOREACH bc IN branch_categories.independent_group %] +
  1. + + [% IF ( bc.value.checked ) %] + + [% ELSE %] + + [% END %] + [% bc.value.codedescription %] +
  2. + [% END %] +
  3. If independent library groups are enabled ( via the IndependentBranches system preference ), a library may access and alter records and patrons from libraries in any group that also library belongs to. A library may belong to multiple library groups.
  4. +
    +
+
+ [% END %] +
  1. @@ -252,90 +278,122 @@ tinyMCE.init({ [% ELSE %]
    There are no libraries defined. Start defining libraries.
    [% END %] - - [% IF ( branchcategories ) %] - [% FOREACH branchcategorie IN branchcategories %] -

    Group(s): [% IF ( branchcategorie.properties ) %]Properties[% ELSE %][% IF ( branchcategorie.searchdomain ) %]Search domain[% END %][% END %]

    - [% IF ( branchcategorie.catloop ) %] - - - - - - - - - - - - [% FOREACH catloo IN branchcategorie.catloop %] - - - - - - - - [% END %] - -
    NameCodeDescription  
    [% catloo.categoryname %][% catloo.categorycode %][% catloo.codedescription %] - Edit - - Delete -
    + +

    Search domain groups

    + [% IF branch_categories.searchdomain %] + + + + + + + + + + + + [% FOREACH bc IN branch_categories.searchdomain %] + + + + + + + + [% END %] + +
    NameCodeDescription  
    [% bc.value.categoryname %][% bc.key %][% bc.value.codedescription %] + Edit + + Delete +
    [% ELSE %] - No [% IF ( branchcategorie.properties ) %]properties[% ELSIF ( branchcategorie.searchdomain ) %]search domain[% END %] defined. Add a new group. + No search domain groups defined. [% END %] - [% END %] - [% ELSE %] -

    No groups defined.

    - [% END %] + Add a new group. + +

    Independent library groups:

    + [% IF branch_categories.independent_group %] + + + + + + + + + + + + [% FOREACH bc IN branch_categories.independent_group %] + + + + + + + + [% END %] + +
    NameCodeDescription  
    [% bc.value.categoryname %][% bc.key %][% bc.value.codedescription %] + Edit + + Delete +
    + [% ELSE %] + No independent library groups defined. + [% END %] + Add a new group. [% END %] [% IF ( editcategory ) %] -

    [% IF ( categorycode ) %]Edit group [% categorycode %][% ELSE %]Add group[% END %]

    +

    [% IF ( category ) %]Edit group [% category.categorycode %][% ELSE %]Add group[% END %]

    - [% IF ( categorycode ) %] - - [% ELSE %] - - [% END %] + [% IF ( category.categorycode ) %] + + [% ELSE %] + + [% END %]
    1. - [% IF ( categorycode ) %] + [% IF ( category.categorycode ) %] Category code: - - [% categorycode %] + + [% category.categorycode %] [% ELSE %] - - + + [% END %]
    2. - +
    3. - +
    4. - [% IF ( show_in_pulldown ) %] + [% IF ( category.show_in_pulldown ) %] [% ELSE %] @@ -343,7 +401,13 @@ tinyMCE.init({
    -
    +
    + [% IF category %] + + [% ELSE %] + + [% END %] +
    [% END %] --- a/members/deletemem.pl +++ a/members/deletemem.pl @@ -67,10 +67,16 @@ if ($bor->{category_type} eq "S") { } if (C4::Context->preference("IndependentBranches")) { - my $userenv = C4::Context->userenv; if ( !C4::Context->IsSuperLibrarian() && $bor->{'branchcode'}){ - unless ($userenv->{branch} eq $bor->{'branchcode'}){ - print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$member&error=CANT_DELETE_OTHERLIBRARY"); + unless ( + GetIndependentGroupModificationRights( + { for => $bor->{'branchcode'} } + ) + ) + { + print $input->redirect( + "/cgi-bin/koha/members/moremember.pl?borrowernumber=$member&error=CANT_DELETE_OTHERLIBRARY" + ); exit; } } --